ci(qa): recency-aware active-channel matrix via quickchr 0.4.2 (B-2) - #71
Conversation
Replace qa.yaml's hard-coded `[stable, long-term, development]` matrix axis
with a `resolve-matrix` pre-flight job that asks quickchr 0.4.2's public
version/channel API which channels are worth booting: released channels
(stable, long-term) always, plus any pre-release (testing, development) at or
ahead of stable. The four RouterOS channels are not monotonically ordered, so
this closes the `testing` blind spot and auto-adapts as MikroTik promotes
builds — a stale `testing` rc is skipped and picked up automatically once it
leapfrogs stable (quickchr's suffix-aware compareRouterOsVersion now orders
7.24beta2 < 7.24rc1 < 7.24).
Boundary: quickchr owns recency ("what's worth booting"); centrs owns the gate
("what must pass"). The must-pass policy stays in scripts/qa-results-db.ts
(MUST_PASS_CHANNELS / evaluateMustPassGate, mirrored by the matrix
continue-on-error); the new scripts/qa-active-channels.ts only maps the active
set onto the matrix axis. A concrete dispatch channel still pins a single leg;
"all"/push/schedule/the release sweep fan the active set. On a network failure
the script falls back to the released channels (never drops a must-pass leg)
rather than hard-failing.
quickchr is loaded through a runtime specifier (as in test/integration/chr.ts)
so its shipped .ts stays out of centrs's stricter tsc graph. Bumps
@tikoci/quickchr ^0.4.1 → ^0.4.2 (the release that adds the public exports,
`version --json`, and the suffix-aware comparator — quickchr#3).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughReplaces the static RouterOS channel list in ChangesRecency-aware QA channel matrix resolution
Sequence Diagram(s)sequenceDiagram
participant Trigger as Workflow Trigger
participant ResolveMatrix as resolve-matrix job
participant QAScript as qa-active-channels.ts
participant QuickChr as `@tikoci/quickchr`
participant ChrMatrix as chr-matrix job
Trigger->>ResolveMatrix: inputs.routeros_channel (REQUESTED_CHANNEL)
ResolveMatrix->>QAScript: bun run --requested-channel $REQUESTED_CHANNEL
QAScript->>QuickChr: resolveAllVersions()
QuickChr-->>QAScript: Record<Channel, string>
QAScript->>QuickChr: classifyChannels() / selectActiveChannels()
QuickChr-->>QAScript: ChannelStatus[], active Channel[]
QAScript->>QAScript: matrixChannels() merges with MUST_PASS_CHANNELS
QAScript-->>ResolveMatrix: channels=["stable","long-term",...] → GITHUB_OUTPUT
ResolveMatrix-->>ChrMatrix: outputs.channels
ChrMatrix->>ChrMatrix: fromJSON(outputs.channels) → matrix.routeros_channel
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Introduces a recency-aware RouterOS channel selection for the qa.yaml CHR matrix by delegating “what’s worth booting” to @tikoci/quickchr’s channel/version API, while keeping centrs’ must-pass gating policy unchanged.
Changes:
- Adds a new
resolve-matrixpre-flight job inqa.yamlthat computes the active channel set per run and feeds it into the CHR matrix. - Adds
scripts/qa-active-channels.tsplus unit tests to resolve/fallback and summarize the chosen matrix axis. - Bumps
@tikoci/quickchrto^0.4.2and updates docs/changelog to reflect the new QA behavior.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
test/unit/qa-active-channels.test.ts |
Adds unit coverage for channel pinning/fan-out, fallback behavior, and the quickchr-driven recency contract. |
scripts/qa-active-channels.ts |
New resolver script that queries quickchr for the active set, falls back safely, and emits matrix JSON + summary. |
package.json |
Bumps @tikoci/quickchr to ^0.4.2. |
bun.lock |
Lockfile update for @tikoci/quickchr@0.4.2. |
CHANGELOG.md |
Documents the recency-aware QA matrix behavior and boundary between quickchr recency vs centrs gating. |
.github/workflows/qa.yaml |
Adds resolve-matrix job and wires its output into the CHR matrix. |
.github/instructions/ci-test-tiers-and-release-versioning.instructions.md |
Updates CI doctrine to describe the new recency-aware QA matrix resolution. |
| - name: Checkout repository | ||
| uses: actions/checkout@v7 |
| await Bun.write( | ||
| summaryPath, | ||
| activeMatrixSummary(statuses, channels, degraded), | ||
| ); | ||
| } |
| id: matrix | ||
| env: | ||
| REQUESTED_CHANNEL: ${{ inputs.routeros_channel || '' }} | ||
| run: | | ||
| bun run scripts/qa-active-channels.ts \ | ||
| --requested-channel "$REQUESTED_CHANNEL" \ | ||
| --summary "$GITHUB_STEP_SUMMARY" |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
CHANGELOG.md (1)
51-51: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueReplace "exactly" with a less-repetitive alternative.
The word "exactly" is flagged by static analysis as overused; consider alternatives like "precisely" or a rephrasing to "is what a long history captures" (dropping the intensifier).
Suggested rewording
- and the channel→version drift over time is exactly what a long history captures) and fails the run **only when a released + and the channel→version drift over time is what a long history captures) and fails the run **only when a releasedOr:
- and the channel→version drift over time is exactly what a long history captures) and fails the run **only when a released + and the channel→version drift over time is precisely what a long history captures) and fails the run **only when a released🤖 Prompt for 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. In `@CHANGELOG.md` at line 51, In the CHANGELOG.md file, locate the word "exactly" in the phrase "exactly what a long history captures" around line 51. Replace "exactly" with a less repetitive alternative such as "precisely", or alternatively rephrase the sentence to remove the intensifier entirely by changing it to "is what a long history captures" to improve readability and reduce word overuse as flagged by static analysis.Source: Linters/SAST tools
🤖 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/qa.yaml:
- Around line 71-72: In the resolve-matrix job where actions/checkout is used at
line 72, replace the version tag reference (actions/checkout@v7) with an
explicit commit SHA pin to improve supply-chain security. Additionally, since
this job only reads the repository and does not require git credentials for any
modifications, add a with block to disable credential persistence by setting
persist-credentials to false. This reduces unnecessary token exposure while
maintaining the necessary repository access for matrix resolution.
---
Nitpick comments:
In `@CHANGELOG.md`:
- Line 51: In the CHANGELOG.md file, locate the word "exactly" in the phrase
"exactly what a long history captures" around line 51. Replace "exactly" with a
less repetitive alternative such as "precisely", or alternatively rephrase the
sentence to remove the intensifier entirely by changing it to "is what a long
history captures" to improve readability and reduce word overuse as flagged by
static analysis.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 716dfaf5-b6c1-4e3b-8e89-373656495dcd
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
.github/instructions/ci-test-tiers-and-release-versioning.instructions.md.github/workflows/qa.yamlCHANGELOG.mdpackage.jsonscripts/qa-active-channels.tstest/unit/qa-active-channels.test.ts
| - name: Checkout repository | ||
| uses: actions/checkout@v7 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Read the workflow file to understand context
cat -n .github/workflows/qa.yaml | sed -n '65,85p'Repository: tikoci/centrs
Length of output: 1067
🏁 Script executed:
# Also check the resolve-matrix job definition to understand its purpose
cat -n .github/workflows/qa.yaml | sed -n '50,120p'Repository: tikoci/centrs
Length of output: 4098
Pin actions/checkout by SHA and disable credential persistence in resolve-matrix.
Line 72 uses actions/checkout@v7 without a commit SHA pin. This job only reads the repository to resolve the active channel matrix—it doesn't require git credentials and makes no modifications. Pinning by version tag rather than commit SHA weakens supply-chain security, and persisting credentials unnecessarily increases token exposure.
Suggested hardening
- - name: Checkout repository
- uses: actions/checkout@v7
+ - name: Checkout repository
+ uses: actions/checkout@<full-commit-sha-for-v7>
+ with:
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.25.2)
[warning] 71-72: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 72-72: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for 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.
In @.github/workflows/qa.yaml around lines 71 - 72, In the resolve-matrix job
where actions/checkout is used at line 72, replace the version tag reference
(actions/checkout@v7) with an explicit commit SHA pin to improve supply-chain
security. Additionally, since this job only reads the repository and does not
require git credentials for any modifications, add a with block to disable
credential persistence by setting persist-credentials to false. This reduces
unnecessary token exposure while maintaining the necessary repository access for
matrix resolution.
Source: Linters/SAST tools
… summary append - resolve-matrix: pin a single CHR leg when `routeros_version` is set (it overrides recency), instead of fanning the active set and re-booting the same build N times (Copilot). A concrete channel keeps its label; otherwise the leg is labelled `stable`. - qa-active-channels.ts: write the job summary with appendFile, not Bun.write, so it coexists with other summary writers (Copilot, matches chr.ts). - resolve-matrix checkout: `persist-credentials: false` — the job only reads the repo, so it needs no git credentials (CodeRabbit/zizmor). Kept the `@v7` tag: repo convention is tags for first-party actions/*, SHA pins for third-party. - CHANGELOG: drop the flagged "exactly" intensifier (CodeRabbit nitpick). - Tests: cover the version-pinned single-leg path (12 unit tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review dispositionThanks @coderabbitai / Copilot — all items addressed in 9876027:
Note: the failing Unit tests (windows-latest) check is the pre-existing Windows UDP-loopback |
|
Tip For best results, initiate chat on the files or code changes.
The Windows 🐇✨ |
…des #10) (#72) The npm dev-dep group bump dependabot proposed in #10, redone on fresh main (its branch went stale/conflicting after the quickchr 0.4.2 bump in #71): - @biomejs/biome 2.4.14 → 2.5.0 - secretlint + @secretlint/secretlint-rule-preset-recommend ^12.3.1 → ^13.0.2 Ran `biome migrate`: `$schema` → 2.5.0 and the deprecated `recommended: true` linter field → `preset: "recommended"` (the 2.6 removal). No new lint findings; secretlint 13 runs clean. Full recipe green (lint, lint:ci, test, build). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
What
Replaces
qa.yaml's hard-coded[stable, long-term, development]matrix axis with a recency-aware active set, resolved per run by a newresolve-matrixpre-flight job that consumes quickchr 0.4.2's public version/channel API (quickchr#3).The active set = released channels (stable, long-term) always, plus any pre-release (testing, development) at or ahead of stable. Because the four RouterOS channels are not monotonically ordered, this:
testingblind spot (previously only reachable via explicit single-channel dispatch), andtestingrc is skipped and picked up automatically once it leapfrogs stable. This relies on quickchr's now suffix-awarecompareRouterOsVersion(7.24beta2 < 7.24rc1 < 7.24).Boundary (kept)
resolveAllVersions/selectActiveChannels).MUST_PASS_CHANNELS/evaluateMustPassGatestay inscripts/qa-results-db.ts, mirrored by the matrixcontinue-on-error. A pre-release leg can be booted (active) yet never gate a merge.The new
scripts/qa-active-channels.tsonly maps the active set onto the GitHub Actions matrix axis. A concrete dispatch channel still pins a single leg;all/ push / schedule / the release sweep fan the active set. On a network failure it falls back to the released channels (never drops a must-pass leg) instead of hard-failing.quickchr is loaded through a runtime specifier (as in
test/integration/chr.ts) so its shipped.tsstays out of centrs's strictertscgraph.Changes
package.json/bun.lock:@tikoci/quickchr^0.4.1→^0.4.2.scripts/qa-active-channels.ts(new): recency-aware matrix-axis resolver.test/unit/qa-active-channels.test.ts(new): 10 tests — pure mapping, fallback, and the recency contract on fixtures..github/workflows/qa.yaml:resolve-matrixpre-flight job;chr-matrixconsumesneeds.resolve-matrix.outputs.channels..github/instructions/ci-test-tiers-and-release-versioning.instructions.md,CHANGELOG.md: doctrine + Unreleased entry.Verification
bun run lint+bun run lint:ci+bun run test(745 pass) +bun run build— all green locally.qa.yaml -f routeros_channel=allon this branch (recency-aware matrix end-to-end on real CHR). Today's resolved active set =[stable, long-term, development](testing 7.23rc4 correctly excluded, behind stable 7.23.1).Closeout: June-Gloom Track B-2. Consumes quickchr#3.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores