Skip to content

fix(ci): make docs-only PRs mergeable (gate required e2e/smoke per-job)#334

Merged
Andrey Kolkov (androndo) merged 1 commit into
mainfrom
fix/docs-pr-required-checks
Jun 15, 2026
Merged

fix(ci): make docs-only PRs mergeable (gate required e2e/smoke per-job)#334
Andrey Kolkov (androndo) merged 1 commit into
mainfrom
fix/docs-pr-required-checks

Conversation

@lllamnyp

@lllamnyp Timofei Larkin (lllamnyp) commented Jun 12, 2026

Copy link
Copy Markdown
Member

What

Move the path filtering on the e2e and release-smoke workflows off the on: trigger and into a per-job if: gate, so that PRs which touch none of the filtered paths (docs-only PRs in particular) become mergeable.

Closes #333.

Why

Branch protection on main requires six contexts: DCO, verify, image-multiarch, kamaji-datastore, smoke (helm), smoke (manifest). The last three come from workflows that filtered themselves out at the trigger:

  • kamaji-datastore (e2e.yml) — pull_request: paths-ignore: ['**.md', 'docs/**']
  • smoke (helm) / smoke (manifest) (release-smoke.yml) — a pull_request: paths: allowlist

A workflow skipped at the trigger never creates its check context, so branch protection holds the required context in Expected forever and the PR stays BLOCKED. enforce_admins is on, so there is no admin-merge bypass. That is exactly what happened to #331.

How

The fix relies on the distinction GitHub draws between the two ways a check can be absent:

  • skipped at the trigger → context never reported → blocks (the bug);
  • skipped via a job-level if: → context reported as skipped → branch protection treats it as passing.

So each workflow now:

  1. always triggers on pull_request (no path filter);
  2. runs a cheap changes job (dorny/paths-filter, no checkout — it uses the PR API, ~seconds) that detects whether relevant paths changed;
  3. guards the expensive job with if: on that output, plus github.event_name != 'pull_request' so tag pushes / manual dispatch still run unconditionally.

On a docs-only PR the workflows start, the detector runs, and the ~30–45 min kamaji-datastore and the two kind smokes are skipped (zero compute) — but each required context reports skipped → passing. The cost-saving intent of the original filters is preserved; only the deadlock is removed.

The smoke matrix (mode: [manifest, helm]) is kept as-is so the required context names smoke (helm) / smoke (manifest) are unchanged — splitting it into two jobs would rename the contexts and require editing branch protection.

Verification needed before relying on it

Confirm that the smoke matrix job, when skipped via the job-level if:, still emits the per-leg contexts smoke (helm) and smoke (manifest) as skipped rather than a single collapsed smoke. It normally does, but this PR is itself a non-docs change (it edits workflows), so its own run will exercise the jobs rather than skip them — the skip path is best confirmed with a throwaway docs-only PR stacked on this branch, or by watching the next real docs-only PR. If the matrix collapses, the fallback is a sentinel job.

Note on #331

#331 (the docs PR that surfaced this) was unblocked out-of-band by dispatching both workflows against its head ref via workflow_dispatch, which produces the three contexts on the head SHA. That is a one-off; this PR removes the need to repeat it.

Summary by CodeRabbit

  • Chores
    • Updated CI/CD workflows to improve test execution efficiency. Documentation-only pull requests now display test status checks as skipped rather than omitted, while expensive integration tests are skipped when only non-code files are modified.

The `kamaji-datastore`, `smoke (helm)` and `smoke (manifest)` contexts are
required by branch protection, but their workflows filtered themselves out at
the `on:` trigger via path filters. A workflow skipped at the trigger never
reports its check, so the required contexts stayed in "Expected" and blocked
any PR that touched none of the filtered paths (docs-only PRs in particular).
enforce_admins is on, so there was no admin bypass either.

Move the path filtering off the trigger and into a cheap `changes` job
(dorny/paths-filter, no checkout): the workflows now always start, and the
expensive jobs are skipped via a job-level `if:` when nothing relevant
changed. A job skipped via `if:` still reports its check as "skipped", which
branch protection treats as passing — so docs-only PRs are mergeable while the
~30-45 min e2e and the kind smokes still skip (zero compute) on them. The
smoke matrix is kept intact so the required context names are unchanged.

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
@gemini-code-assist

Copy link
Copy Markdown

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Both e2e and release-smoke workflows are refactored to move path filtering from trigger level to job-level conditionals. A new changes job using dorny/paths-filter detects relevant file modifications in seconds, while expensive jobs conditionally run only when needed. This ensures docs-only PRs emit all required status checks as skipped rather than never triggering.

