From 7ab20b07c0fdbe64e0374466f533e098b99d35e7 Mon Sep 17 00:00:00 2001 From: pasta Date: Sun, 4 Oct 2026 22:17:52 -0500 Subject: [PATCH] ci: skip builds for documentation-only changes Pull requests that only change Markdown files outside src/ currently run the full depends, build, sanitizer and functional-test matrix even though they cannot affect the compiled software. Classify the pull request's changed paths (including the previous name of renamed files) in the check-skip job and gate the full build container and the depends-source cache on the result, so every depends, build and test job skips transitively. The slim container and lint job still run. Markdown under src/ (for example the dist-listed src/crypto/ctaes/README.md) still triggers the full matrix. Pushes always run the full matrix, and an API failure or empty file list fails open. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/build.yml | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a8332aa110e9..3cd658e55b51 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ permissions: actions: read contents: read packages: write + pull-requests: read concurrency: group: | @@ -25,6 +26,7 @@ jobs: runs-on: ${{ vars.RUNNER_CHECK_SKIP || 'ubuntu-24.04-arm' }} outputs: skip: ${{ steps.skip-check.outputs.skip }} + run-build-tests: ${{ steps.classify-changes.outputs.run-build-tests }} runner-amd64: ${{ steps.select-runner.outputs.runner_amd64 }} runner-arm64: ${{ steps.select-runner.outputs.runner_arm64 }} runner-lint: ${{ steps.select-runner.outputs.runner_lint }} @@ -48,6 +50,28 @@ jobs: echo "skip=false" >> $GITHUB_OUTPUT fi + - name: Classify changed paths + id: classify-changes + if: ${{ steps.skip-check.outputs.skip == 'false' }} + env: + EVENT_NAME: ${{ github.event_name }} + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPOSITORY: ${{ github.repository }} + run: | + # Pull requests that only touch Markdown outside src/ skip the full + # build and test matrix. Any API failure leaves the full matrix on. + RUN=true + if [[ "$EVENT_NAME" == "pull_request_target" ]]; then + FILES="$(gh api --paginate "repos/$REPOSITORY/pulls/$PR_NUMBER/files" \ + --jq '.[] | .filename, (.previous_filename // empty)')" || FILES="" + if [[ -n "$FILES" ]] && ! grep -qvE '\.md$' <<< "$FILES" && ! grep -qE '^src/' <<< "$FILES"; then + RUN=false + fi + fi + echo "Full build and test matrix: $RUN" + echo "run-build-tests=$RUN" >> "$GITHUB_OUTPUT" + - name: Checkout code if: ${{ steps.skip-check.outputs.skip == 'false' }} uses: actions/checkout@v6 @@ -91,7 +115,9 @@ jobs: cache-sources: name: Cache depends sources needs: [check-skip] - if: ${{ needs.check-skip.outputs.skip == 'false' }} + if: | + needs.check-skip.outputs.skip == 'false' && + needs.check-skip.outputs.run-build-tests == 'true' uses: ./.github/workflows/cache-depends-sources.yml with: runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }} @@ -99,7 +125,9 @@ jobs: container: name: Build container needs: [check-skip] - if: ${{ needs.check-skip.outputs.skip == 'false' }} + if: | + needs.check-skip.outputs.skip == 'false' && + needs.check-skip.outputs.run-build-tests == 'true' uses: ./.github/workflows/build-container.yml with: context: ./contrib/containers/ci