diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d2dc28..7cc09e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,8 +15,35 @@ permissions: contents: read jobs: + changes: + name: Detect changed paths + runs-on: ubuntu-latest + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Filter changed paths + id: filter + uses: dorny/paths-filter@v3 + with: + # "code" = anything that isn't docs-site-only. Keep this in sync + # with the equivalent filter in security.yml. + filters: | + code: + - '**' + - '!docs/**' + - '!mkdocs.yml' + - '!overrides/**' + - '!README.md' + checks: name: Python ${{ matrix.python-version }} + needs: changes + # Skip the full Python matrix for docs-site-only changes; a manual + # workflow_dispatch always runs it. + if: needs.changes.outputs.code == 'true' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest strategy: fail-fast: false @@ -74,21 +101,53 @@ jobs: - name: Build verification run: uv build + docs: + name: Build documentation + runs-on: ubuntu-latest + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install dependencies + run: uv sync --locked + + - name: Build MkDocs site + run: uv run mkdocs build --strict + ci-required: name: CI Required - needs: + needs: + - changes - checks + - docs if: ${{ always() }} runs-on: ubuntu-latest steps: - - name: Verify CI matrix + - name: Verify CI results run: | - echo "CI matrix result: ${{ needs.checks.result }}" + echo "Docs-site-only change: ${{ needs.changes.outputs.code == 'false' }}" + echo "Python matrix result: ${{ needs.checks.result }}" + echo "Docs build result: ${{ needs.docs.result }}" + + if [[ "${{ needs.docs.result }}" != "success" ]]; then + echo "Documentation build failed." + exit 1 + fi - if [[ "${{ needs.checks.result }}" != "success" ]]; then - echo "CI matrix did not succeed" + if [[ "${{ needs.changes.outputs.code }}" == "true" && "${{ needs.checks.result }}" != "success" ]]; then + echo "Python matrix did not succeed." exit 1 fi - echo "All CI checks passed." \ No newline at end of file + echo "All CI checks passed." diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index ac56873..a2f4def 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -14,8 +14,38 @@ permissions: actions: read jobs: + changes: + name: Detect changed paths + runs-on: ubuntu-latest + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Check out source + uses: actions/checkout@v4 + + - name: Filter changed paths + id: filter + # On schedule there's no diff to filter against; the action reports + # `false` for every filter in that case, which the codeql/audit + # `if:` below explicitly overrides for github.event_name == 'schedule'. + uses: dorny/paths-filter@v3 + with: + # "code" = anything that isn't docs-site-only. Keep this in sync + # with the equivalent filter in ci.yml. + filters: | + code: + - '**' + - '!docs/**' + - '!mkdocs.yml' + - '!overrides/**' + - '!README.md' + codeql: name: CodeQL + needs: changes + # Skip for docs-site-only changes; the weekly schedule and manual + # dispatch always run it. + if: needs.changes.outputs.code == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest strategy: fail-fast: false @@ -38,6 +68,8 @@ jobs: dependency-audit: name: Dependency audit + needs: changes + if: needs.changes.outputs.code == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: @@ -72,6 +104,7 @@ jobs: security-required: name: Security Required needs: + - changes - codeql - dependency-audit - dependency-review @@ -82,22 +115,26 @@ jobs: steps: - name: Verify security checks env: + CODE_CHANGED: ${{ needs.changes.outputs.code }} CODEQL_RESULT: ${{ needs.codeql.result }} AUDIT_RESULT: ${{ needs.dependency-audit.result }} REVIEW_RESULT: ${{ needs.dependency-review.result }} run: | + echo "Docs-site-only change: $([[ "$CODE_CHANGED" == "false" ]] && echo true || echo false)" echo "CodeQL: $CODEQL_RESULT" echo "Dependency audit: $AUDIT_RESULT" echo "Dependency review: $REVIEW_RESULT" - if [[ "$CODEQL_RESULT" != "success" ]]; then - echo "CodeQL failed or did not complete successfully." - exit 1 - fi + if [[ "$CODE_CHANGED" == "true" || "$GITHUB_EVENT_NAME" == "schedule" || "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then + if [[ "$CODEQL_RESULT" != "success" ]]; then + echo "CodeQL failed or did not complete successfully." + exit 1 + fi - if [[ "$AUDIT_RESULT" != "success" ]]; then - echo "Dependency audit failed or did not complete successfully." - exit 1 + if [[ "$AUDIT_RESULT" != "success" ]]; then + echo "Dependency audit failed or did not complete successfully." + exit 1 + fi fi if [[ "$REVIEW_RESULT" != "success" && "$REVIEW_RESULT" != "skipped" ]]; then @@ -105,4 +142,4 @@ jobs: exit 1 fi - echo "All required security checks passed." \ No newline at end of file + echo "All required security checks passed."