feat(gha): use released mip to fetch pkgs artifacts for CI - #692
Conversation
📝 WalkthroughWalkthroughA new reusable GitHub composite action resolves a channel-specific ChangesGuest artifact materialization
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Workflow as GitHub workflow
participant Action as materialize action
participant Storage as storage.googleapis.com/minimal-one
participant Mip as mip materialize
Workflow->>Action: provide artifact output and target architecture
Action->>Storage: fetch channel pointer and mip binary
Action->>Mip: materialize output into destination
Mip-->>Workflow: produce kernel or rootfs artifact
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (5)
.github/workflows/ci-macos.yml (1)
46-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStale comment: job no longer builds the
minimalCLI to materialize artifacts.With this change, materializing the kernel/rootfs (Lines 79-92) is now done by fetching a prebuilt
mipvia the composite action, not by buildingminimalfrom source. The remaining toolchain/cargo-cache steps are for cross-compilingminimaldinto the initramfs (Line 97), not for the materialize step. Worth updating the comment so it doesn't mislead future readers about what's actually happening here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/ci-macos.yml around lines 46 - 54, Update the stale explanatory comment in the CI macOS workflow so it matches the current flow: the kernel/rootfs materialization is no longer done by building the `minimal` CLI from this repo, but by fetching a prebuilt `mip` through the composite action. Keep the comment focused on the actual steps around the materialize job and the later `minimald` cross-compilation/initramfs cache steps, and remove references to building `minimal` or repo-source artifact generation..github/actions/materialize/action.yml (4)
71-73: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
fetch()has no request timeout.
--retry 3only retries failed connections; it doesn't bound a stalled/slow transfer. A hung download would block the step until the job-leveltimeout-minuteskills it.⏱️ Suggested fix
fetch() { - curl --proto '=https' --proto-redir '=https' --tlsv1.2 --retry 3 -fsSL "$1" -o "$2" + curl --proto '=https' --proto-redir '=https' --tlsv1.2 --retry 3 \ + --connect-timeout 10 --max-time 120 -fsSL "$1" -o "$2" }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/materialize/action.yml around lines 71 - 73, The fetch() helper currently relies on curl retries but has no request timeout, so a stalled download can hang the action step. Update fetch() in the materialize action to add an explicit curl timeout option (for both connect and overall transfer) while keeping the existing HTTPS-only and retry behavior, so the download fails fast instead of waiting for the job timeout.
83-88: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value
INPUT_CHANNELisn't restricted to an allowlist before being interpolated into the fetch URL.
archis validated with acasestatement (Lines 49-52), butchannelflows straight into"$BASE/$INPUT_CHANNEL"unchecked. All current callers pass hardcoded literals (stable/unstable), so this isn't exploitable today, but as a reusable action it's worth constraining for defense-in-depth.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/materialize/action.yml around lines 83 - 88, Validate INPUT_CHANNEL in the action before it is used in fetch and only allow the expected literals (for example, stable and unstable), similar to the existing arch case check. Update the version-resolution block in materialize/action.yml so the "$BASE/$INPUT_CHANNEL" URL is only constructed after the allowlist check, and fail early with a clear error if the channel is anything else.
90-98: 🔒 Security & Privacy | 🔵 Trivial | 🏗️ Heavy liftNo integrity verification of the downloaded
mipbinary before execution.The script fetches
mipover TLS and immediatelychmod +x+ executes it (Line 98) with no checksum/signature check against the resolvedversion. TLS protects transport, but not against a compromised/tampered object in the bucket. Other fetch scripts in this repo are described elsewhere as "pin-verified" (e.g. gvproxy fetch) — this new path departs from that pattern for a binary that gets executed directly.🔒 Suggested approach
Publish a checksum (e.g.
sha256) alongside eachmip-linux-$runner_archbuild and verify it after fetch:bin="$RUNNER_TEMP/mip" fetch "$BASE/versions/$version/mip-linux-$runner_arch" "$bin" + fetch "$BASE/versions/$version/mip-linux-$runner_arch.sha256" "$bin.sha256" + (cd "$RUNNER_TEMP" && sha256sum -c <(awk '{print $1, "mip"}' mip.sha256)) chmod +x "$bin"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/materialize/action.yml around lines 90 - 98, The `mip` download-and-execute path in the action script is missing integrity verification before running the binary. Update the fetch flow around the `fetch`, `chmod +x`, and `materialize` steps to verify the downloaded `mip-linux-$runner_arch` artifact against a checksum or signature tied to the resolved `version` before execution. Use the existing `version`/`runner_arch` resolution in this action to locate the right verification data, and only proceed to `"$bin" materialize` after the verification succeeds.
83-93: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winEvery
materializecall re-resolves the channel and re-downloadsmip, even within the same job.
release.yml'sfetch-release-guest-artifactsjob invokes this action 4 times back-to-back;ci-macos.yml/ci-linux-kvm.ymlinvoke it twice each. Each call re-fetches the channel pointer and themipbinary from scratch, since nothing persists resolution across steps in the same job ($RUNNER_TEMPis per-job, but the script never checks for an existing/matching binary before fetching again).♻️ Suggested optimization
+ if [[ -x "$bin" ]] && [[ "$(cat "$RUNNER_TEMP/.mip-version" 2>/dev/null)" == "$version" ]]; then + echo "Reusing already-fetched mip $version" + else + fetch "$BASE/versions/$version/mip-linux-$runner_arch" "$bin" + chmod +x "$bin" + echo "$version" > "$RUNNER_TEMP/.mip-version" + fi🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/materialize/action.yml around lines 83 - 93, The materialize action always re-resolves the channel and re-downloads mip on every invocation, even when the same job has already resolved the same channel/version. Update the action logic around the channel-pointer resolution and mip download to first check for an existing cached/matching binary in the job temp area before calling fetch again, and only re-fetch when the channel or version has changed. Keep the behavior localized to the existing resolve-and-download flow using the channel-pointer, version, and bin steps.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/actions/materialize/action.yml:
- Around line 71-73: The fetch() helper currently relies on curl retries but has
no request timeout, so a stalled download can hang the action step. Update
fetch() in the materialize action to add an explicit curl timeout option (for
both connect and overall transfer) while keeping the existing HTTPS-only and
retry behavior, so the download fails fast instead of waiting for the job
timeout.
- Around line 83-88: Validate INPUT_CHANNEL in the action before it is used in
fetch and only allow the expected literals (for example, stable and unstable),
similar to the existing arch case check. Update the version-resolution block in
materialize/action.yml so the "$BASE/$INPUT_CHANNEL" URL is only constructed
after the allowlist check, and fail early with a clear error if the channel is
anything else.
- Around line 90-98: The `mip` download-and-execute path in the action script is
missing integrity verification before running the binary. Update the fetch flow
around the `fetch`, `chmod +x`, and `materialize` steps to verify the downloaded
`mip-linux-$runner_arch` artifact against a checksum or signature tied to the
resolved `version` before execution. Use the existing `version`/`runner_arch`
resolution in this action to locate the right verification data, and only
proceed to `"$bin" materialize` after the verification succeeds.
- Around line 83-93: The materialize action always re-resolves the channel and
re-downloads mip on every invocation, even when the same job has already
resolved the same channel/version. Update the action logic around the
channel-pointer resolution and mip download to first check for an existing
cached/matching binary in the job temp area before calling fetch again, and only
re-fetch when the channel or version has changed. Keep the behavior localized to
the existing resolve-and-download flow using the channel-pointer, version, and
bin steps.
In @.github/workflows/ci-macos.yml:
- Around line 46-54: Update the stale explanatory comment in the CI macOS
workflow so it matches the current flow: the kernel/rootfs materialization is no
longer done by building the `minimal` CLI from this repo, but by fetching a
prebuilt `mip` through the composite action. Keep the comment focused on the
actual steps around the materialize job and the later `minimald`
cross-compilation/initramfs cache steps, and remove references to building
`minimal` or repo-source artifact generation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 411f96dd-dc7f-4f83-8d0f-47333ca05a9c
📒 Files selected for processing (4)
.github/actions/materialize/action.yml.github/workflows/ci-linux-kvm.yml.github/workflows/ci-macos.yml.github/workflows/release.yml
Resolves against #692, which introduced the materialize composite (channel-released prebuilt mip; no source build) for the guest kernel/rootfs pulls — superseding this branch's guest-artifacts composite, which wrapped the same call sites around scripts/fetch-artifact.sh. Resolution: adopt materialize at every conflicted call site (ci-macos artifacts, ci-linux-kvm, release fetch-release-guest-artifacts, including main's removal of the now unneeded toolchain/protoc/cargo-cache steps in the release fetch job), delete the guest-artifacts composite, and point the VM lanes' composite path filters at .github/actions/materialize/** instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Base moved to main's materialize composite (#692); union the mac lane's composite path filters (materialize replaces guest-artifacts, the vendor/libkrun/** pin entry stays). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hopefully this will shave 20 mins off our CI.
Summary by CodeRabbit
New Features
Bug Fixes