Skip to content

👷 ci(changelog): self-healing changelog-sync workflow - #180

Merged
konih merged 3 commits into
mainfrom
ci/changelog-sync
Jul 31, 2026
Merged

👷 ci(changelog): self-healing changelog-sync workflow#180
konih merged 3 commits into
mainfrom
ci/changelog-sync

Conversation

@konih

@konih konih commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

What

Ports kollect's changelog-sync.yaml to MKurator. On every push to main it runs task changelog:write and, if CHANGELOG.md drifted, commits the regenerated file back via a GitHub App.

Why

cliff.toml embeds each commit's {{ commit.id }} (SHA). Rebase/squash merges mint a new SHA the pre-merge CHANGELOG.md can't predict, so CHANGELOG.md drifts on main after any user-facing (feat/fix/perf/refactor) merge. Today that's fixed by hand with task changelog:write + a docs(changelog) commit. This automates it. (docs/test/chore/ci/build/style/merge commits are cliff-skipped and never drift.)

A local pre-commit hook cannot do this — the merge SHA doesn't exist until after merge — which is exactly why kollect solves it in CI.

Safety / loop guards

  • paths-ignore: CHANGELOG.md + [skip ci] on the sync commit → no self-retrigger.
  • Sync commit message :memo: docs(changelog): … is cliff-skipped (gitmoji stripped → ^docs skip), so it never re-drifts the changelog.
  • Read-only default token; contents: write scoped to the sync job only.
  • Soft-fails (non-blocking) until activated — not a required check.

Operator activation required (workflow no-ops until then)

  1. Install a GitHub App on platformrelay/MKurator that can push to main (kollect uses org Integration App ID 4389790 — same App can be installed here).
  2. Add that App as a protect-main ruleset bypass actor (bypass_mode: always). github-actions[bot]/GITHUB_TOKEN cannot bypass a ruleset — only a User/Team/Role/Integration can.
  3. Set repo secrets: CHANGELOG_SYNC_GITHUB_APP_ID, CHANGELOG_SYNC_GITHUB_APP_PRIVATE_KEY (App private-key PEM).

Validated locally: yaml.safe_load OK, actionlint clean, action pins match repo conventions (checkout v7.0.1, arduino/setup-task v3.0.0).

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@konih
konih marked this pull request as ready for review July 31, 2026 11:19
konih added 2 commits July 31, 2026 13:25
…kollect)

Regenerates CHANGELOG.md on push to main and commits it back, so rebase/squash SHA drift self-heals instead of needing a manual `task changelog:write`. Soft-fails (non-blocking) until the operator installs the GitHub App + sets CHANGELOG_SYNC_GITHUB_APP_ID/PRIVATE_KEY secrets + adds the App as a protect-main bypass actor.
…ntil activated

The create-github-app-token step hard-fails on an empty app-id, so pre-activation the
workflow would red on every push to main (contradicting the header's 'soft-fails' claim).
Add a tiny `gate` job that resolves CHANGELOG_SYNC_GITHUB_APP_ID presence into an output;
`sync` now runs only when set (needs+if), and is SKIPPED cleanly (green) otherwise. This
lets the workflow merge inert and activate later via secrets, with no red runs on main.
@konih
konih force-pushed the ci/changelog-sync branch from 2073ea4 to 2a07a5a Compare July 31, 2026 11:26
…thubactions:S8264)

SonarCloud flagged the workflow-level `contents: read` (S8264, MAJOR) on the new file,
failing the PR's new-code security rating (C). Move to a deny-all baseline (`permissions: {}`)
with per-job opt-in: `gate` gets none (reads a secret only), `sync` keeps contents:write.
Also tightens OpenSSF Token-Permissions.
@sonarqubecloud

Copy link
Copy Markdown

@konih
konih merged commit 9033e1f into main Jul 31, 2026
21 checks passed
@konih
konih deleted the ci/changelog-sync branch July 31, 2026 11: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.

1 participant