github cloudposse/atmos v1.223.0-rc.3

pre-release3 hours ago
feat: YAML key delimiter for dot notation in stack files @osterman (#2139) ## what
  • Implement configurable settings.yaml.key_delimiter that expands dotted YAML keys into nested maps in stack files (e.g., metadata.component: vpc-base -> metadata: { component: vpc-base })
  • Unquoted keys containing the delimiter expand automatically; quoted keys stay literal (escape mechanism)
  • Support custom delimiters, not just . (e.g., ::)
  • Mark feature as experimental with runtime notifications via ui.Experimental()
  • 21 comprehensive unit tests covering expansion logic, merging, conflicts, quoted preservation, edge cases

example

With settings.yaml.key_delimiter enabled:

settings:
  yaml:
    key_delimiter: "."

Stack files can use concise unquoted dotted keys for nested component configuration. metadata stays at the component level; it is not nested under vars:

components:
  terraform:
    vpc:
      metadata.component: vpc-base
      metadata.description: Base VPC component
      vars.tags.environment: prod
      vars.tags.team: network

Atmos expands that as if the stack had been written in nested form:

components:
  terraform:
    vpc:
      metadata:
        component: vpc-base
        description: Base VPC component
      vars:
        tags:
          environment: prod
          team: network

Quoted mapping keys remain literal, so existing dotted keys can be preserved:

components:
  terraform:
    app:
      vars:
        "output.json": true
        'config.file': /etc/app.conf

why

Documentation claimed dot notation worked in stack files but it didn't. Go's yaml.v3 treats dotted keys literally without expansion. Users want concise notation instead of deeply nested YAML structures. This brings feature parity with atmos.yaml's native support via Viper's deepSearch() algorithm. Backwards compatible (disabled by default) and opt-in.

references

Extends experimental features system (like atmos devcontainer, atmos list affected). Respects settings.experimental mode configuration (silence/warn/error/disable).

Summary by CodeRabbit

  • New Features
    • Experimental YAML key expansion (settings.yaml.key_delimiter): unquoted dotted keys can expand into nested maps in stack and settings files; custom delimiters are supported.
    • Enhanced experimental configuration checks so YAML/settings features follow the same warn/disable/error modes.
  • Documentation
    • Added a blog post and expanded YAML dot-notation reference with examples for quoting, custom delimiters, and edge cases.
  • Tests
    • Added coverage for delimiter expansion behavior and merge/conflict scenarios.
  • Chores
    • Updated the Playwright-Go license reference.
Refactor Make workflows into Atmos commands @osterman (#2677) ## what
  • Moves build, lint, test, screengrab, check, format, and cache tasks from Make into grouped .atmos.d Atmos commands, with atmos build as the default binary build command.
  • Converts Makefiles to migration guidance, updates CI/docs to call Atmos commands, adds setup-atmos bootstrapping, and adds Linux/macOS/Windows install script smoke coverage.
  • Cleans example commands from root atmos.yaml, keeps .tool-versions installs explicit to atmos toolchain install, adds atmos shell, and adds a blog post embedding live .atmos.d examples.
  • Fixes custom-command dogfooding gaps for default subcommands, .atmos.d command-list merging across files with YAML tags, .cwd template data, and local alias precedence over config custom commands.

why

  • Dogfoods Atmos custom commands for Atmos development while removing Make from active local and CI workflows.
  • Keeps command definitions grouped and reusable while preserving existing build, lint, test, screengrab, and devcontainer alias behavior.

references

  • Validation: go test ./cmd ./pkg/config ./pkg/schema, git commit hooks, ./build/atmos build, ./build/atmos build --target linux, ./build/atmos build version --target linux, ./build/atmos screengrabs build --all, ./build/atmos screengrabs build about, Makefile migration checks, atmos build deps, pnpm build.
  • Note: atmos test short still reports unrelated workspace failures in internal/tui/utils and pkg/utils.

Summary by CodeRabbit

  • New Features
    • Added grouped .atmos.d command entrypoints for build, test (short/full/coverage/race/mocks), lint, check, format, cache (list/clear), and screengrabs (including Docker).
    • Added a cross-platform smoke test for website/static/install.sh.
  • Bug Fixes
    • Custom commands can now fall back to a configured default subcommand when run without arguments.
    • Improved environment handling and made coverage/profile merging more reliable.
  • Documentation
    • Updated development, CLI, demo, screengrabs, and test docs to use atmos; Makefile now redirects to atmos commands.
  • Tests
    • Expanded CLI/custom-command and config-merge regression coverage.
Add CEL-backed when conditions @osterman (#2689) ## what
  • Add pkg/condition to own when parsing, predicate handling, CEL compilation/evaluation, runtime context, and tests.
  • Keep pkg/schema compatible through aliases while wiring CEL-aware when evaluation into workflow steps, custom command steps, and hooks.
  • Update YAML tag normalization, JSON schemas, validation tests, and docs so bare CEL strings and explicit !cel conditions are supported.

why

  • This lets users write expressive, sandboxed boolean when expressions without replacing the existing predicate keywords.
  • Keeping schema aliases preserves current call sites while allowing condition behavior to evolve in a focused package.
  • Hook implicit-success behavior and workflow/custom-command failure predicate restrictions remain intact.

example

workflows:
  deploy:
    steps:
      - name: plan-prod
        type: shell
        command: terraform plan
        when: !cel 'ci && stack == "prod" && status == "success"'

references

  • Validation: go test ./pkg/condition ./pkg/schema ./pkg/workflow ./pkg/hooks ./pkg/datafetcher; go test ./cmd -run TestCustomCommandIntegration_SkipsStepWhenConditionIsFalse; go test ./pkg/workflow/... ./pkg/hooks/...; ./custom-gcl run --new-from-rev=origin/main.

Summary by CodeRabbit

  • New Features
    • Added CEL expressions support for when conditions across workflows, hooks, and custom command steps, including explicit !cel tagging and access to ci, status, stack, component, workflow, step, hook, event, and env.
  • Bug Fixes
    • when evaluation errors now fail fast instead of being treated as non-matching.
    • Step/hook execution context is now richer and more precise when deciding matches/skips.
  • Documentation
    • Updated CLI/docs and JSON schemas to reflect CEL-capable when validation and evaluation.
  • Tests
    • Expanded unit/integration coverage for CEL and env-gated scenarios.
  • Chores
    • Updated NOTICE and dependency/license allowlists.
feat(ci): fork-PR safety gate for `atmos git clone` @osterman (#2661) ## what
  • atmos git clone (Atmos's native actions/checkout replacement) now refuses by default to clone untrusted fork content under GitHub's elevated pull_request_target and workflow_run events.
  • The gate triggers only on the dangerous combination — an elevated event plus a fork-targeting clone (a PR head/merge ref override like refs/pull/<N>/merge, or an ad hoc clone URI whose owner/repo differs from the base GITHUB_REPOSITORY). Safe no-arg base checkouts and low-privilege pull_request/push/merge_group events are unaffected.
  • Adds a grep-able opt-in: --allow-unsafe-fork flag, ATMOS_ALLOW_UNSAFE_FORK_EXECUTION env var, and ci.allow_unsafe_fork_execution config key.
  • Adds the provider-agnostic gate core (pkg/ci.EvaluateForkCheckout), a Context.ElevatedEvent trust signal set by the GitHub provider, the ErrUnsafeForkCheckout sentinel, and unit tests (incl. negative paths).
  • Documents it: new PRD docs/prd/native-ci/framework/fork-pr-trust-gate.md, atmos git clone CLI docs, CI configuration reference, and a changelog blog post + roadmap milestone.

why

  • Because atmos git clone fills the same role as actions/checkout, it inherited the same "pwn request" risk: cloning a fork's PR code in a job that holds the base repository's secrets/GITHUB_TOKEN/cloud credentials lets a malicious contributor exfiltrate them.
  • This mirrors the actions/checkout v7 hardening (fail-closed by default, explicit grep-able opt-out), bringing Atmos's checkout replacement to parity.

references

Summary by CodeRabbit

  • New Features
    • Added a “Fork-PR safety gate” to atmos git clone: it refuses to clone untrusted fork content during elevated GitHub CI events (pull_request_target, workflow_run) when checkout targets look like PR ref overrides or forked repositories.
    • Added an opt-in bypass via --allow-unsafe-fork, ATMOS_ALLOW_UNSAFE_FORK_EXECUTION, or ci.allow_unsafe_fork_execution.
  • Bug Fixes
    • Fail-closed behavior when CI context can’t be evaluated, with guidance for safer workflows.
  • Documentation
    • Updated CLI docs, CI configuration, PRD/overview, roadmap, and release blog with behavior details and a full opt-in matrix.
  • Tests
    • Added unit tests covering trust evaluation, ref/URI detection, and bypass behavior.
  • Chores
    • Improved native CI Go module fetching resilience.
fix(algolia): surface page Intro as search-result subtext @osterman (#2429) ## what
  • Reorder Algolia customRanking to [desc(weight.pageRank), asc(weight.position), desc(weight.level)] so the first content record on a page wins the per-URL distinct dedup.
  • Broaden the content selector to lead with article .intro so every page's <Intro> block is indexed even when MDX doesn't wrap its children in a <p>.
  • Update crawler unit-test assertions for the new selector and ranking; add a live-relevance regression test (gated on ALGOLIA_LIVE_RELEVANCE_TESTS) asserting the top atmos auth hit has a non-empty _snippetResult.content.

why

  • Queries matching page titles (e.g. atmos auth) were resolving to lvl1 records, which the DocSearch React UI renders title-only with no snippet — so search results looked like a bare list with no description text.
  • With desc(weight.level) ahead of asc(weight.position), heading records always outranked content records inside distinct, locking in the no-subtext outcome. The reorder lets the Intro content record (position 0) win the dedup so its snippet renders as subtext.
  • MDX v3 emits <Intro>foo</Intro> with no blank lines as a bare text node inside <div class="intro">, so the prior article p, … selector missed the Intro text entirely. Adding article .intro indexes it regardless of MDX paragraph wrapping.

references

  • Requires a recrawl for the selector change to take effect (npm run algolia:deploy); the ranking change applies as soon as initialIndexSettings is pushed.

Summary by CodeRabbit

  • Search Improvements
    • Search results now capture more complete content from article introductions, improving snippet quality and relevance
    • Optimized search result ranking for better relevance

Review Change Stack

🚀 Enhancements

[codex] Fix CI and native component compatibility regressions @osterman (#2685) ## what
  • Fix Terraform native CI planfile upload for workdir-provisioned components by resolving the effective .workdir artifact path.
  • Fix native Helm plugin binary resolution to use the helm dependency scope, and expose --ci on native Kubernetes operation commands.
  • Stabilize tests by disabling telemetry in schema dogfood tests, clearing color-disabling env vars in TUI output tests, and ignoring environment-dependent GitHub token debug noise in snapshots.
  • Document each fix separately under docs/fixes.
  • Fail loudly when --verify-plan (or ATMOS_TERRAFORM_VERIFY_PLAN=true) is set but planfile storage is not configured under components.terraform.planfiles — previously the flag silently no-op'd and deploy applied an unverified fresh plan. A config-set verify: mode without storage now logs a warning. Docs updated everywhere the flag/prerequisite is mentioned, and the missing planfiles section was added to the terraform configuration reference.
  • Raise patch test coverage: REST artifact download error paths, workdir artifact-path failure path, and emulator shared-network attachment.
  • Fix the Acceptance Tests Playwright failure and broken aws/saml Browser-driver installs: playwright-go's driver download hits the retired azureedge.net CDN (build purged from the replacement CDN), so Atmos now pre-seeds the driver from the official npm registry and nodejs.org with checksum verification (docs/fixes/playwright-driver-retired-cdn.md).

why

  • These changes address compatibility gaps found during the recent merged-code audit, including issue #2684 where Terraform planfiles could be skipped for auto-provisioned workdir components.
  • The test updates remove unrelated environment and network side effects so local and CI verification are deterministic.

references

  • Fixes #2684
  • Verified with go test ./cmd/... ./internal/... ./pkg/... and go test ./tests -count=1.

Summary by CodeRabbit

  • New Features
    • Added a --ci flag to all native Kubernetes operation commands to enable consistent CI-mode behavior.
  • Bug Fixes
    • Fixed native Helm plugin helm binary resolution to use the correct native dependency scope.
    • terraform deploy --verify-plan now errors when Terraform planfile storage isn’t configured (instead of silently skipping).
    • CI planfile uploads now correctly handle workdir-provisioned components.
  • Documentation
    • Updated docs to clarify --verify-plan requires components.terraform.planfiles.
    • Added documentation for Playwright driver pre-seeding and Linux musl Node.js handling.
Support --profile flag for custom commands with autocomplete @osterman (#2190) ## what
  • Added early parsing of --profile flag (before Cobra parses) to ensure profiles are applied during initial config load, so custom commands receive a properly profiled atmosConfig
  • Extended StringSliceFlag to support custom completion functions
  • Implemented profile autocomplete that lists available profiles from the profile manager
  • Updated FlagRegistry.SetCompletionFunc() to support both StringFlag and StringSliceFlag types

why

Previously, custom commands could accept --profile but the flag was never applied because atmosConfig was loaded at boot time (before Cobra parsed flags). Custom commands captured this pre-profile config in their closure. Built-in commands worked because they called GetConfigAndStacksInfo() which re-extracted --profile during command execution.

This fix follows the same pattern as --chdir: parse the flag early from os.Args and pass it to InitCliConfig, ensuring all commands (built-in and custom) get properly profiled configuration.

The autocomplete feature provides users with shell suggestions of available profiles when typing atmos commands.

references

Resolves the gap where custom commands couldn't use the --profile flag effectively.

Summary by CodeRabbit

  • New Features

    • CLI supports profiles via a global --profile and ATMOS_PROFILE; profiles are loaded at startup and available for shell completion.
    • Early config selection via command-line or environment variables (base path, config, config-path).
    • Improved shell completion for profile and multi-value flags.
  • Tests

    • Added tests for flag completion and for profile/config selection parsing.
fix: replace log.Info/Error with ui.* in vendor non-TTY output @osterman (#2268) ## what
  • Replaced all log.Info and log.Error calls in the vendor non-TTY code path with proper ui.* methods (ui.Success, ui.Error, ui.Info)
  • Per-package status lines now use ui.Successf/ui.Errorf which provide consistent icons and styling
  • Summary and dry-run messages use ui.Successf/ui.Info instead of structured log key-value pairs
  • Extracted repeated format string into a pkgStatusFmt constant

why

  • The vendoring non-TTY path was abusing log.Info for user-facing status messages, which are UI output not diagnostic logs
  • log.Info renders as structured key-value pairs (e.g., INFO package=vpc version=(v1.0)) instead of the clean styled output the TUI provides
  • Using ui.* methods ensures consistent formatting with proper icons (checkmarks/X marks) across both TTY and non-TTY environments

references

  • pkg/ui/formatter.go — UI output methods used
  • docs/logging.md — logging level guidelines

Summary by CodeRabbit

  • Improvements
    • Refined vendoring CLI output for non-interactive runs with consistent symbol-based status lines and clearer success/error reporting.
    • Improved per-component status messages to clearly distinguish failures vs. successes.
    • Updated completion/dry-run summaries to use consistent info/check symbols and explicit success/failed counts.
  • Tests
    • Updated stderr golden snapshots and matchers for the new formatting.
    • Added non-TTY test coverage for per-component and final vendoring status output.
  • Chores
    • Updated the Playwright-Go license reference in the NOTICE file.

Don't miss a new atmos release

NewReleases is sending notifications on new releases.