Repository navigation
Description
Summary
Umbrella tracking issue for the remaining CI / build / release / E2E-testing automation work. It is a companion to the individual epics (#2937, #2677, #2499, #2847, #2653, #2585, #3238, #4642) and gives one place to see what is done, what is ready, and what is externally blocked. Action IDs (A1-A20) are stable references. A2 was split into A2a and A2b on 2026-10-20.
Update 2026-10-20
#4861 merged on 2026-10-20 (d1d4e92). A release cut from a tree that has hack/sign-release-assets.sh now carries cozystack-source-sbom.spdx.json (SPDX 2.3 of the source tree and the cozypkg binaries), cozystack-checksums.txt and a keyless Sigstore bundle over the checksums, and docs/release.md shows how to verify a download. That is the release-asset half of A2, now A2a. It is not an SBOM of what runs, the container images and the Talos images are not in it. Those are A2b, still open, and what it needs changed (see below).
A2a has not run for real yet. The keyless signature needs the OIDC token of a release job, so the first rc or alpha cut after the merge is its test, and the first signed stable is the promotion of an rc cut after the merge (release-1.6 only after a backport). #4759 stays open for two follow-ups that wait for a signed release: project.documentation.signature-verification in security-insights.yml and the SBOM row in docs/security/self-assessment.md, which keeps the image caveat.
The identity check in docs/release.md now pins tags.yaml to v* tag pushes and promote-rc.yaml to main. Until A3 exists anyone with write access can still push a v* tag whose tree has an edited tags.yaml, and its signature passes, so A3 also decides what the signature proves. New A20: nothing refuses a promote-rc.yaml dispatch from another ref up front. On 2026-10-16 a dispatch from release-1.6 ran that branch's older copy of the workflow (one job instead of five, https://github.com/cozystack/cozystack/actions/runs/38882938797) and was re-run from main. With signing in place such a dispatch now fails at its upload step, after the staging branch, the promotion-* candidate and the draft already exist.
Update 2026-10-01
The E2E lane items were re-checked first. The remaining actions were checked against main at bc400dff1 on 2026-10-02 and the bullets below carry the corrections, the 2026-08-13 text further down is the older snapshot.
A14 and A15 are done via #4020 (2026-09-07, backported in #4437): srv1-srv3 of both merge-gating lanes run as Talos containers, and #3238 is closed. What the container lane cannot run (DRBD, the replicated StorageClass, live migration, the cozystack talos image) is the new action A18, tracked in #4642. nightly.yaml and e2e-tag.yaml still boot QEMU, the rc e2e job failed on v1.6.2-rc.1, v1.6.3-rc.1, v1.6.3-rc.2 and v1.6.4-rc.1, and v1.6.2, v1.6.3 and v1.6.4 were promoted with skip_e2e_gate: true. The nightly mirror job failure since 2026-09-15 is #4423 and is not part of A18.
Nightly is worse than the 2026-08-13 text says. The last scheduled green was 2026-09-03, before that 2026-08-17, and Artifact Retention has been red on every scheduled run since 2026-08-18 (new action A19). Promote RC skipped the e2e gate on all five runs since 2026-08-05 (v1.6.1, v1.6.2, v1.5.4, v1.6.3 and v1.6.4), each logged Promoting <rc> without verified green full E2E evidence.
Status as of 2026-08-13
Re-verified against main at 09dc7f47f plus live PR, run and registry state. Two actions moved to done since the 2026-07-20 snapshot: A5, because promote-rc.yaml has now cut two releases live (v1.6.0 on 2026-07-22 and v1.6.1 on 2026-08-05), and A16, closed by #3441 on 2026-08-10, which removes the sequencing constraint it placed on A9. One diagnosis is obsolete rather than resolved. A4's "nightly has never completed a run" was fixed by #3332 and nightly published for ten days, but it has failed every scheduled run since 2026-08-02 on its E2E (full suite) job. That failure is known and is being worked, so what changes here is the recorded cause, not the ownership. A17 is now partial, the specific retired-digest blocker is gone and the systemic preflight is not. The other twelve actions are unchanged, and none has been overtaken by the Chainsaw migration.
One sequencing change: A9 is gated on measurement rather than merely unblocked. Its payoff rests on a "~60% of PRs touch one app" figure that has never been measured, while docs/agents/e2e-testing.md §7 records that most PRs legitimately escalate to the full suite. The install-telemetry task in #2847 Track A is A9's prerequisite. The escalation surface that measurement would run against moved three times in the six days to 2026-08-10 and settled when #3434 closed on 2026-08-13, so a number taken now describes post-#3441 behaviour and should record the commit it was taken at.
Status snapshot
| Epic | Area | State | Remaining |
|---|---|---|---|
| #2937 | build, ci | ~90% | SBOM of the container images (A2b), physical runner retire + rehome the breakpoint rendezvous server (A1 code done) |
| #2677 | release | closed 2026-08-14 | tag-protection ruleset (A3, admin), tracked here rather than there. Nightly publishes again, and its E2E job is red and being worked (A4). Promote flow proven live (A5, done) |
| #2499 | ci, testing | gates exist | go build ./... runs in codeql.yml on every PR and go-module-tests runs go test in the nested modules, A6 is a decision now |
| #2847 | ci, testing | ~40% of its checklist | Track A: A8 and A16 are done, A9 moved to select-install.sh --disabled in #4022 (open) and the measurement was read by hand, install takes about 28 min and 73% of PR runs are full-suite. Track B is #3276 (A11), which needs a rework on the container lane |
| #2653 | testing | audit redone | redone on the Chainsaw suites on 2026-10-01, no cleanup PR yet (A12) |
| #2585 | ci, release | closed 2026-08-27 | namespaced backport labels (A13, done) |
| #3238 | testing | closed 2026-10-01 | done via #4020 (A14 and A15). What the container lane cannot run is A18 (#4642). The opt-in OpenEBS LocalPV package #3266 is open on its own, changes requested |
Done since the 2026-07-20 snapshot
- A2a, feat(release): sign the release assets and attach a source SBOM #4861 (2026-10-20) signs the release assets and attaches a source SBOM, see the update above. Not run for real yet, the first rc or alpha after the merge is the test.
- A5, the promote flow is proven live, twice.
promote-rc.yamlsucceeded on 2026-07-21, twice on 2026-07-22 and on 2026-08-05, covering v1.6.0-rc.4 → v1.6.0 (2026-07-22) and v1.6.1-rc.1 → v1.6.1 (2026-08-05).cut-prerelease.yamlsucceeded four times of five. Update 2026-10-02: the promotes since then (v1.6.2, v1.5.4, v1.6.3, v1.6.4) succeeded too, all with the e2e gate skipped, see A18. - A16, fix(ci): decide E2E test coverage per changed path #3441 (2026-08-10) closed select-e2e.sh: a per-suite test edit silently defeats the full-suite escalation #3330 and ci: select-e2e maps only *-application sources, so kuberture and securitygroup suites are never selected by dependency #3665. Coverage is now decided per changed path instead of inferred from an empty merged selection, so a per-suite test edit can no longer swallow a system-package escalation, see the "Coverage is decided per changed path" bullet in
docs/agents/e2e-testing.md§7. Related: fix(ci): close the silent-green gaps in e2e selection and the helm unit sweep #3670 (2026-08-08) closed e2e: an empty TIA selection concludes "E2E Tests" green with no suite run #3392, so an unclassified path escalates rather than producing an empty selection that both lanes read as "skip Chainsaw" before postingE2E Testsgreen (hack/select-e2e.sh:322). A9 no longer has a correctness prerequisite ahead of it, what stands in front of it now is the measurement described under "Ready now". - A14 and A15, test(e2e): run the merge-gating lanes on Talos containers #4020 (2026-09-07, backport [Backport release-1.6] test(e2e): run the merge-gating lanes on Talos containers #4437 on 2026-09-24) runs srv1-srv3 of both merge-gating lanes as Talos containers on the LINSTOR
localStorageClass. test(e2e): lightweight E2E cluster (kind / Talos-in-Docker) for diff-scoped PR runs #3238 was closed on 2026-10-01 as done via test(e2e): run the merge-gating lanes on Talos containers #4020. The suites and cases that still need a real cluster are listed in e2e: retire the QEMU lane, run what only it covered on a temporary cluster #4642 (A18). The OpenEBS LocalPV hostpath package from feat(local-storage): add opt-in OpenEBS LocalPV hostpath package #3266 (open, changes requested) is not part of it, the lane runs on the LINSTORlocalStorageClass. - A13, namespaced backport labels (chore(ci): align backport labels with namespaced label convention #2585, closed 2026-08-27). The adjacent fix did not land,
full-e2eis still not declared in.github/labels.ymland survives only because the label sync runs withdelete-other-labels: false. - A3, tag-protection rulesets. Created on 2026-11-04 over
v*andapi/apps/v1alpha1/v*: creation is restricted to the CI app (cozystack-ciis the only bypass actor) and the tags can't be deleted, updated or force-moved. The rollout order is indocs/release.md(feat(release): add Cut Pre-release Tag workflow (#2677) #3253). The live ruleset does not carry the "limit tags updated in a single push" rule thatdocs/release.mdlists. - A6,
go build ./...gate.codeql.ymlruns it in the root module,api/apps/v1alpha1and the three image modules on every PR since 2026-06-26, andgo-module-testsrunsgo test ./...in the nested modules. CodeQL and API Review Gate are required checks onmainnow, next topre-commitandE2E Tests, so ci: add CI gates for codegen drift, Go build, and Go unit tests #2499 can close. - A9, install wiring. feat(platform, tests): select E2E packages and declare controller dependencies #4022 merged on 2026-10-07 and both merge-gating lanes pass
select-install.sh --disabledinto the install (pull-requests.yaml:1108,e2e-fork.yaml:681), sotest-minimalandCOZYSTACK_ENABLED_PACKAGESare obsolete. Whether it saves anything is the soak in [Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847 Track A, the measurement is there too. - A19, retention listing. ci(retention): sweep packages named by the published nightly tree #4826 merged on 2026-10-12. The org package listing answered
gh: Invalid argument. (HTTP 400)to the app token, so the job never reached its sweep. The names now come from the published nightly tree, and the scheduledArtifact Retentionruns have been green since 2026-10-13. It is still a dry-run, that is A4.
Carried forward from earlier snapshots, still true:
- A8, diff-driven install selector merged (test(e2e): diff-driven install selector select-install.sh #3279, 2026-07-15). Sub-epic [Epic] Diff-driven E2E install selector — hack/select-install.sh + test-minimal (#2847 Track A) #3277 closed as completed. The script and its tests are described in [Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847 Track A.
- A10, Chainsaw app-suite migration merged (test(e2e): migrate app suite from BATS to Chainsaw and wire into CI #2826, 2026-07-12): 22 suite directories under
hack/e2e-chainsaw/, 21 runnable,backupparked aschainsaw-test.yaml.disabled. The migration issue test(e2e): migrate the E2E app suite from BATS to Kyverno Chainsaw #2979 was closed on 2026-08-14 as done. The two unported monitoring OIDC suites moved to [Tracking] Shell test architecture: vanilla BATS for unit tests, assert library, testable suite shell #3453 item 7 and were deleted in test(e2e): remove unused monitoring suites and audit BATS runners #4019 (2026-09-25). Update 2026-10-02: 23 suites are runnable now,backupandkubernetes-proxmoxare parked. - A1 (code), every workflow moved off the persistent self-hosted runner incl. the
debugreroute (ci: move remaining workflows off the persistent self-hosted runner #3268, 2026-07-09). Everyruns-ononmainisubuntu-*ororacle-vm-*, excepte2e-proxmox.yaml, which uses[self-hosted, proxmox]on purpose and is gated behind thePROXMOX_NIGHTLYvariable (unset). Residual is the physical host retirement plus rehoming the breakpoint rendezvous server, which is still load-bearing: the breakpoint step reaches it through theBREAKPOINT_ENDPOINTrepository variable (pull-requests.yaml:1026).
Corrections to the previous snapshot
- A4's diagnosis is obsolete, the symptom is not. fix(ci): resolve nightly packages digest without image-specific skopeo ops #3332 merged 2026-07-20 and it worked: nightly completed successfully on 2026-07-22, 07-23, 07-24, 07-30, 07-31 and 08-01, and both artifacts exist today, an anonymous GHCR manifest GET returns 200 for
cozy-installer:nightlyand 200 forcozystack-packages:nightly, where both previously 404'd. What is true now is a different failure: 12 consecutive scheduled failures since 2026-08-02, and on the latest run the failing job isE2E (full suite)atRun E2E tests (full suite)whileMirror images to GHCRandBuild & publish nocloud diskboth succeed. Six of the last 29 scheduled runs passed, plus one manual dispatch on 2026-07-21. The current failure is known and is actively being worked, so A4's remaining repo-side content is theRETENTION_APPLYflip, and what this correction changes is the recorded cause, which is no longer the digest-resolution bug fix(ci): resolve nightly packages digest without image-specific skopeo ops #3332 fixed. docs: add CNCF General Technical Review (GTR) questionnaire #3572's GTR questionnaire reports the same flapping independently and adds thate2e-tag.yamlalso failed around the v1.6.1 release, which may share a cause. Update 2026-10-02: scheduled nightly was green on 2026-08-17 and 2026-09-03, so the count of failures above is off by those two. - A17 is partial rather than open. The specific ci: guard against pinned base-image digests disappearing upstream #3305 trigger is fixed: fix(kubernetes): re-pin deleted centos:stream9 digest for kubevirt-csi-driver #3386 re-pinned the deleted digest (2026-07-21) and fix(kubernetes): move kubevirt-csi-driver base off quay.io/centos to almalinux #3400 moved the base off quay entirely, so
packages/apps/kubernetes/images/kubevirt-csi-driver/Dockerfile:17is nowdocker.io/library/almalinux:9@sha256:d2515c76…and noquay.io/centosbase remains underpackages/. The systemic half, an inventory of volatile digest-pinned bases, a project-controlled mirror, a scheduled preflight that verifies every pinned base still resolves, is untouched, and ci: guard against pinned base-image digests disappearing upstream #3305 stays open on that. - A11 has gone backwards rather than forwards. test(e2e): add chainsaw-native release upgrade testing lane #3276 is still open, still
CHANGES_REQUESTED, and now conflicting (last updated 2026-07-31), so a rebase is part of the work. The jobs it has to sequence against also changed under ci(release): move release validation to rc time — e2e lane, changelog button, promote gate, docs at promote #3449 (2026-07-29):tags.yamlnow runsrc-e2e(line 322) ahead ofgenerate-changelog(368) andupdate-website-docs(625), andpromote-rc.yamlcarries its ownchangelog(499) andwebsite-docs(536). - A10 was not what closed test(e2e): migrate the E2E app suite from BATS to Kyverno Chainsaw #2979. The app-suite bulk landed under A10, and the two monitoring BATS suites that never ported are now [Tracking] Shell test architecture: vanilla BATS for unit tests, assert library, testable suite shell #3453 item 7.
Ready now, no blockers
-
A2b, SBOM of the container images, on the release lane. The old A2 text said the blocker was an OCIR referrers probe, and that was the wrong place to look: release images are pushed to GHCR (
REGISTRY ?= ghcr.io/cozystack/cozystack, OCIR is onlyCACHE_REGISTRYthere), and the PR and main builds that do push to OCIR are not what users install. What blocks it, checked on a local registry with docker 29.8 and buildx 0.37.1 and by reading the scripts:--sbom=trueturns the pushed single-platform image into an OCI index of the image and an attestation manifest.image_archinhack/stitch-multiarch.shprints nothing for an index, so with SBOM on it would skip every image ("not one amd64 and one arm64 image") andhack/verify-multiarch.shwould then fail the release with "index without linux/arm64". The rerun branch, which looks for the amd64 digest among the children of the existing index, would not match either.- the release
make buildintags.yamlruns on the default docker driver (use: false), which cannot attach attestations. The arm64 leg already uses docker-container withhack/buildkitd.toml(the docker.io mirror), the amd64 leg needs the same. SBOM=1passes--sbom=true, which pullsdocker.io/docker/buildkit-syft-scanner:stable-1, a floating tag. It should be pinned by digest like the other build inputs.- the comment at
hack/common-envs.mk:69says CycloneDX, BuildKit writes SPDX 2.3 (predicatehttps://spdx.dev/Document) with the image's own packages.
What works: an index stitched from two such images keeps both attestations and passes the
verify-multiarch.shcheck, andskopeo copy --multi-arch all(whatpromote-retag.shandnightly-mirror.shrun) keeps the index digest and its children. So the delivery decision is attestation: the SBOM travels in the index through retag and mirror, and images need no workflow artifact or release attachment. Not checked: that GHCR accepts the attestations (the first alpha shows it), what retention does to the child manifests (retention-packages.sh), the Talos and matchbox builds intags.yaml, and the fork lane'sOCI_EXPORT_DIRoutput. Ties into the OpenSSF supply-chain work (ci: harden GitHub Actions workflows for OpenSSF Scorecard (pin, permissions, zizmor gate) #3223) and is cited as a gap in the CNCF GTR questionnaire (docs: add CNCF General Technical Review (GTR) questionnaire #3572). -
A12, drop redundant post-HR-Ready waits across
hack/e2e-chainsaw/*/chainsaw-test.yaml, find theassert/waitsteps that duplicateHR Ready, keep the CR-operator-async waits. The audit in Audit e2e Chainsaw post-HR-Ready asserts for redundancy under Flux v2.8 kstatus #2653 was redone on the Chainsaw suites on 2026-10-01, the candidate list, the check of the nested-systemHR on a dev cluster and the scope of the first PR are in its comments. Coordinate with [Epic] Adopt the kstatus readiness model platform-wide (Flux 2.8 / helm-controller v1.5.0) #2642: feat(api): typed waitStrategy/healthCheckExprs for kstatus readiness (#2642) #3273 (merged 2026-07-21) landed the typedwaitStrategy/healthCheckExprsAPI, adopted so far only inpackages/extra/monitoringandpackages/extra/seaweedfs, and feat(flux): gate releases on operator status kstatus cannot read #3264 is still a draft with changes requested. -
A20 (new), refuse a
promote-rc.yamldispatch from any ref butmainin theparsejob, before the first write. Onegithub.refcheck and a test, and the author of feat(release): sign the release assets and attach a source SBOM #4861 offered to send it. The update above has the dispatch fromrelease-1.6on 2026-10-16.
Blocked / sequential
- A4, enable
RETENTION_APPLY. Retention is still a dry-run: the default isfalseat.github/workflows/retention.yaml:89, and the scheduled run of 2026-11-10 printedAPPLY: falseandMODE: dry-runand listed the versions it would delete. What stood in front of it is done, A3 (rulesets), the workflow fix (fix(ci): resolve nightly packages digest without image-specific skopeo ops #3332), A19 (the listing) and ci(nightly): Mirror images to GHCR fails on ghcr write_package, so the nightly e2e has not run since 2026-09-15 #4423 (mirror job, closed 2026-10-02). The flip itself is a repo-admin setting and starts real deletes. - A11, upgrade lane (test(e2e): add chainsaw-native release upgrade testing lane #3276), Track B in [Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847. Open, conflicting,
CHANGES_REQUESTEDon 2026-09-29, and it needs a rework on the container lane more than a rebase. The review points are listed in [Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847. - A17 (systemic half), inventory volatile digest-pinned bases, mirror into a project-controlled registry, add a scheduled preflight that verifies every pinned base still resolves. The ci: guard against pinned base-image digests disappearing upstream #3305 trigger itself is fixed (fix(kubernetes): re-pin deleted centos:stream9 digest for kubevirt-csi-driver #3386, fix(kubernetes): move kubevirt-csi-driver base off quay.io/centos to almalinux #3400). Sibling of chore(maintenance): refresh and automate alpine/k8s hook image pins #2565. A third incident happened: 14 of 16 pinned
quay.io/kubev2vdigests inpackages/system/forklift-operator/templates/forklift-operator.yamlno longer resolve (forklift-operator: 14 of 16 pinned images no longer exist on quay.io #4486). It sits in a vendored template, outside what ci: guard against pinned base-image digests disappearing upstream #3305 looks at (Dockerfiles and.tagfiles), so the scope has to widen to templates and values. - A18, retire the QEMU lane and run what only it covered on a temporary three-node cluster (e2e: retire the QEMU lane, run what only it covered on a temporary cluster #4642). The design for the temporary cluster is not started. The interim step proposed in the issue, nightly and rc e2e on the container lane the way test(e2e): run the merge-gating lanes on Talos containers #4020 did it for the PR jobs, is not decided and not tried against a published tag. Until one of them lands,
nightly.yamlande2e-tag.yamlstay on QEMU, rc e2e is red and releases go out withskip_e2e_gate: true.
Effort and closeability
Sizes recalculated 2026-08-13 against current state, not carried over. The A6, A9, A11 and A13 rows were updated on 2026-10-02, A2 was split into A2a and A2b on 2026-10-20. S = hours, M = a day or two, L = multi-day.
| Action | Issue | Size | Note |
|---|---|---|---|
| A6 | #2499 | - | Done, CodeQL is a required check. |
| A13 | #2585 | - | Done 2026-08-27. full-e2e is still undeclared in labels.yml. |
| A3 | #2677 | - | Done 2026-11-04. |
| A4 | #2677 | S | One RETENTION_APPLY flip. A3 and A19 are done. |
| A1 (residual) | #2937 | S | Ops, outside the repo, physical host retire + rehome the breakpoint rendezvous server. |
| A2a | #4759 | - | Done 2026-10-20 (#4861). Keyless signing is unproven until the first rc or alpha after the merge. |
| A2b | #2937 | M | Release lane only: a docker-container builder for make build in tags.yaml, the scanner pinned by digest, stitch-multiarch.sh and verify-multiarch.sh taught about indexes with the stub-registry tests extended, docs. No OCIR probe. |
| A20 | - | S | One github.ref check in parse and a test. |
| A11 | #2847 | - | Rework on the container lane, not a rebase. Size not re-estimated. |
| A12 | #2653 | M | Read-through of 21 runnable Chainsaw suites, lands as one cleanup PR. A14, the audit that shared this pass, is done via #4020. |
| A17 (systemic) | #3305 | M-L | M for the inventory + scheduled preflight, L if the base-image mirror lands with it. |
| A9 | #2847 | - | Done, #4022 merged on 2026-10-07 and the lanes are wired. The soak is in #2847. |
| A18 | #4642 | L | The temporary-cluster half needs a design first: provisioning from CI in OCI, quota, cost, when it runs. The interim swap of nightly and rc e2e onto the container lane is not sized. |
Issue → closeability
- chore(ci): align backport labels with namespaced label convention #2585 closed on 2026-08-27 (A13).
- ci: add CI gates for codegen drift, Go build, and Go unit tests #2499 can close, A6 is decided.
- Audit e2e Chainsaw post-HR-Ready asserts for redundancy under Flux v2.8 kstatus #2653 closes on A12, one PR.
- RFC: immutable release tags & rc-promotion flow #2677 was closed on 2026-08-14 as implemented: feat(release): immutable tags & rc→stable promotion (#2677) #3017, feat(release): add Cut Pre-release Tag workflow (#2677) #3253, ci(release): move release validation to rc time — e2e lane, changelog button, promote gate, docs at promote #3449 and feat(release): cutting an rc freezes the line into release-X.Y #3399 landed the flow, and A5 proved it live on v1.6.0 and v1.6.1. A3 and A4 stay tracked here as repo-admin settings, which is why closing the RFC did not wait on them.
- Finish the CI image-build refactor: SBOM emission and pr-* tag retention #2937 closes on A2b plus the physical runner retirement and the rendezvous rehome (the A1 residual). A17 is adjacent rather than a closure gate.
- Sign release assets and attach an SBOM to each release #4759 stays open after feat(release): sign the release assets and attach a source SBOM #4861 for the two follow-ups in the 2026-10-20 update.
- [Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847 closes on its remaining Track A tasks and A11 (Track B), and A8, A9, A10 and A16 are done.
- test(e2e): lightweight E2E cluster (kind / Talos-in-Docker) for diff-scoped PR runs #3238 was closed on 2026-10-01 as done via test(e2e): run the merge-gating lanes on Talos containers #4020 (A14 and A15).
- e2e: retire the QEMU lane, run what only it covered on a temporary cluster #4642 closes on A18.
- ci: guard against pinned base-image digests disappearing upstream #3305 (A17) closes on the systemic inventory + preflight, not on the almalinux swap that unblocked the build.
- test(e2e): migrate the E2E app suite from BATS to Kyverno Chainsaw #2979 (Chainsaw migration) was closed on 2026-08-14. The two unported
hack/e2e-apps/monitoring-oidc-*.batssuites moved to [Tracking] Shell test architecture: vanilla BATS for unit tests, assert library, testable suite shell #3453 item 7 as a coverage regression rather than a migration remnant, and neither is covered by an action ID here. They were deleted in test(e2e): remove unused monitoring suites and audit BATS runners #4019 instead of being ported.
Recommended sequence
- The
RETENTION_APPLYflip in A4. - Close ci: add CI gates for codegen drift, Go build, and Go unit tests #2499, A6 is done.
- One Chainsaw read-through for A12.
- A2b SBOM of the images: builder, scanner pin, stitch and verify for indexes, then one alpha as the end-to-end check for A2a and A2b together.
- A11 once A18 says which substrate the upgrade lane runs on, then A17's preflight.
- The nightly lane's red runs are ci(nightly): Mirror images to GHCR fails on ghcr write_package, so the nightly e2e has not run since 2026-09-15 #4423 (mirror job, closed on 2026-10-02) and A18 (e2e: retire the QEMU lane, run what only it covered on a temporary cluster #4642, E2E job).
Activity
test(e2e): diff-driven install selector select-install.sh (#2847)
test(e2e): diff-driven install selector select-install.sh (#3279)
myasnikovdaniil commentedon Jul 20, 2026
State refresh — 2026-07-20
Body updated to the 2026-07-20 snapshot, verified against
main+ live PR/issue state. What moved since the 07-13 snapshot:Done
hack/select-install.sh+select-install_test.batsonmain; sub-epic [Epic] Diff-driven E2E install selector — hack/select-install.sh + test-minimal (#2847 Track A) #3277 closed as completed.Two corrections to what the previous snapshot claimed
NIGHTLY_ENABLEDas a partial win. The Nightly workflow has in fact never completed a run — every scheduled run since the variable was set fails ~80s in at "Resolve source commit and version", becausecozystack-packagesis a Flux OCI artifact (application/vnd.cncf.flux.config.v1+json) andskopeo inspect --format '{{.Digest}}'is an image-specific operation on it. Nothing has been published:cozy-installer:nightlyandcozystack-packages:nightlyboth 404 on GHCR. fix(ci): resolve nightly packages digest without image-specific skopeo ops #3332 fixes that plus twoflux pull artifact --outputfailures queued behind it. A4 is enabled but non-functional, not partially done.upgrade-e2ejob. Remaining is review + a dev-cluster run for the canary access paths and the env-gated tenant-Kubernetes suites.Two new action IDs
select-e2e.sh's full-suite escalation is silently defeated when a PR also edits one unrelated suite's tests. The empty-final_appssafety net keys off emptiness alone, so any other contributed suite name swallows the escalation — the same system-package change selects 22 suites alone and exactly 1 alongside a suite edit. This is in the selection foundation A8 mirrors and A9 wires into CI, so it is sequenced ahead of A9.quay.io/centos/centos:stream9retired its pinned manifest on 07-15, five days after the last Renovate digest bump). Direction: mirror volatile bases into a project-controlled registry + a scheduled preflight that verifies every pinned base still resolves.Verified unchanged — A6 (no
go build ./...gate inpull-requests.yaml), A13 (backport/backport-previousstill top-level in.github/labels.yml), A12, A14 not started; A3 and A5 still admin / event-driven. A15's #3266 is still an open draft.docs(security): make the disclosure line and the support test checkable
myasnikovdaniil commentedon Aug 14, 2026
State refresh, 2026-08-13
Body re-verified against
mainat09dc7f47fplus live PR, workflow-run and registry state. A5 is done,promote-rc.yamlhas cut two releases live, v1.6.0 (2026-07-22) and v1.6.1 (2026-08-05), so the orchestration has been proven twice rather than never. A16 is done, #3441 (2026-08-10) closed #3330 and #3665 by deciding coverage per changed path, and #3670 closed #3392 before it, which removes the correctness prerequisite that was sequenced ahead of A9. A9 is re-sequenced rather than started: it is now gated on the install-telemetry measurement in #2847 Track A, because the "~60% of PRs touch one app" payoff has never been measured and §7 ofdocs/agents/e2e-testing.mdrecords that most PRs legitimately escalate to the full suite. The escalation surface moved three times in the six days to 2026-08-10 and settled when #3434 closed on 2026-08-13, so a measurement should record the commit it was taken at. A4's recorded diagnosis is obsolete. #3332 worked,cozy-installer:nightlyandcozystack-packages:nightlyboth resolve on GHCR now where both previously 404'd, and the lane published for ten days, but every scheduled run since 2026-08-02 fails on itsE2E (full suite)job. That failure is known and being worked, so A4's remaining repo-side content is theRETENTION_APPLYflip and the action ID stays whole. A17 is partial: #3386 and #3400 fixed the retired-digest trigger and moved kubevirt-csi-driver todocker.io/library/almalinux:9, but the inventory, mirror and scheduled preflight #3305 asks for do not exist. Two smaller corrections: A11 has gone backwards (#3276 is now conflicting as well asCHANGES_REQUESTED, and #3449 moved the release-validation jobs it sequences against), and A10 should not be read as closing #2979, which still has two BATS suites left. Everything else on the list is unchanged, and #3572 is a citation of this issue in the CNCF GTR questionnaire rather than work in scope.myasnikovdaniil commentedon Sep 1, 2026
Status as of 2026-09-01
Re-verified against
mainate84a44689plus live run, PR and label state.A13 is done, #2585 closed 2026-08-27.
kind/backportandkind/backport-previousare in.github/labels.ymlwith bare names kept asaliases:, andbackport.yamluses the namespaced literals. Adjacent fix noted alongside it did not land:full-e2eis still undeclared (zero occurrences inlabels.yml) and survives only because sync runs withdelete-other-labels: false. Worth folding into next labels change.Everything else was re-checked individually rather than carried forward, and is unchanged: A6 (no
go build ./...gate inpull-requests.yaml), A9 (select-install.shinvoked by no workflow), A12 (.chainsaw.yamlstillparallel: 1), A14/A15 (hack/e2e-chainsaw/backup/chainsaw-test.yaml.disabledstill parked), A2 (SBOM ?= 0inhack/common-envs.mk, no workflow sets it), A17 systemic half (no scheduled base-digest preflight among the 27 workflows), A3 (one ruleset) and A4'sRETENTION_APPLY(stillfalse). A1 code half remains done, everyruns-onisubuntu-*ororacle-vm-*.A4: nightly is the steady state, not an incident
The 2026-08-13 snapshot recorded nightly's
E2E (full suite)job as a known failure being worked. It has failed every scheduled run since 2026-08-02, thirty days in a row, always atRun E2E tests (full suite). Latest: https://github.com/cozystack/cozystack/actions/runs/33462145699"Being worked" doesn't describe that anymore. Platform has had no daily full-suite signal for a month, so whatever TIA narrows away on the PR lane is unobserved until a release cut re-runs the full suite. It also blocks work nobody has proposed yet: any plan that moves an expensive suite off the PR lane and into nightly needs somewhere green to move it to, and there isn't one right now. I suggest promoting this from a note under A4 into its own action, size is unknown and other things queue behind it.
A9: the measurement it waits on is partly answered, and points elsewhere
A9 is gated on measuring the "~60% of PRs touch one app" figure. A related number is already available from workflow-run history, and it reframes the action instead of unblocking it. Over 2026-06-23..2026-08-23, of 2,118 E2E job executions only ~12% selected light suites, 1,260 selected
kubernetes-*, and 692 died before the selector ran. Most runs escalate, which matches whatdocs/agents/e2e-testing.mdalready says about escalation being usually correct.So wiring
select-install.shas it stands would act on roughly one run in eight, because escalation decides install scope before the closure ever gets to narrow it. That doesn't make A9 wrong, but its payoff is bounded by escalation rate rather than by closure precision, so narrowing what an escalation escalates to should come first.Not currently tracked
Three items with no action ID, all acting on the PR lane without touching what any suite asserts.
Fourth selector outcome.
select-e2e.shhas three now: full suite, a scoped set, nothing. Fail-closed is right and stays, but the only thing to fail closed to is the full suite, which includes the two most expensive tests in the tree.kubernetes-latestandkubernetes-previousare 68 of the 131 minutes of chainsaw time on a green run, measured on run 33372552453 via itschainsaw-reportartifact. A broad-but-not-heaviest tier, every app suite withoutkubernetes-*, keeps every path classified and every escalation mandatory, only the destination changes. This is the prerequisite for A9 above.Suite parallelism.
.chainsaw.yamlrunsparallel: 1and the stated reason is one suite's fixed port-forward port. The 17 suites that are neitherkubernetes-*nor a backup round-trip cost 26 minutes sequentially. Needs scoping rather than a global flip, the heavy suites are already CPU starved on the current runner class, so per-Testconcurrency control is likelier to be the right shape.Expensive lane once per PR instead of once per push. Currently 4.5 runs per PR on average, and one renovate branch got 41. Trigger it on
pull_request_review(approved) rather than onsynchronize. This costs nothing in coverage and that is checkable rather than asserted: renovate runs withautomerge: falseandplatformAutomerge: false, the ruleset requires one approving review, so every PR that reachesmainis approved by definition and gets the lane. Organization admins can still bypass, exactly as they can today.dismiss_stale_reviews_on_pushis already on, so a push after approval invalidates it and the next approval re-runs the lane.Worth separating two axes that the
full-e2elabel currently carries together: when the lane runs, and what scope it runs at. The gating sites readgithub.event.label.name(the concurrency key,plan, and the two job guards), the scope sites readcontains(labels.*.name, 'full-e2e')(the rc check, the TIA skip, and theFULL_E2Eenv). They are already in separate places. A second label for "run the lane now at the scope this diff selects" fits the gating sites only, and leavesfull-e2eowning scope alone. It should be one-shot, removed when the run starts, whilefull-e2estays sticky because promote PRs rely on that. Naming:e2e/runande2e/full, withaliases: ['full-e2e']on the second, same shape A13 just gave the backport labels.full-e2ehas to be declared inlabels.ymlanyway, so declaring the pair in the right form now is cheaper than renaming it later.One caution for whoever writes it: the concurrency key and
plan's guard are exact complements of each other by design, and the comment above them records what happened on live CI when they disagreed. A third label name has to be added to both.A15 has moved
Tracker points A15 at #3266, which is still a draft with changes requested and hasn't moved since 2026-07-20. Live work is #3961 now, container lane plus three storage fixes it exposed. Worth repointing.
docs(security): make the disclosure line and the support test checkable
myasnikovdaniil commentedon Oct 2, 2026
State refresh, 2026-10-02
Added the rest of the re-check to the body, against
mainatbc400dff1. A18 stays as written (#4642).Two things I wrote on 2026-09-01 are wrong. Nightly was not red 30 days in a row, there was a green scheduled run on 2026-09-03 (and one on 2026-08-17). And A15 should not point at #3961, it was closed unmerged on 2026-09-30 after #4020 landed the container lane.
New is A19: the GHCR retention job fails on its package listing (HTTP 400, red on every scheduled run since 2026-08-18), so flipping
RETENTION_APPLYin A4 would delete nothing. A6 is partial,go build ./...already runs incodeql.yml, it is just not a required check. A9 changed design, #4022 uses a--disabledlist, sotest-minimalis obsolete. A13 is done. A17 got a third incident (#4486) outside the scan scope of #3305.The PR-cost series was in no tracker before. #4005, #4008, #4022 and #4023 are open, #4019, #4020 and #4021 are merged.
lexfrei commentedon Oct 9, 2026
A19 has a cause: GitHub refuses to list an org's container packages to a GitHub App installation token.
GET /orgs/{org}/packages?package_type=containerreturns400 Invalid argumentfor that token type, other package types work with the same token, andretention.yamlcalls it with the cozystack-ci app token. A classic PAT withread:packageslists all 97 org packages with the same request. This is undocumented but known, see actions/github-script#449 and cli/cli#9606.The listing never worked in this workflow. Every scheduled run from 2026-07-15 to 2026-08-17 logged the same 400 and still exited green with "No cozystack/* container packages found", so retention has never pruned anything. ffae003 only made the old failure visible, from 2026-08-18 on.
Two ways out. One is a classic PAT with
read:packagesanddelete:packagesas a secret for this job only. The other is to drop the org-wide listing and loop over a known list of package names, because/orgs/{org}/packages/container/{name}/versionsaccepts an installation token. I didn't check whether the version DELETE accepts the app token either, that needs a test beforeRETENTION_APPLYis flipped.lexfrei commentedon Oct 9, 2026
A4 follow-up from #4826: the retention workflow will not prune
cozystack/cozystack-ui. It has 68 dated nightly versions today, 54 over the keep count of 14, and the number grows with every nightly.The reason is the token. #4826 deletes with this repository's
GITHUB_TOKEN, because the app token gets 404 on DELETE. That token deleted a version of a package linked tocozystack/cozystack, butcozystack/cozystack-uiis linked to thecozystack/cozystack-uirepository. I did not test the token there and the workflow does not try: it skips the package and names it in a warning on every run.Two ways to cover it:
cozystack/cozystack-uiitself, deleting with that repository's ownGITHUB_TOKENcozystack/cozystackin the package settings (needs a package admin, and it is untested whether that is enough for DELETE)ci(retention): sweep packages named by the published nightly tree (#4826
feat(release): sign the release assets and attach a source SBOM (#4861)
feat(build): attach a provenance attestation beside the SBOM
feat(release): sign the release images and attach their SBOMs
feat(release): attach an SBOM to every release image (#4997)
feat(release): sign the release images and attach their SBOMs
feat(build): attach a provenance attestation beside the SBOM
themoriarti commentedon Nov 2, 2026
Status of A2a, A2b, A20 and two re-checks, 2026-11-02
Checked against
main,release-1.7and the releases page. The body still says A2a has not run for real, and that is still true, but three releases have been cut since it merged, so here is why.A2a is still unproven. v1.7.0-rc.2 (2026-10-21), v1.7.0-rc.3 (2026-10-27) and v1.7.0 (2026-10-29) all came out of
release-1.7, which does not havehack/sign-release-assets.sh, so each of them carriescozypkg-checksums.txtand nothing else: nocozystack-source-sbom.spdx.json, nocozystack-checksums.txt, no Sigstore bundle. The backport is #5172, approved and mergeable, held only by the redUnit & controller testscheck, which is #5178 (the release prep rewrote two image refs the tests read) and not the signing change. #5179 fixes it onrelease-1.7and #5180 onmain, both green, both waiting for review. Order: #5179, then #5172 rebased on it, then the firstv1.7.1-rc.*is the test of the keyless signature.mainhas had no tag since 2026-10-20, so there is no alpha to look at either.A2b moved. #4997 (merged 2026-11-01) attaches an SPDX SBOM to every release image, which is the part the body lists as "ready now": a docker-container builder for
make buildintags.yaml, the scanner pinned by digest,stitch-multiarch.shandverify-multiarch.shtaught about indexes. What is left is the image signature, #5042, and the provenance attestation beside the SBOM, #5043. Both are rebased onto #4997 and ready for review; they touch the same block ofdocs/release.md, so whichever lands second needs a rebase. Like A2a, none of it has run on a real tag yet.A20 is mine and not sent yet. I offered it on 2026-10-20 and have not opened the PR. Nothing in
promote-rc.yamlonmainchecksgithub.reftoday, the tworef:lines in it only passgithub.ref_namethrough to checkouts. #5169 reorders the same workflow's publish step, so I will open A20 after it lands or against it, not beside it.Two re-checks against the body.
main:pull-requests.yaml:1108ande2e-fork.yaml:681both call./hack/select-install.sh --disabled "${apps}". What remains for A9 is whether it saves anything, which the 73% full-suite figure says is bounded, not whether it is wired.RETENTION_APPLYstill resolves tofalseatretention.yaml:89, andcozystack/cozystack-uiis skipped with a warning on every run, as described in the follow-up. A4 is therefore unblocked on the listing and blocked on the two token questions.themoriarti commentedon Nov 2, 2026
A20 is #5181: the first step of
parseinpromote-rc.yamlfails whengithub.refis notrefs/heads/main, with a bats test over the step's shell. It does not overlap with #5169's hunks, so the two can land in either order.feat(release): sign the release images and attach their SBOMs
feat(build): attach a provenance attestation beside the SBOM
myasnikovdaniil commentedon Nov 10, 2026
State refresh, 2026-11-10
A3, A6, A9 and A19 are done and moved to the done list. Tag rulesets exist since 2026-11-04 (creation only by the CI app, tags immutable), CodeQL and API Review Gate are required on
main, #4022 merged on 2026-10-07 and #4826 on 2026-10-12, retention runs are green since 2026-10-13. A4 is only theRETENTION_APPLYflip now, it is still a dry-run.A8, A10 and A11 lost text that #2847 and #3453 already carry, IDs are the same. A2b and A20 are not done, #5042 and #5181 are open for them.