v1.225.0-rc.2
Pre-release
Pre-release
ci: run required checks for GitHub merge queue Erik Osterman (Cloud Posse) (@osterman) (#2813)
## what- Run the existing required test, CodeQL, CODEOWNERS, and symlink workflows for merge-group commits.
- Run golangci lint for merge groups and keep CODEOWNERS validation safe when no pull-request payload is present.
why
- GitHub merge queues require required checks to report on their synthetic merge commits before a queued pull request can merge.
references
Summary by CodeRabbit
- Chores
- Added merge queue support to automated security, testing, linting, CODEOWNERS, and symlink verification checks.
- Ensured required validations run consistently for merge queue commits, including appropriate handling of CODEOWNERS checks.
🚀 Enhancements
fix: close yq/merge concurrency races, route yq logs through Atmos logger Erik Osterman (Cloud Posse) (@osterman) (#2826)
## what- Route yq's internal (
go-logging) diagnostics through the Atmos logger via a newinternal/yqpackage, so they inherit Atmos's formatting, configured log destination, and secret masking instead of writing straight to stderr, unformatted and unmasked. - Centralize yq's process-global logger backend and expression-parser init in that same package, shared by both
pkg/utilsandpkg/yaml, closing a cross-package data race left over after #2822. - Fix an unrelated data race in
pkg/merge.MergeContext.WithFile, where concurrent per-stack-file goroutines sharing a parent import chain could write into the same backing-array slot at the same time. - Bump the website's
brace-expansiondependency (viapnpm.overrides) to patched versions, closing Dependabot alert #261.
why
- yq processes YAML that can carry secrets, so letting its diagnostics bypass Atmos's masking-aware I/O layer was a real leak risk whenever Trace-level logging is enabled.
go-logging'sSetBackendwraps any plainBackendin an unsynchronized, map-based type unless the backend itself implementsLeveled. #2822's mutex-based fix for #2821 only coveredpkg/utils, leavingpkg/yaml/edit.gofree to mutate the same global state independently — confirmed withgo test -race.- The
MergeContext.WithFilerace surfaced incidentally while validating the yq fix under-race(TestExecuteHelmfile_ComponentNotFound), and turned out to be a genuine, separate concurrency bug worth fixing here rather than leaving in place. brace-expansion'sexpand()bounded the number of results but not their length, letting a small attacker-controlled input crash the Node process with an uncatchable out-of-memory error (CVE-2026-14257). The fix stays within the pinned major lines, so it isn't blocked bydependabot.yml's major-version-bump policy.
references
- #2821 / #2822 (the yq concurrency fix this PR builds on and closes the remaining gap in)
- https://github.com/cloudposse/atmos/security/dependabot/261
Summary by CodeRabbit
- Bug Fixes
- Improved concurrency safety when creating child merge contexts, preventing sibling interference.
- Centralized yq diagnostics/logging so it routes to the configured destination, masks secrets, and remains properly silenced during YAML edits.
- Improved yq evaluation concurrency and isolation with evaluation-scoped logging controls and one-time parser initialization.
- Updated Podman lifecycle integration tests to skip when runtime start fails.
- Tests
- Added race-focused regression tests for merge-context siblings and yq concurrent evaluation/logging behavior.
- Expanded unit tests for yq backend routing, masking, parser initialization, and evaluation scoping.
- Documentation
- Added fix notes for merge-context, yq diagnostics, and Podman test skipping.
- Reduced CI link-check flakiness by excluding specific flaky GitHub blob URLs.
fix(config): validate invalid configuration Erik Osterman (Cloud Posse) (@osterman) (#2825)
## what- Make built-in configuration validation run after configuration decoding fails, and include the affected file in parser errors.
- Validate every YAML file discovered through recursive profile configuration discovery, including nested profile files.
- Add coverage for command selection, fallback logging, schema validation, and profile discovery.
why
atmos config validatemust diagnose invalid Atmos configuration instead of being blocked by the same decoding failure it is intended to report.
references
- Zack profile/workdir reproduction.
Summary by CodeRabbit
- Bug Fixes
- Made built-in configuration validation commands run even when main configuration loading fails.
- Excluded generated/irrelevant discovery fragments to prevent incorrect config merging.
- Improved schema validation output by including the affected file path in errors.
- Adjusted schema checks for the embedded built-in config schema so unnecessary checks are skipped.
- Tests
- Added/extended coverage for built-in config/schema matching, validation behavior, and profile stack override scenarios.
Add env-step export controls to workflows and hooks Erik Osterman (Cloud Posse) (@osterman) (#2814)
## what- Add default-on process export control for
type: envsteps while preserving template assignment. - Propagate exported values through workflows, custom-command steps, and ordered step hooks.
- Add behavior-focused regression coverage, documentation, and a fix record.
why
- Separate template state from child-process state so template-only values are explicit and subprocess propagation is consistent.
references
- Closes #2810
Summary by CodeRabbit
- New Features
- Added an
exportoption for workflow and taskenvsteps to control whether values propagate to later child-process environments (default:true).
- Added an
- Bug Fixes
- Improved
envpropagation and precedence so later steps can reliably resolve{{ .env.NAME }}and so exports are isolated across retries and ordered hooks. - Ensured
export: falsekeeps values template-only (not set for later subprocess environments).
- Improved
- Documentation
- Updated workflow/task and hook docs, plus schemas, to clarify scoping and precedence for
envstep exports.
- Updated workflow/task and hook docs, plus schemas, to clarify scoping and precedence for
- Tests
- Added unit and end-to-end coverage for propagation, template-only behavior, and hook/step isolation.
fix(container): apply Buildx driver and cache configuration Erik Osterman (Cloud Posse) (@osterman) (#2815)
## what- Propagate resolved Buildx driver and cache settings from workflow container builds to Docker.
- Support cache settings for Buildx Bake, reject ineffective non-Buildx cache/driver configuration, and stabilize builder option ordering.
- Add workflow, component, command-argv, registry-cache integration, and CI coverage.
why
- Prevent native workflow builds from silently using Docker's default builder and bypassing remote cache settings.
references
Summary by CodeRabbit
-
New Features
- Added full propagation for Buildx driver and registry-backed build cache, including bake cache
cache-from/cache-to.
- Added full propagation for Buildx driver and registry-backed build cache, including bake cache
-
Bug Fixes
- Strengthened build configuration validation: driver/cache settings now require a
buildx-compatible engine (unless using bake). - Improved Buildx builder creation behavior for consistent driver option ordering.
- Strengthened build configuration validation: driver/cache settings now require a
-
Tests / CI
- Added remote registry cache integration coverage (gated) and expanded local/unit test coverage for Buildx args and cache wiring.
- Enhanced fake Docker runtime verification and improved a few flaky test synchronizations.
fix(utils): initialize yq globals once instead of per evaluation Michael Pursifull (@arcaven) (#2822)
Concurrent stack file processing can end an Atmos run with `fatal error: concurrent map writes`. That is a runtime fatal error rather than a panic, so the global handler added in #2334 cannot intercept it and no retry inside Atmos can either. `go test -race` flags the cause on `main` from a 20 line test, and the fix keeps the hot path read-only.what
configureYqLoggerno longer callslogging.SetLevelon everyEvaluateYqExpressionandEvaluateYqExpressionWithTypecall. The default level is installed ininit(), and later calls rewrite it only when the wanted level is not already installed, under a mutex.- yq's process-global expression parser is initialized under a
sync.Oncerather than being lazily assigned by everyEvaluatecall. - Adds
TestEvaluateYqExpression_ConcurrentCallsAreRaceFree, which fails under-racewithout either change.
why
Both globals were written on every evaluation, from the per stack file goroutines that processYAMLConfigFileWithContextInternal spawns:
logging.SetLevelwrites an unsynchronized map insidego-logging, and yq reads that same map from every decoder throughLogger.Debugf. The Go runtime checks concurrent map access, so this is the one that reaches users as a crash.yqlib.InitExpressionParserassigns the exported globalyqlib.ExpressionParserbehind a plain nil check. That write is a pointer, so the runtime does not catch it and it corrupts quietly instead.
On unmodified main at fc4960a the new test reports Found 2 data race(s). With the change, pkg/utils, pkg/yaml/... and internal/exec all pass, the last two unchanged here but sharing the same yq globals.
Two notes for reviewers:
- Installing the level in
init()is what removes the write entirely for a non-Trace run.--logs-level Tracestill performs one write on the first transition, which could in principle race a yq read already in flight. Hoisting the call to configuration load would close that as well; I did not want to reach intopkg/configuninvited. pkg/yaml/edit.go:71callslogging.SetLevelon everyevaluateWithOptions, so it writes the same map. I have not measured whether that path runs concurrently, so I left it alone rather than guess. Happy to fold it in here, or to file it separately, whichever you prefer.
Cost: yqlib.InitExpressionParser measures about 0.4ms once, and the sync.Once keeps that off commands which never evaluate an expression.
references
- Closes #2821
- #2347 looks like the same class of failure in the same goroutine fan-out, for the shared merged context
- #2334 added the global panic handler that cannot catch this one
Summary by CodeRabbit
-
Bug Fixes
- Improved reliability when evaluating yq expressions concurrently.
- Prevented unexpected yq logging changes during parallel evaluations.
- Ensured expression parsing is initialized consistently before use.
-
Tests
- Added coverage for concurrent evaluations, including result consistency and logging behavior.