Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions docs/bumping-upstream.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,18 @@ and `"sha256": ""`. **Keep the previous engine listed** with its checksum
intact: that is what `skrog engine list` offers and what `skrog engine
rollback` returns to. Dropping it would strand anyone who needs to go back.

The empty checksum is deliberate and temporary, and it makes this commit
**red**: `TestTheDefaultEngineShipsBothArchitectures` and
`TestTheDefaultEngineResolvesOnThisHost` require the default engine to be
installable on both architectures, and nothing with an empty checksum is.
There is no green intermediate state, so do not look for one. The release is
cut from this PR's commit (step 7) and its checksums land in the same PR, which
then merges green -- `main` never carries a manifest it cannot install.
The empty checksum is deliberate and temporary. `TestTheDefaultEngineShipsBothArchitectures`
and `TestTheDefaultEngineResolvesOnThisHost` require the default engine to be
installable on both architectures, and nothing with an empty checksum is. On a
**pull request** they skip, with a `::warning::` annotation saying the rootfs is
pending, rather than fail: a red the author expects is a red reviewers learn to
scroll past. They skip only when the sole problem is an empty checksum -- a
missing architecture or a bad URL still fails -- and only when
`GITHUB_EVENT_NAME` is `pull_request`, so a push to `main` and a local
`go test` still fail. The release is cut from this PR's commit (step 7) and its
checksums land in the same PR, which then merges with the tests running for
real -- `main` never carries a manifest it cannot install. **Do not merge
while those two tests show as skipped.**

### 6. Open the PR and let CI build it

Expand Down Expand Up @@ -160,7 +165,7 @@ letting the two drift silently.
- [ ] containerd / runc / buildkit: moved with a stated reason, or deliberately left alone
- [ ] `versions.env` updated, `ROOTFS_REVISION` reset to 1
- [ ] `manifest.json`: new default entry with empty sha256, previous engine retained
- [ ] `go test ./internal/release/` fails ONLY on the two default-engine checksum tests (expected until step 7)
- [ ] `go test ./internal/release/` fails ONLY on the two default-engine checksum tests (expected until step 7; they skip on a PR, so check that they are NOT skipped before merging)
- [ ] `rootfs.yml` green on both architectures, including the boot test and reference diff
- [ ] Rootfs release tagged on the PR head and published
- [ ] Checksums verified against the downloaded bytes, committed to the same PR, PR green and merged
Expand Down
8 changes: 4 additions & 4 deletions guest/rootfs/versions.env
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ ALPINE_ROOTFS_SHA256=auto # verified against Alpine's published .sha256 at bui

# Engine components, built from source (git tags in their upstream repos).
# ENGINE_VERSION is the user-facing number; MOBY_TAG is moby's own tag spelling.
ENGINE_VERSION=29.8.2
MOBY_TAG=docker-v29.8.2
ENGINE_VERSION=29.9.0
MOBY_TAG=docker-v29.9.0
CONTAINERD_VERSION=v2.3.6
RUNC_VERSION=v1.5.2
BUILDKIT_VERSION=v0.33.1
Expand All @@ -18,7 +18,7 @@ BUILDKIT_VERSION=v0.33.1
# engine VM. build-engine.sh fails the build on mismatch. Bump a *_SHA in the
# same commit as its *_VERSION; discover a new value by running the build with
# the SHA blank, which logs the resolved commit instead of failing.
MOBY_SHA=8af9fe3a36bab3e039862a2ab1cef1880c9b4d03
MOBY_SHA=a5b58c94d334674eae3a3207d4f05417643a90d0
CONTAINERD_SHA=ee2735368117d2eb259779949d5e75cdafec9761
RUNC_SHA=29dd3dc2b13b4123162e5fe132504bb4b15569f1
BUILDKIT_SHA=8c91502cf280bd70a0c50912ce251c46a8881d9f
Expand All @@ -42,7 +42,7 @@ ALPINE_DIGEST=sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec4349
# "engine upgrade refuses combinations outside the tested matrix" (PLAN §04).

# Toolchain used to build them; bumping this changes output, so it is pinned too.
# Floor is set by moby's go.mod (docker-v29.8.2 requires >= 1.26.8, as do
# Floor is set by moby's go.mod (docker-v29.9.0 requires >= 1.26.8, as do
# containerd v2.3.6 and buildkit v0.33.1).
GO_VERSION=1.26.8