Changes

Workflow Conditional Gating for Docs-Only PR Unblock

Layer / File(s) Summary
E2E workflow conditional gating
.github/workflows/e2e.yml
pull_request trigger is simplified to remove paths-ignore; a changes job detects non-doc code files via dorny/paths-filter, and kamaji-datastore job now runs conditionally only for tag/dispatch events or when changes.outputs.code == 'true'.
Release-smoke workflow conditional gating
.github/workflows/release-smoke.yml
pull_request trigger is simplified to remove paths allowlist; a changes job detects release-relevant files (workflows, charts, api, hack/release-smoke.sh, Docker/Makefile) via dorny/paths-filter, and smoke matrix now runs conditionally only for dispatch events or when changes.outputs.release == 'true'.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A rabbit hops through workflows bright,
Where docs won't block the tests at night,
Cheap checks now gate the costly run,
Skipped checks report—the deadlock's done!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: moving path filters from workflow triggers to per-job gating to fix the docs-only PR branch protection deadlock.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from #333: removes path filters from workflow triggers, adds dorny/paths-filter change-detection jobs, guards expensive jobs with conditional logic, and preserves matrix job contexts for branch protection.
Out of Scope Changes check ✅ Passed All changes are scoped to the two GitHub Actions workflows (e2e.yml and release-smoke.yml) and directly address the requirements in #333 with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/docs-pr-required-checks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/e2e.yml:
- Line 35: The workflow uses an unpinned action reference
`dorny/paths-filter@v3`; replace that tag with a specific commit SHA for the
intended v3 release to mitigate supply-chain risk. Locate the `uses:
dorny/paths-filter@v3` entry in the e2e.yml workflow, find the corresponding v3
commit SHA from the dorny/paths-filter GitHub releases or tags, and update the
line to `uses: dorny/paths-filter@<commit-sha>` ensuring the SHA matches the
v3.x release you want to pin to.
- Around line 48-52: The dependent jobs 'kamaji-datastore' (in e2e.yml) and
'smoke' (in release-smoke.yml) currently declare needs: changes but their
existing if: condition is skipped when the 'changes' job itself is skipped;
update each job's if to guard with always(), e.g. if: ${{ always() &&
(github.event_name != 'pull_request' || needs.changes.outputs.code == 'true')
}}, so the job evaluates the condition even when 'changes' is skipped and will
run correctly for tag pushes and workflow_dispatch; keep the needs: changes
declaration and only change the if expression to include always().
- Around line 25-45: Add a minimal permissions block to the "changes" job so it
doesn't run with default repo permissions; under the job named changes (the job
that defines outputs from the dorny/paths-filter step with id filter) add e.g.
permissions: pull-requests: read (and any other specific read-only scopes you
need) to limit access to read-only PR metadata via the GitHub API.

In @.github/workflows/release-smoke.yml:
- Around line 27-51: In the "changes" job (the job block labeled changes that
runs the dorny/paths-filter step with id "filter"), replace the default
repository permissions by adding a minimal permissions block that grants only
what is needed to read PR metadata (e.g., set pull-requests: read and contents:
none) so the job has explicit read-only access and no write permissions; ensure
the permissions block is placed at the same indentation level as runs-on and
steps within the "changes" job.
- Line 35: The workflow uses an unpinned action reference
"dorny/paths-filter@v3" which must be replaced with a commit SHA to mitigate
supply-chain risks; update the "uses: dorny/paths-filter@v3" line to "uses:
dorny/paths-filter@<commit-sha>" where <commit-sha> is the full SHA of the v3
release commit (verify the SHA matches the intended v3.x tag on the
dorny/paths-filter repository before committing).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aea80e42-6775-4d26-9aba-4a54053ee804

📥 Commits

Reviewing files that changed from the base of the PR and between 7d20b1a and 9ea07e4.

📒 Files selected for processing (2)
  • .github/workflows/e2e.yml
  • .github/workflows/release-smoke.yml

Comment thread .github/workflows/e2e.yml
Comment thread .github/workflows/e2e.yml
Comment thread .github/workflows/e2e.yml
Comment thread .github/workflows/release-smoke.yml
Comment thread .github/workflows/release-smoke.yml
@androndo Andrey Kolkov (androndo) merged commit 4248ade into main Jun 15, 2026
10 checks passed
@androndo Andrey Kolkov (androndo) deleted the fix/docs-pr-required-checks branch June 15, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs-only PRs are unmergeable: required checks skipped at trigger never report

2 participants