Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 71 additions & 9 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,8 @@ on:
push:
branches:
- main
paths:
- 'pywry/docs/**'
- 'pywry/**/*.py'
- '.github/workflows/docs.yml'
pull_request:
branches: [main, master, develop]
paths:
- 'pywry/docs/**'
- 'pywry/**/*.py'
- '.github/workflows/docs.yml'
branches: [main, develop]
workflow_dispatch:

permissions:
Expand All @@ -24,7 +16,47 @@ concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
detect-doc-impact:
name: Detect docs impact
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
should-build: ${{ steps.detect.outputs.should-build }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Decide whether docs build is required
id: detect
shell: bash
env:
IS_PR: ${{ github.event_name == 'pull_request' }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
set -euo pipefail

if [[ "$IS_PR" != "true" ]]; then
echo "should-build=true" >> "$GITHUB_OUTPUT"
exit 0
fi

git fetch --depth=1 origin "$BASE_SHA"

CHANGED=$(git diff --name-only "$BASE_SHA" HEAD)
DOC_RELATED=$(echo "$CHANGED" | grep -E '^(pywry/docs/|pywry/.*\.py$|\.github/workflows/docs\.yml$)' || true)

if [[ -n "$DOC_RELATED" ]]; then
echo "should-build=true" >> "$GITHUB_OUTPUT"
else
echo "should-build=false" >> "$GITHUB_OUTPUT"
fi

build:
if: github.event_name != 'pull_request' || needs.detect-doc-impact.outputs.should-build == 'true'
needs: detect-doc-impact
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -70,3 +102,33 @@ jobs:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

docs-required:
name: Docs Required
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && always()
needs:
- detect-doc-impact
- build
permissions:
contents: read
steps:
- name: Enforce required docs outcomes
shell: bash
env:
SHOULD_BUILD: ${{ needs.detect-doc-impact.outputs.should-build }}
BUILD_RESULT: ${{ needs.build.result }}
run: |
set -euo pipefail

if [[ "$SHOULD_BUILD" == "false" ]]; then
echo "No docs-impacting changes detected; docs build intentionally skipped."
exit 0
fi

if [[ "$BUILD_RESULT" != "success" ]]; then
echo "Docs build did not succeed (result: $BUILD_RESULT)"
exit 1
fi

echo "Docs validation passed."
61 changes: 59 additions & 2 deletions .github/workflows/publish-pywry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -439,13 +439,21 @@ jobs:
path: pywry/dist/*.whl
retention-days: 30

generate-sbom:
name: Generate release SBOM
needs: [test]
if: ${{ !cancelled() && (needs.test.result == 'success' || needs.test.result == 'skipped') }}
permissions:
contents: read
uses: ./.github/workflows/sbom.yml

# =============================================================================
# Step 3: Merge all artifacts into single dist
# =============================================================================
merge-artifacts:
name: Merge artifacts
needs: [build-linux-x86_64, build-linux-aarch64, build-macos-x86_64, build-macos-arm64, build-windows-amd64, build-windows-arm64]
if: ${{ !cancelled() && needs.build-linux-x86_64.result == 'success' }}
needs: [build-linux-x86_64, build-linux-aarch64, build-macos-x86_64, build-macos-arm64, build-windows-amd64, build-windows-arm64, generate-sbom]
if: ${{ !cancelled() && needs.build-linux-x86_64.result == 'success' && needs.generate-sbom.result == 'success' }}
runs-on: ubuntu-24.04
defaults:
run:
Expand All @@ -469,6 +477,15 @@ jobs:
name: sdist
path: artifacts/sdist/

- name: Download SBOM artifacts
uses: actions/download-artifact@v8.0.1
with:
name: sbom
path: artifacts/sbom/

- name: Ensure output directories exist
run: mkdir -p dist

- name: Consolidate artifacts and fail on duplicate wheel names
shell: bash
run: |
Expand Down Expand Up @@ -522,6 +539,34 @@ jobs:
print(f"Skipped {skipped_identical} identical duplicate wheel artifact(s)")
PY

- name: Add distributed artifacts to merged SBOM
shell: bash
run: |
test -f artifacts/sbom/sbom.cdx.json
docker run --rm \
-v "$PWD:/work" \
-w /work \
cyclonedx/cyclonedx-cli:latest \
add files \
--input-file artifacts/sbom/sbom.cdx.json \
--input-format json \
--output-format json \
--output-file dist/sbom.cdx.json \
--base-path dist \
--include "**/*.whl" "**/*.tar.gz"

- name: Validate release SBOM
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cyclonedx/cyclonedx-cli:latest \
validate \
--input-file dist/sbom.cdx.json \
--input-format json \
--fail-on-errors

- name: Validate wheel archives for duplicate ZIP members
shell: bash
run: |
Expand Down Expand Up @@ -834,6 +879,12 @@ jobs:
contents: write

steps:
- name: Download dist artifacts
uses: actions/download-artifact@v8.0.1
with:
name: dist
path: dist/

- name: Create draft release
uses: softprops/action-gh-release@v2
with:
Expand Down Expand Up @@ -866,8 +917,14 @@ jobs:

- Python 3.10, 3.11, 3.12, 3.13, 3.14

### SBOM

- CycloneDX SBOM is included in this release as `sbom.cdx.json`.

---
*This is a draft release. Wheels are published to PyPI separately.*
files: |
dist/*

# =============================================================================
# Step 6: Publish to PyPI - Trusted Publisher (workflow_dispatch only)
Expand Down
Loading
Loading