feat: Improve source provisioner UX with spinners and interactive delete @osterman (#1965)
what
- Added spinner feedback during auto-provisioning in
vendorToTarget() - Introduced
PromptForConfirmation()topkg/flags/interactive.gofor reusable destructive action confirmation prompts - Updated delete command to prompt interactively instead of requiring
--forceflag - Delete operation now shows spinner during deletion with consistent visual feedback
- Added blog post and roadmap milestone documenting the enhancement
why
These changes improve UX consistency across the CLI by providing:
- Better visual feedback during vendoring operations with spinners matching other long-running operations
- Interactive confirmation prompts for destructive actions that gracefully degrade in non-TTY environments
- A reusable pattern for other commands that need confirmation prompts
references
Related to source provisioner improvements for better developer experience with JIT vendoring.
Summary by CodeRabbit
-
New Features
- Interactive confirmation for destructive actions (requires TTY unless --force).
- Interactive component/stack selection added to pull, delete, describe, and list; positional args now optional.
- Shell completion for component and stack names.
- Progress spinners for vendoring, provisioning and deletion flows; clearer interactive/error messaging.
-
Tests
- Expanded coverage for prompts, confirmations, non‑TTY flows, provisioning detection, and completion helpers.
-
Documentation
- UX docs updated with TTY vs non‑TTY guidance and force behavior.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: announcement bar responsive wrapping @osterman (#1966)
what
- Override Docusaurus default fixed 30px height on the announcement bar at desktop widths
- Allow the announcement bar to wrap gracefully to multiple lines at mid-range viewport widths instead of clipping text
why
- At viewport widths between 997px and ~1400px, the announcement bar was clipping the text to a single 30px line
- Very wide screens displayed correctly (text fit on one line), and mobile displayed correctly (height: auto)
- The fix enables responsive text wrapping at mid-range widths where the message needs multiple lines
references
- Docusaurus AnnouncementBar default styles:
website/node_modules/@docusaurus/theme-classic/src/theme/AnnouncementBar/styles.module.css
Summary by CodeRabbit
- Style
- Improved announcement bar layout and text wrapping on desktop viewports (997px and above) for better content visibility and presentation.
✏️ Tip: You can customize this high-level summary in your review settings.
docs: nest role_arn under assume_role @kyledecot (#1963)
what
Fixes minor error w/ docs so that role_arn is properly nested under assume_role.
why
Docs incorrectly had role_arn at the top-level of s3 backend configuration.
references
https://developer.hashicorp.com/terraform/language/backend/s3
Summary by CodeRabbit
Release Notes
- Documentation
- Updated Terraform S3 backend configuration examples to reflect the new nested
assume_rolestructure for specifying IAM role access.
- Updated Terraform S3 backend configuration examples to reflect the new nested
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Add source provisioning example @osterman (#1962)
what
- Added
examples/source-provisioning/demonstrating the source provisioner feature for Just-in-Time component vendoring - Includes separate dev and prod stacks using different module versions
- Demonstrates workdir isolation for terraform execution
- Simple, focused example showing one feature without catalog complexity
why
- Provides a working reference for users learning source provisioning
- Complements existing test fixtures and documentation with a clean runnable example
- Enables quick validation that source provisioning works end-to-end
references
Summary by CodeRabbit
- Documentation
- Added source provisioning example with comprehensive README documentation and configuration samples demonstrating just-in-time component vendoring across development and production environments.
✏️ Tip: You can customize this high-level summary in your review settings.
docs: refactor terraform usage page @osterman (#1952)
what
- Refactored
terraform usage.mdxfrom 871 to 149 lines into a focused overview page - Added Multi-Component Operations sections to
terraform-plan,terraform-apply,terraform-deploy, andterraform-destroycommand pages - Moved 300+ lines of multi-component examples and flag documentation to individual command pages
- Eliminated 765 lines of duplicate content across documentation
why
The terraform usage page served as both a landing page and comprehensive reference, resulting in massive duplication. Multi-component operations documentation now lives in individual command pages where it's directly relevant, improving maintainability and following the pattern used by other command groups like describe.
references
Issue: Terraform usage page was not refactored after subcommands were broken out into separate pages.
Summary by CodeRabbit
- Documentation
- Added comprehensive multi-component operations documentation for terraform apply, deploy, and plan commands, covering filtering flags and deployment modes including affected components and query-based selection.
- Reorganized terraform usage documentation with a new Command Modes section, streamlined examples, and improved navigation for single and multi-component workflows.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Add data-driven roadmap slide deck with pagination @osterman (#1953)
what
- Created a new data-driven slide deck at
/slides/roadmapthat visualizes the Atmos product roadmap - Featured initiatives appear first, followed by other initiatives with progress bars
- Paginated milestone viewer with clickable dots and Shift+Left/Right keyboard navigation
- Styled milestones with status icons, badges for releases/docs, inline code formatting
- Progress bar visualization for initiative completion percentages
why
- Provides a modern, interactive way to present the Atmos roadmap to stakeholders and the community
- Data-driven from roadmapConfig ensures the slides stay in sync with product planning
- Paginated milestones allow initiatives to showcase multiple achievements without cluttering slides
- Keyboard navigation provides power-user experience alongside mouse interaction
references
- Roadmap data source:
website/src/data/roadmap.js - Slide deck system:
website/src/components/SlideDeck/
Summary by CodeRabbit
-
New Features
- Added "Atmos Roadmap 2025-2026" interactive slide deck with paginated milestone lists, status badges, progress bars, links, and presenter notes.
- Milestone pagination supports Shift+ArrowLeft/Right; holding Shift while paging no longer advances slides.
-
Style
- Extensive visual and responsive styling for slides: badges, icons, progress bars, pagination dots, typography, and layout refinements.
-
Other
- Updated roadmap theme title to "Reducing Tool Fatigue".
✏️ Tip: You can customize this high-level summary in your review settings.
feat: stack name identity with zero-config filename fallback @osterman (#1934)
what
- Enforce single stack name identity - each stack now has exactly ONE valid identifier
- Add filename-based identity - stacks work with just filenames when no naming config exists (zero-config for newcomers)
- Improve error messages - when using an invalid stack name, error now says "invalid stack" and provides hints suggesting the correct name and how to list available stacks
- Fix
ProcessStacksto recognize the stack manifestnamefield when matching stacks - Add JSON schema documentation for the
namefield - Add PRD documenting the stack name identity rules
- Add CLI smoke tests with golden snapshots
why
Issue 1: Manifest name not recognized
When a stack manifest has name: "my-explicit-stack", users expect to use that name in commands:
atmos tf plan vpc -s my-explicit-stackPreviously this failed with "Could not find the component vpc in the stack".
Issue 2: Multiple names worked (incorrect)
After the initial fix, ALL of these worked for the same stack:
atmos tf plan vpc -s my-explicit-stack # explicit name
atmos tf plan vpc -s prod-ue1 # generated from name_template
atmos tf plan vpc -s legacy-prod # filenameThis is incorrect - a stack should have exactly ONE valid identifier.
Issue 3: Misleading error message
When using an invalid stack name (e.g., filename when explicit name exists), the error said "invalid component" instead of "invalid stack":
**Error:** invalid component
Could not find the component vpc in the stack legacy-prod.
New: Zero-config for newcomers
When no name, name_template, or name_pattern is configured, stacks are now identified by their filename. This lets newcomers get started without any naming configuration:
# stacks/prod.yaml - no naming config needed
components:
terraform:
vpc:
vars:
cidr: "10.0.0.0/16"# Just works!
atmos terraform plan vpc -s prodStack Name Identity Rule
Each stack has exactly ONE valid identifier based on precedence:
| Priority | Source | When Valid |
|---|---|---|
| 1 | name field in manifest
| If set, ONLY this name works |
| 2 | name_template result
| If set (and no explicit name), ONLY this works |
| 3 | name_pattern result
| If set (and no template/name), ONLY this works |
| 4 | Filename | Only if nothing else is configured |
Evidence
atmos list stacks - shows canonical names
my-legacy-prod-stack
no-name-prod
Note: my-legacy-prod-stack is shown (explicit name), not legacy-prod (filename).
atmos describe component vpc -s no-name-prod - filename works when no naming config
{
"atmos_component": "vpc",
"atmos_stack": "no-name-prod",
"atmos_stack_file": "no-name-prod",
"stack": "no-name-prod",
"workspace": "no-name-prod"
}atmos describe component vpc -s my-legacy-prod-stack - explicit name works
{
"atmos_component": "vpc",
"atmos_stack": "my-legacy-prod-stack",
"atmos_stack_file": "legacy-prod",
"atmos_manifest": "legacy-prod",
"stack": "my-legacy-prod-stack",
"workspace": "my-legacy-prod-stack"
}Note: atmos_stack is my-legacy-prod-stack (explicit name), while atmos_stack_file shows legacy-prod (the actual filename).
atmos describe component vpc -s legacy-prod - FAILS with helpful suggestions
# Error
**Error:** invalid stack
## Explanation
Stack legacy-prod not found.
## Hints
💡 Did you mean my-legacy-prod-stack?
💡 Run atmos list stacks to see all available stacks.
This is correct - legacy-prod.yaml has name: my-legacy-prod-stack, so only that identifier is valid. The error now correctly identifies this as an invalid stack (not component) and provides hints suggesting the correct name and how to list available stacks.
atmos terraform plan vpc -s legacy-prod - FAILS with helpful suggestions
# Error
**Error:** invalid stack
## Explanation
Stack legacy-prod not found.
## Hints
💡 Did you mean my-legacy-prod-stack?
💡 Run atmos list stacks to see all available stacks.
Changes
errors/errors.go: AddErrInvalidStacksentinel errorinternal/exec/utils.go: Enforce single-identity matching infindComponentInStacks; return helpful error with suggestion when filename is used for stack with explicit name; enable filename fallback inprocessStackContextPrefixinternal/exec/stack_manifest_name_test.go: Add tests for identity enforcement, filename fallback, and improved error messagestests/test-cases/stack-manifest-name.yaml: Add CLI smoke tests with golden snapshots for stack name identitypkg/datafetcher/schema/atmos/manifest/1.0.json: Add schema documentation fornamefielddocs/prd/stack-name-identity.md: PRD documenting the specification (status: Implemented)website/blog/2026-01-06-stack-name-identity.mdx: Blog post documenting the changeswebsite/src/data/roadmap.js: Add "Filename-based stack identity" to DX roadmap
References
- Closes #1932
Summary by CodeRabbit
-
New Features
- Single canonical stack identity with precedence (name → name_template → name_pattern → filename), zero‑config filename naming, and clearer "Did you mean…?" suggestions for invalid stacks.
-
Documentation
- Added product requirements and a blog post explaining identity rules, examples, migration guidance, and UX notes.
-
Tests
- Expanded test suites and updated snapshots to validate naming precedence, listing/describe behavior, and suggestion messages.
-
Chores
- Roadmap updated and CLI telemetry notice added to outputs.
✏️ Tip: You can customize this high-level summary in your review settings.
chore: Upgrade Docusaurus from 3.6.3 to 3.9.2 @osterman (#1926)
what
- Upgrades all Docusaurus packages to version 3.9.2 (latest stable)
- Updates package.json and pnpm-lock.yaml dependencies
why
The upgrade includes support for DocSearch v4 with AI-powered search features, improved i18n configuration options for multi-domain deployments, React 19 compatibility fixes, and new build APIs.
references
Summary by CodeRabbit
-
New Features
- Ask AI conversational search now integrated into documentation, powered by DocSearch v4 and ChatGPT for natural language queries and contextual answers.
-
Documentation
- Added Algolia search indexing setup guide and Ask AI feature announcement blog post.
-
Chores
- Updated documentation framework dependencies and roadmap entries.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Add robots.txt for search engine indexing @osterman (#1943)
what
- Adds robots.txt to website/static/ for search engine indexing
- Includes Algolia crawler verification token
- Explicitly allows all crawlers with User-agent: * and Allow: /
- References sitemap for efficient crawler discovery
why
- Improves search engine discoverability of the Atmos documentation
- Enables Algolia crawler verification for site search functionality
- Maximizes indexing potential by explicitly allowing all crawlers
references
- Algolia crawler verification: 10F61B92D9EB1214
Summary by CodeRabbit
- Chores
- Added web crawler configuration to improve site indexing and point crawlers to the sitemap.
- Updated deployment configuration to make the site base URL configurable via an environment variable, enabling PR-specific preview hosts during builds.
✏️ Tip: You can customize this high-level summary in your review settings.
Add generate section inheritance and auto-generation support @osterman (#1878)
what
- Add
generatesection to stack config inheritance pipeline with full support for base components, component-level overrides, and component overrides - Implement
atmos terraform generate filescommand with--all,--dry-run, and--cleanflags for generating auxiliary configuration files - Add
auto_generate_files: trueconfiguration option to automatically generate files during terraform operations - Extension-aware serialization:
.json,.yaml,.ymlfiles serialize in their respective formats,.tfand.hclfiles generate valid HCL - Go template support: String values in generate sections are processed as Go templates with full access to component context
- Update all integration test snapshots to reflect new
auto_generate_filesconfiguration field
why
Teams often need to generate auxiliary configuration files alongside Terraform components—files like .tool-versions, terragrunt.hcl shims for gradual migration, or environment-specific locals. This feature brings file generation directly into Atmos's declarative configuration model, maintaining the principle that infrastructure configuration should be fully described in YAML and reproducible from stack manifests. The inheritance support ensures teams can define common generate patterns in base components while allowing component-specific customization.
references
- Implements declarative file generation PRD
- Feature branch:
osterman/generate-section-prd
Summary by CodeRabbit
-
New Features
- Added declarative file generation for Terraform components via new
generatesections in stack configurations. - New
atmos terraform generate filescommand to automatically create auxiliary configuration files. - Support for extension-aware serialization (JSON, YAML, HCL, Terraform).
- Go template processing for dynamic content in generated files.
- Dry-run mode to preview generated files without writing.
- Multi-level configuration inheritance for generated files.
- Auto-generation toggle via
auto_generate_filesconfiguration.
- Added declarative file generation for Terraform components via new
-
Documentation
- Added comprehensive guides for declarative file generation and CLI usage.
-
Tests
- Added extensive test coverage for file generation and cleanup workflows.
✏️ Tip: You can customize this high-level summary in your review settings.
feat(auth): add PRD for native Okta authentication identity @RoseSecurity (#1924)
what
[!NOTE]
This is my first PRD, so any feedback is appreciated!
Add PRD for native Okta authentication as a first-class identity provider in Atmos. Unlike the existing SAML-based integration, this introduces dedicated okta/* providers enabling:
- OAuth 2.0 Device Authorization Grant for CLI authentication
- Direct Okta API access with automatic token refresh
- AWS/Azure/GCP federation via OIDC (
AssumeRoleWithWebIdentity) - XDG-compliant credential storage (
~/.config/atmos/okta/)
why
- Provides implementation reference following established auth patterns (AWS, Azure PRDs)
- Addresses user requests for native Okta support without browser-based SAML
Test plan
- PRD follows universal file isolation pattern
- Code samples reviewed for Atmos conventions
- Implementation checklist is complete and actionable
references
Summary by CodeRabbit
- Documentation
- Added a comprehensive Okta PRD defining goals, use cases (AWS OIDC federation, API access, multi-cloud), technical specification, token/file isolation and storage guidance, phased implementation roadmap, testing and security considerations, example policies, and an implementation checklist.
- Chores
- Added a roadmap milestone for Native Okta Authentication (Device Code Flow).
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Implement unified import adapter registry @osterman (#1897)
what
- Added extensible ImportAdapter interface for pluggable import sources
- Implemented ImportAdapterRegistry with lazy initialization and thread-safe registration
- Created GoGetterAdapter handling http, https, git, s3, oci, and other remote schemes
- Created LocalAdapter as default fallback for filesystem paths
- Created MockAdapter for testing with mock:// scheme
- Unified import handling via registry pattern instead of if/else chains
- Removed obsolete functions (isRemoteImport, processRemoteImport, processLocalImport, downloadRemoteConfig)
- Added comprehensive adapter tests with 90%+ coverage
why
- Extensible design: New import sources (terragrunt://, etc) can be added without modifying core logic
- Clear separation of concerns: Each adapter handles its own scheme
- Testability: Mock adapter enables unit testing without external dependencies
- Thread-safe: Lazy initialization with sync.Once prevents import cycles and race conditions
- Reduced complexity: Unified registry replaces scattered conditional logic
- Better error handling: Adapters can implement their own error strategies
references
- Implements design from
docs/prd/import-adapter-registry.md - Resolves circular dependency issues with lazy adapter initialization
- Provides foundation for future adapters (terragrunt, etc)
Summary by CodeRabbit
-
New Features
- Unified, extensible import adapter system enabling custom schemes, adapter-first routing, and improved handling of nested imports.
-
Tests
- Expanded adapter-focused tests covering routing, error handling, nested imports, mock scenarios, and registry behavior.
-
Documentation
- Added a detailed PRD for the Import Adapter Registry with architecture, examples, and phased rollout.
-
Chores
- Bumped Atmos version in build/config and added a roadmap milestone for the adapter registry.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Add multiple terraform output formats for CI integration @osterman (#1885)
Summary
- Moved all terraform output execution logic from
internal/exec/to newpkg/terraform/output/package - Implemented dependency injection pattern using
ComponentDescriberinterface to eliminate circular dependency - Created backward-compatible wrappers to maintain API compatibility
- Added 39 comprehensive unit tests with 89 total passing tests
What Changed
- Architecture: Package-based dependency injection removes circular dependency
- Logic: No behavioral changes, same functionality with improved organization
- Testing: Comprehensive unit test coverage with mocks for testability
- Performance: Identical behavior, slight code organization improvements
Verification
- ✅
make buildpasses - ✅
make lintpasses (0 issues) - ✅ All 89 tests pass
- ✅ No circular dependencies
Summary by CodeRabbit
-
New Features
- terraform output: new --format (json,yaml,hcl,env,dotenv,bash,csv,tsv), --output-file, --uppercase and --flatten; supports single-output or all-outputs and write-to-file.
- Automatic generation of Terraform backend and provider override files; improved workspace handling and a TTY-aware spinner for CLI feedback.
-
Tests
- Extensive unit and integration tests covering formatting, executor, backend, environment and workspace behaviors.
-
Documentation
- CLI docs and blog post for output formatting and examples.
- Added “Concurrent Sessions (MANDATORY)” guidance.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Add native Terraform provider caching with XDG support @osterman (#1882)
what
Atmos now automatically caches Terraform providers across all components using the TF_PLUGIN_CACHE_DIR environment variable with XDG-compliant default paths (~/.cache/atmos/terraform/plugins). This feature is enabled by default with zero configuration required, dramatically reducing terraform init times and network bandwidth.
why
In large Atmos projects with many components, each terraform init downloads the same providers repeatedly. For the AWS provider alone, this can mean downloading 300+ MB per component. With provider caching, Atmos downloads each provider version once and reuses it across all components - achieving 10-50x faster init times in testing.
references
This implements automatic provider caching with validation for invalid TF_PLUGIN_CACHE_DIR values (empty string or root path) and respects user overrides via environment variables or atmos.yaml configuration.
Summary by CodeRabbit
-
New Features
- Zero‑config Terraform provider caching enabled by default with optional custom cache directory and new terraform clean --cache flag (supports --force, dry‑run, interactive and non‑TTY flows). Exposes ATMOS_COMPONENTS_TERRAFORM_PLUGIN_CACHE and ATMOS_COMPONENTS_TERRAFORM_PLUGIN_CACHE_DIR plus TF_PLUGIN_CACHE_DIR behavior.
-
Documentation
- Added blog and CLI docs with examples, flags, and env var references.
-
Tests
- Extensive unit and end‑to‑end tests for configuration, cache path resolution, init/reuse, and cleaning.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Create pkg/runner with unified task execution @osterman (#1901)
what
- Introduced
pkg/runnerpackage with unified Task type and CommandRunner interface - Tasks support flexible YAML parsing for both simple strings and structured syntax with timeout, retry, and identity config
- Timeout enforcement via context.WithTimeout
- Proper shell argument parsing using mvdan.cc/sh for quote handling
- Updated custom commands to use the new Tasks type, enabling backward compatibility while supporting new syntax
why
Provides a shared execution layer for both custom commands and workflows, enabling code reuse and consistent task execution patterns across Atmos. Fixes DEV-3005.
references
Closes #DEV-3005
Summary by CodeRabbit
-
New Features
- Unified task runner with structured per-step entries (timeout, retry, working_directory, stack) and support for shell and atmos task types.
-
Breaking Change
- Command step format changed from simple string lists to structured Tasks — update custom command definitions accordingly.
-
Tests
- Expanded tests and new mocks/helpers covering runner behavior, YAML decoding, task parsing, timeouts, overrides, and sequential execution.
-
Chores
- Config decoding updated to handle the new task formats.
-
Documentation
- Blog post documenting the unified task runner and Task formats.
✏️ Tip: You can customize this high-level summary in your review settings.
🚀 Enhancements
Fix markdown rendering offset bug in toast messages @osterman (#1968)
what
- Added
trimLeftSpaces()function to properly handle leading space trimming when Glamour wraps spaces in ANSI escape codes - Updated
toastMarkdown()andrenderInlineMarkdownWithBase()to use ANSI-aware trimming - Multi-line toast messages now have consistent bullet point indentation with color enabled
why
Glamour wraps spaces in ANSI codes when color is enabled. The previous code used strings.TrimLeft() which isn't ANSI-aware and failed to remove leading spaces, causing inconsistent indentation in multi-line markdown output.
references
Fixes: Markdown rendering with inconsistent bullet list indentation in terminal UI messages
Summary by CodeRabbit
-
Bug Fixes
- Improved trimming of leading/trailing spaces in styled/colored text so notifications, hints and inline markdown keep visual formatting intact.
-
User Experience
- Backend provisioning now collects and shows backend warnings after the progress spinner completes to avoid interleaved output.
-
Tests
- Added comprehensive tests covering whitespace trimming with styled/ANSI content.
✏️ Tip: You can customize this high-level summary in your review settings.
feat: Automatic toolchain integration for custom commands and workflows @osterman (#1958)
what
New Feature: Automatic Toolchain Integration
- Custom commands and workflows now automatically load tools from
.tool-versionsfile - Workflow-specific dependencies can be declared in the workflow definition and override
.tool-versions - Command-specific dependencies can be declared in the command definition
- Tools are automatically installed and PATH is updated before execution
- Component-level tool dependencies - Terraform/Helmfile/Packer components can declare tool dependencies that are resolved and installed before execution
Bug Fixes (Toolchain Bootstrap)
- Fix
atmos bootstrapfailures for AWS CLI, jq, gum, and replicated by removing unconditional version prefix - Follow Aqua's actual behavior where
version_prefixdefaults to empty string, not "v" - Include
ErrHTTP404in 404 errors to enable version fallback mechanism - Fix template expansion in
files.srcfor tools like Helm that use{{.OS}}-{{.Arch}}paths - Preserve all fields in
resolveVersionOverridesfor version-specific configs - Add
darwin_allpattern support for universal macOS binaries
Bug Fixes (Workflows)
- Fix workflow conditional stack processing - Workflows no longer require stacks configuration when
--stackflag is not provided. Previously, runningatmos workflow <name>would fail with "stack base path must be provided" even for simple shell workflows that don't use stacks. Now stacks are only validated when--stackis explicitly passed.
Bug Fixes (Batch Install UX)
- Prevent .tool-versions duplication - Add
SkipToolVersionsUpdateoption to prevent duplicate entries when bothInstallSingleToolandupdateToolVersionsFileare called - Enable spinner during batch installs - Spinner now animates during downloads, not just after each tool completes
- Reduce batch install message noise - Add
ShowInstallDetailsoption to show only simple "Installed X" messages in batch mode, while single-tool mode retains verbose output (path, size, registered) - Add
showProgressBarparameter -RunInstallnow acceptsshowProgressBarto control spinner visibility for custom command installs
Bug Fixes (Error Handling)
- Guard against nil error in ErrorBuilder.WithCause - Prevent panic when
b.erris nil by using cause directly as the stored error - Preserve error hints through error chain propagation - Hints from cause errors are now properly preserved via
GetAllHints() - Add alias configuration hint - When tool not found in registry, suggest adding an alias in
atmos.yaml - Suppress PATH hint for dependency installs - Only show PATH export hint when running
toolchain installdirectly
Documentation & Examples
- Add documentation for toolchain integration in custom commands and workflows
- Add
examples/toolchain/with working examples showing:.tool-versionsfile with tool dependencies- Custom command with dependencies declaration
- Workflow with dependencies declaration
- Component-level tool dependencies - Mock component with
opentofu: "^1.10.0"constraint - Inline registry with custom tool definitions (jq, yq)
- SemVer constraint examples (
^1.7.0,~> 4.40.0)
Test Coverage
- Add
DependencyProviderinterface for testability - Add 9 new tests for
ensureToolchainDependencies()covering all code paths - Add tests for extraction edge cases (gzip, tar.gz, MIME type dispatch)
- Add test for
.tool-versionsdirectory error path - Add workflow conditional stack processing tests:
TestWorkflowWithoutStacksConfig- workflows succeed without stacks configTestWorkflowWithStackFlagRequiresStacksConfig- workflows fail when--stackpassed but stacks not configuredTestWorkflowWithStackFlagAndStacksConfigured- workflows succeed when both are present
- Coverage improvements: executor ~19% → 100%, extract functions to 100%
why
Toolchain Integration
Users managing infrastructure often need specific tool versions (terraform, kubectl, helm). The .tool-versions file is a standard way to declare these dependencies (used by asdf, mise). This PR enables Atmos to:
- Read
.tool-versionsand automatically install required tools - Allow workflows to override versions for specific requirements
- Update PATH so commands execute with the correct tool versions
- Support component-level dependencies so different components can require different tool versions
Bootstrap Fixes
After PR #1948, multiple tools failed to install during bootstrap because version prefix handling didn't match Aqua's behavior. The code was unconditionally adding a "v" prefix when version_prefix was empty, breaking HTTP URLs (AWS CLI expects AWSCLIV2-2.32.31 not AWSCLIV2-v2.32.31).
Workflow Conditional Stack Processing
The workflow command was always requiring stacks configuration even when running simple shell workflows that don't reference any stacks. This was because InitCliConfig(info, true) unconditionally validated stacks. Now the second parameter is set based on whether --stack flag was provided, allowing workflows to run without any stacks configured.
Batch Install UX Improvements
The batch installer had several UX issues:
- Duplicate entries - Both
handleInstallSuccessandupdateToolVersionsFilewere writing to.tool-versionswith different keys (e.g., "gum" vs "charmbracelet/gum") - No animation during downloads - Spinner only animated after each tool completed, leaving users with no feedback during 5-30 second downloads
- Too noisy - Each tool produced 3 lines of output; reduced to 1 concise line in batch mode
Error Handling Robustness
ErrorBuilder.WithCausecould panic if called with nil base error - now handles gracefully- Error hints from wrapped causes were being lost - now preserved through the chain
Example Usage
.tool-versions:
terraform 1.10.3
kubectl 1.32.0
helm 3.16.4
Workflow with override:
workflows:
deploy:
description: Deploy infrastructure
dependencies:
tools:
terraform: "1.11.0" # Override .tool-versions
steps:
- command: terraform init
- command: terraform applyComponent with tool dependency:
components:
terraform:
mock:
metadata:
component: mock
dependencies:
tools:
opentofu: "^1.10.0" # Install OpenTofu before execution
vars:
message: "Hello from toolchain demo"references
- Related to bootstrap failures in PR #1948
- Documentation:
website/docs/core-concepts/custom-commands/commands.mdx - Documentation:
website/docs/core-concepts/workflows/workflows.mdx - Examples:
examples/toolchain/
Summary by CodeRabbit
-
New Features
- Automatic tool management from .tool-versions in commands and workflows; injectable dependency provider; batch installs; richer install options (progress bar, PATH hint, skip .tool-versions update); explicit version_prefix support so templates/URLs and SemVer behave only when configured.
-
Bug Fixes
- Better 404 detection for version fallbacks, more robust archive extraction and binary detection, and spinner suppressed during debug to avoid garbled output.
-
Documentation
- New docs and many examples for toolchain integration.
-
Tests
- Large expansion of unit and integration tests across installs, prefix handling, extraction, dependency flows, and UI helpers.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Fix backend CRUD issues - create visibility, error messages, and false success bug @osterman (#1960)
what
- Fix
createcommand not appearing in subcommands list (Use field was wrong) - Add ErrorBuilder pattern for missing
--stackflag with helpful context - Add
ErrProvisioningNotConfiguredsentinel error to errors/errors.go - Fix false success bug: ProvisionBackend now returns error when provisioning not configured (strict behavior)
- Update all affected tests to expect errors instead of nil returns
why
The backend commands had multiple issues:
createsubcommand wasn't visible in help becauseUse: "<component>"doesn't include the command name- Error messages said "required flag not provided" without indicating which flag or how to fix it
- Running
createwithout provisioning configuration would show "Successfully provisioned" even though nothing was done (false success) - Tests incorrectly expected nil returns when configuration was missing
These fixes ensure the backend commands are discoverable, errors are helpful and actionable, and operations fail-fast with clear context.
references
- Fixes false success bug in backend provisioning
- Improves error messages for CLI usability
- Ensures backend create command is discoverable in help
Summary by CodeRabbit
-
New Features
- Optional positional args with interactive prompting for backend commands; bracket-style usage.
- Automatic, opt-in backend provisioning during Terraform init with progress spinner, backend existence/name detection, and clearer progress messages.
-
Bug Fixes
- Clear, actionable error when backend provisioning is missing or disabled; improved provisioning error signaling.
-
Tests
- Expanded unit, integration, and end-to-end tests for backend flows, S3 backend (fake S3), prompting, and provisioning scenarios.
-
Documentation
- New blog post and reference updates describing automatic backend provisioning and prompting behavior.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Workflow name showing `` in `atmos list workflows` @aknysh (#1964)
what
- Fixed
atmos list workflowscommand showing<no value>for workflow names - The workflow name column now correctly displays workflow names instead of
<no value>
why
- The default column template for "Workflow" used
{{ .name }}but the data extractor uses"workflow"as the key - This mismatch caused Go templates to output
<no value>when the.namefield wasn't found in the data - Users were seeing output like:
Instead of:networking.yaml <no value> Run terraform plan on all vpc components...networking.yaml plan-all-vpc Run terraform plan on all vpc components...
Changes
cmd/list/workflows.go- Changed default column template from{{ .name }}to{{ .workflow }}to match the extractor's keypkg/list/column/column.go- Added explicit mapping for"workflow"key inbuildTemplateContext()for consistency- Tests - Added tests to verify default columns use the correct template keys
Testing
# Before fix
$ atmos list workflows
networking.yaml <no value> Run terraform plan...
# After fix
$ atmos list workflows
networking.yaml plan-all-vpc Run terraform plan...Summary by CodeRabbit
-
Bug Fixes
- Fixed the Workflow column in workflow lists to display the correct data source.
-
New Features
- Added support for configuring workflow columns and templates via atmos.yaml configuration file.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Workflow command parsing for quoted arguments @aknysh (#1961)
what
- Fixed workflow command parsing to correctly handle quoted arguments like
-var="key=value" - Previously,
strings.Fields()was used which doesn't handle shell quoting, causing quoted arguments to be passed with literal quote characters - Now uses
shell.Fields()frommvdan.cc/sh/v3/shellwhich properly parses shell-style quoting
why
- Workflow commands with
-var="access_roles_enabled=false"were failing with:Error: Value for undeclared variable A variable named "\"access_roles_enabled" was assigned on the command line - The issue was that
strings.Fields()splits on whitespace but preserves quote characters, so-var="enabled=false"was passed to Terraform with the literal quotes included - Running the same command directly from the CLI worked because the shell strips the quotes before passing to the process
shell.Fields()correctly parses shell quoting and strips quotes, matching the behavior users expect
Example
Before (broken):
# Workflow command
command: terraform deploy tfstate-backend -var="access_roles_enabled=false"
# Parsed as: ["terraform", "deploy", "tfstate-backend", "-var=\"access_roles_enabled=false\""]
# Terraform sees variable name as: "access_roles_enabled (with leading quote)After (fixed):
# Same workflow command
command: terraform deploy tfstate-backend -var="access_roles_enabled=false"
# Parsed as: ["terraform", "deploy", "tfstate-backend", "-var=access_roles_enabled=false"]
# Terraform correctly sees variable name as: access_roles_enabledTesting
Added comprehensive tests for the fix:
Unit Tests (internal/exec/workflow_test.go)
TestShellFieldsQuoteParsing- verifiesshell.Fields()correctly parses various quoted argument patterns
Unit Tests (internal/exec/workflow_utils_test.go)
TestShellFieldsFallback- tests shell parsing with various argument patternsTestExecuteWorkflow_WithQuotedVarFlag- tests-var="key=value"pattern in workflowsTestPrepareStepEnvironment_WithGlobalEnv- tests global env mergingTestExecuteWorkflow_*- multiple tests for stack overrides, dry run, from-step, identity precedence
Workflow Test Fixtures (tests/fixtures/scenarios/workflows/stacks/workflows/test.yaml)
terraform-var-double-quotes--var="key=value"patternterraform-var-single-quotes--var='key=value'patternterraform-var-multiple- multiple var flagsterraform-var-with-spaces- values containing spacesterraform-var-equals-in-value- values containing=
references
- Uses same approach as
pkg/workflow/executor.go:332-337which already had the correct implementation mvdan.cc/sh/v3/shellis already a dependency used in other parts of the codebase
Summary by CodeRabbit
Release Notes
-
Bug Fixes
- Improved command argument parsing to correctly handle quoted strings and complex flags (e.g., Terraform -var with spaces and equals signs).
-
Tests
- Expanded test coverage for quoted argument parsing and workflow execution scenarios.
- Added test cases for various Terraform variable flag quoting patterns.
-
Dependencies
- Updated Go module dependencies to latest patch versions.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Fix Aqua registry factory and add darwin_all pattern support @osterman (#1948)
what
- Fix nil registry factory by injecting real Aqua registry factory
- Load configured registries from atmos.yaml in NewInstaller()
- Add Asset field to AquaPackage for github_release types
- Support platform-specific asset patterns (e.g., darwin_all)
- Add test for replicated darwin_all override pattern
- Move test fixtures to proper testdata directories
- Refactor FindTool to reduce complexity and improve logging
why
The installer subpackage refactoring broke registry lookups because defaultRegistryFactory.NewAquaRegistry() was returning nil. Additionally, NewInstaller() wasn't loading configured registries from atmos.yaml, preventing custom registry support. This fix properly injects a working registry factory and loads configuration during initialization.
references
Fixes toolchain registry factory issues from the installer subpackage refactoring work.
🤖 Generated with Claude Code
Summary by CodeRabbit
-
New Features
- Configurable toolchain registries with platform-specific overrides, OS/arch replacements, multi-file extraction and macOS .pkg handling
- Enhanced CLI help and explicit telemetry notice across toolchain commands
-
Documentation
- Added Aqua package manager README and expanded CLI docs with AWS CLI install example and templating/override guidance
-
Tests
- Large expansion of fixtures, snapshots and unit/integration tests covering registries, install/info/download/extract flows, and overrides
-
Style
- Minor workflow comment update (non-functional)
✏️ Tip: You can customize this high-level summary in your review settings.
fix(provenance): add regression tests and fix flag inheritance @osterman (#1949)
what
- Add comprehensive regression tests for line-level provenance tracking
- Fix flag inheritance regression where custom commands could not define flags that already exist on parent commands
- Custom commands can now declare
--stack,--verbose, or other existing flags when the type matches - Type mismatches still produce clear error messages (e.g., defining
--stackas bool when parent has it as string)
why
- Provenance output format needs regression tests to prevent accidental breakage of import chains, depth tracking, and source attribution
- PR #1947 introduced overly strict flag conflict checking that rejected valid use cases
- Custom commands legitimately need to use flags like
--stackand--verbosethat are defined elsewhere - The fix allows flag inheritance when types match (skip re-registration) while still catching actual conflicts (type mismatch)
references
- Fixes flag regression introduced in #1947
- Adds test fixtures:
tests/fixtures/scenarios/provenance-advanced/andtests/fixtures/scenarios/flag-inheritance/ - Test cases:
tests/test-cases/provenance-snapshots.yamlandtests/test-cases/flag-inheritance.yaml
Summary by CodeRabbit
-
New Features
- Custom commands now support flag inheritance with type-safety validation and conflict detection
- Custom commands can define their own
--versionflags independent of the global version flag - Configuration provenance tracking now displays where each setting originates in the stack hierarchy
- Enhanced
atmos list componentscommand shows unique components with stack counts
-
Configuration
- Updated list command configuration structure in atmos.yaml under new
list.components,list.instances, andlist.stackspaths
- Updated list command configuration structure in atmos.yaml under new
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Resolve file-scoped locals in stack configurations @aknysh (#1939)
what
- Fixed file-scoped locals feature that was documented but not functional (GitHub issue #1933)
- Templates using
{{ .locals.* }}now correctly resolve to their defined values - Added proper integration of locals extraction into the stack processing pipeline
- Section-specific locals (
terraform:,helmfile:,packer:) correctly override global locals - Component-level locals with inheritance support via
metadata.inherits - Added
atmos describe localscommand to inspect and debug locals configurations--stackflag is required - locals are file-scoped, so a specific stack must be specified- Component-level output: shows merged locals available to a specific component
- Supports both logical stack names (e.g.,
prod-us-east-1) and file paths (e.g.,deploy/prod) - Output follows Atmos schema format (direct stack manifest format, can be used as valid YAML)
Example Output
Stack Locals (by file path or logical name)
# Using file path
atmos describe locals --stack deploy/dev
# Using logical stack name (derived from atmos.yaml name_template)
atmos describe locals --stack dev-us-east-1locals:
environment: dev
namespace: acme
name_prefix: acme-dev
full_name: acme-dev-us-east-1
tags:
Environment: dev
Namespace: acme
terraform:
locals:
backend_bucket: acme-dev-tfstate
tf_specific: terraform-onlyThe output is in direct stack manifest format - it can be redirected to a file and used as a valid stack manifest:
atmos describe locals -s dev --file locals.yamlComponent Locals
When a component is specified, the output shows the merged locals available to that component (global + section-specific + component-level + inherited from base components):
atmos describe locals vpc -s prod-us-east-1components:
terraform:
vpc:
locals:
backend_bucket: acme-prod-tfstate
environment: prod
namespace: acme
name_prefix: acme-prod
vpc_type: production
cidr_prefix: "10.0"Query Specific Values
# Query the namespace from locals
atmos describe locals -s deploy/dev --query '.locals.namespace'
# Output: acme
# Output as JSON
atmos describe locals -s dev --format jsonComponent-Level Locals with Inheritance
Components can define their own locals: section that inherits from base components:
components:
terraform:
vpc/base:
metadata:
type: abstract
locals:
vpc_type: standard
cidr_prefix: "10.0"
vpc/prod:
metadata:
inherits:
- vpc/base
locals:
vpc_type: production # Overrides base
vars:
cidr: "{{ .locals.cidr_prefix }}.0.0/16" # Uses inherited localLocals resolution order: Global → Section → Base Component → Component
Manual Testing Results
Test Fixture: locals-logical-names
Stack-level locals (using logical stack name):
cd tests/fixtures/scenarios/locals-logical-names
atmos describe locals --stack dev-us-east-1locals:
env_prefix: acme-dev
full_prefix: acme-dev-us-east-1
namespace: acme
terraform:
locals:
backend_bucket: acme-dev-tfstate
tf_only: terraform-specific-devStack-level locals (using file path):
atmos describe locals --stack deploy/devSame output as above.
Stack-level locals (JSON format):
atmos describe locals -s dev-us-east-1 --format json{
"locals": {
"env_prefix": "acme-dev",
"full_prefix": "acme-dev-us-east-1",
"namespace": "acme"
},
"terraform": {
"locals": {
"backend_bucket": "acme-dev-tfstate",
"tf_only": "terraform-specific-dev"
}
}
}Terraform component locals:
atmos describe locals vpc -s dev-us-east-1components:
terraform:
vpc:
locals:
backend_bucket: acme-dev-tfstate
env_prefix: acme-dev
full_prefix: acme-dev-us-east-1
namespace: acme
tf_only: terraform-specific-devHelmfile component locals:
atmos describe locals nginx -s prod-us-west-2components:
helmfile:
nginx:
locals:
env_prefix: acme-prod
full_prefix: acme-prod-us-west-2
hf_only: helmfile-specific-prod
namespace: acme
release_name: acme-prod-releaseTest Fixture: locals-component-level
Standalone component with its own locals:
cd tests/fixtures/scenarios/locals-component-level
atmos describe locals standalone -s dev-us-east-1components:
terraform:
standalone:
locals:
backend_bucket: acme-dev-tfstate
computed_ref: acme-dev
environment: dev
name_prefix: acme-dev
namespace: acme
standalone_value: standalone-only
tf_specific: terraform-onlyComponent inheriting from base with locals override (vpc/dev):
atmos describe locals vpc/dev -s dev-us-east-1components:
terraform:
vpc/dev:
locals:
backend_bucket: acme-dev-tfstate
cidr_prefix: "10.0" # inherited from base
environment: dev
extra_tag: dev-only # added in child
name_prefix: acme-dev
namespace: acme
tf_specific: terraform-only
vpc_type: development # overridden from "standard"Component inheriting from base without locals override (vpc/standard):
atmos describe locals vpc/standard -s dev-us-east-1components:
terraform:
vpc/standard:
locals:
backend_bucket: acme-dev-tfstate
cidr_prefix: "10.0" # inherited from base
environment: dev
name_prefix: acme-dev
namespace: acme
tf_specific: terraform-only
vpc_type: standard # inherited from basewhy
- The file-scoped locals feature was announced in v1.203.0 but the implementation was incomplete
ProcessStackLocals()existed but was never called during stack processing- The
.localscontext was not provided to template execution, causing templates to remain unresolved - Users reported that
{{ .locals.* }}templates showed raw template strings instead of resolved values
Technical Changes
- Added
extractLocalsFromRawYAML()- Parses YAML and extracts/resolves locals before template processing - Added
extractAndAddLocalsToContext()- Helper to add resolved locals to template context - Added
LocalsContext.MergeForTemplateContext()- Merges all scope levels into flat map for templates - Added section tracking flags -
HasTerraformLocals,HasHelmfileLocals,HasPackerLocalsto properly handle overrides - Added
atmos describe localscommand - Command to inspect locals for a specific stack with schema-compliant output - Added component-level locals extraction -
ComponentLocalsandBaseComponentLocalsfields in stack processing - Added component locals inheritance - Locals inherit from base components via
metadata.inherits - Direct output format - Output is in stack manifest format that can be used as valid YAML
Test Coverage
| Category | Count |
|---|---|
Unit tests (stack_processor_utils_test.go)
| 16 |
Unit tests (stack_processor_locals_test.go)
| 41 |
Unit tests (describe_locals_test.go)
| 40+ |
Unit tests (cmd/describe_locals_test.go)
| 12 |
Integration tests (cli_locals_test.go)
| 26 |
| Total | 135+ |
Key test areas:
extractLocalsFromRawYAML- 95.8% coverageProcessStackLocals- 100% coverageExtractAndResolveLocals- 100% coverage- Deep import chain tests (4-level: base → layer1 → layer2 → final)
- File-scoped behavior verification (locals NOT inherited across imports)
- Component-level locals with inheritance
- Logical stack name resolution
- Direct output format validation
Test Fixtures
tests/fixtures/scenarios/locals-deep-import-chain/- Tests file-scoped locals across deep import chainstests/fixtures/scenarios/locals-logical-names/- Tests logical stack name resolutiontests/fixtures/scenarios/locals-component-level/- Tests component-level locals with inheritance
Documentation
- CLI docs:
website/docs/cli/commands/describe/describe-locals.mdx - Blog post:
website/blog/2026-01-06-file-scoped-locals-fix.mdx - PRD:
docs/prd/file-scoped-locals.md
references
Summary by CodeRabbit
-
New Features
- Added a CLI command to describe merged locals per stack/component with format, file, and query options.
-
Bug Fixes
- File-scoped locals are now resolved before template processing, don’t leak across imports, and are stripped from final outputs.
-
Documentation
- New blog post and CLI docs explaining locals behavior, examples, and upgrade notes.
-
Tests
- Extensive unit/integration tests and fixtures covering locals resolution, scopes, inheritance, circular deps, and deep-import chains.
-
UX
- Improved CLI validation and clearer error messages (e.g., stack requirement).
✏️ Tip: You can customize this high-level summary in your review settings.
fix(auth): normalize ATMOS_IDENTITY=false (issue #1931) @osterman (#1935)
what
- Fix
ATMOS_IDENTITY=falsenot being recognized in the legacyProcessCommandLineArgs()code path - Create shared
NormalizeIdentityValue()function inpkg/config/identity.goto centralize normalization logic - Add comprehensive tests for
ATMOS_IDENTITY=false,0,no,offincli_utils_test.go - Refactor three duplicate
normalizeIdentityValue()functions to use shared implementation
why
PR #1900 fixed ATMOS_IDENTITY=false normalization for the flag parsing path (pkg/flags/global_registry.go), but missed a separate code path in internal/exec/cli_utils.go that reads ATMOS_IDENTITY directly via os.Getenv().
Two independent code paths exist:
- Flag path (
pkg/flags/global_registry.go): Used by Cobra commands with proper global flag inheritance - ✅ Fixed in PR #1900 - Legacy path (
internal/exec/cli_utils.go:ProcessCommandLineArgs()): Used by terraform commands - ❌ Not fixed until this PR
The legacy path was added in PR #1720 (Oct 2025) without normalization. When PR #1900 fixed the flag path (Dec 2025), this code path was missed, causing the regression reported in issue #1931.
Verified with user's reproduction case:
# From issue #1931's auth_bug.tar.gz
ATMOS_IDENTITY=false atmos terraform plan myapp -s dev
# Before: "Error: identity not found" (treats "false" as identity name)
# After: Terraform plan runs successfully with auth disabledNote: This class of problems (duplicate code paths for auth handling) should be eliminated by #1919, which refactors Atmos auth to use the command registry pattern. Once that lands, there will be a single, unified code path for identity/auth handling across all commands.
references
Closes #1931
Related: #1900 (partial fix), #1720 (introduced the unfixed code path), #1919 (architectural fix to prevent this class of bugs)
Summary by CodeRabbit
-
Refactor
- Consolidated identity value normalization logic across the system. Identity values are now consistently processed to treat false-like representations (false, 0, no, off in various cases) uniformly, regardless of whether they originate from environment variables, configuration files, or command-line arguments.
-
Tests
- Added test coverage for identity value normalization with comprehensive edge case handling.
✏️ Tip: You can customize this high-level summary in your review settings.
Fix custom command flag conflicts with global flags @osterman (#1947)
what
- Add validation to detect and prevent custom command flag conflicts with global persistent flags
- Return actionable error messages instead of panicking when conflicts are detected
- Query global flags dynamically to ensure new flags are automatically protected
- Update existing tests to use non-conflicting flag names
why
When custom commands in atmos.yaml define flags that conflict with global flags, Cobra would panic with a stack overflow. This fix gracefully detects conflicts before flag registration and returns a clear error message using the ErrorBuilder pattern, giving users explicit guidance on how to resolve the issue.
references
No GitHub issues referenced. This is a critical bug fix improving stability and user experience when working with custom commands.
Summary by CodeRabbit
-
New Features
- Runtime validation blocks custom commands from defining flag names or shorthands that conflict with global/parent reserved flags (including the identity flag); conflicts yield a clear reserved-flag error.
-
Changes
- Added a public reserved-flag error sentinel.
- Renamed debug flag from verbose to customDebug (shorthand d).
- Example/fixture command renamed from terraform to tf-custom; CLI help listings updated accordingly.
-
Tests
- Extensive unit and integration tests covering flag reservation, shorthands, nesting, inheritance, defaults, and error reporting.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Resolve assume role issues and improve error handling @aknysh (#1938)
what
- Fix panic when using
!terraform.outputwith authentication enabled - Fix silent/confusing errors when referenced component is missing in template functions
- Add comprehensive documentation for env template function behavior
- Document
base_pathbehavior change as a breaking change in changelog
why
Issue #1921: Panic in !terraform.output with Authentication
When using !terraform.output with AWS SSO authentication, Atmos panicked with:
panic: authContextWrapper.GetChain should not be called
Root Cause: The authContextWrapper.GetChain() method was implemented as a panic stub, but the auth system evolution now calls this method during nested component resolution.
Fix: Changed GetChain() to return an empty slice instead of panicking. An empty chain means no inherited identity from the wrapper, so nested components use their own defaults.
Issue #1030: Missing Component Results in Silent Failure
When using template functions like atmos.Component() or !terraform.output to reference components that are removed from configuration, Atmos produced confusing errors or silent failures.
Root Cause: The ErrInvalidComponent error chain was preserved when wrapping errors from DescribeComponent. This caused the component type fallback logic (detectComponentType()) to incorrectly trigger, producing misleading "component not found as Helmfile/Packer" errors instead of clear "referenced component missing" errors.
Fix: Added WrapComponentDescribeError() helper in errors/error_funcs.go that breaks the ErrInvalidComponent chain using %v instead of %w formatting, ensuring errors about referenced components are returned immediately with clear messages.
Env Template Function Analysis (Not a Bug)
Investigated user report that env template function returns empty strings while .vars.* works correctly. Analysis confirmed this is expected behavior:
-
The
envfunction is from Sprig and callsos.Getenv() -
When an env var is NOT set, it returns empty string (standard Go behavior)
-
.vars.*works because it comes from stack YAML config passed to template -
User needs to ensure env vars are set before running atmos commands
-
Generated files (backend.tf.json) looking correct is from cached runs when vars WERE set
-
Closes #1909
Document base_path Behavior Change
A recent Atmos CLI change (v1.202.0) altered how base_path is interpreted in atmos.yaml. Previously, base_path: "" was implicitly treated as the current directory. Now it triggers git root discovery.
Impact: Users with multiple Atmos projects in a single repo, or where the Atmos project root differs from the git root, must update their configuration:
# Before (no longer works as expected)
base_path: ""
# After (explicit current directory)
base_path: "."Fix: Added breaking change blog post to the changelog documenting:
- The behavior change and affected versions
- Who is affected (multi-project repos, non-git-root configs)
- Migration steps with examples
- Path resolution semantics table
references
Testing
- Unit tests: All new functionality covered with tests
- Error chain verification: Tests use
assert.NotErrorIs()to verify chain is broken - Regression test:
TestAuthContextWrapper_GetChain_NoLongerPanicsprevents future panics - Env function tests: Document expected behavior when env vars are/aren't set
Summary by CodeRabbit
-
Bug Fixes
- Prevented incorrect error propagation when describing missing components and eliminated panics during authenticated Terraform output handling, improving error stability and clarity.
-
Tests
- Added regression tests for component error wrapping, auth-chain behavior, and template env-var rendering (populated and unset scenarios).
-
Documentation
- Added a troubleshooting guide for Terraform output issues and a blog post explaining base_path behavior changes and migration guidance.
-
Diagnostics
- Added debug logging for YAML/template function errors.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Terraform state path for disabled workspaces @aknysh (#1929)
what
- Fixed
!terraform.stateYAML function to use correct state file paths when Terraform workspaces are disabled (workspaces_enabled: false) - For S3 backend: state is now correctly read from
<key>instead of<workspace_key_prefix>/default/<key> - For Local backend: state is now correctly read from
terraform.tfstateinstead ofterraform.tfstate.d/default/terraform.tfstate - Added comprehensive unit tests for both S3 and local backend default workspace handling
- Added integration tests with a new test fixture for workspaces-disabled scenario
why
- When
workspaces_enabled: falseis set in atmos.yaml, Atmos sets the workspace to "default" but Terraform stores state at different paths for the default workspace vs named workspaces:- S3 backend: Default workspace stores state at
<key>, not<workspace_key_prefix>/default/<key> - Local backend: Default workspace stores state at
terraform.tfstate, notterraform.tfstate.d/default/terraform.tfstate
- S3 backend: Default workspace stores state at
- The
!terraform.stateYAML function was looking in the wrong locations, causing it to fail to find state files when workspaces are disabled - This aligns with Terraform's documented behavior for backend state storage
references
- closes #1920
Summary by CodeRabbit
-
Bug Fixes
- Fixed Terraform state lookup so default/disabled workspaces read state from the root terraform.tfstate location across backends (local, S3, Azure).
-
Tests
- Added unit and end-to-end tests covering state reads and path resolution for default, empty, and named workspaces.
-
Documentation
- Added fixtures and a blog post explaining behavior and upgrade notes when workspaces are disabled.
✏️ Tip: You can customize this high-level summary in your review settings.