Commit Graph
7 Commits
Author SHA1 Message Date
Myasnikov Daniil ce054baa34 feat(release): attach an SBOM to every release image
A release said nothing about what is inside its container images, so a
user could not tell which packages a cluster runs. SBOM=1 had been
plumbed for it and left off.

BuildKit attaches the SBOM as an attestation, which makes the pushed
image an index of the image and its attestation manifest. The stitch took
such an index for something other than one amd64 and one arm64 image,
skipped it and still exited 0, and the multi-arch gate then failed the
release, so the stitch now reads through the index and the stitched one
keeps both attestations. The release build ran on the default docker
driver, which cannot attach attestations, so it moves to the
docker-container builder with the docker.io mirror, as the arm64 leg
already did. The scanner is pinned by digest where --sbom=true pulls a
floating tag.

The Talos installer image is built by the imager and pushed by skopeo, so
it carries no attestation.

Assisted-by: LLM
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-10-20 16:40:06 +05:00
Myasnikov Daniil cc942fed68 test(tests): run unit suites with Bats and retain POSIX coverage
The shell translator rewrites test bodies and loses Bats reporting.
The unit lane needs complete TAP results and JUnit reports without
changing how live-cluster suites run.

Sourced production helpers still need a dash pass, and unit test bodies
need nounset without exporting shell options into subprocesses.

Assisted-by: LLM
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
2026-10-07 11:04:00 +03:00
Aleksei Sviridkin 6df5d076b1 ci(workflows): pin flux, yq and helm-unittest installs
Every flux install fetched fluxcd.io/install.sh and ran it as root, so
whatever that host served at the moment executed on runners that later
hold registry credentials. Use the upstream setup action instead, pinned
by commit and given an explicit version: it checks the release tarball
against that release's checksums file and runs no script fetched at run
time.

nightly and the fork e2e lane still took yq from the floating latest
release. They now use the pinned, checksum-verified install the
promotion steps already have.

The helm-unittest plugin embeds its own Helm and was installed at
whatever version was newest, so a plugin release could change chart
test results on a PR that touched no chart. Pin it, and replace a
different version a persistent runner may carry.

A contract test scans every workflow for these three tools, so an
unpinned flux, yq or helm-unittest install copied from an older step
fails the unit lane.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-10-02 11:02:18 +03:00
Aleksei Sviridkin afe23a2c3f ci(release): pin flux where the release pushes the packages artifact
prepare-release now runs flux push artifact to publish the rc's packages
artifact, and it installed whatever flux was latest, while build-amd64
and the candidate checks pin one version. It installs that version now.
The arm64 leg and the nightly never run flux, so they no longer install
it. The rc-e2e comment gave a stable tag as the reason for its
!cancelled(), but the job only runs for an rc; it now says it follows
the rule every job below build-arm64 has.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-09-29 12:36:56 +03:00
Aleksei Sviridkin 71144d4fd6 ci(release): pin the matchbox rebuild in the release job
tags.yaml only runs on tags, so no pull request exercises it. The
matchbox rebuild is the only thing that makes its ref an index, and
losing the step, moving it past the tree capture or letting it switch
the default builder would surface as a failed gate on the next rc. The
comments that called the talos images amd64 only now say they are
built for both arches in the amd64 job.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-09-29 11:52:08 +03:00
Aleksei Sviridkin 67fa638f2a ci(release): publish every pre-release image as an amd64 and arm64 index
A release was amd64 only: prepare-release built on an x86 runner and
nothing built arm64. A pre-release now builds its images twice, side
by side: build-amd64 on x86, build-arm64 on a native arm64 runner
under <tag>-arm64, reading the arm64 build cache. Neither waits for
the other, so the rc takes as long as the slower build rather than
the sum of both.

prepare-release runs once both have succeeded. It applies the tree
build-amd64 stamped, stitches each image and its arm64 twin into one
index under the tags build-amd64 logged, gates on every pinned image
being multi-arch, republishes the packages artifact and the installer
chart pinned on the index digests, and only then commits, creates and
publishes the release and pushes the staging branch. The stamped
tree, the tag log and the assets reach it as artifacts that must
exist, so a lost hand-off fails loudly. The assets are built in
build-amd64, reusing the Talos images make build produced, while the
arm64 build is still running.

An rc whose arm64 or amd64 build fails is not published at all rather
than published amd64 only. A stable tag skips the arm64 build: it
never builds, and promotion copies the rc's indexes with every
platform. build-amd64 keeps the release-exists no-op and the
rejection of a hand-pushed stable tag, and prepare-release no-ops
with it. A skipped ancestor makes the implicit success() false for
every job below it, so each job below prepare-release states
!cancelled() itself; without it the stable-tag changelog backstop
would never run. The arm64 build makes the same no-op when the tag's
release already exists, so re-running a prepared rc rebuilds nothing.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-09-28 01:32:36 +03:00
Aleksei Sviridkin 9a7094427e feat(build): stitch amd64 and arm64 builds into multi-arch indexes
The arm64 images are built on native arm64 runners, apart from the
amd64 build, so each build pushes a single-platform image. The stitch
joins every first-party image with its -arm64 twin into one index,
moves every tag this build pushed for it to that index, and repins
the tree on the index digest, so one ref serves both architectures.

Most refs in the tree name only the build's IMAGE_TAG, while under
PUBLISH_VERSIONED=1 the build also pushes the component version, so
the refs alone cannot say which tags to move. The image-tags macro
therefore appends every tag it pushes to PUSHED_TAGS_LOG when that is
set, and the stitch moves exactly those, plus IMAGE_TAG and the tag a
ref carries. It reads no other tag: another build's tag that sits on
the same amd64 bytes is not this build's to move, and scanning every
tag of every repository would cost thousands of registry reads per
release.

It reads refs through hack/lib/image-refs.sh like every other
consumer, rewrites only the files that enumeration names, and then
searches the whole tree outside charts/, gzip payloads included, for
any old digest it re-pointed. A ref whose digest is also pinned where
the rewrite cannot reach is skipped instead of half rewritten.

The kamaji control-plane provider's chart ships its ref only inside
files/components.gz, built from a plain copy with gzip -n, which no
text search sees. The stitch rewrites both copies, recompressing with
gzip -n so the result is what the package's image target would have
written, rather than leaving that image amd64 only.

An image with no arm64 twin (talos, the e2e sandbox), or a pair that
is not one amd64 and one arm64 image, is skipped and named. A
registry read answered with a rate limit or a 5xx is retried a
bounded number of times; any other registry error fails the run at
once rather than reading as a missing arm64 image.

On a rerun after a stitch that failed partway, the build tag can
already sit on an index of the pinned image and an arm64 image, not
necessarily this run's if the arm64 leg rebuilt it. The stitch repins
on that index instead of skipping the image, and copies it to any of
the build's other tags still left on the amd64 image. A tag moved to
anything else fails the run, since the tree then no longer matches
the registry.

MATRIX_ARCH=arm64 makes hack/build-matrix.sh leave out the e2e
sandbox, which pins linux/amd64: an arm64 leg building it would push
a second amd64 image under its -arm64 tag.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-09-27 07:57:30 +03:00