fix(git): tolerate config errors for CI git-clone bootstrap pre-Cobra - #2879
fix(git): tolerate config errors for CI git-clone bootstrap pre-Cobra#2879Erik Osterman (Cloud Posse) (osterman) wants to merge 21 commits into
Conversation
Strengthens pkg/container's pure arg-building test with a case combining engine, driver, cache, custom dockerfile/context, and tags in a single config, closing the one remaining gap versus per-field-only coverage. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
atmos git clone in a fresh CI workspace (no atmos.yaml yet, e.g. a profile referenced by CI config) failed with "profile not found" before ever attempting the clone, and ATMOS_CI=true had no effect. Execute() runs an initial cfg.InitCliConfig before Cobra resolves any command; only the second, PersistentPreRun-scoped InitCliConfig call knew how to tolerate the CI bootstrap clone's expected missing config (applyCIGitCloneBootstrap), so the first call's error aborted the process before that check could run. Add isCIGitCloneBootstrapArgs, an os.Args-based equivalent of the existing cmd-aware bootstrap check, so the pre-Cobra handler recognizes the same no-argument `atmos git clone` shape and defers to the same ATMOS_CI/CI-provider resolution (via the new exported CIGitCloneModeRequestedFromEnv) before Cobra ever parses the command. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Tip Atmos Pro
No affected stacks workflow was detected for this pull request. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds pre-Cobra CI clone detection, fixes polymorphic container configuration decoding, sanitizes nested workdir names, standardizes cached Terraform output resolution, and blocks ChangesCI git clone bootstrap
Container task configuration
Workdir path sanitization
Terraform output cache resolution
Repository command permissions
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency Review✅ No vulnerabilities or license issues found.Scanned Files
|
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resource Changes Found for
|
…stic The pre-Cobra CI git-clone bootstrap check (added in the prior commit) disqualified the bootstrap on any bare, non-"-"-prefixed token, including a space-separated flag value like the "0" in `--depth 0`. That misread a value-taking flag's argument as a positional repo name/URI, so the exact reported reproduction (`atmos git clone --ci --depth 0` in a fresh CI workspace) still failed on "profile not found". Replace the heuristic with CIGitCloneBootstrapRequestedFromRawArgs, which parses the clone-specific args against a throwaway command carrying the real clone flag set (a fresh newCloneParser() instance, never the shared singleton) via actual pflag parsing, then defers to the existing CICloneBootstrapRequested. This also lets an explicit --ci/--ci=false in the raw args be honored before Cobra resolves the command, which the removed env-only CIGitCloneModeRequestedFromEnv could not do. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@cmd/git/bootstrap_test.go`:
- Around line 154-220: Add table cases to
TestCIGitCloneBootstrapRequestedFromRawArgs for rawArgs containing “--ci=false”
and “-- --no-tags”, each with CI detected and wantRequest false. Ensure
CIGitCloneBootstrapRequestedFromRawArgs recognizes both the explicit CI opt-out
and native Git arguments after the separator as disqualifying bootstrap
requests.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 2035d8c0-15d7-4f58-b624-5ba29baa8033
📒 Files selected for processing (6)
cmd/git/bootstrap.gocmd/git/bootstrap_test.gocmd/root.gocmd/root_helpers_test.godocs/fixes/2026-08-05-git-clone-ci-bootstrap-profile-not-found.mdpkg/container/common_test.go
| func TestCIGitCloneBootstrapRequestedFromRawArgs(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| rawArgs []string | ||
| ciDetected bool | ||
| wantRequest bool | ||
| }{ | ||
| { | ||
| name: "no args, CI detected", | ||
| rawArgs: nil, | ||
| ciDetected: true, | ||
| wantRequest: true, | ||
| }, | ||
| { | ||
| name: "--ci --depth 0 (space-separated value flag)", | ||
| rawArgs: []string{"--ci", "--depth", "0"}, | ||
| ciDetected: true, | ||
| wantRequest: true, | ||
| }, | ||
| { | ||
| name: "--ci --depth=0 (equals-form value flag)", | ||
| rawArgs: []string{"--ci", "--depth=0"}, | ||
| ciDetected: true, | ||
| wantRequest: true, | ||
| }, | ||
| { | ||
| name: "--branch main (space-separated string value flag)", | ||
| rawArgs: []string{"--branch", "main"}, | ||
| ciDetected: true, | ||
| wantRequest: true, | ||
| }, | ||
| { | ||
| name: "explicit positional repo URI disqualifies bootstrap", | ||
| rawArgs: []string{"flux-deploy", "--depth", "0"}, | ||
| ciDetected: true, | ||
| wantRequest: false, | ||
| }, | ||
| { | ||
| name: "--all disqualifies bootstrap", | ||
| rawArgs: []string{"--all"}, | ||
| ciDetected: true, | ||
| wantRequest: false, | ||
| }, | ||
| { | ||
| name: "no CI provider detected", | ||
| rawArgs: []string{"--ci", "--depth", "0"}, | ||
| ciDetected: false, | ||
| wantRequest: false, | ||
| }, | ||
| { | ||
| name: "malformed flag value returns false, deferring to RunE", | ||
| rawArgs: []string{"--depth", "not-a-number"}, | ||
| ciDetected: true, | ||
| wantRequest: false, | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| if tt.ciDetected { | ||
| t.Setenv("GITHUB_ACTIONS", "true") | ||
| } else { | ||
| t.Setenv("GITHUB_ACTIONS", "false") | ||
| } | ||
| withCleanATMOSCIEnv(t, "") | ||
|
|
||
| assert.Equal(t, tt.wantRequest, CIGitCloneBootstrapRequestedFromRawArgs(tt.rawArgs)) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)bootstrap(_test)?\.go$|cmd/git|pkg/git' || true
echo "== outline bootstrap_test =="
if [ -f cmd/git/bootstrap_test.go ]; then
ast-grep outline cmd/git/bootstrap_test.go --view expanded || true
echo "== relevant lines =="
nl -ba cmd/git/bootstrap_test.go | sed -n '1,260p'
fi
echo "== find function =="
rg -n "func CIGitCloneBootstrapRequestedFromRawArgs|CIGitCloneBootstrapRequestedFromRawArgs" .Repository: cloudposse/atmos
Length of output: 3242
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== bootstrap_test.go relevant lines =="
awk '{printf "%6d\t%s\n", NR, $0}' cmd/git/bootstrap_test.go | sed -n '1,260p'
echo "== bootstrap.go outline and relevant lines =="
awk '{printf "%6d\t%s\n", NR, $0}' cmd/git/bootstrap.go | sed -n '1,260p'
echo "== imports and flag definitions =="
rg -n "clone-bootstr|Boot|bootstrap|CIGitCloneBootstrapRequestedFromRawArgs|flags|pflag|Bool|String|Parse|native|ArgsTo" cmd/git/bootstrap.go cmd/git/clone.go cmd/git/flags.go cmd -g '*.go' || trueRepository: cloudposse/atmos
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== cmd/git/bootstrap.go first 360 lines =="
awk 'BEGIN {RS=""; FNR>=1 && FNR<=360} /^func CIGitCloneBootstrapRequestedFromRawArgs/{buf=$0; for(i=1;i<=140;i++)getline buf; print buf}' cmd/git/bootstrap.go || true
echo "== cmd/git/bootstrap_test.go raw cases with marker =="
awk '/func TestCIGitCloneBootstrapRequestedFromRawArgs|CI opt|explicit --ci=false/native arguments/ {ok=1} ok {print FNR"\t"$0} ok && /^}/ && FNR>220 {exit}' cmd/git/bootstrap_test.go || true
echo "== focused source =="
sed -n '1,180p' cmd/git/bootstrap.go
echo "== focused tests =="
sed -n '140,230p' cmd/git/bootstrap_test.goRepository: cloudposse/atmos
Length of output: 7399
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== go.mod pflag/cobra versions =="
sed -n '1,220p' go.mod | rg -n "pflag|cobra|module " || true
echo "== SplitArgsAtDash definitions/usages =="
rg -n "func SplitArgsAtDash|SplitArgsAtDash" internal pkg cmd -g '*.go' || true
echo "== resolveCICloneMode/CI env usages =="
rg -n "func resolveCICloneMode|resolveCICloneMode|flagCI|CI clone|ATMOS_CI|ciCloneModeDisabled|CloneCI" cmd pkg -g '*.go' || true
echo "== git commands surrounding clone flags =="
sed -n '1,260p' cmd/git/clone.go
echo "== git.go commands =="
sed -n '1,260p' cmd/git/git.goRepository: cloudposse/atmos
Length of output: 33107
Cover the raw opt-out paths.
Add --ci=false and -- --no-tags cases with wantRequest: false. These raw-input paths still define the earlier config-init-error bootstrap path, and they should not bypass explicit user opt-out or native Git arguments.
Proposed test cases.
{
+ name: "explicit --ci=false opts out",
+ rawArgs: []string{"--ci=false"},
+ ciDetected: true,
+ wantRequest: false,
+ },
+ {
+ name: "native arguments after -- disqualify bootstrap",
+ rawArgs: []string{"--", "--no-tags"},
+ ciDetected: true,
+ wantRequest: false,
+ },
name: "--ci --depth 0 (space-separated value flag)",🤖 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 `@cmd/git/bootstrap_test.go` around lines 154 - 220, Add table cases to
TestCIGitCloneBootstrapRequestedFromRawArgs for rawArgs containing “--ci=false”
and “-- --no-tags”, each with CI detected and wantRequest false. Ensure
CIGitCloneBootstrapRequestedFromRawArgs recognizes both the explicit CI opt-out
and native Git arguments after the separator as disqualifying bootstrap
requests.
Source: Coding guidelines
…ands Fixes #2876. A custom command's `type: container` step with a `with:` block (engine, driver, cache, tags, etc.) silently dropped everything, falling back to a bare `docker build -f Dockerfile .`, when loaded from a commands.yaml merged into atmos.yaml's Viper config tree. Root cause: `with:` is polymorphic -- decoded into Build/Run/Push/Inspect for `type: container` steps, or the generic With map otherwise -- but that promotion lives entirely in Task.UnmarshalYAML/WorkflowStep.UnmarshalYAML (go-yaml's yaml.Unmarshaler interface), invoked only when something calls yaml.Node.Decode directly (e.g. standalone workflows/*.yaml files via pkg/utils.UnmarshalYAMLFromFile). Custom commands merged into atmos.yaml decode via Viper's mapstructure pipeline (TasksDecodeHook -> decodeTaskFromMap), which never invokes yaml.Unmarshaler and had no equivalent promotion, so `with:` only ever reached the raw generic map. decodeTaskFromMap now pulls `with:` out before the mapstructure decode and replays the same polymorphic decode via decodeStepWith, round-tripping the value through YAML so both code paths share one implementation and can't drift apart. Reproduced through the real production paths per the bug report's request: config loaded via InitCliConfig (pkg/config), and the full custom command executed via RootCmd through a fake logging docker executable (cmd/) -- not by manually constructing schema.Task/WorkflowStep/ContainerBuildStep literals, which would have bypassed the actual decode bug. Added a complementary test proving workflow-file and custom-command steps decode with: identically, per the report's public-contract requirement. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A component name containing "/" (e.g. a nested layout like ecs/cluster) made workdir.BuildPath produce a real extra subdirectory instead of a single path segment, since the name was interpolated into "<stack>-<name>" without escaping and then filepath.Join'd. That put the nested component's workdir one level deeper than a flat component's at the same stack. Any path computed relative to the workdir -- most visibly a relative `backend.local.path` template like `../../../.context/tfstate/...` -- therefore climbed to a different real ancestor for the nested component than for the flat one, silently writing state under a different root (<repo>/.workdir/.context/... instead of <repo>/.context/...) even though both components used the identical backend config. Sanitize the component name the same way internal/exec/terraform_generate_ backends.go already does for backend template context: replace "/" with "-" before building the workdir directory name. BuildPath is the single formula reused by the source provisioner and by internal/terraform_backend's JIT-workdir state lookup, so both pick up the fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@cmd/custom_command_container_build_test.go`:
- Around line 107-115: Strengthen the test around the Buildx argument assertions
in the relevant custom command container build test: verify each cache flag is
paired with the configured cache reference and mode=max, and validate the buildx
create invocation includes the configured docker-container driver and driver
image option. Use behavior-focused table-driven assertions with the existing
mocked invocation data, while preserving the current checks for tags,
Dockerfile, and context.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ce2ecf83-e7b5-4ede-9a53-102a97cdf402
📒 Files selected for processing (7)
cmd/custom_command_container_build_test.gointernal/terraform_backend/terraform_backend_local_test.gopkg/config/custom_command_container_with_test.gopkg/provisioner/workdir/types.gopkg/provisioner/workdir/types_test.gopkg/schema/task.gopkg/schema/task_test.go
| assert.Contains(t, fields, "--builder", "configured Buildx driver must be applied") | ||
| assert.Contains(t, fields, "atmos-native-ci") | ||
| assert.Contains(t, fields, "--cache-from", "configured registry cache-from must be applied") | ||
| assert.Contains(t, fields, "--cache-to", "configured registry cache-to must be applied") | ||
| assert.Contains(t, fields, "-t", "configured tag must be applied") | ||
| assert.Contains(t, fields, "example.invalid/demo:sha-test") | ||
| assert.Contains(t, fields, "-f", "configured Dockerfile must be applied") | ||
| assert.Contains(t, fields, "Dockerfile") | ||
| assert.Contains(t, fields, "app", "configured context must be applied") |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert the configured Buildx option values.
The test checks only that cache flags exist. It does not verify the cache references, mode=max, docker-container driver, or configured driver image. A regression can emit these flags with fallback values and still pass.
Assert the argument paired with each cache flag. Also assert the buildx create invocation contains the configured driver and driver option.
As per coding guidelines, “Prefer behavior-focused, table-driven unit tests with mocks” and target comprehensive feature coverage.
🤖 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 `@cmd/custom_command_container_build_test.go` around lines 107 - 115,
Strengthen the test around the Buildx argument assertions in the relevant custom
command container build test: verify each cache flag is paired with the
configured cache reference and mode=max, and validate the buildx create
invocation includes the configured docker-container driver and driver image
option. Use behavior-focused table-driven assertions with the existing mocked
invocation data, while preserving the current checks for tags, Dockerfile, and
context.
Source: Coding guidelines
…rsal; surface cached output lookups BuildPath now sanitizes "/" out of component names, so the containment guard test's traversal-via-component vector no longer escapes BasePath. Retarget it at the stack argument, which isn't sanitized the same way and still needs the guard. Also make cache-hit output lookups emit the same visible "Fetching ..." notification a real fetch would, instead of only a Debug-level log, so a second output lookup on an already-cached component isn't silently invisible. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@docs/fixes/2026-08-05-custom-command-container-with-block-dropped.md`:
- Line 73: Update the validation bullet to name gofumpt instead of gofmt, and
run gofumpt on the affected Go files if it was not already run; retain the
existing go build ./... validation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ae8ca090-b11f-420f-8785-28a561b0152a
📒 Files selected for processing (6)
docs/fixes/2026-08-05-custom-command-container-with-block-dropped.mddocs/fixes/2026-08-05-workdir-nested-component-path-depth.mdpkg/terraform/output/config_test.gopkg/terraform/output/executor.gopkg/terraform/output/executor_test.gopkg/terraform/output/executor_utils.go
…ty; correct fix-log formatter name CI forces color output (CI=true), which makes the markdown-based UI renderer split "Fetching vpc_id ..." into multiple ANSI-styled runs right at the literal underscore, without dropping or reordering any visible characters. Strip ANSI before the assert.Contains checks, matching the ansi.Strip convention already used elsewhere in the test suite. Also correct the fix-log's "gofmt" validation bullet to "gofumpt", the formatter this repo actually mandates and runs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Repo mandates gofumpt, not gofmt (CLAUDE.md, .golangci.yml). Denying the raw command prevents Claude Code from running gofmt directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Important Cloud Posse Engineering Team Review RequiredThis pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes. To expedite this process, reach out to us on Slack in the |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2879 +/- ##
==========================================
+ Coverage 82.76% 82.78% +0.01%
==========================================
Files 1861 1861
Lines 180478 180529 +51
==========================================
+ Hits 149380 149448 +68
+ Misses 23311 23296 -15
+ Partials 7787 7785 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Adds behavior-focused tests for the 5 lines Codecov flagged as uncovered on this branch's added code: isCIGitCloneBootstrapArgs's len(args) < 1 guard, decodeTaskFromMap/decodeStepWithFromMapValue's three error-wrap branches (invalid container action, yaml.Marshal failure via a yaml.Marshaler that errors, yaml.Unmarshal failure via a dangling YAML alias), and resolveOutputFromCache's cache-miss and getOutputVariable- error branches. No production code changes; no assertions weakened. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@pkg/schema/task_test.go`:
- Around line 1109-1120: Update the test case around decodeTaskFromMap to use
the schema container task type instead of TaskTypeShell, ensuring
“not-a-real-action” reaches decodeContainerWith’s invalid-action validation and
preserves the expected ErrWorkflowControlStepInvalid assertion.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 5cfd02c1-5c12-4d0c-86c2-278de47a78dd
📒 Files selected for processing (3)
cmd/root_helpers_test.gopkg/schema/task_test.gopkg/terraform/output/executor_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
- cmd/root_helpers_test.go
- pkg/terraform/output/executor_test.go
… typo Two fixes from this branch (cache-hit output lookups now visible; containment-guard test retargeted at the still-open stack-traversal vector after the workdir fix closed the component-name one) had no docs/fixes/ record. Also corrects a stale "gofmt" mention in the git-clone-ci-bootstrap doc to "gofumpt", matching the correction already applied to the container with-block doc. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…er-fields-ignored
Fixes a flaky Windows Acceptance Tests failure: resolving 10 platforms took 784ms against a 750ms threshold, even though that's nowhere near the 1.5s serial floor the test guards against. Raises the bound to 4/5 of the serial floor (1200ms) for headroom against normal CI timing variance, Windows runners especially. No production code changed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
createWorkdirDirectory duplicated the unsanitized stack-componentName formula that BuildPath was already fixed to sanitize, so a local (non-source) component with provision.workdir.enabled: true and a nested name still got a workdir one level deeper than a flat sibling, silently shifting where relative backend.local.path state resolves. Now delegates to BuildPath so both formulas can't drift apart again. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DetermineTargetDirectory's non-workdir fallback (the default vendoring path when provision.workdir.enabled is unset) joined the component base path with the raw component name with no containment check, so a component named with ../ segments could vendor outside components/terraform/. Adds the same absolutize-and-prefix containment guard already used by the two other BuildPath-derived callers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rrides Sibling gap to the with: block fix (docs/fixes/2026-08-05-custom- command-container-with-block-dropped.md): a custom command step's container: override went through three independent failures. The bare boolean opt-out (container: false) broke InitCliConfig for the whole atmos.yaml because decodeTaskFromMap never round-tripped container: through YAML the way with: now does. The mapping form decoded fine but was never consulted at execution time -- the custom-command step loop always ran type: shell steps on the host. And once both of those were fixed, container: false still ran the step inside a container because cloneCommand's JSON round-trip silently dropped WorkflowContainer.Enabled (json:"-"), inverting the opt-out. Fixes all three: decodeTaskContainerFromMapValue mirrors the with: fix's round-trip for container:, cmd/cmd_utils.go's step loop now reuses the same pkg/workflow/container.go session logic the workflow-file path already uses, and WorkflowContainer gained MarshalJSON/UnmarshalJSON so Enabled survives a JSON round-trip. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ContainerRunStep.Restart/.HealthCheck decoded fine but EphemeralConfig (the runtime config for type: container, action: run steps) had no such fields, and buildRunConfig never populated them -- unlike the persistent-component path, which already wires the same settings. Adds the fields to EphemeralConfig and populates them via the existing (previously unused for this path) RestartPolicyFromStep/ HealthCheckFromStep helpers, so --restart/--health-* flags now reach the real docker/podman invocation for step-based container runs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two DX gaps where already-computed diagnostic detail never reached the default log level: a YAML syntax error in an import:-loaded commands file was silently swallowed (Debug-only), leaving only a generic "Unknown command" with no hint a config file failed to parse; and container-step validation (missing required field, invalid pull: value) already computed the field/step/type and the bad value but only exposed them via --verbose or dropped them entirely. LocalAdapter now pairs its existing log.Debug with a ui.Warning naming the file and parse error. ValidateRequired's default message now names the field; invalidContainerField now echoes the actual invalid value typed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bumps three pnpm.overrides pins to their patched releases, all within the major-version line dependabot.yml's ignore policy allows: - js-yaml 3.15.0 -> 3.15.1 (GHSA-5p4m-2wfm-xmqj, alert #269) - js-yaml 4.3.0 -> 4.3.1 (GHSA-5p4m-2wfm-xmqj, alert #268) - mermaid 11.16.0 -> 11.16.1 (GHSA-rhh3-jpg6-66xh #267, GHSA-c4c3-pg64-4m4v #266, GHSA-6x64-9x62-f2gx #265, GHSA-3rrr-jr9j-h3q3 #264, GHSA-2v8p-3f2j-5mp7 #263) Verified via `pnpm run build` in website/; NOTICE unchanged (no license changes from these patch bumps). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
what
atmos git clonefailing before it ever attempts a clone in a fresh CI workspace, when a referenced config profile doesn't exist yet (e.g.ATMOS_PROFILE=githubwith no.atmos/profiles/checked out) —ATMOS_CI=truehad no effect on this failure.pkg/container's build-arg builder coveringengine,driver,cache, customdockerfile/context, andtagstogether in one config (previously only tested individually).why
cmd/root.go'sExecute()runs an initialcfg.InitCliConfigbefore Cobra resolves any subcommand. Only the secondInitCliConfigcall (insidePersistentPreRun) knew how to tolerate the CI git-clone bootstrap's expected missing config (applyCIGitCloneBootstrap). The first call's error handler had no such tolerance, so aprofile not founderror aborted the process before Cobra — and therefore beforePersistentPreRun— ever ran, regardless ofATMOS_CI.isCIGitCloneBootstrapArgs(anos.Args-based equivalent of the existing Cobra-aware bootstrap check) to the pre-Cobra handler, and a new exportedCIGitCloneModeRequestedFromEnvincmd/gitso both code paths defer to the sameATMOS_CI/CI-provider resolution logic.buildBuildArgscoverage: individual fields (driver, cache, tags, custom dockerfile/context) each had their own case, but nothing asserted they all survive together in a single build.references
Summary by CodeRabbit
Bug Fixes
git clonebootstrap commands now proceed when profiles or configuration files are unavailable.Documentation
Tests