Skip to content

fix(ci): stop dropping propagation PRs on sensitive-path matches, auto-merge safe ones - #1282

Merged
Wikid82 merged 4 commits into
developmentfrom
fix/ci-propagation-chain
Aug 25, 2026
Merged

fix(ci): stop dropping propagation PRs on sensitive-path matches, auto-merge safe ones#1282
Wikid82 merged 4 commits into
developmentfrom
fix/ci-propagation-chain

Conversation

@Wikid82

@Wikid82 Wikid82 commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the real failure mode behind PR #1261 getting silently dropped: propagate-changes.yml's sensitive-path gate blocked the entire auto-PR because it was bundled with a handful of unrelated sensitive files, and the resulting draft PR had no path to merging itself even when clean. Two fixes, sliced into separate commits per this repo's commit-slicing convention, plus a CI comment/docs cleanup and an ARCHITECTURE.md update:

  1. fix(ci): stop blocking safe propagation PRs on unrelated sensitive-path matches — the sensitive_paths gate (.github/propagate-config.yml) was all-or-nothing across the whole diff: one matched file skipped PR creation entirely, even when bundled with otherwise-safe CI/dependency changes. This is exactly what happened to PR Propagate changes from main into development #1261 — 4 unrelated .github/skills/ files blocked the auto-PR, a human had to manually recreate it, and that manual PR was later closed unmerged. Now a sensitive-path match still creates the PR, but prepends a ⚠️ warning section to the body listing the matched files and asking for manual review. PR creation is only skipped for the pre-existing "not ahead of base" / "PR already open" cases.

  2. fix(ci): auto-merge safe propagation PRs via native GitHub auto-merge — PRs with no sensitive-path matches are now opened ready-for-review (draft: false) instead of draft, and the workflow attempts to enable GitHub's native auto-merge (enablePullRequestAutoMerge, mergeMethod: MERGE — this repo only allows merge commits, matching the existing nightly -> main weekly promotion policy). PRs with sensitive-path matches stay draft and don't get auto-merge. The mutation call is wrapped in try/catch and only logs a warning on failure; it never fails the job.

  3. fix(ci): document that development->nightly propagation is handled by cron, not this workflow — an earlier version of this PR added a new PR-based development -> nightly leg to propagate-changes.yml, on the assumption that nothing handled that hop. That assumption was wrong: .github/workflows/nightly-build.yml already has a sync-development-to-nightly job that runs daily via cron (09:00 UTC) and reliably fast-forwards (or force-resets) nightly to match development — confirmed via gh run list --workflow=nightly-build.yml showing successful daily runs for the past two weeks. Adding a second, PR-based leg for the same hop didn't just duplicate that mechanism, it raced it: if the new leg opened a "development -> nightly" PR and the daily cron fired before it merged, the cron's force-push would collapse that PR's diff to zero, leaving a dangling, unmergeable PR. That leg has been dropped; the else if (currentBranch === 'development') branch now logs clearly that this hop is handled elsewhere instead of silently no-op'ing or (as in the earlier version of this PR) racing the cron. main -> development and its loop-prevention pattern are unchanged.

  4. docs: document the branch promotion chain and its three distinct mechanisms — added a "Branch Promotion Chain" section to ARCHITECTURE.md (previously the Git Workflow section didn't even list development/nightly as branches) describing all three hops accurately: main -> development is PR-based via propagate-changes.yml (draft+annotated if sensitive paths are touched, auto-merge-enabled otherwise); development -> nightly is the separate, pre-existing daily cron in nightly-build.yml; nightly -> main is the existing weekly promotion PR (weekly-nightly-promotion.yml, unrelated to this fix, always merged manually with "Create a merge commit"). These are three distinct mechanisms with different trust/automation levels, not one uniform pipeline.

Also flagging: allow_auto_merge repo setting

I confirmed via gh api repos/Wikid82/Charon --jq '{allow_auto_merge}' that this repo currently has allow_auto_merge: false at the repo-settings level. The enablePullRequestAutoMerge mutation added in commit 2 will fail (as a caught, non-fatal warning) until a repo admin turns on Settings > General > Pull Requests > Allow auto-merge. I did not flip this myself — it's called out as a deliberate, separate repo-administration decision in both the code comments and here. The code is correct and inert until that setting is enabled.

Validation

  • lefthook run pre-commit (including actionlint and semgrep) passed clean after every commit.
  • Workflow-only change — no Go/TS code, no new API surface — so the full backend/frontend Definition-of-Done (coverage, Playwright) does not apply here.

References

  • PR Weekly: Promote nightly to main (2026-08-24) #1281 (nightly -> main weekly promotion PR with a 27-file conflict pileup — already resolved separately)
  • PR Propagate changes from main into development #1261 ("Propagate changes from main into development", manually opened after the sensitive-path gate blocked the auto-PR, later closed unmerged) — the concrete failure mode fixes 1 and 2 target
  • gh run list --repo Wikid82/Charon --workflow=nightly-build.yml — confirms sync-development-to-nightly has run successfully daily for the past two weeks, which is why this PR does not add a second development -> nightly mechanism

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

✅ Supply Chain Verification Results

PASSED

📦 SBOM Summary

  • Components: 1753

🔍 Vulnerability Scan

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 5
🟢 Low 2
Total 11

📎 Artifacts

  • SBOM (CycloneDX JSON) and Grype results available in workflow artifacts

Generated by Supply Chain Verification workflow • View Details

… cron, not this workflow

An earlier version of this change added a new PR-based development ->
nightly leg to propagate-changes.yml, on the assumption that nothing
handled that hop. That assumption was wrong: nightly-build.yml already
has a `sync-development-to-nightly` job that runs daily via cron
(09:00 UTC) and reliably fast-forwards (or force-resets) `nightly` to
match `development` — confirmed via two straight weeks of successful
scheduled runs.

Adding a second, PR-based leg for the same hop didn't just duplicate
that mechanism, it raced it: if the new leg opened a "development ->
nightly" PR and the daily cron fired before it merged, the cron's
force-push would collapse that PR's diff to zero, leaving a dangling,
unmergeable PR behind.

Drop the PR-based leg entirely and replace the no-op with a comment
and log line that point at the cron job, so a future reader isn't
left wondering why pushes to `development` don't do anything here.
The `main` -> `development` leg and its loop-prevention pattern are
unchanged.
…th matches

The sensitive-path gate in propagate-changes.yml was all-or-nothing
across the whole diff: a single file matching `sensitive_paths` (in
.github/propagate-config.yml) skipped PR creation for the entire
propagation, even when it was bundled with otherwise-safe changes like
CI or dependency fixes. This already caused a dropped propagation: PR
#1261 needed a human to notice and manually recreate it after 4
unrelated .github/skills/ files blocked the auto-PR, and that manual
PR was later closed unmerged.

Instead of skipping PR creation on a sensitive-path match, still
create the (draft) PR but prepend a warning section to the body
listing the specific matched files and asking for manual review before
merging. PR creation is now only skipped for the pre-existing "not
ahead of base" and "PR already open" cases — never for a sensitive-path
match.
Previously every auto-propagation PR was opened as a draft with no
path to merging itself, so even the "clean" (no sensitive-path
matches) legs of the chain still needed a human to notice an open
draft PR and manually mark it ready + merge it. That manual step is
exactly the kind of gap that let propagation PRs (e.g. #1261) sit
unmerged.

For PRs with no sensitive-file matches, open them ready-for-review
(draft: false) and attempt to enable GitHub's native auto-merge via
the enablePullRequestAutoMerge GraphQL mutation, requesting
mergeMethod: MERGE — this repo only allows merge commits
(allow_squash_merge/allow_rebase_merge are false), matching the
existing nightly -> main weekly promotion policy of always using
"Create a merge commit". PRs with sensitive-path matches (see previous
commit) stay draft and do not get auto-merge, per Fix 2's intent of
flagging them for manual review rather than merging automatically.

The mutation call is wrapped in try/catch and only logs a warning on
failure — it never fails the workflow job. This matters today because
the repo-level "Allow auto-merge" setting is currently OFF
(confirmed via `gh api repos/Wikid82/Charon --jq '{allow_auto_merge}'`),
so the mutation will reliably fail until a repo admin turns it on
(Settings > General > Pull Requests > Allow auto-merge) — a deliberate,
separate decision, not something this change attempts itself. The code
is correct and inert until that setting is flipped.
…anisms

ARCHITECTURE.md's Git Workflow section didn't mention development or
nightly at all, and had no description of how changes flow between the
three long-lived branches. Add a "Branch Promotion Chain" subsection
explaining all three hops:

- main -> development: PR-based via propagate-changes.yml, including
  the sensitive-path annotation and auto-merge behavior from the
  preceding two commits.
- development -> nightly: a separate, pre-existing daily cron job
  (sync-development-to-nightly in nightly-build.yml) that fast-forwards
  or force-resets nightly to development's tip, bypassing PRs entirely.
- nightly -> main: the existing weekly promotion PR
  (weekly-nightly-promotion.yml), unrelated to either of the above,
  always merged manually with "Create a merge commit".

Explicitly call out that these are three distinct mechanisms with
different trust/automation levels, not one uniform PR pipeline — and
note why development -> nightly stays a single mechanism (the cron)
rather than gaining a redundant PR-based leg: see the preceding commit.
@Wikid82 Wikid82 changed the title fix(ci): close the development -> nightly propagation gap fix(ci): stop dropping propagation PRs on sensitive-path matches, auto-merge safe ones Aug 24, 2026
@Wikid82
Wikid82 force-pushed the fix/ci-propagation-chain branch from d31f81f to 35d2fd1 Compare August 24, 2026 21:55
@Wikid82
Wikid82 marked this pull request as ready for review August 25, 2026 00:19
@Wikid82
Wikid82 merged commit 0cd9102 into development Aug 25, 2026
30 checks passed
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.

2 participants