Repository navigation
feat(bundle): add resume support to deploy - #1559
Conversation
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
|
@codex review |
|
@copilot review |
|
@greptileai review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 998da8c668
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-authored-by: slaskawi <8417158+slaskawi@users.noreply.github.com>
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
This reverts commit 5868626. Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
|
@greptileai review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ffb7da48e0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🔵 Needs a closer look
Address the local archive extraction cost, cover the deployed-state read failure path, and update the documented command with verification-policy flags.
Pull request overview
Adds --resume/-r to Next-mode bundle deployments, matching packages against successful Zarf deployment state before redeploying.
Changes:
- Adds CLI and deployment-layer resume support.
- Implements digest-, namespace-, and component-aware matching.
- Adds tests, documentation, and ADR 0027.
File summaries
| File | Description |
|---|---|
tests/testutil/cluster.go |
Adds a structured deployment test helper. |
tests/cluster/bundle_deploy_test.go |
Tests resume for directory, artifact, and OCI deployments. |
pkg/bundle/zarf.go |
Adds package-spec and state loader adapters. |
pkg/bundle/zarf_test.go |
Tests adapters and dependency behavior. |
pkg/bundle/deploy.go |
Wires resume options into bundle deployment. |
internal/zarf/source.go |
Handles filtered package metadata. |
internal/zarf/resume.go |
Implements deployment-state matching. |
internal/zarf/resume_test.go |
Tests resume matching and orchestration. |
internal/zarf/remote.go |
Resolves and pins OCI digests. |
internal/zarf/remote_test.go |
Tests remote digest behavior. |
internal/zarf/local.go |
Loads local package metadata and digests. |
internal/zarf/local_test.go |
Tests local package loading. |
internal/zarf/layout.go |
Loads package specs from layouts. |
internal/zarf/layout_test.go |
Tests layout filtering and errors. |
internal/zarf/deploy.go |
Applies resume filtering after selection and validation. |
internal/cli/bundle/dev_deploy.go |
Adds the development deploy resume flag. |
internal/cli/bundle/dev_deploy_test.go |
Tests development deploy propagation. |
internal/cli/bundle/deploy.go |
Adds the deploy resume flag. |
internal/cli/bundle/deploy_test.go |
Tests deploy flags and signatures. |
internal/cli/bundle/deploy_runner.go |
Propagates resume through the runner. |
internal/cli/bundle/deploy_runner_test.go |
Tests runner propagation. |
docs/how-to-guides/next/deploy-a-bundle.mdx |
Documents resume usage and limitations. |
docs/how-to-guides/migrate-legacy-to-next.mdx |
Updates migration guidance. |
docs/adr/0027-resume-bundle-deploy.md |
Defines resume behavior and boundaries. |
Review details
Suppressed comments (3)
docs/how-to-guides/next/deploy-a-bundle.mdx:104
- This new copy-paste command omits the artifact verification policy.
--resumedoes not bypass signature verification, so with the default flags this fails validation before resume is reached unless the artifact embeds a usable policy; please show the same--public-key/keyless or explicit unsigned-artifact flags used for the initial deployment.
CLI_FEATURES=NextMode=true uds bundle deploy ./my-bundle.tar.zst --resume
internal/zarf/local.go:54
packager.PackageDigestis not metadata-only for tarballs: it calls Zarf'slayout.LoadFromTar, which decompresses the entire archive into Zarf's global temp directory before computing the digest. As a result, every--resumeattempt on a large local.tar.zstmaterializes all payload layers (and line 63 then extracts metadata again), requiring full-package disk/time even when the package will be skipped; it also ignores this loader's configureds.tmpDir. Please use a digest path that can read archive metadata/checksums without materializing the payload, or otherwise avoid this full extraction and honor the configured workspace.
digest, err := packager.PackageDigest(ctx, path, packager.PackageDigestOptions{Architecture: s.arch})
internal/zarf/resume_test.go:132
- This case never reaches the state-read branch: because it omits
SpecLoader,filterResumeLevelsreturnsresume requires a package spec loaderbefore invokingDeployedPackagesFn. Consequently the test namedstate readdoes not cover the newErrReadDeployedPackagesfailure path or prove it aborts before hooks and deployment; give this case a valid spec loader (and keep the failing state callback) so that path is exercised.
{name: "state read", opts: DeployOptions{DeployedPackagesFn: func(context.Context) ([]state.DeployedPackage, error) { return nil, errors.New("state") }}},
- Files reviewed: 24/24 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
|
@codex review |
|
@greptileai review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
🟡 Changes recommended
A critical loader mismatch and moderate local archive I/O issue remain, along with documentation corrections.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
docs/how-to-guides/next/deploy-a-bundle.mdx:104
- This copy-paste resume command omits the trust policy required for the default artifact signature verification path. Unless the user's config already supplies a public-key or keyless policy, it fails validation before deployment; carry over the same verification input shown in the signed-artifact example or state that it is required.
docs/how-to-guides/next/deploy-a-bundle.mdx:101
- This matching summary omits the Zarf
metadata.name, which is part of the actual identity key. A package with the same digest, namespace, and components but a different Zarf name is intentionally redeployed, so the guide should state that name requirement explicitly.
Re-run a deployment with `--resume` to skip packages Zarf recorded with the same package digest, namespace override, filtered component names, and successful component status:
internal/zarf/local.go:54
- Calling
packager.PackageDigesthere uses Zarf's tarball path, which fully decompresses the archive before the selectivezarf.yaml/checksums.txtextraction below. A--resumeof a local.tar.zsttherefore still stages every payload (and then extracts metadata again), so a package that will be skipped pays the full package I/O and disk cost; use a digest path that does not materialize the archive payload or otherwise avoid the full unpack for resume.
digest, err := packager.PackageDigest(ctx, path, packager.PackageDigestOptions{Architecture: s.arch})
- Files reviewed: 26/26 changed files
- Comments generated: 1
- Review effort level: Lite
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
|
@codex review |
|
@greptileai review |
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
🟡 Changes recommended
Critical remote pinning and moderate filtering/temp-directory issues remain unresolved.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (4)
Previously missed (1) — in code that hasn't changed since the last review.
docs/how-to-guides/next/deploy-a-bundle.mdx:104
- This copy-paste resume example omits the trust-policy input used by the signed-artifact examples above. Unless the user has configured an embedded trust policy, rerunning this command on a signed artifact fails verification because the earlier
--public-key/keyless options are not persisted; include the required trust flags here or explicitly show the unsigned--skip-signature-verificationcase.
internal/zarf/layout.go:275
- The resume-only spec path filters out components targeted at another OS, but
LoadPackageLayoutdeploys withBuildComponentFilteralone (lines 259-263). For a package containingonly.localOScomponents, Zarf records the unfiltered component set while the resume matcher sees the OS-filtered set, so an otherwise identical deployment is never skipped. Align the component filter used for spec loading with the one used for deployment.
filter := filters.Combine(BuildComponentFilter(pkg.OptionalComponents), filters.ByLocalOS(runtime.GOOS))
internal/zarf/layout.go:182
- The artifact resume spec applies
ByLocalOS, whileLoadPackageLayoutbelow still applies onlyBuildComponentFilter(lines 165-168). A package with foreign-OS components therefore has a different intended component set from the set recorded during deployment and will be redeployed on every--resumerun instead of being skipped. Use one shared component filter for both paths.
filter := filters.Combine(BuildComponentFilter(pkg.OptionalComponents), filters.ByLocalOS(runtime.GOOS))
internal/zarf/local.go:54
packager.PackageDigestdoes not accept the configured Next temp directory and, for local archives, calls Zarf'sLoadFromTar, which allocates through the process-globalconfig.CommonOptions.TempDirectory. The Next CLI only carries--tmp-dirinConfigOptions, so resume of a local.tar.zstcan ignore the user's temp location and fail when the system temp is unavailable even though normal staging honors the configured directory. Use a digest/loading path that takess.tmpDir, or otherwise wire this Zarf temp configuration safely.
digest, err := packager.PackageDigest(ctx, path, packager.PackageDigestOptions{Architecture: s.arch})
- Files reviewed: 26/26 changed files
- Comments generated: 1
- Review effort level: Lite
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
|
@greptileai review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b7fc0393f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
🔵 Needs a closer look
Address the moderate local archive handling issue and the two remaining review findings.
Review details
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
internal/zarf/local.go:54
packager.PackageDigestloads a tarball through Zarf'sLoadFromTar, which extracts the entire archive underconfig.CommonOptions.TempDirectory, nots.tmpDir. This new resume path therefore ignores the configured--tmp-dirand performs a full extraction before the selective metadata extraction below, so large local archives can use the wrong filesystem and lose the intended metadata-only path. Use a temp-dir-aware digest calculation and avoid the duplicate extraction.
docs/how-to-guides/next/deploy-a-bundle.mdx:104
- This copy-paste resume command omits the trust policy required by artifact deployment. With no
--configcontainingsignature_verificationand no--skip-signature-verification, the default configuration has no public key or keyless policy, so validation fails before resume runs. Include the required--public-key/keyless flags or explicitly reference the configuration file used by the example.
CLI_FEATURES=NextMode=true uds bundle deploy ./my-bundle.tar.zst --resume
internal/zarf/remote.go:19
- Please keep OCI reference parsing and pinning behind
internal/oci(or use the already canonicalized repository reference). The repository's Next OCI boundary centralizes ORAS reference handling there; parsings.refdirectly ininternal/zarfduplicates that ownership and can diverge from the canonicalization performed by the Zarf/OCI remote layer.
"oras.land/oras-go/v2/registry"
- Files reviewed: 26/26 changed files
- Comments generated: 0 new
- Review effort level: Lite
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
bradclawsie
left a comment
There was a problem hiding this comment.
Looks nice so far! One UX question: the ADR says this can be used in the case of an interrupted or repeated deploy. How would I know when to reach for --resume? Does "interrupted" mean a previous deploy failed cleanly with an error message or actual disaster recovery?
Thanks for the review @bradclawsie ! Technically, in order the
At this point, we don't really care what happened. If the Zarf "state" Secret exists for a given package, we'll try to resume it. |
joelmccoy
left a comment
There was a problem hiding this comment.
Pretty happy with this. Would just request we actually test this feature in a a real e2e test for a resume scenario.
…i-177 Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com> # Conflicts: # docs/how-to-guides/next/deploy-a-bundle.mdx # internal/cli/bundle/deploy.go # internal/cli/bundle/deploy_test.go # internal/cli/bundle/dev_deploy.go
Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
chance-coleman
left a comment
There was a problem hiding this comment.
all my comments were addressed by others, im happy with this. Would want to get @jasonwashburn approval as well before merging.
jasonwashburn
left a comment
There was a problem hiding this comment.
looks like there's conflicts to resolve, but otherwise lgtm
…i-177 Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com> # Conflicts: # tests/cluster/bundle_deploy_test.go
Description
Adds
--resume(-r) to Next-modeuds bundle deployanduds bundle dev deploy.Resume runs after package selection and dependency validation. It skips a package only when Zarf records one unambiguous deployment with:
SucceededstateBundle hooks still run when every package is skipped. Cluster-state or intended-package metadata errors stop deployment before hooks or package deployment.
The implementation uses current Zarf APIs for schema-aware package loading, archive digest calculation, selective archive extraction, digest-pinned OCI resolution, and deployment digest recording.
Values-file and deploy-time configuration changes are not represented in the resume match. This boundary is documented in ADR 0027 and the deployment guide.
Related Issue
Relates to CLI-177
Type of change
Checklist before merging