Skip to content

[Tracking] Remaining CI / build / release / E2E automation work #3278

Description

@myasnikovdaniil

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-A19) are stable references.

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 delivery (A2), 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

Carried forward from earlier snapshots, still true:

Corrections to the previous snapshot

Ready now, no blockers

Blocked / sequential

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. S = hours, M = a day or two, L = multi-day.

Action Issue Size Note
A6 #2499 S Decision only, the gate exists in codeql.yml.
A13 #2585 - Done 2026-08-27. full-e2e is still undeclared in labels.yml.
A3 #2677 S Admin-only, long external lead time, so request early.
A4 #2677 S One RETENTION_APPLY flip, bundled with A3. The nightly lane's red runs are #4423 and A18.
A1 (residual) #2937 S Ops, outside the repo, physical host retire + rehome the breakpoint rendezvous server.
A2 #2937 M Probe is small, the delivery decision (attestation vs artifact vs release attachment) is the work.
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 - #4022 (open) plus the workflow wiring, test-minimal is obsolete. Size not re-estimated.
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

Recommended sequence

  1. Fix A19, then fire off the admin request for A3 + the RETENTION_APPLY flip in A4 (longest external lead time).
  2. Decide A6 and close ci: add CI gates for codegen drift, Go build, and Go unit tests #2499.
  3. One Chainsaw read-through for A12.
  4. A9: get feat(platform, tests): select E2E packages and declare controller dependencies #4022 green and reviewed, then wire select-install.sh --disabled into the PR and fork lanes.
  5. A2 SBOM (probe → enable → delivery decision).
  6. A11 once A18 says which substrate the upgrade lane runs on, then A17's preflight.
  7. 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, being worked separately) and A18 (e2e: retire the QEMU lane, run what only it covered on a temporary cluster #4642, E2E job).

Activity

  1. added
    epicA large development increment that brings definite value to Cozystack users
    area/ciIssues or PRs related to CI workflows, GitHub Actions, automation
    area/testingIssues or PRs related to testing (e2e, bats, unit tests)
    area/buildIssues or PRs related to image build infrastructure, multi-arch support
    area/releaseIssues or PRs related to release tooling (changelog, backport, release pipeline)
    on Jul 13, 2026
  2. myasnikovdaniil commented on Jul 20, 2026

    @myasnikovdaniil
    ContributorAuthor

    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

    Two corrections to what the previous snapshot claimed

    • A4 was overstated. It recorded NIGHTLY_ENABLED as 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", because cozystack-packages is a Flux OCI artifact (application/vnd.cncf.flux.config.v1+json) and skopeo inspect --format '{{.Digest}}' is an image-specific operation on it. Nothing has been published: cozy-installer:nightly and cozystack-packages:nightly both 404 on GHCR. fix(ci): resolve nightly packages digest without image-specific skopeo ops #3332 fixes that plus two flux pull artifact --output failures queued behind it. A4 is enabled but non-functional, not partially done.
    • A11 changed shape. No longer "unstall the [ci] Add upgrade test job to release pipeline #2401 review". [ci] Add upgrade test job to release pipeline #2401 predates the BATS→Chainsaw migration and is now a single conflicting 895-line BATS file; test(e2e): add chainsaw-native release upgrade testing lane #3276 supersedes it with a Chainsaw-native upgrade lane (install-previous → seed canary data → upgrade → assert survival/data-integrity/HR-reconciliation/migration-stamp) as a parallel non-blocking upgrade-e2e job. Remaining is review + a dev-cluster run for the canary access paths and the env-gated tenant-Kubernetes suites.

    Two new action IDs

    • A16 — select-e2e.sh: a per-suite test edit silently defeats the full-suite escalation #3330: select-e2e.sh's full-suite escalation is silently defeated when a PR also edits one unrelated suite's tests. The empty-final_apps safety 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.
    • A17 — ci: guard against pinned base-image digests disappearing upstream #3305: retired base-image digests block unrelated builds (quay.io/centos/centos:stream9 retired 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 in pull-requests.yaml), A13 (backport / backport-previous still 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.

  3. myasnikovdaniil commented on Aug 14, 2026

    @myasnikovdaniil
    ContributorAuthor

    State refresh, 2026-08-13

    Body re-verified against main at 09dc7f47f plus live PR, workflow-run and registry state. A5 is done, promote-rc.yaml has 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 of docs/agents/e2e-testing.md records 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:nightly and cozystack-packages:nightly both 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 its E2E (full suite) job. That failure is known and being worked, so A4's remaining repo-side content is the RETENTION_APPLY flip and the action ID stays whole. A17 is partial: #3386 and #3400 fixed the retired-digest trigger and moved kubevirt-csi-driver to docker.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 as CHANGES_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.

  4. myasnikovdaniil commented on Sep 1, 2026

    @myasnikovdaniil
    ContributorAuthor

    Status as of 2026-09-01

    Re-verified against main at e84a44689 plus live run, PR and label state.

    A13 is done, #2585 closed 2026-08-27. kind/backport and kind/backport-previous are in .github/labels.yml with bare names kept as aliases:, and backport.yaml uses the namespaced literals. Adjacent fix noted alongside it did not land: full-e2e is still undeclared (zero occurrences in labels.yml) and survives only because sync runs with delete-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 in pull-requests.yaml), A9 (select-install.sh invoked by no workflow), A12 (.chainsaw.yaml still parallel: 1), A14/A15 (hack/e2e-chainsaw/backup/chainsaw-test.yaml.disabled still parked), A2 (SBOM ?= 0 in hack/common-envs.mk, no workflow sets it), A17 systemic half (no scheduled base-digest preflight among the 27 workflows), A3 (one ruleset) and A4's RETENTION_APPLY (still false). A1 code half remains done, every runs-on is ubuntu-* or oracle-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 at Run 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 what docs/agents/e2e-testing.md already says about escalation being usually correct.

    So wiring select-install.sh as 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.

    1. Fourth selector outcome. select-e2e.sh has 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-latest and kubernetes-previous are 68 of the 131 minutes of chainsaw time on a green run, measured on run 33372552453 via its chainsaw-report artifact. A broad-but-not-heaviest tier, every app suite without kubernetes-*, keeps every path classified and every escalation mandatory, only the destination changes. This is the prerequisite for A9 above.

    2. Suite parallelism. .chainsaw.yaml runs parallel: 1 and the stated reason is one suite's fixed port-forward port. The 17 suites that are neither kubernetes-* 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-Test concurrency control is likelier to be the right shape.

    3. 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 on synchronize. This costs nothing in coverage and that is checkable rather than asserted: renovate runs with automerge: false and platformAutomerge: false, the ruleset requires one approving review, so every PR that reaches main is approved by definition and gets the lane. Organization admins can still bypass, exactly as they can today. dismiss_stale_reviews_on_push is already on, so a push after approval invalidates it and the next approval re-runs the lane.

      Worth separating two axes that the full-e2e label currently carries together: when the lane runs, and what scope it runs at. The gating sites read github.event.label.name (the concurrency key, plan, and the two job guards), the scope sites read contains(labels.*.name, 'full-e2e') (the rc check, the TIA skip, and the FULL_E2E env). 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 leaves full-e2e owning scope alone. It should be one-shot, removed when the run starts, while full-e2e stays sticky because promote PRs rely on that. Naming: e2e/run and e2e/full, with aliases: ['full-e2e'] on the second, same shape A13 just gave the backport labels. full-e2e has to be declared in labels.yml anyway, 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.

  5. myasnikovdaniil commented on Oct 2, 2026

    @myasnikovdaniil
    ContributorAuthor

    State refresh, 2026-10-02

    Added the rest of the re-check to the body, against main at bc400dff1. 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_APPLY in A4 would delete nothing. A6 is partial, go build ./... already runs in codeql.yml, it is just not a required check. A9 changed design, #4022 uses a --disabled list, so test-minimal is 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.

  6. lexfrei commented on Oct 9, 2026

    @lexfrei
    Contributor

    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=container returns 400 Invalid argument for that token type, other package types work with the same token, and retention.yaml calls it with the cozystack-ci app token. A classic PAT with read:packages lists 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:packages and delete:packages as 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}/versions accepts an installation token. I didn't check whether the version DELETE accepts the app token either, that needs a test before RETENTION_APPLY is flipped.

  7. lexfrei commented on Oct 9, 2026

    @lexfrei
    Contributor

    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 to cozystack/cozystack, but cozystack/cozystack-ui is linked to the cozystack/cozystack-ui repository. 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:

    • a retention job in cozystack/cozystack-ui itself, deleting with that repository's own GITHUB_TOKEN
    • an explicit Actions access role for cozystack/cozystack in the package settings (needs a package admin, and it is untested whether that is enough for DELETE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area/buildIssues or PRs related to image build infrastructure, multi-arch supportarea/ciIssues or PRs related to CI workflows, GitHub Actions, automationarea/releaseIssues or PRs related to release tooling (changelog, backport, release pipeline)area/testingIssues or PRs related to testing (e2e, bats, unit tests)epicA large development increment that brings definite value to Cozystack userstriage/acceptedIndicates an issue is ready to be actively worked on

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions