From 123a5ac706474b35259a2ff02c9170bd915098fa Mon Sep 17 00:00:00 2001 From: Jeroen Date: Mon, 24 Aug 2026 11:37:56 +0200 Subject: [PATCH 1/3] Allow CodeQL to run on demand The workflow only had push, pull_request and schedule triggers, so there was no way to confirm a scanning config change was green without pushing a commit to provoke one. That gap is why the switch away from default setup was merged on a stale red check instead of a fresh green one. --- .github/workflows/codeql.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dd474e2..9358c02 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -16,6 +16,9 @@ on: # Weekly, Tuesday 05:44 UTC. Off the top of the hour and off the Security # workflow's Monday slot. - cron: '44 5 * * 2' + # On demand, so a scanning change can be verified green without pushing a + # commit to trigger it. + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 754d1f02ba740dd181541761cfdb00c3c499fca3 Mon Sep 17 00:00:00 2001 From: Jeroen Date: Mon, 24 Aug 2026 11:47:03 +0200 Subject: [PATCH 2/3] Protect master and write down the merging rules PR #23 merged while a CodeQL check was red. The red job was the old default setup running autobuild, racing the API call that disabled it, and our own manual-build job passed on the same commit. The conclusion was right but the practice was wrong, and nothing stopped the merge: master had no protection at all. Master now requires lint, test and both CodeQL analyze jobs, must be up to date before merge, and rejects force-pushes and deletion. Administrators can still override for emergencies. Two rules protection cannot enforce go in CONTRIBUTING: never merge on a red check even when it looks stale, and confirm a fresh green run after changing CI or scanning config, because those changes take minutes to take effect on the GitHub side. CI gains a workflow_dispatch trigger so it can be verified on demand, as Security, Integration and now CodeQL already could. Release stays tag driven. --- .github/workflows/ci.yml | 3 +++ CONTRIBUTING.md | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2461592..6cc7a67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,9 @@ on: pull_request: branches: - master + # On demand, so a CI change can be verified green without pushing a commit + # to trigger it. + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c671a97..611cdf4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,6 +81,25 @@ Follow the patterns documented in `AGENTS.md` and `documentation/architecture.md - The PR description must include a clear summary, a test plan, and any breaking change notes. - Do not push generated artefacts (`out/`, `bin/`, `.env`, IDE files). The `.gitignore` covers these. +## Merging + +`master` is protected. `lint`, `test`, `Analyze (go, manual)` and `Analyze (actions, none)` +must pass before a PR can merge, and the branch must be up to date with `master` first. +Force-pushing and deleting `master` are blocked. Administrators can override, for +emergencies only. + +Two rules the protection cannot enforce on its own: + +- Never merge on a red check, including one you believe is stale. A check that is + genuinely obsolete still has to be re-run green before the merge. If it cannot + re-run, push a commit so the checks re-evaluate on a fresh SHA. +- After changing CI or code scanning configuration, confirm a fresh fully green run + before merging the change that depends on it. Configuration changes on the GitHub + side can take minutes to take effect, so a run started near the change may still + reflect the old setup. CI, Security, Integration and CodeQL all carry a + `workflow_dispatch` trigger for exactly this check. Release is driven by its tag + and is deliberately not dispatchable. + ## Reporting bugs Open an issue with: From 3ed82e270981bd7e221ac1fd6d5fdae7f7c13f33 Mon Sep 17 00:00:00 2001 From: Jeroen Date: Mon, 24 Aug 2026 12:02:03 +0200 Subject: [PATCH 3/3] Note that both CodeQL default setups are replaced Settings has two independent default setups, Code security and Code quality, and each spawns its own CodeQL run with its own pinned Go toolchain. Both failed on Go 1.27 with the same autobuild error, which made it look like one disable had not taken effect. Record which runs come from where so the next person does not spend the same time on it. --- .github/workflows/codeql.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9358c02..5c11f1d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,9 +1,17 @@ name: CodeQL -# Replaces CodeQL default setup. Default setup pins its own Go toolchain and -# runs the extractor with GOTOOLCHAIN=local, so it cannot build a module whose -# go directive is newer than the bundle. Driving it here lets setup-go install -# the toolchain go.mod asks for, so a Go bump never blocks code scanning. +# Replaces CodeQL default setup. Both of them: Settings has a Code security +# default setup and a separate Code quality default setup, and each one spawns +# its own CodeQL run. Both are now off, and both are replaced by this workflow. +# +# They pin their own Go toolchain and run the extractor with GOTOOLCHAIN=local, +# so neither can build a module whose go directive is newer than the bundle. +# Driving CodeQL here lets setup-go install the toolchain go.mod asks for, so a +# Go bump never blocks code scanning. +# +# Their runs are titled "Code Quality: ..." and "PR #N" in the Actions list and +# have event "dynamic". If one reappears, a default setup got re-enabled in +# Settings; neither is fully manageable over the REST API. on: push: