From 83e4e13c4be9d3211fc8e0160d28fd3a377011a8 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Mon, 9 Nov 2026 15:27:57 -0800 Subject: [PATCH] feat: pin virtee/beacon component versions via versions.env Introduce a top-level versions.env that pins the upstream release tags for snphost, snpguest, and beacon. Bumps are now deliberate, reviewed PR changes instead of silently tracking whatever the latest upstream release happens to be at build time. - CI: add a resolve-tags job that reads versions.env (falling back to the upstream latest when an entry is empty) and passes the resolved tags to the build job. - images/Makefile: include ../versions.env in the tags target; pinned values are used as-is, empty entries still fetch latest. Signed-off-by: Harika Nittala --- .github/workflows/build-and-release.yml | 50 ++++++++++++++++++++----- README.md | 2 + docs/how-to-add-new-os-images.md | 4 ++ images/Makefile | 16 +++++--- versions.env | 6 +++ 5 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 versions.env diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 7d83fd2f..6efa75e2 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -27,9 +27,42 @@ permissions: actions: read # Required for workflow access jobs: + # Resolve component versions once: pinned in versions.env, else upstream latest + resolve-tags: + name: resolve component tags + runs-on: ubuntu-latest + outputs: + snphost: ${{ steps.resolve.outputs.snphost }} + snpguest: ${{ steps.resolve.outputs.snpguest }} + beacon: ${{ steps.resolve.outputs.beacon }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Resolve tags (pin from versions.env, fallback to latest) + id: resolve + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + . versions.env + resolve() { # $1=repo $2=pinned tag + if [ -n "$2" ]; then + echo "$2" + else + gh release view --repo "$1" --json tagName --jq '.tagName' + fi + } + { + echo "snphost=$(resolve virtee/snphost "${SNPHOST_TAG:-}")" + echo "snpguest=$(resolve virtee/snpguest "${SNPGUEST_TAG:-}")" + echo "beacon=$(resolve AMDEPYC/beacon "${BEACON_TAG:-}")" + } >> "$GITHUB_OUTPUT" + # Development release for tag or main pushes create-release: name: create new release for tagged or latest assets + needs: resolve-tags runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.replace_release == 'true') steps: @@ -63,6 +96,7 @@ jobs: build: name: ${{ matrix.distro }}-${{ matrix.release }} + needs: resolve-tags runs-on: ubuntu-24.04 strategy: fail-fast: false @@ -99,17 +133,15 @@ jobs: sudo apt update sudo apt install -y mkosi - - name: Fetch latest release tags - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Apply resolved release tags run: | set -euo pipefail - - # Fetch latest tags using gh CLI (automatically authenticated) - SNPGUEST_TAG=$(gh release view --repo virtee/snpguest --json tagName --jq '.tagName') - BEACON_TAG=$(gh release view --repo AMDEPYC/beacon --json tagName --jq '.tagName') - SNPHOST_TAG=$(gh release view --repo virtee/snphost --json tagName --jq '.tagName') - + + # Tags resolved once by the resolve-tags job (pinned in versions.env, else upstream latest) + SNPGUEST_TAG="${{ needs.resolve-tags.outputs.snpguest }}" + BEACON_TAG="${{ needs.resolve-tags.outputs.beacon }}" + SNPHOST_TAG="${{ needs.resolve-tags.outputs.snphost }}" + # Inject environment variables into mkosi.conf files sed -i "/^\[Build\]/a\Environment=SNPGUEST_TAG=$SNPGUEST_TAG" modules/build/common/snpguest/mkosi.conf sed -i "/^\[Build\]/a\Environment=BEACON_TAG=$BEACON_TAG" modules/build/host/beacon/mkosi.conf diff --git a/README.md b/README.md index 527003e3..73127380 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ Each certification run automatically creates a GitHub Issue containing the resul Host and Guest images are constructed in GitHub Workflows via [`mkosi`](https://github.com/systemd/mkosi). Host images are designed to be booted on a SEV-enabled EPYC server, and are configured with a series of tests in the form of custom systemd services that will run on an embedded guest image. The resulting host and guest images are available in GitHub releases. +The upstream release versions of the components baked into the images — [`snphost`](https://github.com/virtee/snphost), [`snpguest`](https://github.com/virtee/snpguest), and [`beacon`](https://github.com/AMDEPYC/beacon) — are pinned in [`versions.env`](./versions.env) at the repository root. Bumps are made deliberately via a pull request so that any breakage in a new upstream release is caught at review time; the `build-and-release` workflow resolves the pinned tags (falling back to the upstream latest for any empty entry) and reports the resolved `repository → version` pairs in the `resolve-tags` job summary. Leave a value empty in `versions.env` to track the upstream latest release at build time. + [cert-3.0]: ./docs/certifications.md#amd-epyc-7003-milan [cert-3.1]: ./docs/certifications.md#amd-epyc-9004-genoa [cert-4.0]: ./docs/certifications.md#amd-epyc-7004-bergamo diff --git a/docs/how-to-add-new-os-images.md b/docs/how-to-add-new-os-images.md index b06fbd9e..0cec7ee7 100644 --- a/docs/how-to-add-new-os-images.md +++ b/docs/how-to-add-new-os-images.md @@ -53,6 +53,8 @@ You can create and publish new host or guest images in `sev-certify` with `mkosi Then, verify for successful execution with the built new host and guest OS images under `devel` tag. + The `build-and-release` workflow resolves the `snphost`, `snpguest` and `beacon` release tags in its `resolve-tags` job before building. Versions are pinned in [`versions.env`](https://github.com/AMDEPYC/sev-certify/blob/main/versions.env) at the repository root (an empty entry falls back to the upstream latest release). The resolved repository/version pairs are shown as a table in the `resolve-tags` job summary. + If the `build-and-release` workflow fails, you need to troubleshoot for the error in the workflow log, implement changes, and retest until successful execution. - **Test the new OS Host/Guest Images:** @@ -183,6 +185,8 @@ make GENERATE_MANIFEST=yes guest-- The `GENERATE_MANIFEST` variable defaults to empty in the Makefile. When set to a truthy value (`y`, `yes`, or `1`), mkosi is invoked with the environment variable to generate manifest files. +The `make tags` target resolves the `snphost`, `snpguest` and `beacon` versions from [`versions.env`](https://github.com/AMDEPYC/sev-certify/blob/main/versions.env); pinned entries are used as-is and empty entries fall back to fetching the upstream latest release. + **For local builds using mkosi directly**, pass the environment variable: ```bash diff --git a/images/Makefile b/images/Makefile index a00878d7..65bf1e5b 100644 --- a/images/Makefile +++ b/images/Makefile @@ -5,22 +5,28 @@ CLEAN_IMAGES := $(addprefix clean-,$(IMAGES)) GH_AUTH := $(if $(GITHUB_TOKEN),-H "Authorization: Bearer $(GITHUB_TOKEN)") GH_LATEST = curl -sf $(GH_AUTH) https://api.github.com/repos/$(1)/releases/latest | jq -r '.tag_name' +# Pinned component versions (override on the command line with make VAR=x) +-include ../versions.env + .PHONY: all clean list status tags $(IMAGES) $(CLEAN_IMAGES) +# Pinned versions from ../versions.env are used as-is; empty entries fall back +# to fetching the latest upstream release. tags: @set -e; \ trap 'rm -f .tags.tmp' EXIT; \ fetch() { \ - tag=$$($(call GH_LATEST,$$1)); \ + tag=$$3; \ + if [ -z "$$tag" ]; then tag=$$($(call GH_LATEST,$$1)); fi; \ if [ -z "$$tag" ] || [ "$$tag" = "null" ]; then \ - echo "Failed to fetch tag for $$1. Try: export GITHUB_TOKEN=\$$(gh auth token)" >&2; \ + echo "Failed to resolve tag for $$1. Try: export GITHUB_TOKEN=\$$(gh auth token)" >&2; \ exit 1; \ fi; \ echo "$$2=$$tag"; \ }; \ - { fetch virtee/snpguest SNPGUEST_TAG; \ - fetch AMDEPYC/beacon BEACON_TAG; \ - fetch virtee/snphost SNPHOST_TAG; } > .tags.tmp; \ + { fetch virtee/snpguest SNPGUEST_TAG "$(SNPGUEST_TAG)"; \ + fetch AMDEPYC/beacon BEACON_TAG "$(BEACON_TAG)"; \ + fetch virtee/snphost SNPHOST_TAG "$(SNPHOST_TAG)"; } > .tags.tmp; \ mv .tags.tmp .tags @cat .tags diff --git a/versions.env b/versions.env new file mode 100644 index 00000000..c113f54f --- /dev/null +++ b/versions.env @@ -0,0 +1,6 @@ +# Upstream release versions used to build the host/guest images. +# Bump deliberately via a PR so any breakage in a new release is caught at review time. +# Leave a value empty to fall back to the upstream latest release at build time. +SNPHOST_TAG=v0.9.0 +SNPGUEST_TAG=v0.10.0 +BEACON_TAG=v1.1.0