Skip to content

ci: skip Build & Test e2e for docs/workflow-only PRs#101

Merged
ricogu merged 9 commits into
mainfrom
ci/skip-build-and-test-on-non-code-changes
Jun 3, 2026
Merged

ci: skip Build & Test e2e for docs/workflow-only PRs#101
ricogu merged 9 commits into
mainfrom
ci/skip-build-and-test-on-non-code-changes

Conversation

@ricogu
Copy link
Copy Markdown
Contributor

@ricogu ricogu commented May 23, 2026

fix #51

Summary

Stop running the full ~5-minute Build & Test e2e suite on PRs that only change documentation, license metadata, or unrelated workflow files (CodeQL, Dependabot, Renovate, Codeowners). The repository ruleset still requires the all-tests-passed commit status to merge, so a paired skip workflow reports it directly for the ignored paths.

PR #99 is a concrete example of where this would have helped: 4 commits to .github/workflows/codeql.yml triggered 4 full e2e runs, the cancel-in-progress concurrency caused a ~5-minute pending stretch on the latest commit, and none of those runs could possibly have caught a behavior regression — the action runtime wasn't touched.

Why a skip workflow at all

GitHub's required status check rule (required_status_checkscontext: all-tests-passed) treats a workflow that doesn't run as not satisfied rather than skipped/passed. Without a paired skip workflow, adding paths-ignore to build-and-test.yml would leave docs-only PRs permanently BLOCKED. The pattern below is GitHub's documented solution for required checks with path filters.

Changes

Modified

  • .github/workflows/build-and-test.yml — added paths-ignore: listing files that cannot affect the action runtime.

Added

  • .github/workflows/build-and-test-skip.yml — runs on the inverse path set (paths: matches what build-and-test.yml's paths-ignore: excludes) and reports all-tests-passed = success via the same myrotvorets/set-commit-status-action@master call the real workflow uses. Both workflows share name: Build & Test so the status context is identical.

Path list

Files that cannot break the action runtime (skip e2e):

**/*.md
LICENSE
LICENSES/**
REUSE.toml
renovate.json
.gitignore
.github/workflows/codeql.yml
.github/codeql/**
.github/dependabot.yml
.github/CODEOWNERS

Notably not in the list (they still run e2e):

  • .github/workflows/build-and-test.yml — changes to the test workflow itself must be exercised end-to-end.
  • .github/workflows/release.yml — release logic uses the same composite actions.
  • .github/actions/** — the action source itself.
  • action.yml — composite action entry point.
  • test-resources/** — e2e test fixtures.
  • package.json, tsconfig.json, jest.config.* — change the build/test toolchain.

Behavior matrix

PR changes build-and-test.yml (real) build-and-test-skip.yml (paired) Final all-tests-passed status
Only docs/workflow-metadata Skipped (paths-ignore) Runs → success success (from skip)
Only action source Runs full e2e Skipped (paths) success/failure (from real)
Mixed (docs + code) Runs full e2e Also runs → success Real is last write — wins

The mixed case is benign because the skip workflow finishes in ~30s while the real run takes ~3min, so the real result is always the last write to the commit status. (Even in the unlikely race where skip wrote last, GitHub recomputes mergeability on each status update — the real workflow's eventual write would still settle the merge gate.)

Compatibility & impact

Breaking changes

  • None.

CI impact

Status-context identity

Confirmed: the ruleset rule is required_status_checks: [{context: "all-tests-passed", integration_id: 15368}]integration_id: 15368 is the GitHub Actions app, and both workflows post via set-commit-status-action using ${{ secrets.GITHUB_TOKEN }}, so the status integration_id matches.

Verification

After merge, expected behavior on a docs-only PR:

  • Build & Test / build-dist, test-* checks: not present (skipped).
  • Build & Test / all-tests-passed check: present and green (from skip workflow).
  • Commit status all-tests-passed: success.
  • Ruleset gate: satisfied.

On a source-only PR, behavior is unchanged.

Checklist

  • paths-ignore covers only files that demonstrably cannot affect runtime
  • build-and-test.yml itself is excluded from the ignore list (test changes still run)
  • Paired skip workflow shares name: Build & Test for status-context identity
  • Skip workflow uses the same set-commit-status-action and context name as the real one
  • Mixed-path race condition analyzed and documented as benign
  • After merge, verify on a doc-only follow-up PR that all-tests-passed is reported by the skip workflow

…green

Adds a path filter to .github/workflows/build-and-test.yml so PRs that
only touch documentation, license metadata, or workflow files unrelated
to the action runtime no longer spend ~5 minutes running the full e2e
matrix (build-dist + test-python/npm/maven/version-file).

The repository ruleset requires the `all-tests-passed` commit status,
so a paired skip workflow (.github/workflows/build-and-test-skip.yml)
runs on the inverse path set and reports `all-tests-passed = success`
directly. Both workflows share `name: Build & Test` for status-context
identity.

paths-ignore covers (inverse for the skip workflow):
- **/*.md
- LICENSE, LICENSES/**, REUSE.toml
- renovate.json, .gitignore
- .github/workflows/codeql.yml
- .github/codeql/**
- .github/dependabot.yml, .github/CODEOWNERS

build-and-test.yml itself is intentionally NOT in the list \u2014 changes to
the test workflow logic must run the full e2e suite.
Comment thread .github/workflows/build-and-test-skip.yml Fixed
CodeQL's `actions/unpinned-tag` rule (security-and-quality suite)
flagged the `@master` ref as a supply-chain risk: a third-party action's
master branch can be force-pushed by its maintainer at any time, and any
malicious version would run in our CI with our GITHUB_TOKEN.

Pin to the v2.0.1 release commit (3730c0a3) in both:

- .github/workflows/build-and-test.yml (existing tech debt; same finding
  was waiting to surface as soon as the new CodeQL workflow ran on any
  non-skipped PR)
- .github/workflows/build-and-test-skip.yml (the new file in this PR)

The trailing `# v2.0.1` comment is renovate/dependabot-friendly so
future updates can still be automated against the upstream tag.
@ricogu ricogu requested a review from mdanish98 May 23, 2026 20:23
@ricogu
Copy link
Copy Markdown
Contributor Author

ricogu commented May 23, 2026

@mdanish98 . please kindly help do a review, thanks!

@ricogu ricogu enabled auto-merge (squash) May 26, 2026 09:10
@ricogu ricogu disabled auto-merge May 26, 2026 10:49
@ricogu ricogu enabled auto-merge (squash) May 26, 2026 10:49
mdanish98
mdanish98 previously approved these changes Jun 3, 2026
Copy link
Copy Markdown
Member

@mdanish98 mdanish98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@ricogu ricogu merged commit 8926506 into main Jun 3, 2026
15 checks passed
@ricogu ricogu deleted the ci/skip-build-and-test-on-non-code-changes branch June 3, 2026 08:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build-and-test workflow does not run reliably for Dependabot PRs

3 participants