Expand Down
14 changes: 14 additions & 0 deletions internal/release/arch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,25 @@ func TestTheDefaultEngineShipsBothArchitectures(t *testing.T) {
if err != nil {
t.Fatalf("default: %v", err)
}
var pending error
failed := false
for _, arch := range []string{"amd64", "arm64"} {
if _, err := def.RootfsFor(arch); err != nil {
if isPending(err) {
pending = err
continue
}
failed = true
t.Errorf("default engine %s cannot be installed on %s: %v",
def.Version, arch, err)
}
}
// Skip only when pending is ALL that is wrong: a missing arm64 entry next to
// a pending amd64 one must still fail.
if !failed && pending != nil {
skipWhilePending(t, pending) // does not return when it skips
t.Errorf("default engine %s is not released yet: %v", def.Version, pending)
}
}

// Every engine must have an amd64 ENTRY, which is the architecture the
Expand Down Expand Up @@ -141,6 +154,7 @@ func TestTheDefaultEngineResolvesOnThisHost(t *testing.T) {
}
r, err := def.HostRootfs()
if err != nil {
skipWhilePending(t, err)
t.Fatalf("the default engine has no rootfs for %s: %v", runtime.GOARCH, err)
}
// The URL must actually name this architecture. Selecting the wrong entry
Expand Down
24 changes: 23 additions & 1 deletion internal/release/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,30 @@
],
"engines": [
{
"version": "29.8.2",
"version": "29.9.0",
"default": true,
"rootfs": {
"amd64": {
"url": "https://github.com/wslkit/skrog/releases/download/rootfs-v29.9.0-1/skrog-rootfs-29.9.0-1-amd64.tar.gz",
"sha256": "bc219b98f770f0d9ebbfaa82154412a8f383f477877465e8c9818d00445272d0"
},
"arm64": {
"url": "https://github.com/wslkit/skrog/releases/download/rootfs-v29.9.0-1/skrog-rootfs-29.9.0-1-arm64.tar.gz",
"sha256": "4b06bbd5ef479ea0e8a8f2208a55643d0f5681db9263e5d078fca1f56909aff8"
}
},
"components": {
"dockerd": "29.9.0",
"containerd": "2.3.6",
"runc": "1.5.2",
"buildkit": "0.33.1",
"alpine": "3.24.1",
"nvidia-cdi-hook": "1.20.0"
}
},
{
"version": "29.8.2",
"default": false,
"rootfs": {
"amd64": {
"url": "https://github.com/wslkit/skrog/releases/download/rootfs-v29.8.2-1/skrog-rootfs-29.8.2-1-amd64.tar.gz",
Expand Down
40 changes: 40 additions & 0 deletions internal/release/pending_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package release_test

import (
"errors"
"fmt"
"os"
"testing"

"github.com/wslkit/skrog/internal/release"
)

// skipWhilePending turns "the default engine's rootfs is not released yet"
// into a skip, on a pull request only.
//
// An engine bump is red by construction until its rootfs is published: the
// release is cut from the PR's own head, and its checksums land in the same PR
// (docs/bumping-upstream.md, step 7). A red the author expects is a red every
// reviewer learns to scroll past, which is the habit that lets a real failure
// through. So while the checksum is the ONLY thing missing, the PR says so
// plainly instead of failing.
//
// Narrow on purpose:
// - only ErrNotPublished, i.e. a well-formed entry with an empty checksum.
// A missing architecture, a bad URL or a wrong engine still fail.
// - only when GITHUB_EVENT_NAME is pull_request. A push to main and any local
// run still fail, so an empty checksum cannot merge and stay unnoticed.
func isPending(err error) bool {
var notPublished *release.ErrNotPublished
return errors.As(err, &notPublished)
}

func skipWhilePending(t *testing.T, err error) {
t.Helper()
if err == nil || !isPending(err) || os.Getenv("GITHUB_EVENT_NAME") != "pull_request" {
return
}
msg := fmt.Sprintf("default engine rootfs is not released yet (expected on an engine-bump PR until its checksums are added): %v", err)
fmt.Printf("::warning title=engine rootfs pending::%s\n", msg)
t.Skip(msg)
}
Loading