Skip to content

Add working_directory support to commands and workflows#1852

Merged
aknysh merged 17 commits intomainfrom
feature/dev-3007-add-optional-working_directory-to-workflow-steps
Dec 14, 2025
Merged

Add working_directory support to commands and workflows#1852
aknysh merged 17 commits intomainfrom
feature/dev-3007-add-optional-working_directory-to-workflow-steps

Conversation

@osterman
Copy link
Member

@osterman osterman commented Dec 10, 2025

what

  • Add optional working_directory field to custom commands and workflow steps to control where they execute
  • Support absolute paths, relative paths (resolved against base_path), and !repo-root YAML function
  • Automatically discover .atmos.d/ at git repository root for repo-wide configuration
  • Add parent directory search for atmos.yaml configuration file
  • Introduce Profiles as first-class configuration concept in precedence list
  • Document all features with comprehensive examples in CLI configuration docs

why

Users need fine-grained control over where commands and workflows execute, especially when using .atmos.d/ at the repository root for shared configurations. Parent directory search and git root discovery make Atmos work seamlessly from any subdirectory, mirroring Git's behavior.

Profiles deserve first-class documentation as a primary configuration mechanism for environment-specific overrides.

references

Closes #DEV-3007

Summary by CodeRabbit

  • New Features

    • Working directory support for commands and workflows (workflow- and step-level overrides; relative paths resolved against the project base).
    • Repo-wide fragments: automatic parent-directory search for atmos.yaml and discovery of .atmos.d at the Git repository root.
  • Documentation

    • New docs and blog posts covering working_directory, discovery precedence, profiles, and examples.
  • Improvements

    • Better config discovery diagnostics and more consistent path normalization in outputs and tests.

✏️ Tip: You can customize this high-level summary in your review settings.

@osterman osterman requested a review from a team as a code owner December 10, 2025 04:26
@github-actions github-actions bot added the size/l Large size PR label Dec 10, 2025
@github-actions
Copy link

github-actions bot commented Dec 10, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

📝 Walkthrough

Walkthrough

Adds optional working_directory fields for commands, workflows, and steps; implements resolution/validation and per-step/workflow working-directory propagation into command execution; extends config discovery to search repository root .atmos.d; adds related errors, tests, sanitization updates, and docs/blog posts.

Changes

Cohort / File(s) Summary
Schema additions
pkg/schema/command.go, pkg/schema/workflow.go
Added WorkingDirectory fields to Command, WorkflowStep, and WorkflowDefinition with YAML/JSON/mapstructure tags.
Working directory resolver
cmd/working_directory.go, cmd/working_directory_test.go
New resolveWorkingDirectory(workDir, basePath, defaultDir) resolves relative paths against basePath, validates existence/type with os.Stat, and returns wrapped sentinel errors; comprehensive tests covering symlinks, permissions, and edge cases.
Command execution integration
cmd/cmd_utils.go
Per-command workDir computed via resolver and applied when executing ENV-value commands and command steps (replaces prior use of current dir); logs when non-empty working_directory specified.
Workflow execution
pkg/workflow/executor.go, pkg/workflow/executor_test.go
Added calculateWorkingDirectory() (workflow vs step precedence), added workingDirectory to runCommandParams, updated runCommand() and executeAtmosCommand() to accept/pass workDir to RunShell / Atmos execution; tests validate absolute/relative resolution and propagation.
Errors
errors/errors.go
Added sentinel errors: ErrWorkingDirNotFound, ErrWorkingDirNotDirectory, ErrWorkingDirAccessFailed.
Config loading & git-root discovery
pkg/config/load.go, pkg/config/load_test.go, pkg/config/config_import_test.go
Extended discovery to search git/worktree root for .atmos.d and .atmos.d/ fragments, added helpers loadAtmosDFromDirectory() and loadAtmosDFromGitRoot(), introduced shouldExcludePathForTesting() and additional trace logging; tests for git-root loading and precedence added.
Logging / sanitization / tests
tests/cli_test.go, tests/cli_sanitize_test.go, tests/test-cases/log-level-validation.yaml, tests/cli_sanitize_test.go, tests/snapshots/*
Expanded sanitizeOutput cases to normalize environment-specific paths (mock git roots, homes, runner paths), updated golden stderr to reflect discovery trace lines for atmos.yaml and .atmos.d lookups; unit tests updated/added accordingly.
Executor / cmd glue
cmd/cmd_utils.go, pkg/workflow/executor.go
Propagated working directory into Atmos execution paths and shell runs; executeAtmosCommand signature updated to accept workDir and passed to Atmos Dir.
Git utilities
pkg/utils/git.go
Lowered log level to Trace when TEST_GIT_ROOT is used.
Docs & blog
website/docs/cli/configuration/*.mdx, website/docs/cli/configuration/commands.mdx, website/docs/cli/configuration/workflows.mdx, website/blog/*.mdx
Added working_directory documentation for commands and workflows, updated configuration discovery docs (parent-directory search, repo-root .atmos.d), and added blog posts describing the features.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as CLI (cmd/cmd_utils)
  participant Resolver as resolveWorkingDirectory
  participant Executor as Workflow Executor
  participant FS as Filesystem (os.Stat)
  participant Runner as RunShell / RunAtmos

  CLI->>Resolver: Request workDir (step/workflow/basePath, default)
  Resolver->>FS: stat(resolvedPath)
  alt exists && is directory
    FS-->>Resolver: ok
    Resolver-->>CLI: resolved workDir
    CLI->>Executor: execute step with workDir
    Executor->>Runner: run command with Dir=workDir
    Runner-->>Executor: command result
    Executor-->>CLI: step result
  else not found / not dir / access
    FS-->>Resolver: error
    Resolver-->>CLI: wrapped sentinel error (ErrWorkingDir*)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to: path resolution edge cases and symlink handling in resolveWorkingDirectory.
  • Verify calculateWorkingDirectory() precedence (step over workflow) and relative resolution against basePath.
  • Confirm executeAtmosCommand() signature change is consistently propagated where called.
  • Review config load changes for non-fatal behavior and test-exclusion handling around git-root .atmos.d.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately summarizes the main change: adding working_directory support to commands and workflows as requested in DEV-3007.
Linked Issues check ✅ Passed All core requirements from DEV-3007 are implemented: working_directory field added to commands/workflows/steps, relative paths resolved against base path, absolute paths supported, directory validation with clear errors, and per-step/per-workflow mixing allowed.
Out of Scope Changes check ✅ Passed Changes include parent-directory search and git-root discovery (.atmos.d) for configuration which extends beyond strict DEV-3007 scope but aligns with PR objectives for seamless subdirectory operation; profiles introduced as documented precedence mechanism; documentation and tests support core feature.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/dev-3007-add-optional-working_directory-to-workflow-steps

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
cmd/cmd_utils.go (1)

453-470: Custom command working directory resolution matches design; consider minor hardening.

  • Defaulting to ".", resolving relative paths against atmosConfig.BasePath, and validating via os.Stat gives predictable behavior and clear failures for bad paths.
  • Reusing workDir for both env valueCommand execution and step execution keeps everything aligned with the configured working directory.

One small optional improvement: trim whitespace around commandConfig.WorkingDirectory before IsAbs/Stat so configs like " subdir " don’t produce confusing “does not exist” errors, and to stay consistent with the workflow calculateWorkingDirectory behavior.

Also applies to: 553-553, 595-595

website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx (1)

22-33: Duplicate “Git Root Discovery for .atmos.d/” section in blog.

The “Git Root Discovery for .atmos.d/” section (including the repo tree example) appears twice with identical content. Dropping one of them will tighten the post without losing information.

Also applies to: 64-75

pkg/workflow/executor_test.go (1)

968-1155: Working directory tests give solid coverage of workflow semantics.

TestExecutor_Execute_WorkingDirectory and TestCalculateWorkingDirectory clearly pin down the precedence and resolution rules (step vs workflow, absolute vs relative vs empty, BasePath resolution, whitespace trimming), and verify both shell and Atmos paths use the same computed directory. That’s a good behavioral safety net for future changes.

If you later add explicit existence checks for workflow working_directory (similar to custom commands), consider adding a negative-case test to assert the error message/path handling, but what’s here is already strong.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 448d405 and fa5e0f2.

📒 Files selected for processing (12)
  • cmd/cmd_utils.go (3 hunks)
  • pkg/config/config_import_test.go (1 hunks)
  • pkg/config/load.go (9 hunks)
  • pkg/config/load_test.go (1 hunks)
  • pkg/schema/command.go (1 hunks)
  • pkg/schema/workflow.go (1 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (1 hunks)
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
  • website/docs/cli/configuration/configuration.mdx (3 hunks)
  • website/docs/cli/configuration/workflows.mdx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • pkg/config/load.go
  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/schema/workflow.go
  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • pkg/schema/command.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/config/load.go
  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • pkg/schema/workflow.go
  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • pkg/schema/command.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • website/docs/cli/configuration/commands.mdx
  • website/docs/cli/configuration/configuration.mdx
  • website/docs/cli/configuration/workflows.mdx
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts require YAML front matter with slug, title, authors, and tags. Use <!--truncate--> after intro. ONLY use existing tags from website/blog/*.mdx - check before writing. Author field must be GitHub username, added to website/blog/authors.yml. Filename format: YYYY-MM-DD-feature-name.mdx. PRs labeled minor/major MUST include blog post

Files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Use assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • pkg/workflow/executor_test.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

cmd/**/*.go: CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to pkg/ packages
Use flags.NewStandardParser() for command-specific flag parsing. NEVER call viper.BindEnv() or viper.BindPFlag() directly - use the unified pkg/flags/ infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling
All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/cmd_utils.go
🧠 Learnings (60)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: `cfg`, `log`, `u`, `errUtils`

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions. Use `nil` if no atmosConfig param

Applied to files:

  • pkg/config/load.go
  • pkg/config/load_test.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/config/load.go
  • pkg/config/config_import_test.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` for environment variables - ATMOS_ prefix required. Configuration loading precedence: CLI flags → ENV vars → config files → defaults

Applied to files:

  • pkg/config/load.go
  • pkg/config/load_test.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/config/load.go
  • cmd/cmd_utils.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • pkg/config/load.go
  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-03-12T21:38:42.699Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1139
File: pkg/config/go-homedir/homedir.go:183-196
Timestamp: 2025-03-12T21:38:42.699Z
Learning: The code in pkg/config/go-homedir is a direct fork of the mitchellh/go-homedir package and was intentionally imported as-is without modifications to maintain consistency with the original source. Security concerns or other improvements may be addressed in future PRs.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to pkg/**/*.go : Create focused purpose-built packages in `pkg/` for new functionality, each with clear responsibility. DO NOT add new functions to `pkg/utils/` or `internal/exec/`. Each package should have focused business logic with tests

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-05-30T03:21:37.197Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1274
File: go.mod:63-63
Timestamp: 2025-05-30T03:21:37.197Z
Learning: The redis dependency (github.com/redis/go-redis/v9) in the atmos project is only used in tests, not in production code.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/config/load.go
  • pkg/config/config_import_test.go
  • website/docs/cli/configuration/configuration.mdx
  • pkg/workflow/executor.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-23T04:43:31.857Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1430
File: pkg/config/config.go:98-107
Timestamp: 2025-09-23T04:43:31.857Z
Learning: In the Atmos codebase, NO_PAGER environment variable handling is intentionally kept as direct os.Getenv() access in pkg/config/config.go rather than using Viper binding, because adding no_pager to the config file would be confusing for users. This is an acknowledged exception to the normal Viper binding pattern for environment variables.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • pkg/config/load.go
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • cmd/cmd_utils.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • website/docs/cli/configuration/commands.mdx
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2024-10-23T22:11:41.077Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.go : Use `cmd.NewTestKit(t)` for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : New configs support Go templating with `FuncMap()` from `internal/exec/template_funcs.go`. Implement template functions in `internal/exec/template_funcs.go`, register them, add tests, and update documentation

Applied to files:

  • pkg/config/load_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • pkg/config/load_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • pkg/config/load_test.go
  • pkg/config/config_import_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • pkg/config/config_import_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to cmd/**/*.go : Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under `cmd/` directory

Applied to files:

  • cmd/cmd_utils.go
  • pkg/schema/command.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Update website documentation in the `website/` directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands need Docusaurus documentation using `<dl>` for arguments/flags. Follow Docusaurus conventions: frontmatter (slug, title, etc.), purpose note, screengrab, usage/examples/arguments/flags sections. File location: `website/docs/cli/commands/<command>/<subcommand>.mdx`. Always build after changes: `cd website && npm run build`

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-07T18:07:00.549Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T17:34:52.568Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/providers/github/oidc.go:96-100
Timestamp: 2025-09-10T17:34:52.568Z
Learning: The ATMOS_ environment variable binding guideline applies to Atmos configuration variables, not external service-required environment variables like GitHub Actions OIDC variables (GITHUB_ACTIONS, ACTIONS_ID_TOKEN_*) which must use their standard names.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-01-19T22:30:27.600Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-01-19T22:30:27.600Z
Learning: The Atmos YAML function `!env` is used to retrieve environment variables and assign them to sections in stack manifests. It supports both simple types (string, number, boolean) and complex types (JSON-encoded lists, maps, objects).

Applied to files:

  • website/docs/cli/configuration/workflows.mdx
📚 Learning: 2025-09-29T02:20:11.636Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1540
File: internal/exec/validate_component.go:117-118
Timestamp: 2025-09-29T02:20:11.636Z
Learning: The ValidateComponent function in internal/exec/validate_component.go had its componentSection parameter type refined from `any` to `map[string]any` without adding new parameters. This is a type safety improvement, not a signature change requiring call site updates.

Applied to files:

  • pkg/schema/command.go
🧬 Code graph analysis (5)
pkg/config/load.go (2)
pkg/logger/log.go (2)
  • Debug (24-26)
  • Trace (14-16)
pkg/utils/git.go (1)
  • ProcessTagGitRoot (16-67)
pkg/config/load_test.go (2)
pkg/config/load.go (1)
  • LoadConfig (191-310)
pkg/schema/schema.go (1)
  • ConfigAndStacksInfo (646-741)
cmd/cmd_utils.go (4)
errors/error_funcs.go (1)
  • CheckErrorPrintAndExit (216-258)
pkg/logger/log.go (1)
  • Debug (24-26)
pkg/utils/shell_utils.go (1)
  • ExecuteShellAndReturnOutput (33-62)
internal/exec/shell_utils.go (1)
  • ExecuteShell (109-142)
pkg/schema/workflow.go (2)
pkg/schema/command.go (1)
  • Command (5-17)
pkg/schema/schema.go (1)
  • RetryConfig (762-770)
pkg/workflow/executor.go (3)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/interfaces.go (1)
  • WorkflowParams (105-118)
pkg/logger/log.go (1)
  • Debug (24-26)
🪛 LanguageTool
website/docs/cli/configuration/configuration.mdx

[style] ~43-~43: ‘merged together’ might be wordy. Consider a shorter alternative.
Context: ... Multiple profiles can be activated and merged together (left-to-right). See [Profiles](/cli/co...

(EN_WORDINESS_PREMIUM_MERGED_TOGETHER)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (16)
pkg/schema/command.go (1)

6-16: WorkingDirectory field wiring in Command schema looks good.

Field naming and tags are consistent with existing schema patterns and with how WorkingDirectory is consumed in command execution. No issues from a schema perspective.

pkg/config/config_import_test.go (1)

17-19: Nice isolation from real git-root .atmos.d in import test.

Using t.Setenv("TEST_GIT_ROOT", tempDir) cleanly decouples this test from any actual repo-level .atmos.d and follows the preferred t.Setenv pattern.

pkg/schema/workflow.go (1)

8-14: Workflow working_directory schema extension looks consistent.

Adding WorkingDirectory to both WorkflowStep and WorkflowDefinition with matching tags keeps workflows aligned with command behavior and the executor’s expectations.

Also applies to: 18-21

website/docs/cli/configuration/workflows.mdx (1)

76-143: Workflow working_directory documentation matches implementation.

The section clearly explains resolution rules (absolute, relative vs base_path, !repo-root) and the override behavior between workflow-level and step-level settings, with solid examples. This lines up with the executor tests and schema changes.

website/docs/cli/configuration/commands.mdx (1)

458-510: Command working_directory docs are clear and aligned with code.

The description and examples (repo root, /tmp, component directory) match how WorkingDirectory is resolved and used in executeCustomCommand, and the tip about .atmos.d + !repo-root captures the main use case nicely.

pkg/config/load_test.go (2)

1039-1078: Good test coverage for git root .atmos.d with default config.

The test correctly validates that custom commands from .atmos.d at the git root are discovered even when no atmos.yaml exists and running from a subdirectory. The assertions on config.Commands properly verify the expected behavior.


1080-1189: Solid table-driven tests for git root discovery.

The two subtests effectively cover:

  1. Discovery from subdirectories
  2. Priority ordering (config-dir > git-root)

The second test case properly validates that from_config_dir wins over from_git_root. This aligns well with the documented precedence order.

pkg/workflow/executor.go (3)

180-201: Clean integration of working directory calculation.

The error handling pattern here matches the existing step error handling. The workDir is correctly passed through runCommandParams to downstream execution.


236-256: Working directory correctly propagated to both command types.

The default to "." maintains backward compatibility. Both shell and atmos execution paths now respect the configured working directory.


391-415: Well-designed working directory calculation.

The precedence (step > workflow) is correctly implemented. Deferring directory validation to execution time is sensible since YAML functions like !repo-root need to resolve first during config loading.

One note: the function signature returns an error but currently always returns nil. This is forward-thinking for when validation might be added. The comment on lines 410-411 explains this design choice.

pkg/config/load.go (3)

222-233: Good addition of git root .atmos.d loading for default config.

When no atmos.yaml is found, this still discovers .atmos.d at the repo root. The non-fatal error handling (log.Trace and continue) maintains backward compatibility.


860-901: Correct priority ordering for .atmos.d discovery.

Git root is loaded first (lower priority), then config directory (higher priority). The absolute path comparison correctly prevents double-loading when they're the same. The new loadAtmosDFromDirectory helper reduces duplication.


428-428: Good addition of trace logging for config discovery.

The consistent log.Trace calls across system, home, working directory, and parent directory checks will help users debug configuration loading issues.

website/docs/cli/configuration/configuration.mdx (3)

34-43: Clear documentation of the configuration precedence order.

The updated precedence list correctly reflects the implementation:

  • Profiles at #3
  • Parent directories at #5
  • Git repository root at #6

The explanation about git root .atmos.d/ being special (always checked) is helpful.

Minor: "merged together" (line 43) could be shortened to just "merged" per static analysis, but it reads fine as-is.


45-64: Practical example for parent directory search.

The directory structure example and command demonstration clearly explain this Git-like behavior. The note about disabling via ATMOS_CLI_CONFIG_PATH is important for users needing explicit control.


249-286: Well-documented .atmos.d discovery from git root.

The precedence order (git root first/lower priority, config dir second/higher priority) matches the implementation in mergeDefaultImports. The example showing repo-wide commands available from subdirectories effectively illustrates the use case.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 10, 2025
@codecov
Copy link

codecov bot commented Dec 10, 2025

Codecov Report

❌ Patch coverage is 84.04255% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.33%. Comparing base (4bb3135) to head (fcc87ac).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/config/load.go 77.14% 4 Missing and 4 partials ⚠️
cmd/cmd_utils.go 28.57% 3 Missing and 2 partials ⚠️
pkg/workflow/executor.go 92.59% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1852      +/-   ##
==========================================
+ Coverage   73.31%   73.33%   +0.02%     
==========================================
  Files         563      564       +1     
  Lines       54258    54336      +78     
==========================================
+ Hits        39777    39850      +73     
+ Misses      11625    11622       -3     
- Partials     2856     2864       +8     
Flag Coverage Δ
unittests 73.33% <84.04%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/working_directory.go 100.00% <100.00%> (ø)
errors/errors.go 100.00% <ø> (ø)
pkg/utils/git.go 52.94% <100.00%> (ø)
pkg/workflow/executor.go 96.99% <92.59%> (-0.68%) ⬇️
cmd/cmd_utils.go 55.41% <28.57%> (-0.28%) ⬇️
pkg/config/load.go 78.26% <77.14%> (-0.26%) ⬇️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/cli_sanitize_test.go (1)

70-89: Good coverage for temp paths; consider adding non-temp HOME cases.

These cases nicely pin down /var/folders/... and /tmp/... normalization. Given the pipeline failure mentioning /Users/runner/.atmos still leaking into snapshots, it’d be worth adding similar tests for /Users/<user>/.atmos (and possibly C:/Users/<user>/.atmos) once the sanitizer is extended to handle them.

pkg/workflow/executor.go (1)

180-205: Workflow working_directory plumbing matches the spec; test expectations need another look.

The new flow is coherent:

  • Step stack and identity are computed as before.
  • calculateWorkingDirectory cleanly applies the precedence (step > workflow) and resolves relative paths via filepath.Join(basePath, workDir), which lines up with “relative paths resolved against base_path”.
  • runCommand consistently passes that directory into both RunShell and RunAtmos, defaulting to "." when unset.
  • executeAtmosCommand now uses Dir: workDir, so Atmos steps honor the same working directory.

Given that, the reported test failure in TestExecutor_Execute_WorkingDirectory (“Got: \base\tmp; Want: /tmp”) looks more like a mismatch between the test’s expectation and these semantics and/or OS path rules:

  • If the intention is indeed “relative working_directory is anchored to base_path”, tests should assert something like filepath.Join(basePath, "tmp") (or compare with filepath.ToSlash(dir)), not hard‑coded /tmp, especially on Windows.
  • If instead the intended semantics are “unqualified tmp should mean /tmp regardless of base_path, then calculateWorkingDirectory` should be revisited to reflect that rule explicitly.

From the PR objectives, the current implementation seems aligned; I’d recommend adjusting the mock expectations in TestExecutor_Execute_WorkingDirectory to use filepath helpers and verify on both POSIX and Windows before changing this logic.

Also applies to: 215-245, 331-355, 381-405

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 50ede4c and 9b61bd1.

📒 Files selected for processing (9)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/working_directory.go (1 hunks)
  • errors/errors.go (1 hunks)
  • pkg/utils/git.go (1 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (1 hunks)
  • tests/cli_sanitize_test.go (1 hunks)
  • tests/cli_test.go (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/workflow/executor_test.go
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • pkg/utils/git.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • cmd/working_directory.go
  • errors/errors.go
  • pkg/workflow/executor.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/utils/git.go
  • pkg/workflow/executor.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Use assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
tests/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use cmd.NewTestKit(t) for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from tests/test_preconditions.go

Files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
tests/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use pipe redirection (2>&1, | head, | tail) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots. NEVER manually edit golden snapshot files - always use -regenerate-snapshots flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace)

Files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

cmd/**/*.go: CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to pkg/ packages
Use flags.NewStandardParser() for command-specific flag parsing. NEVER call viper.BindEnv() or viper.BindPFlag() directly - use the unified pkg/flags/ infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling
All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/cmd_utils.go
  • cmd/working_directory.go
🧠 Learnings (44)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.
📚 Learning: 2025-01-30T16:56:43.004Z
Learnt from: mcalhoun
Repo: cloudposse/atmos PR: 980
File: pkg/utils/log_utils.go:62-63
Timestamp: 2025-01-30T16:56:43.004Z
Learning: In pkg/utils/log_utils.go, LogTrace is intentionally redirected to LogDebug since charmbracelet logger doesn't support Trace level, maintaining backward compatibility with the original LogTrace functionality.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • pkg/utils/git.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-02-13T07:30:28.946Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: internal/exec/go_getter_utils.go:74-75
Timestamp: 2025-02-13T07:30:28.946Z
Learning: In the `CustomGitDetector.Detect` method of `internal/exec/go_getter_utils.go`, verbose debug logging of raw URLs is intentionally kept for debugging purposes, despite potential credential exposure risks.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.go : Use `cmd.NewTestKit(t)` for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • pkg/utils/git.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to pkg/**/*.go : Create focused purpose-built packages in `pkg/` for new functionality, each with clear responsibility. DO NOT add new functions to `pkg/utils/` or `internal/exec/`. Each package should have focused business logic with tests

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/utils/git.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • cmd/working_directory.go
  • pkg/workflow/executor.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • tests/cli_sanitize_test.go
  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
  • cmd/cmd_utils.go
  • cmd/working_directory.go
  • pkg/workflow/executor.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*_test.go : NEVER use pipe redirection (`2>&1`, `| head`, `| tail`) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots. NEVER manually edit golden snapshot files - always use `-regenerate-snapshots` flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace)

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • tests/cli_sanitize_test.go
  • cmd/cmd_utils.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.yaml : NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`

Applied to files:

  • tests/cli_test.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/errors.go
  • pkg/workflow/executor.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Use sentinel errors from `errors/errors.go` with ErrorBuilder for all user-facing errors. Use `errors.Is()` for checking errors, never string comparison. `WithCause()` preserves underlying error messages, `WithExplanation()` adds context, `WithHint()` provides guidance, `WithContext()` adds key-value pairs

Applied to files:

  • errors/errors.go
📚 Learning: 2025-04-26T15:54:10.506Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1195
File: internal/exec/terraform_clean.go:99-99
Timestamp: 2025-04-26T15:54:10.506Z
Learning: The error variable `ErrRelPath` is defined in `internal/exec/terraform_clean_util.go` and is used across files in the `exec` package, including in `terraform_clean.go`. This is part of an approach to standardize error handling in the codebase.

Applied to files:

  • errors/errors.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.

Applied to files:

  • errors/errors.go
  • pkg/workflow/executor.go
📚 Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
🧬 Code graph analysis (3)
pkg/utils/git.go (1)
pkg/logger/log.go (1)
  • Trace (14-16)
cmd/cmd_utils.go (3)
errors/error_funcs.go (1)
  • CheckErrorPrintAndExit (216-258)
pkg/utils/shell_utils.go (1)
  • ExecuteShellAndReturnOutput (33-62)
internal/exec/shell_utils.go (1)
  • ExecuteShell (109-142)
pkg/workflow/executor.go (2)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/interfaces.go (1)
  • WorkflowParams (105-118)
🪛 GitHub Actions: Tests
pkg/workflow/executor.go

[error] 236-236: Unexpected call to *workflow.MockCommandRunner.RunShell(...) in TestExecutor_Execute_WorkingDirectory. Expected different argument at index 2. Got: \base\tmp; Want: /tmp.


[error] 236-236: Test expectation mismatch: argument at index 2 should be '/tmp' but was '\base\tmp' (path separator difference).

tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden

[error] 1-1: TestCLICommands/Valid_Log_Level_in_Config_File: Stderr diff mismatch detected in golden snapshot. Actual stderr shows home directory path '/Users/runner/.atmos' while expected expects '/mock-home/.atmos' or '/absolute/path/to/external' depending on environment. This indicates environment-specific path differences in test output.

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (4)
pkg/utils/git.go (1)

22-26: Trace-level logging for TEST_GIT_ROOT override looks good

Using log.Trace for the TEST_GIT_ROOT override and tightening the comment punctuation is appropriate. This keeps the message clearly test-only/very-verbose while, given the existing Trace→Debug mapping, not changing effective behavior in practice. Based on learnings, this is consistent with how trace is handled elsewhere.

errors/errors.go (1)

440-442: Working directory sentinel errors look consistent and well-scoped.

Names/messages are precise and align with how ErrorBuilder is used elsewhere for user-facing errors. No changes needed.

cmd/working_directory.go (1)

10-45: resolveWorkingDirectory matches the desired semantics.

Relative vs absolute handling, existence checks, and the structured errors (with context + hints) all look solid and align with the new sentinels. No changes from my side.

cmd/cmd_utils.go (1)

453-460: Custom command working_directory wiring looks correct.

Using resolveWorkingDirectory with atmosConfig.BasePath and then feeding workDir into both ExecuteShellAndReturnOutput and ExecuteShell gives the expected behavior: validated, per-command working directories with relative paths anchored to base_path, and no change when working_directory is omitted.

No issues from my side here.

Also applies to: 540-545, 583-585

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/cli_sanitize_test.go (1)

70-89: Consider adding Windows test case for home directory path normalization.

The test suite covers macOS and Linux for both git root and home directory paths, but doesn't include a Windows test case for home directory normalization (line 86-89 equivalent for Windows). Adding this would improve cross-platform test coverage.

Add this test case after line 89:

{
	name:     "Windows temp home directory path should be normalized",
	input:    "TRCE  Checking for atmos.yaml in home directory path=C:/Users/RUNNER~1/AppData/Local/Temp/TestCLICommands123456789/001/.atmos",
	expected: "TRCE  Checking for atmos.yaml in home directory path=/mock-home/.atmos",
},
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 50ede4c and 9b61bd1.

📒 Files selected for processing (9)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/working_directory.go (1 hunks)
  • errors/errors.go (1 hunks)
  • pkg/utils/git.go (1 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (1 hunks)
  • tests/cli_sanitize_test.go (1 hunks)
  • tests/cli_test.go (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • cmd/cmd_utils.go
  • pkg/workflow/executor.go
  • pkg/workflow/executor_test.go
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
Import organization: three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit
Use sentinel errors from errors/errors.go with ErrorBuilder for all user-facing errors. Use errors.Is() for checking errors, never string comparison. WithCause() preserves underlying error messages, WithExplanation() adds context, WithHint() provides guidance, WithContext() adds key-value pairs
Use context.Context as first parameter for: cancellation signals (prop...

Files:

  • pkg/utils/git.go
  • cmd/working_directory.go
  • errors/errors.go
  • tests/cli_test.go
  • tests/cli_sanitize_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: Business logic packages must follow the Service-Oriented Architecture pattern with: one Service struct per domain, Provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability
Use interface-driven design: define interfaces for all major functionality, use dependency injection for testability, generate mocks with go.uber.org/mock/mockgen with //go:generate directives, avoid integration tests by mocking external dependencies
Create focused purpose-built packages in pkg/ for new functionality, each with clear responsibility. DO NOT add new functions to pkg/utils/ or internal/exec/. Each package should have focused business logic with tests
Implement registry pattern for extensibility and plugin-like architecture. Define interfaces for provider implementations, register implementations in registry, generate mocks with mockgen. Examples: Command Registry in cmd/internal/registry.go, Store Registry in pkg/store/registry.go

Files:

  • pkg/utils/git.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

cmd/**/*.go: CLI command files must be thin wrappers that only handle CLI concerns (flags, arguments, command registration). All business logic must be delegated to pkg/ packages
Use flags.NewStandardParser() for command-specific flag parsing. NEVER call viper.BindEnv() or viper.BindPFlag() directly - use the unified pkg/flags/ infrastructure instead. Register flags with Cobra command and bind to Viper for precedence handling
All CLI commands MUST implement the CommandProvider interface and register via command registry pattern in cmd/internal/registry.go
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown()

Files:

  • cmd/working_directory.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Use assert.ErrorIs(t, err, ErrSentinel) for checking our own errors and stdlib errors. Only use string matching for third-party errors
NEVER use assert.Contains(err.Error(), ...) for error checking. ALWAYS use assert.ErrorIs() instead. NEVER use string comparison: err.Error() == "..." or strings.Contains(err.Error(), ...)
Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid os.Exit, CheckErrorPrintAndExit, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks. Pattern: //go:generate go run go.uber.org/mock/mockgen@latest -source=filename.go -destination=mock_filename_test.go
Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
tests/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use cmd.NewTestKit(t) for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from tests/test_preconditions.go

Files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
tests/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use pipe redirection (2>&1, | head, | tail) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots. NEVER manually edit golden snapshot files - always use -regenerate-snapshots flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace)

Files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
🧠 Learnings (39)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.
📚 Learning: 2025-01-30T16:56:43.004Z
Learnt from: mcalhoun
Repo: cloudposse/atmos PR: 980
File: pkg/utils/log_utils.go:62-63
Timestamp: 2025-01-30T16:56:43.004Z
Learning: In pkg/utils/log_utils.go, LogTrace is intentionally redirected to LogDebug since charmbracelet logger doesn't support Trace level, maintaining backward compatibility with the original LogTrace functionality.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-02-13T07:30:28.946Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: internal/exec/go_getter_utils.go:74-75
Timestamp: 2025-02-13T07:30:28.946Z
Learning: In the `CustomGitDetector.Detect` method of `internal/exec/go_getter_utils.go`, verbose debug logging of raw URLs is intentionally kept for debugging purposes, despite potential credential exposure risks.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests. Make code testable using dependency injection to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. Remove always-skipped tests - fix or delete. Table-driven tests must have real scenarios

Applied to files:

  • pkg/utils/git.go
  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/utils/git.go
  • cmd/working_directory.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • cmd/working_directory.go
  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*.go : Use sentinel errors from `errors/errors.go` with ErrorBuilder for all user-facing errors. Use `errors.Is()` for checking errors, never string comparison. `WithCause()` preserves underlying error messages, `WithExplanation()` adds context, `WithHint()` provides guidance, `WithContext()` adds key-value pairs

Applied to files:

  • errors/errors.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Use `assert.ErrorIs(t, err, ErrSentinel)` for checking our own errors and stdlib errors. Only use string matching for third-party errors

Applied to files:

  • errors/errors.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/errors.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • errors/errors.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • errors/errors.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*_test.go : NEVER use pipe redirection (`2>&1`, `| head`, `| tail`) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots. NEVER manually edit golden snapshot files - always use `-regenerate-snapshots` flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace)

Applied to files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.go : Use `cmd.NewTestKit(t)` for any test touching RootCmd. This auto-cleans RootCmd state. Tests skip gracefully with helpers from `tests/test_preconditions.go`

Applied to files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • tests/cli_test.go
  • tests/cli_sanitize_test.go
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to **/*_test.go : Use table-driven tests for comprehensive coverage. Tests must call actual production code, never duplicate logic. Target >80% test coverage (enforced by CodeCov)

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-06T19:24:49.343Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-06T19:24:49.343Z
Learning: Applies to tests/**/*.yaml : NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes. Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
🧬 Code graph analysis (1)
cmd/working_directory.go (2)
errors/builder.go (1)
  • Build (24-37)
errors/errors.go (3)
  • ErrWorkingDirNotFound (440-440)
  • ErrWorkingDirAccessFailed (442-442)
  • ErrWorkingDirNotDirectory (441-441)
🪛 GitHub Actions: Tests
tests/cli_test.go

[error] 1704-1704: Stderr diff mismatch for TestCLICommands_Valid_Log_Level_in_Config_File. Expected path references differed (system config path vs absolute path).

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (4)
pkg/utils/git.go (1)

22-26: LGTM!

Log level change from Debug to Trace is appropriate here. Test isolation mechanisms shouldn't pollute debug output. The comment punctuation fix aligns with godot linter requirements.

tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1)

1-65: Snapshot correctly reflects expanded config discovery.

The trace output captures the new git-root-based config discovery flow. Mock paths (/mock-home, /mock-git-root) ensure test isolation. The repeated discovery cycles and "Failed to load" messages at trace level are expected behavior when .atmos.d directories don't exist.

cmd/working_directory.go (1)

10-46: Clean implementation with proper error handling.

Good use of sentinel errors with ErrorBuilder pattern. The three error cases (not found, access failed, not a directory) are well-differentiated with helpful hints. Path resolution via filepath.Join is cross-platform safe.

errors/errors.go (1)

440-442: New sentinel errors are well-placed and clearly named.

These complement the working directory resolution in cmd/working_directory.go. Messages are clear and actionable. Placement near workflow errors makes sense given the feature context.

@github-actions github-actions bot added size/xl Extra large size PR and removed size/l Large size PR labels Dec 10, 2025
@mergify
Copy link

mergify bot commented Dec 10, 2025

Warning

This PR exceeds the recommended limit of 1,000 lines.

Large PRs are difficult to review and may be rejected due to their size.

Please verify that this PR does not address multiple issues.
Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/workflow/executor.go (1)

177-246: Add explicit working directory validation in workflow adapters or update error classification. The workflow layer intentionally defers directory validation to execution time (as noted in calculateWorkingDirectory line 400-401, allowing YAML functions like !repo-root to resolve first). However, ExecuteShell and ExecuteShellCommand don't validate the dir parameter before use—when exec.Cmd.Run() fails due to an invalid working directory, it returns a generic *os.PathError rather than using the semantic ErrWorkingDir* sentinels that already exist in errors/errors.go and are used in the CLI layer (cmd/working_directory.go). Either add explicit validation in the adapters (e.g., os.Stat + sentinel return) matching the CLI pattern, or update the comment to clarify that validation happens implicitly at runtime and errors will surface as generic exec failures.

🧹 Nitpick comments (2)
errors/errors.go (1)

440-443: Avoid “workdir” vs “working dir” sentinel confusion (consider consolidating or documenting intent). The repo now has both ErrWorkdirNotExist and ErrWorkingDirNotFound-style sentinels; tightening the naming/usage contract would reduce mistakes.

cmd/working_directory.go (1)

10-46: Tighten path canonicalization + include the underlying stat error in the “not found” branch. This improves debuggability and makes path handling less surprising across OSes.

 func resolveWorkingDirectory(workDir, basePath, defaultDir string) (string, error) {
 	if workDir == "" {
 		return defaultDir, nil
 	}

 	// Resolve relative paths against base_path.
-	resolvedDir := workDir
+	resolvedDir := workDir
 	if !filepath.IsAbs(workDir) {
 		resolvedDir = filepath.Join(basePath, workDir)
 	}
+	resolvedDir = filepath.Clean(resolvedDir)

 	// Validate directory exists and is a directory.
 	info, err := os.Stat(resolvedDir)
 	if os.IsNotExist(err) {
 		return "", errUtils.Build(errUtils.ErrWorkingDirNotFound).
+			WithCause(err).
 			WithContext("path", resolvedDir).
 			WithHint("Check that the working_directory path exists").
 			Err()
 	}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 07c11e5 and 16670d9.

📒 Files selected for processing (18)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/working_directory.go (1 hunks)
  • errors/errors.go (1 hunks)
  • pkg/config/config_import_test.go (1 hunks)
  • pkg/config/load.go (9 hunks)
  • pkg/config/load_test.go (1 hunks)
  • pkg/schema/command.go (1 hunks)
  • pkg/schema/workflow.go (1 hunks)
  • pkg/utils/git.go (1 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (1 hunks)
  • tests/cli_sanitize_test.go (1 hunks)
  • tests/cli_test.go (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1 hunks)
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
  • website/docs/cli/configuration/configuration.mdx (3 hunks)
  • website/docs/cli/configuration/workflows.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • website/docs/cli/configuration/workflows.mdx
  • cmd/cmd_utils.go
  • pkg/config/config_import_test.go
  • pkg/schema/workflow.go
  • pkg/config/load_test.go
🧰 Additional context used
📓 Path-based instructions (8)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Comments document why/how/what/where. Preserve helpful comments, update to match code, refactor for clarity, add context when modifying.
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() with a blank line to all public functions. Use nil if no atmosConfig parameter is available.
Define interfaces for all major functionality. Use dependency injection for testability. Generate mocks with go.uber.org/mock/mockgen. Avoid integration tests by mocking external dependencies.
Use //go:generate directives with go.uber.org/mock/mockgen for mock generation. Never creat...

Files:

  • errors/errors.go
  • pkg/workflow/executor_test.go
  • cmd/working_directory.go
  • pkg/config/load.go
  • pkg/utils/git.go
  • pkg/workflow/executor.go
  • tests/cli_sanitize_test.go
  • pkg/schema/command.go
  • tests/cli_test.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/docs/cli/configuration/commands.mdx
  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
website/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

ALWAYS build website after doc changes: cd website && npm run build. Verify: no broken links, missing images, MDX component rendering.

Files:

  • website/docs/cli/configuration/commands.mdx
  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Prefer unit tests with mocks over integration tests. Use interfaces and dependency injection for testability. Generate mocks with go.uber.org/mock/mockgen. Use table-driven tests for comprehensive coverage. Target >80% coverage.
Test behavior, not implementation. Never test stub functions. Avoid tautological tests. Make code testable using DI. No coverage theater. Remove always-skipped tests. Table-driven tests need real scenarios. Use assert.ErrorIs(err, ErrSentinel) for our/stdlib errors.
Tests must call actual production code, never duplicate logic.
Use t.Skipf("reason") with clear context for test skipping. CLI tests auto-build temp binaries.
Never use pipe redirection (2>&1, | head, | tail) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots.
Tests skip gracefully with helpers from tests/test_preconditions.go.

Files:

  • pkg/workflow/executor_test.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: For complex domains with multiple operations, use Service-Oriented Architecture with one Service struct per domain, provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability.
Follow multi-provider registry pattern: 1) Define interface in dedicated package, 2) Implement per provider, 3) Register implementations, 4) Generate mocks.

Files:

  • pkg/workflow/executor_test.go
  • pkg/config/load.go
  • pkg/utils/git.go
  • pkg/workflow/executor.go
  • pkg/schema/command.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

cmd/**/*.go: Use registry pattern for extensibility and plugin-like architecture. New commands MUST use command registry pattern via CommandProvider interface.
Separate I/O (streams) from UI (formatting) for clarity and testability. User interaction → stderr via ui.*. Data for processing/piping → stdout via data.*. Never use fmt.Fprintf(os.Stdout/Stderr, ...), fmt.Println(), or direct stream access.
CRITICAL: Unified flag parsing infrastructure is FULLY IMPLEMENTED in pkg/flags/. Commands MUST use flags.NewStandardParser() for command-specific flags. NEVER call viper.BindEnv() or viper.BindPFlag() directly - Forbidigo enforces this.
Configuration loading precedence: CLI flags → ENV vars → config files → defaults (use Viper).
Embed examples from cmd/markdown/*_usage.md using //go:embed. Render with utils.PrintfMarkdown().
Use viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK") - ATMOS_ prefix required for environment variables.
Telemetry auto-enabled via RootCmd.ExecuteC(). Non-standard paths use telemetry.CaptureCmd(). Never capture user data.
UI (prompts, status) → stderr. Data → stdout. Logging for system events only. Never use logging for UI.

Files:

  • cmd/working_directory.go
tests/snapshots/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER manually edit golden snapshot files. Always use -regenerate-snapshots flag. Snapshots capture exact output including invisible formatting.

Files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
website/blog/**/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

website/blog/**/*.mdx: Follow PR template (what/why/references). PRs labeled minor/major MUST include blog post: website/blog/YYYY-MM-DD-feature-name.mdx. Use .mdx with YAML front matter, <!--truncate--> after intro. MUST use tags from website/blog/tags.yml only. MUST use existing author from website/blog/authors.yml or add new entry.
Blog posts must have YAML frontmatter with: slug, title, authors, tags. Use <!--truncate--> after introduction. Valid tags must be from website/blog/tags.yml.

Files:

  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
🧠 Learnings (78)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
Learnt from: osterman
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-02-04T22:45:15.845Z
Learning: URL validation in Atmos should support query parameters (like `depth=1` and `ref=`) which are commonly used in Git URLs for shallow clones and version references.
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : ALL user-facing errors MUST use ErrorBuilder with sentinel errors from `errors/errors.go`. ALWAYS use `errors.Is()` for checking, NEVER string comparison. ALWAYS use `assert.ErrorIs()` in tests, NEVER `assert.Contains(err.Error(), ...)`

Applied to files:

  • errors/errors.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to internal/**/*.go : For legacy patterns (internal/non-user-facing only): use `errors.Join` for multiple errors, `fmt.Errorf("%w", err)` for chains (sequential call stack), or `fmt.Errorf` with multiple `%w` like `errors.Join` (Go 1.20+).

Applied to files:

  • errors/errors.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • errors/errors.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/errors.go
  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • errors/errors.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to README.md : Update README.md with new commands and features

Applied to files:

  • website/docs/cli/configuration/commands.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Update website documentation in the `website/` directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to website/** : Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to website/docs/cli/commands/**/*.mdx : All CLI commands/flags need Docusaurus docs in `website/docs/cli/commands/`. Use `<dl>` for args/flags. Build: `cd website && npm run build`

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: When adding new CLI commands, create `cmd/[command]/` with CommandProvider interface, add blank import to `cmd/root.go`, implement in `internal/exec/mycommand.go`, add tests in `cmd/mycommand/mycommand_test.go`, create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-07T18:07:00.549Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1452
File: cmd/auth_login.go:43-44
Timestamp: 2025-09-07T18:07:00.549Z
Learning: In the atmos project, the identity flag is defined as a persistent flag on the auth root command (cmd/auth.go), making it available to all auth subcommands without needing to be redefined in each individual subcommand.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/docs/cli/configuration/commands.mdx
  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • pkg/workflow/executor_test.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • pkg/workflow/executor_test.go
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • pkg/workflow/executor_test.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • cmd/working_directory.go
  • pkg/config/load.go
  • pkg/utils/git.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : Use functional options pattern for configuration instead of many parameters. Provides defaults and extensibility without breaking changes.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/config/load.go
  • tests/cli_test.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: `cfg`, `log`, `u`, `errUtils`

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` with a blank line to all public functions. Use `nil` if no atmosConfig parameter is available.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • pkg/config/load.go
  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • pkg/config/load.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to cmd/**/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required for environment variables.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-05-30T03:21:37.197Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1274
File: go.mod:63-63
Timestamp: 2025-05-30T03:21:37.197Z
Learning: The redis dependency (github.com/redis/go-redis/v9) in the atmos project is only used in tests, not in production code.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • pkg/config/load.go
  • pkg/utils/git.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to cmd/**/*.go : Configuration loading precedence: CLI flags → ENV vars → config files → defaults (use Viper).

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/config/load.go
  • pkg/workflow/executor.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • pkg/config/load.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • pkg/config/load.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-01-30T16:56:43.004Z
Learnt from: mcalhoun
Repo: cloudposse/atmos PR: 980
File: pkg/utils/log_utils.go:62-63
Timestamp: 2025-01-30T16:56:43.004Z
Learning: In pkg/utils/log_utils.go, LogTrace is intentionally redirected to LogDebug since charmbracelet logger doesn't support Trace level, maintaining backward compatibility with the original LogTrace functionality.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-02-13T07:30:28.946Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: internal/exec/go_getter_utils.go:74-75
Timestamp: 2025-02-13T07:30:28.946Z
Learning: In the `CustomGitDetector.Detect` method of `internal/exec/go_getter_utils.go`, verbose debug logging of raw URLs is intentionally kept for debugging purposes, despite potential credential exposure risks.

Applied to files:

  • pkg/utils/git.go
📚 Learning: 2025-11-10T23:23:39.771Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/registry/aqua/aqua_test.go:417-442
Timestamp: 2025-11-10T23:23:39.771Z
Learning: In Atmos toolchain AquaRegistry, tests should not hit real GitHub. Use the options pattern via WithGitHubBaseURL to inject an httptest server URL and make GetLatestVersion/GetAvailableVersions deterministic.

Applied to files:

  • pkg/utils/git.go
  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Search `internal/exec/` and `pkg/` before implementing. Extend, don't duplicate.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Never use pipe redirection (`2>&1`, `| head`, `| tail`) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to tests/snapshots/**/* : NEVER manually edit golden snapshot files. Always use `-regenerate-snapshots` flag. Snapshots capture exact output including invisible formatting.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-11-22T12:38:33.132Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • tests/cli_sanitize_test.go
  • tests/cli_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions. Avoid tautological tests. Make code testable using DI. No coverage theater. Remove always-skipped tests. Table-driven tests need real scenarios. Use `assert.ErrorIs(err, ErrSentinel)` for our/stdlib errors.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Tests skip gracefully with helpers from `tests/test_preconditions.go`.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • tests/cli_sanitize_test.go
📚 Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T17:34:52.568Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/providers/github/oidc.go:96-100
Timestamp: 2025-09-10T17:34:52.568Z
Learning: The ATMOS_ environment variable binding guideline applies to Atmos configuration variables, not external service-required environment variables like GitHub Actions OIDC variables (GITHUB_ACTIONS, ACTIONS_ID_TOKEN_*) which must use their standard names.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-10-23T22:11:41.077Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
  • tests/cli_test.go
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to cmd/**/*.go : Use registry pattern for extensibility and plugin-like architecture. New commands MUST use command registry pattern via `CommandProvider` interface.

Applied to files:

  • pkg/schema/command.go
📚 Learning: 2024-12-25T20:28:19.618Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/workflow_utils.go:167-169
Timestamp: 2024-12-25T20:28:19.618Z
Learning: The user plans to revert the change from `path.Join` to `filepath.Join` in this PR due to testing gaps and will open a new PR to safely handle the migration without breaking `main`.

Applied to files:

  • tests/cli_test.go
📚 Learning: 2024-10-27T04:41:49.199Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:215-223
Timestamp: 2024-10-27T04:41:49.199Z
Learning: In `internal/exec/terraform_clean.go`, the function `determineCleanPath` is necessary and should not be removed.

Applied to files:

  • tests/cli_test.go
📚 Learning: 2025-02-05T11:10:51.031Z
Learnt from: mss
Repo: cloudposse/atmos PR: 1024
File: internal/exec/go_getter_utils.go:31-33
Timestamp: 2025-02-05T11:10:51.031Z
Learning: The path traversal check in `ValidateURI` function in `internal/exec/go_getter_utils.go` is intentionally kept despite potentially blocking valid Git URLs, as this validation is planned to be addressed in a separate ticket.

Applied to files:

  • tests/cli_test.go
📚 Learning: 2025-01-08T19:02:28.099Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/vendor.yaml:48-48
Timestamp: 2025-01-08T19:02:28.099Z
Learning: Test cases in the Atmos project deliberately use different Git URL formats (with and without `git::` prefix) to test various scenarios. These formats should not be normalized to maintain test coverage of different URL handling cases.

Applied to files:

  • tests/cli_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : Linux/macOS/Windows compatible. Use SDKs over binaries. Use `filepath.Join()`, not hardcoded path separators.

Applied to files:

  • tests/cli_test.go
🧬 Code graph analysis (5)
pkg/workflow/executor_test.go (4)
pkg/workflow/interfaces.go (3)
  • AtmosExecParams (10-23)
  • WorkflowParams (105-118)
  • ExecuteOptions (90-102)
pkg/workflow/executor.go (1)
  • NewExecutor (36-42)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/schema/command.go (1)
  • Command (5-17)
pkg/config/load.go (2)
pkg/logger/log.go (2)
  • Debug (24-26)
  • Trace (14-16)
pkg/utils/git.go (1)
  • ProcessTagGitRoot (16-67)
pkg/utils/git.go (1)
pkg/logger/log.go (1)
  • Trace (14-16)
pkg/workflow/executor.go (1)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/schema/command.go (3)
pkg/auth/hooks.go (1)
  • Identity (22-22)
pkg/auth/types/interfaces.go (1)
  • Identity (121-170)
pkg/auth/providers/mock/identity.go (1)
  • Identity (33-36)
🪛 LanguageTool
website/docs/cli/configuration/configuration.mdx

[style] ~43-~43: ‘merged together’ might be wordy. Consider a shorter alternative.
Context: ... Multiple profiles can be activated and merged together (left-to-right). See [Profiles](/cli/co...

(EN_WORDINESS_PREMIUM_MERGED_TOGETHER)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Summary
🔇 Additional comments (8)
pkg/utils/git.go (1)

22-26: Trace-level logging for TEST_GIT_ROOT looks good—confirm it’s surfaced where you expect.
Switching to log.Trace keeps noisy test-only diagnostics out of default logs, but it can also make CI/local troubleshooting harder if Trace isn’t enabled by default. Sanity-check that your test/debug workflows still show this line when needed.

pkg/schema/command.go (1)

5-17: Schema addition looks good (Command.WorkingDirectory).

tests/cli_sanitize_test.go (1)

70-119: Nice coverage expansion for cross-environment path sanitization.

tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1)

2-61: Snapshot reflects new config discovery tracing.

The updated trace output correctly shows the new parent directory search and git root discovery flow. The sanitized paths (/mock-home/.atmos, /mock-git-root) confirm the normalization changes from commit 07c11e5 are working.

tests/cli_test.go (1)

449-471: Well-structured path normalization with proper ordering.

The 12a/12b/12c ordering ensures test-specific paths are normalized before generic external path sanitization. Cross-platform coverage (macOS, Linux, Windows) looks complete. Clear comments explain the ordering dependency.

website/docs/cli/configuration/configuration.mdx (3)

30-64: Clear documentation of new discovery features.

The precedence order is well-documented, and the parent directory search example effectively illustrates the Git-like behavior. The distinction between disabling via ATMOS_CLI_CONFIG_PATH is helpful.


77-101: Good profiles introduction.

Covers the essentials without over-documenting. The link to the dedicated Profiles page is the right approach.


249-286: Solid .atmos.d discovery documentation.

The git-root-first/config-dir-override precedence is clearly explained. The tip directing users to Profiles for environment-specific config is good guidance.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/workflow/executor.go (1)

44-96: Prevent nil CommandRunner panic at runtime. Execute will dereference e.runner via runCommand; today a nil runner would panic despite the docstring saying it’s required. Consider failing fast with an ErrorBuilder error before step execution.

 func (e *Executor) Execute(params *WorkflowParams) (*ExecutionResult, error) {
 	if params == nil || params.AtmosConfig == nil {
 		return nil, errUtils.ErrNilParam
 	}
+	if e.runner == nil {
+		err := errUtils.Build(errUtils.ErrNilParam).
+			WithExplanationf("Workflow executor is missing a command runner and cannot execute workflow `%s`.", params.Workflow).
+			WithHintf("This is a bug. Please report it with the workflow name and command you ran.").
+			Err()
+		return nil, err
+	}
 	defer perf.Track(params.AtmosConfig, "workflow.Executor.Execute")()
🧹 Nitpick comments (2)
pkg/workflow/executor_test.go (1)

936-1136: Nice coverage for working_directory propagation; consider adding an empty-basePath case. You’re validating both shell (RunShell(..., dir, ...)) and atmos (AtmosExecParams.Dir) across precedence scenarios, which matches the feature intent. One additional table row for basePath: "" would lock in the “fallback to '.'” behavior in calculateWorkingDirectory.

pkg/workflow/executor.go (1)

381-410: Solid precedence + basePath fallback; optional normalization. The step-over-workflow rule and basePath == "" -> "." guard are good. As a small hardening, you could filepath.Clean the final workDir (especially for absolute user inputs) so logs/behavior are consistent.

 	if !filepath.IsAbs(workDir) {
 		resolvedBasePath := basePath
 		if strings.TrimSpace(resolvedBasePath) == "" {
 			resolvedBasePath = "."
 		}
 		workDir = filepath.Join(resolvedBasePath, workDir)
 	}
+
+	workDir = filepath.Clean(workDir)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 16670d9 and 7198f0c.

📒 Files selected for processing (5)
  • pkg/config/load.go (9 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (2 hunks)
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • website/blog/2025-12-09-working-directory-and-git-root-discovery.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • website/docs/cli/configuration/commands.mdx
  • pkg/config/load.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: All comments must end with periods (enforced by godot linter)
NEVER delete existing comments without a very strong reason. Comments document why/how/what/where. Preserve helpful comments, update to match code, refactor for clarity, add context when modifying.
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages. Maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() with a blank line to all public functions. Use nil if no atmosConfig parameter is available.
Define interfaces for all major functionality. Use dependency injection for testability. Generate mocks with go.uber.org/mock/mockgen. Avoid integration tests by mocking external dependencies.
Use //go:generate directives with go.uber.org/mock/mockgen for mock generation. Never creat...

Files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Prefer unit tests with mocks over integration tests. Use interfaces and dependency injection for testability. Generate mocks with go.uber.org/mock/mockgen. Use table-driven tests for comprehensive coverage. Target >80% coverage.
Test behavior, not implementation. Never test stub functions. Avoid tautological tests. Make code testable using DI. No coverage theater. Remove always-skipped tests. Table-driven tests need real scenarios. Use assert.ErrorIs(err, ErrSentinel) for our/stdlib errors.
Tests must call actual production code, never duplicate logic.
Use t.Skipf("reason") with clear context for test skipping. CLI tests auto-build temp binaries.
Never use pipe redirection (2>&1, | head, | tail) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots.
Tests skip gracefully with helpers from tests/test_preconditions.go.

Files:

  • pkg/workflow/executor_test.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/**/*.go: For complex domains with multiple operations, use Service-Oriented Architecture with one Service struct per domain, provider interfaces for classes of problems, default implementations, mock implementations, and dependency injection for testability.
Follow multi-provider registry pattern: 1) Define interface in dedicated package, 2) Implement per provider, 3) Register implementations, 4) Generate mocks.

Files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
🧠 Learnings (26)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*.go : Linux/macOS/Windows compatible. Use SDKs over binaries. Use `filepath.Join()`, not hardcoded path separators.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Never use pipe redirection (`2>&1`, `| head`, `| tail`) when running tests. Piping breaks TTY detection → ASCII fallback → wrong snapshots.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Test behavior, not implementation. Never test stub functions. Avoid tautological tests. Make code testable using DI. No coverage theater. Remove always-skipped tests. Table-driven tests need real scenarios. Use `assert.ErrorIs(err, ErrSentinel)` for our/stdlib errors.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2024-12-25T20:28:19.618Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/workflow_utils.go:167-169
Timestamp: 2024-12-25T20:28:19.618Z
Learning: The user plans to revert the change from `path.Join` to `filepath.Join` in this PR due to testing gaps and will open a new PR to safely handle the migration without breaking `main`.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to **/*_test.go : Tests skip gracefully with helpers from `tests/test_preconditions.go`.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-11-22T12:38:33.132Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-12-10T23:12:15.805Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.805Z
Learning: Applies to cmd/**/*.go : Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required for environment variables.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/workflow/executor.go
🧬 Code graph analysis (2)
pkg/workflow/executor_test.go (3)
pkg/workflow/interfaces.go (1)
  • AtmosExecParams (10-23)
pkg/workflow/executor.go (1)
  • NewExecutor (36-42)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/executor.go (3)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/interfaces.go (1)
  • WorkflowParams (105-118)
pkg/logger/log.go (1)
  • Debug (24-26)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (2)
pkg/workflow/executor_test.go (1)

6-6: OS-portable path expectations look fixed. The move to filepath.FromSlash/filepath.Join should keep these tests Windows-safe.

pkg/workflow/executor.go (1)

147-246: working_directory plumbing is clean and consistent. Calculating once in executeStep, defaulting to "." in runCommand, and passing through to both RunShell and AtmosExecParams.Dir is straightforward and matches expected precedence.

@osterman osterman force-pushed the feature/dev-3007-add-optional-working_directory-to-workflow-steps branch from aee754d to accfbde Compare December 13, 2025 03:33
Separate the combined blog post into two posts:
- Parent Directory Search and Git Root Discovery (v1.198.0, already released)
- Working Directory Support (this PR's new feature)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace terraform example with more realistic docker compose use case
and fix !repo-root usage (no argument needed for repo root).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Valid_Log_Level_in_Config_File test was failing on Windows CI because:
- System config path differs between Unix (/usr/local/etc/atmos) and Windows (%LOCALAPPDATA%/atmos)
- Home directory trace log may not be emitted on Windows if env vars aren't set

Add diff patterns to filter out these platform-specific trace lines from
both expected and actual output before comparison.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/cli_test.go (1)

449-470: Make Windows drive-letter matching case-insensitive in sanitizers.
If output ever contains c:/... (lowercase), [A-Z]:/ won’t match. Safer to use (?i) or [A-Za-z]:/ in both tempGitRootRegex and tempHomeDirRegex.

- tempGitRootRegex := regexp.MustCompile(`path=(/var/folders/[^\s]+/mock-git-root|/tmp/[^\s]+/mock-git-root|/Users/[^\s]+/mock-git-root|/home/[^\s]+/mock-git-root|[A-Z]:/[^\s]+/mock-git-root|/absolute/path/to/repo/mock-git-root)`)
+ tempGitRootRegex := regexp.MustCompile(`(?i)path=(/var/folders/[^\s]+/mock-git-root|/tmp/[^\s]+/mock-git-root|/Users/[^\s]+/mock-git-root|/home/[^\s]+/mock-git-root|[A-Z]:/[^\s]+/mock-git-root|/absolute/path/to/repo/mock-git-root)`)

- tempHomeDirRegex := regexp.MustCompile(`path=(/var/folders/[^\s]+/\.atmos|/tmp/[^\s]+/\.atmos|/Users/[^\s]+/\.atmos|/home/[^\s]+/\.atmos|[A-Z]:/[^\s]+/\.atmos|/absolute/path/to/repo/[^\s]+/\.atmos)`)
+ tempHomeDirRegex := regexp.MustCompile(`(?i)path=(/var/folders/[^\s]+/\.atmos|/tmp/[^\s]+/\.atmos|/Users/[^\s]+/\.atmos|/home/[^\s]+/\.atmos|[A-Z]:/[^\s]+/\.atmos|/absolute/path/to/repo/[^\s]+/\.atmos)`)
🧹 Nitpick comments (4)
website/docs/cli/configuration/configuration.mdx (2)

30-65: Clarify that .atmos.d/ is fragments (auto-imports), not “a configuration file discovered.”
Line 41 currently reads like .atmos.d/ participates in the same “each configuration file discovered is deep-merged” flow—worth a small wording tweak to avoid confusion.

-Each configuration file discovered is deep-merged with the preceding configurations. The git repository root is special: even when `atmos.yaml` is found elsewhere, Atmos always checks for `.atmos.d/` at the repo root to load shared configuration fragments like custom commands.
+Each configuration file discovered is deep-merged with the preceding configurations. Separately, Atmos may also auto-import configuration fragments from `.atmos.d/`. The git repository root is special: even when `atmos.yaml` is found elsewhere, Atmos always checks for `.atmos.d/` at the repo root to load shared fragments like custom commands.

77-102: Minor wording nit: “merged together” → “merged”.
Keeps it tighter (matches LanguageTool).

cmd/working_directory.go (1)

10-46: Consider filepath.Clean on absolute workDir too (consistency).
Relative paths get cleaned by filepath.Join, but absolute inputs like /tmp/foo/.. won’t. Low risk, but it keeps returned values normalized.

- resolvedDir := workDir
+ resolvedDir := filepath.Clean(workDir)
  if !filepath.IsAbs(workDir) {
-     resolvedDir = filepath.Join(basePath, workDir)
+     resolvedDir = filepath.Join(basePath, workDir)
  }
cmd/working_directory_test.go (1)

162-233: Missing unit coverage for ErrWorkingDirAccessFailed.
Worth adding a platform-guarded test that creates a dir with no execute/read perms (or chmod 000) and asserts ErrorIs(err, ErrWorkingDirAccessFailed); skip on Windows where perms differ.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7198f0c and a05590b.

📒 Files selected for processing (21)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/working_directory.go (1 hunks)
  • cmd/working_directory_test.go (1 hunks)
  • errors/errors.go (1 hunks)
  • pkg/config/config_import_test.go (1 hunks)
  • pkg/config/load.go (9 hunks)
  • pkg/config/load_test.go (1 hunks)
  • pkg/schema/command.go (1 hunks)
  • pkg/schema/workflow.go (1 hunks)
  • pkg/utils/git.go (1 hunks)
  • pkg/workflow/executor.go (5 hunks)
  • pkg/workflow/executor_test.go (2 hunks)
  • tests/cli_sanitize_test.go (1 hunks)
  • tests/cli_test.go (1 hunks)
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1 hunks)
  • tests/test-cases/log-level-validation.yaml (1 hunks)
  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx (1 hunks)
  • website/blog/2025-12-09-working-directory-support.mdx (1 hunks)
  • website/docs/cli/configuration/commands.mdx (1 hunks)
  • website/docs/cli/configuration/configuration.mdx (3 hunks)
  • website/docs/cli/configuration/workflows.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • website/blog/2025-12-09-working-directory-support.mdx
  • pkg/utils/git.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • website/docs/cli/configuration/commands.mdx
  • errors/errors.go
  • cmd/cmd_utils.go
  • pkg/config/config_import_test.go
  • website/docs/cli/configuration/workflows.mdx
  • pkg/config/load.go
  • tests/cli_sanitize_test.go
🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: Comment style: All comments must end with periods (enforced by godot linter)
Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: cfg, log, u, errUtils
Performance tracking: Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors from errors/errors.go. ALWAYS use errors.Is() for checking, NEVER string comparison. ALWAYS use assert.ErrorIs() in tests, NEVER assert.Contains(err.Error(), ...)
Mock generation: Use go.uber.org/mock/mockgen with //go:generate directives. Never manual mocks
File organization: Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use `//revive:disable:file-lengt...

Files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • pkg/schema/workflow.go
  • cmd/working_directory.go
  • cmd/working_directory_test.go
  • pkg/schema/command.go
  • pkg/config/load_test.go
  • tests/cli_test.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Test skipping conventions: Use t.Skipf("reason") with clear context. CLI tests auto-build temp binaries
Golden snapshots: NEVER manually edit golden snapshot files - Always use -regenerate-snapshots flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace). Different environments produce different output. Never use pipe redirection (2>&1, | head, | tail) when running tests as piping breaks TTY detection

Files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
  • tests/cli_test.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • website/docs/cli/configuration/configuration.mdx
website/blog/*.mdx

📄 CodeRabbit inference engine (CLAUDE.md)

Blog posts: Use .mdx format with YAML front matter in website/blog/YYYY-MM-DD-feature-name.mdx. Include <!--truncate--> after intro. Use only tags defined in website/blog/tags.yml. Use authors from website/blog/authors.yml

Files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/working_directory.go
  • cmd/working_directory_test.go
cmd/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

cmd/**/*_test.go: Testing: Use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args)
Test isolation: ALWAYS use cmd.NewTestKit(t) for cmd tests to auto-clean RootCmd state (flags, args). Required for any test touching RootCmd

Files:

  • cmd/working_directory_test.go
🧠 Learnings (68)
📓 Common learnings
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Test data: Use fixtures in `tests/test-cases/`: `atmos.yaml`, `stacks/`, `components/`. NEVER modify `tests/test-cases/` or `tests/testdata/` unless explicitly instructed. Golden snapshots are sensitive to minor changes

Applied to files:

  • tests/test-cases/log-level-validation.yaml
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.

Applied to files:

  • tests/test-cases/log-level-validation.yaml
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • cmd/working_directory.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
  • tests/cli_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • pkg/schema/workflow.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • cmd/working_directory_test.go
  • tests/cli_test.go
📚 Learning: 2024-12-25T20:28:47.526Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • tests/cli_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
  • pkg/config/load_test.go
  • tests/cli_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_test.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Cross-platform compatibility: Linux/macOS/Windows compatible. Use SDKs over binaries. Use `filepath.Join()`, not hardcoded separators

Applied to files:

  • pkg/workflow/executor_test.go
  • tests/cli_test.go
📚 Learning: 2024-12-25T20:28:19.618Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 887
File: internal/exec/workflow_utils.go:167-169
Timestamp: 2024-12-25T20:28:19.618Z
Learning: The user plans to revert the change from `path.Join` to `filepath.Join` in this PR due to testing gaps and will open a new PR to safely handle the migration without breaking `main`.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_test.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • cmd/working_directory.go
  • cmd/working_directory_test.go
  • tests/cli_test.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Test quality: Test behavior, not implementation. Never test stub functions - implement or remove. Avoid tautological tests - don't test hardcoded stubs return hardcoded values. Make code testable - use DI to avoid `os.Exit`, `CheckErrorPrintAndExit`, external systems. No coverage theater - validate real behavior. Remove always-skipped tests - fix or delete. Table-driven tests need real scenarios. Use `assert.ErrorIs(err, ErrSentinel)` for our/stdlib errors. String matching OK for third-party errors

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • pkg/config/load_test.go
  • tests/cli_test.go
📚 Learning: 2024-11-22T12:38:33.132Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-22T12:38:33.132Z
Learning: In the Atmos project, continue to flag path traversal issues in code reviews but acknowledge when they are expected and acceptable in specific cases.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Ensure all tests pass, verify code coverage meets targets, run golangci-lint and fix any issues, and update documentation before submitting pull requests

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-04-04T02:03:23.676Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:26-26
Timestamp: 2025-04-04T02:03:23.676Z
Learning: The Atmos codebase currently uses `log.Fatal` for error handling in multiple places. The maintainers are aware this isn't an ideal pattern (should only be used in main() or init() functions) and plan to address it comprehensively in a separate PR. CodeRabbit should not flag these issues or push for immediate changes until that refactoring is complete.

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-01-17T00:18:57.769Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/workflow/executor_test.go
  • pkg/workflow/executor.go
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • pkg/workflow/executor_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Use table-driven tests for testing multiple scenarios in Go

Applied to files:

  • pkg/workflow/executor_test.go
  • cmd/working_directory_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • pkg/workflow/executor.go
  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
  • tests/cli_test.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Code reuse: Search `internal/exec/` and `pkg/` before implementing. Extend, don't duplicate

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-11-19T14:50:16.194Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_utils.go:496-513
Timestamp: 2024-11-19T14:50:16.194Z
Learning: In the Atmos project, path traversal is acceptable due to its role in automation. Do not flag path traversal as an issue in code reviews.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-12-13T04:37:18.265Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:18.265Z
Learning: In Atmos cmd/root.go Execute(), after cfg.InitCliConfig, we must call both toolchainCmd.SetAtmosConfig(&atmosConfig) and toolchain.SetAtmosConfig(&atmosConfig) so the CLI wrapper and the toolchain package receive configuration; missing either can cause nil-pointer panics in toolchain path resolution.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/workflow/executor.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/workflow/executor.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to website/blog/*.mdx : Blog posts: Use `.mdx` format with YAML front matter in `website/blog/YYYY-MM-DD-feature-name.mdx`. Include `<!--truncate-->` after intro. Use only tags defined in `website/blog/tags.yml`. Use authors from `website/blog/authors.yml`

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
📚 Learning: 2025-09-30T00:36:22.219Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 0
File: :0-0
Timestamp: 2025-09-30T00:36:22.219Z
Learning: In the Atmos website project using docusaurus-plugin-llms, the postbuild script intentionally copies llms.txt and llms-full.txt from build/ to static/ (reverse of typical Docusaurus flow). This is necessary because: (1) the plugin hardcodes output to build/ directory, (2) files must be in static/ for deployment and dev mode access, (3) the plugin doesn't support configuring output directory. The files are source-controlled in static/ and regenerated on each build.

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*_test.go : Golden snapshots: NEVER manually edit golden snapshot files - Always use `-regenerate-snapshots` flag. Snapshots capture exact output including invisible formatting (lipgloss padding, ANSI codes, trailing whitespace). Different environments produce different output. Never use pipe redirection (`2>&1`, `| head`, `| tail`) when running tests as piping breaks TTY detection

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • tests/cli_test.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
  • tests/cli_test.go
📚 Learning: 2024-10-23T22:11:41.077Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-08-15T14:43:41.030Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1352
File: pkg/store/artifactory_store_test.go:108-113
Timestamp: 2025-08-15T14:43:41.030Z
Learning: In test files for the atmos project, it's acceptable to ignore errors from os.Setenv/Unsetenv operations during test environment setup and teardown, as these are controlled test scenarios.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • pkg/config/load_test.go
📚 Learning: 2025-12-13T03:21:27.620Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:27.620Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
  • pkg/config/load_test.go
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2024-11-25T17:17:15.703Z
Learnt from: RoseSecurity
Repo: cloudposse/atmos PR: 797
File: pkg/list/atmos.yaml:213-214
Timestamp: 2024-11-25T17:17:15.703Z
Learning: The file `pkg/list/atmos.yaml` is primarily intended for testing purposes.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden
  • website/docs/cli/configuration/configuration.mdx
  • pkg/config/load_test.go
📚 Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Configuration loading: Precedence: CLI flags → ENV vars → config files → defaults (use Viper)

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T17:34:52.568Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/providers/github/oidc.go:96-100
Timestamp: 2025-09-10T17:34:52.568Z
Learning: The ATMOS_ environment variable binding guideline applies to Atmos configuration variables, not external service-required environment variables like GitHub Actions OIDC variables (GITHUB_ACTIONS, ACTIONS_ID_TOKEN_*) which must use their standard names.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Environment variables: Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T04:37:40.435Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:40.435Z
Learning: In Go CLI command files using Cobra, constrain the subcommand to accept at most one positional argument (MaximumNArgs(1)) so it supports both listing all items (zero args) and fetching a specific item (one arg). Define and parse flags with a standard parser (e.g., flags.NewStandardParser()) and avoid binding flags to Viper (no viper.BindEnv/BindPFlag). This promotes explicit argument handling and predictable flag behavior across command files.

Applied to files:

  • cmd/working_directory.go
  • cmd/working_directory_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • cmd/working_directory_test.go
  • pkg/config/load_test.go
📚 Learning: 2025-12-10T18:32:43.260Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1808
File: cmd/terraform/backend/backend_delete_test.go:9-23
Timestamp: 2025-12-10T18:32:43.260Z
Learning: In cmd subpackages, tests should avoid using NewTestKit(t) unless tests actually interact with RootCmd (e.g., execute commands via RootCmd or modify RootCmd state). For structural tests that only verify command structure/flags without touching RootCmd, TestKit cleanup is unnecessary.

Applied to files:

  • cmd/working_directory_test.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Performance tracking: Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions. Use `nil` if no atmosConfig param

Applied to files:

  • pkg/config/load_test.go
📚 Learning: 2025-11-11T03:47:45.878Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/add_test.go:67-77
Timestamp: 2025-11-11T03:47:45.878Z
Learning: In the cloudposse/atmos codebase, tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation.

Applied to files:

  • pkg/config/load_test.go
📚 Learning: 2025-11-11T03:47:59.576Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: toolchain/which_test.go:166-223
Timestamp: 2025-11-11T03:47:59.576Z
Learning: In the cloudposse/atmos repo, tests that manipulate environment variables should use testing.T.Setenv for automatic setup/teardown instead of os.Setenv/Unsetenv.

Applied to files:

  • pkg/config/load_test.go
📚 Learning: 2025-02-05T11:10:51.031Z
Learnt from: mss
Repo: cloudposse/atmos PR: 1024
File: internal/exec/go_getter_utils.go:31-33
Timestamp: 2025-02-05T11:10:51.031Z
Learning: The path traversal check in `ValidateURI` function in `internal/exec/go_getter_utils.go` is intentionally kept despite potentially blocking valid Git URLs, as this validation is planned to be addressed in a separate ticket.

Applied to files:

  • tests/cli_test.go
📚 Learning: 2025-01-08T19:02:28.099Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 899
File: examples/tests/vendor.yaml:48-48
Timestamp: 2025-01-08T19:02:28.099Z
Learning: Test cases in the Atmos project deliberately use different Git URL formats (with and without `git::` prefix) to test various scenarios. These formats should not be normalized to maintain test coverage of different URL handling cases.

Applied to files:

  • tests/cli_test.go
🧬 Code graph analysis (6)
pkg/workflow/executor_test.go (3)
pkg/workflow/interfaces.go (1)
  • AtmosExecParams (10-23)
pkg/workflow/executor.go (1)
  • NewExecutor (36-42)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/executor.go (3)
pkg/schema/workflow.go (2)
  • WorkflowDefinition (17-22)
  • WorkflowStep (7-15)
pkg/workflow/interfaces.go (1)
  • WorkflowParams (105-118)
pkg/logger/log.go (1)
  • Debug (24-26)
pkg/schema/workflow.go (2)
pkg/schema/command.go (1)
  • Command (5-17)
pkg/schema/schema.go (1)
  • RetryConfig (763-771)
cmd/working_directory.go (2)
errors/builder.go (1)
  • Build (24-37)
errors/errors.go (3)
  • ErrWorkingDirNotFound (440-440)
  • ErrWorkingDirAccessFailed (442-442)
  • ErrWorkingDirNotDirectory (441-441)
cmd/working_directory_test.go (1)
errors/errors.go (2)
  • ErrWorkingDirNotFound (440-440)
  • ErrWorkingDirNotDirectory (441-441)
pkg/config/load_test.go (1)
pkg/config/load.go (1)
  • LoadConfig (191-310)
🪛 LanguageTool
website/docs/cli/configuration/configuration.mdx

[style] ~43-~43: ‘merged together’ might be wordy. Consider a shorter alternative.
Context: ... Multiple profiles can be activated and merged together (left-to-right). See [Profiles](/cli/co...

(EN_WORDINESS_PREMIUM_MERGED_TOGETHER)

⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (22)
website/blog/2025-11-11-parent-directory-search-and-git-root-discovery.mdx (2)

1-8: Verify blog front-matter authors + tags are registered.
Please ensure aknysh exists in website/blog/authors.yml and feature/dx exist in website/blog/tags.yml (blog build will fail otherwise).


10-38: Content looks aligned with the PR’s discovery behavior.
Examples are clear; <!--truncate--> is present and placement is good.

website/docs/cli/configuration/configuration.mdx (2)

43-65: Double-check the “disable parent directory search” guidance matches runtime behavior.
“Set ATMOS_CLI_CONFIG_PATH to any value (including .) to disable parent directory searching” is plausible, but it’s easy to misread as “set to any garbage string”. Consider tightening to “set it to a specific file/dir you want Atmos to use” (whatever the actual semantics are).


249-286: Nice: explicit .atmos.d precedence + use-cases.
The “git root first (lower priority) then config dir (higher)” explanation is crisp and matches how users think about overrides.

pkg/schema/command.go (1)

5-17: Schema addition is consistent (working_directory, omitempty).
Field placement and tags look correct.

tests/test-cases/log-level-validation.yaml (1)

43-61: Diff predicate update is reasonable, but please confirm fixture policy.
Given the repo convention to avoid editing tests/test-cases/ unless explicitly intended, can you confirm this change is expected/approved for this PR (since discovery logging changed)?

tests/cli_test.go (1)

449-509: Ordering (12a/12b before external path normalization) is a good stabilization move.
This should reduce snapshot churn as new discovery logs appear.

tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden (1)

1-65: Snapshot update seems consistent with new discovery logs—please confirm it was regenerated.
Just sanity-check this came from -regenerate-snapshots (not manual edits), since log ordering/whitespace is brittle.

cmd/working_directory.go (1)

24-43: ErrorBuilder + sentinels usage looks correct.
Good: ErrWorkingDirNotFound/ErrWorkingDirAccessFailed/ErrWorkingDirNotDirectory are returned as the user-facing error with context/hints.

cmd/working_directory_test.go (1)

15-160: Solid table coverage for the main resolver behaviors.
Good mix of absolute/relative and failure-mode assertions via assert.ErrorIs.

pkg/schema/workflow.go (2)

7-14: LGTM on WorkflowStep schema.

The WorkingDirectory field follows the established pattern from Command.WorkingDirectory in pkg/schema/command.go. Tags are consistent with other fields.


17-22: LGTM on WorkflowDefinition schema.

Workflow-level WorkingDirectory enables inheritance to steps, with step-level overrides. Placement between Description and Steps is logical.

pkg/config/load_test.go (2)

1039-1078: Solid test for default config with git root .atmos.d.

Good coverage of the scenario where no atmos.yaml exists but .atmos.d at git root should still be discovered and loaded. Test isolation with TEST_GIT_ROOT env var is clean.


1080-1189: Good table-driven tests for git root priority.

The two cases cover the key scenarios:

  1. Loading .atmos.d from git root when in subdirectory
  2. Config-dir .atmos.d taking priority over git-root

The priority test with settings.test_priority is a nice way to verify merge precedence.

pkg/workflow/executor_test.go (3)

6-7: Good imports for cross-platform compatibility.

Adding path/filepath and runtime enables OS-portable path handling in tests.


937-1069: Well-structured working directory execution tests.

The OS-detection block at lines 943-954 properly handles Windows vs Unix path differences. Test coverage includes:

  • No working directory (defaults to ".")
  • Workflow-level absolute/relative paths
  • Step-level overrides

Both shell and atmos execution paths are verified. Good work addressing the cross-platform concerns.


1071-1156: Comprehensive unit tests for calculateWorkingDirectory.

Good coverage of edge cases including whitespace trimming. The use of filepath.FromSlash for relative paths ensures consistent behavior across platforms.

pkg/workflow/executor.go (5)

180-191: Clean integration of working directory into step execution.

The calculation is properly placed before command execution, and the workDir flows through runCommandParams to both shell and atmos paths.


216-223: Struct extension looks good.

Adding workingDirectory to runCommandParams keeps command execution parameters cohesive.


226-246: Sensible default to current directory.

The fallback to "." when workingDirectory is empty ensures predictable behavior. Both shell and atmos paths now receive the working directory.


331-358: Good propagation to Atmos execution.

The workDir parameter is correctly passed through and set on AtmosExecParams.Dir.


381-410: Well-implemented working directory calculation.

Key aspects handled correctly:

  • Step-level override takes precedence over workflow-level
  • Relative paths resolved against basePath
  • Empty basePath guard at lines 399-401 prevents accidentally relative paths
  • Validation deferred to adapters (noted in comment) is reasonable since YAML functions like !repo-root resolve during config loading

The debug log at line 407 will help with troubleshooting path issues.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 13, 2025
@aknysh
Copy link
Member

aknysh commented Dec 14, 2025

@coderabbitai full review please

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

@aknysh: I'll conduct a full review of all the changes in this PR.


🧠 Learnings used
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:19.505Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:34.794Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/cli_test.go (1)

449-470: Custom replacements are no longer “last” (doc/contract mismatch).
Since 12a/12b/12c now run after the “Apply custom replacements” loop, either move custom replacements to the end of sanitizeOutput (after step 17), or update the docstring for WithCustomReplacements to reflect the new ordering.

🧹 Nitpick comments (4)
cmd/cmd_utils.go (1)

476-484: Make invalid working_directory errors more user-guiding at the call site.
Right now failures exit with an empty title/link (CheckErrorPrintAndExit(err, "", "")), even though this is a user-facing config error.

 	workDir, err := resolveWorkingDirectory(commandConfig.WorkingDirectory, atmosConfig.BasePath, currentDirPath)
 	if err != nil {
-		errUtils.CheckErrorPrintAndExit(err, "", "")
+		errUtils.CheckErrorPrintAndExit(err, "Invalid working_directory", "https://atmos.tools/cli/configuration/commands#working-directory")
 	}
cmd/working_directory.go (1)

10-46: Preserve the underlying os.Stat error as the cause for the “not found” branch too.
Helps debugging while still returning the sentinel for errors.Is.

 	info, err := os.Stat(resolvedDir)
 	if os.IsNotExist(err) {
 		return "", errUtils.Build(errUtils.ErrWorkingDirNotFound).
+			WithCause(err).
 			WithContext("path", resolvedDir).
 			WithHint("Check that the working_directory path exists").
 			Err()
 	}
pkg/config/load.go (1)

860-874: Minor: consider case-insensitive equality when comparing absGitRoot vs absDirPath on Windows. Prevents double-loading when only path casing differs.

website/docs/cli/configuration/configuration.mdx (1)

30-43: Docs update is clear and matches the new mental model (profiles + parent search + repo-wide .atmos.d).

Minor wording nit: “merged together” → “merged” (same meaning, tighter).

Documentation (website/docs/cli/configuration/configuration.mdx):
- Clarify that .atmos.d/ is for auto-imports, not config file discovery
- Fix wording: "merged together" → "merged left-to-right"

Code improvements (cmd/working_directory.go):
- Add filepath.Clean() for absolute paths to normalize paths like /tmp/foo/..
- Preserve underlying os.Stat error as cause for ErrWorkingDirNotFound

Test coverage (cmd/working_directory_test.go):
- Add TestResolveWorkingDirectory_AccessFailed for permission denied scenarios
- Skip on Windows and when running as root (where perms differ)

Error handling (cmd/cmd_utils.go):
- Improve error message for invalid working_directory with title and docs link

Cross-platform (pkg/config/load.go):
- Use case-insensitive path comparison on Windows to prevent double-loading
  when only path casing differs
- Extract loadAtmosDFromGitRoot() helper to reduce nesting complexity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
website/docs/cli/configuration/configuration.mdx (2)

34-43: Clear precedence documentation with minor clarity suggestion.

The precedence list is well-structured and comprehensive. One suggestion: Line 41's explanation combines several concepts (deep-merge, git root discovery, shared fragments) in a single sentence, which may require careful reading. Consider splitting this into separate sentences for improved clarity:

-Each configuration file discovered is deep-merged with the preceding configurations. Separately, Atmos may also auto-import configuration fragments from `.atmos.d/`. The git repository root is special: even when `atmos.yaml` is found elsewhere, Atmos always checks for `.atmos.d/` at the repo root to load shared fragments like custom commands.
+Each configuration file discovered is deep-merged with the preceding configurations. 
+
+Atmos may also auto-import configuration fragments from `.atmos.d/` directories. The git repository root is special: even when `atmos.yaml` is found elsewhere, Atmos always checks for `.atmos.d/` at the repo root to load shared fragments like custom commands.

This maintains accuracy while improving readability.


93-101: Clarify profile discovery location precedence.

The profile discovery locations are listed (lines 93-98) but the precedence order isn't explicitly stated. When multiple profile directories exist, which takes precedence? Consider adding a brief note:

 Profiles are discovered from multiple locations:
-1. Custom path configured in `profiles.base_path`
-2. `.atmos/profiles/` (project-local)
-3. `~/.config/atmos/profiles/` (XDG user profiles)
-4. `~/.atmos/profiles/` (legacy home profiles)
+1. Custom path configured in `profiles.base_path` (highest priority)
+2. `.atmos/profiles/` (project-local)
+3. `~/.config/atmos/profiles/` (XDG user profiles)
+4. `~/.atmos/profiles/` (legacy home profiles, lowest priority)

The "merged left-to-right" note on line 99 explains profile merging but not discovery precedence.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 94e54c4 and fcc87ac.

📒 Files selected for processing (5)
  • cmd/cmd_utils.go (3 hunks)
  • cmd/working_directory.go (1 hunks)
  • cmd/working_directory_test.go (1 hunks)
  • pkg/config/load.go (9 hunks)
  • website/docs/cli/configuration/configuration.mdx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/working_directory_test.go
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: Comment style: All comments must end with periods (enforced by godot linter)
Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: cfg, log, u, errUtils
Performance tracking: Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig param
Error handling: ALL user-facing errors MUST use ErrorBuilder with sentinel errors from errors/errors.go. ALWAYS use errors.Is() for checking, NEVER string comparison. ALWAYS use assert.ErrorIs() in tests, NEVER assert.Contains(err.Error(), ...)
Mock generation: Use go.uber.org/mock/mockgen with //go:generate directives. Never manual mocks
File organization: Keep files small and focused (<600 lines). One cmd/impl per file. Co-locate tests. Never use `//revive:disable:file-lengt...

Files:

  • pkg/config/load.go
  • cmd/working_directory.go
  • cmd/cmd_utils.go
cmd/**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

cmd/**/*.go: Use Cobra's recommended command structure with a root command and subcommands, implementing each command in a separate file under cmd/ directory
Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands

Files:

  • cmd/working_directory.go
  • cmd/cmd_utils.go
website/**

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

website/**: Update website documentation in the website/ directory when adding new features, ensure consistency between CLI help text and website documentation, and follow the website's documentation structure and style
Keep website code in the website/ directory, follow the existing website architecture and style, and test website changes locally before committing
Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases

Files:

  • website/docs/cli/configuration/configuration.mdx
🧠 Learnings (57)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:19.505Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:34.794Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Import organization: Three groups separated by blank lines (stdlib, 3rd-party, Atmos packages), sorted alphabetically within groups, maintain aliases: `cfg`, `log`, `u`, `errUtils`

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Performance tracking: Add `defer perf.Track(atmosConfig, "pkg.FuncName")()` + blank line to all public functions. Use `nil` if no atmosConfig param

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T03:21:27.620Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1813
File: cmd/terraform/shell.go:28-73
Timestamp: 2025-12-13T03:21:27.620Z
Learning: In Atmos, when calling cfg.InitCliConfig, you must first populate the schema.ConfigAndStacksInfo struct with global flag values using flags.ParseGlobalFlags(cmd, v) rather than passing an empty struct. The LoadConfig function (pkg/config/load.go) reads config selection fields (AtmosConfigFilesFromArg, AtmosConfigDirsFromArg, BasePath, ProfilesFromArg) directly from the ConfigAndStacksInfo struct, NOT from Viper. Passing an empty struct causes config selection flags (--base-path, --config, --config-path, --profile) to be silently ignored. Correct pattern: parse flags → populate struct → call InitCliConfig. See cmd/terraform/plan_diff.go for reference implementation.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-07-05T20:59:02.914Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1363
File: internal/exec/template_utils.go:18-18
Timestamp: 2025-07-05T20:59:02.914Z
Learning: In the Atmos project, gomplate v4 is imported with a blank import (`_ "github.com/hairyhenderson/gomplate/v4"`) alongside v3 imports to resolve AWS SDK version conflicts. V3 uses older AWS SDK versions that conflict with newer AWS modules used by Atmos. A full migration to v4 requires extensive refactoring due to API changes and should be handled in a separate PR.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-12-11T18:40:12.808Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 844
File: cmd/helmfile.go:37-37
Timestamp: 2024-12-11T18:40:12.808Z
Learning: In the atmos project, `cliConfig` is initialized within the `cmd` package in `root.go` and can be used in other command files.

Applied to files:

  • pkg/config/load.go
  • cmd/cmd_utils.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Configuration loading: Precedence: CLI flags → ENV vars → config files → defaults (use Viper)

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-10-20T13:12:46.499Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 736
File: pkg/config/const.go:6-6
Timestamp: 2024-10-20T13:12:46.499Z
Learning: In `cmd/cmd_utils.go`, it's acceptable to have hardcoded references to `atmos.yaml` in logs, and it's not necessary to update them to use the `CliConfigFileName` constant.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T04:37:18.265Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/root.go:0-0
Timestamp: 2025-12-13T04:37:18.265Z
Learning: In Atmos cmd/root.go Execute(), after cfg.InitCliConfig, we must call both toolchainCmd.SetAtmosConfig(&atmosConfig) and toolchain.SetAtmosConfig(&atmosConfig) so the CLI wrapper and the toolchain package receive configuration; missing either can cause nil-pointer panics in toolchain path resolution.

Applied to files:

  • pkg/config/load.go
  • cmd/cmd_utils.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Comment style: All comments must end with periods (enforced by `godot` linter)

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Comment preservation: NEVER delete existing comments without very strong reason. Preserve helpful comments, update to match code, refactor for clarity, add context when modifying. Only remove if factually incorrect, code removed, duplicates obvious code, or outdated TODO completed

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Document complex logic with inline comments in Go code

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-10-10T23:51:36.597Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:394-402
Timestamp: 2025-10-10T23:51:36.597Z
Learning: In Atmos (internal/exec/terraform.go), when adding OpenTofu-specific flags like `--var-file` for `init`, do not gate them based on command name (e.g., checking if `info.Command == "tofu"` or `info.Command == "opentofu"`) because command names don't reliably indicate the actual binary being executed (symlinks, aliases). Instead, document the OpenTofu requirement in code comments and documentation, trusting users who enable the feature (e.g., `PassVars`) to ensure their terraform command points to an OpenTofu binary.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Lint exclusions: ALWAYS ask for user approval before adding nolint comments - do not add them automatically. Prefer refactoring over nolint - only use nolint as last resort with explicit user permission. Exception for bubbletea models: `//nolint:gocritic // bubbletea models must be passed by value`. Exception for intentional subprocess calls: `//nolint:gosec // intentional subprocess call`. NEVER add nolint for gocognit, cyclomatic complexity, magic numbers, or nestif - refactor instead. If you think nolint is needed, stop and ask the user first

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T06:07:34.794Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:34.794Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow standard Go coding style: use `gofmt` and `goimports` to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-01-17T00:18:57.769Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-04-04T02:03:23.676Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1185
File: internal/exec/yaml_func_store.go:26-26
Timestamp: 2025-04-04T02:03:23.676Z
Learning: The Atmos codebase currently uses `log.Fatal` for error handling in multiple places. The maintainers are aware this isn't an ideal pattern (should only be used in main() or init() functions) and plan to address it comprehensively in a separate PR. CodeRabbit should not flag these issues or push for immediate changes until that refactoring is complete.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-12-13T06:10:06.715Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:06.715Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-01-25T03:51:57.689Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-13T18:06:07.674Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/list.go:39-42
Timestamp: 2025-09-13T18:06:07.674Z
Learning: In the cloudposse/atmos repository, for UI messages in the toolchain package, use utils.PrintfMessageToTUI instead of log.Error or fmt.Fprintln(os.Stderr, ...). Import pkg/utils with alias "u" to follow the established pattern.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2024-10-28T01:51:30.811Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:329-332
Timestamp: 2024-10-28T01:51:30.811Z
Learning: In the Atmos Go code, when deleting directories or handling file paths (e.g., in `terraform_clean.go`), always resolve the absolute path using `filepath.Abs` and use the logger `u.LogWarning` for logging messages instead of using `fmt.Printf`.

Applied to files:

  • pkg/config/load.go
  • cmd/working_directory.go
  • cmd/cmd_utils.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Applies to **/*.go : Environment variables: Use `viper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")` - ATMOS_ prefix required

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-06T13:38:07.216Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 984
File: internal/exec/copy_glob.go:0-0
Timestamp: 2025-02-06T13:38:07.216Z
Learning: The `u.LogTrace` function in the `cloudposse/atmos` repository accepts `atmosConfig` as its first parameter, followed by the message string.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-05-30T03:21:37.197Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1274
File: go.mod:63-63
Timestamp: 2025-05-30T03:21:37.197Z
Learning: The redis dependency (github.com/redis/go-redis/v9) in the atmos project is only used in tests, not in production code.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-11-08T19:56:18.660Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1697
File: internal/exec/oci_utils.go:0-0
Timestamp: 2025-11-08T19:56:18.660Z
Learning: In the Atmos codebase, when a function receives an `*schema.AtmosConfiguration` parameter, it should read configuration values from `atmosConfig.Settings` fields rather than using direct `os.Getenv()` or `viper.GetString()` calls. The Atmos pattern is: viper.BindEnv in cmd/root.go binds environment variables → Viper unmarshals into atmosConfig.Settings via mapstructure → business logic reads from the Settings struct. This provides centralized config management, respects precedence, and enables testability. Example: `atmosConfig.Settings.AtmosGithubToken` instead of `os.Getenv("ATMOS_GITHUB_TOKEN")` in functions like `getGHCRAuth` in internal/exec/oci_utils.go.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-08-29T20:57:35.423Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1433
File: cmd/theme_list.go:33-36
Timestamp: 2025-08-29T20:57:35.423Z
Learning: In the Atmos codebase, avoid using viper.SetEnvPrefix("ATMOS") with viper.AutomaticEnv() because canonical environment variable names are not exclusive to Atmos and could cause conflicts. Instead, use selective environment variable binding through the setEnv function in pkg/config/load.go with bindEnv(v, "config.key", "ENV_VAR_NAME") for specific environment variables.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-04-23T15:02:50.246Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1202
File: pkg/utils/yaml_func_exec.go:104-104
Timestamp: 2025-04-23T15:02:50.246Z
Learning: In the Atmos codebase, direct calls to `os.Getenv` should be avoided. Instead, use `viper.BindEnv` for environment variable access. This provides a consistent approach to configuration management across the codebase.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-08-16T23:32:40.412Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:455-456
Timestamp: 2025-08-16T23:32:40.412Z
Learning: In the cloudposse/atmos Go codebase, `InitCliConfig` returns a `schema.AtmosConfiguration` value (not a pointer), while `ExecuteDescribeDependents` expects a `*schema.AtmosConfiguration` pointer parameter. Therefore, when passing the result of `InitCliConfig` to `ExecuteDescribeDependents`, use `&atmosConfig` to pass the address of the value.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-01-25T15:21:40.413Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:8-8
Timestamp: 2025-01-25T15:21:40.413Z
Learning: In Atmos, when a directory is specified for configuration loading (e.g., in the `import` section of atmos.yaml), all files within that directory should be treated as Atmos configurations. Do not suggest restricting file extensions in directory-based glob patterns.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-02-03T05:57:18.407Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/cmd_utils.go:121-148
Timestamp: 2025-02-03T05:57:18.407Z
Learning: The Atmos CLI should fail fast (exit) when encountering configuration errors, including command alias configuration issues, to prevent undefined behavior. Use LogErrorAndExit instead of returning errors in such cases.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-04-03T10:57:04.602Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1091
File: pkg/config/load_config_args.go:61-82
Timestamp: 2025-04-03T10:57:04.602Z
Learning: In the Atmos configuration system, errors in `mergeDefaultImports` and `mergeImports` functions are intentionally only logged as debug messages without returning errors, as they are considered non-critical. Only errors in critical functions like `mergeConfigFile` are returned to halt execution.

Applied to files:

  • pkg/config/load.go
📚 Learning: 2025-02-24T22:46:39.744Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/load.go:219-221
Timestamp: 2025-02-24T22:46:39.744Z
Learning: In the Atmos configuration system, imports from atmos.d are optional. When import errors occur, they should be logged at debug level and the process should continue, rather than failing completely.

Applied to files:

  • pkg/config/load.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: The atmos codebase has a custom extension to *testing.T that provides a Chdir method, allowing test functions to call t.Chdir() to change working directories during tests. This is used consistently across test files in the codebase.

Applied to files:

  • cmd/working_directory.go
  • cmd/cmd_utils.go
📚 Learning: 2025-12-13T04:37:40.435Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: cmd/toolchain/get.go:23-40
Timestamp: 2025-12-13T04:37:40.435Z
Learning: In Go CLI command files using Cobra, constrain the subcommand to accept at most one positional argument (MaximumNArgs(1)) so it supports both listing all items (zero args) and fetching a specific item (one arg). Define and parse flags with a standard parser (e.g., flags.NewStandardParser()) and avoid binding flags to Viper (no viper.BindEnv/BindPFlag). This promotes explicit argument handling and predictable flag behavior across command files.

Applied to files:

  • cmd/working_directory.go
  • cmd/cmd_utils.go
📚 Learning: 2025-12-13T06:10:19.505Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: internal/exec/workflow_utils.go:0-0
Timestamp: 2025-12-13T06:10:19.505Z
Learning: Atmos workflows: In internal/exec/workflow_utils.go ExecuteWorkflow, non-identity steps intentionally use baseWorkflowEnv, which is constructed from the parent environment with PATH modifications for the toolchain. Avoid appending os.Environ() again; prefer documenting this behavior and testing that standard environment variables are preserved.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain has been updated to follow XDG Base Directory Specification with helper functions GetXDGCacheDir() and GetXDGTempCacheDir() in toolchain/xdg_cache.go, using XDG_CACHE_HOME when set and falling back to ~/.cache/atmos-toolchain, making it consistent with atmos core's XDG compliance.

Applied to files:

  • cmd/cmd_utils.go
  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: Final XDG Base Directory Specification implementation for atmos toolchain is complete and verified: toolchain/xdg_cache.go provides GetXDGCacheDir() and GetXDGTempCacheDir() functions, all hardcoded ~/.cache/tools-cache paths have been replaced with XDG-compliant paths using ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback), and tests have been updated to expect the new path structure.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method that can be called on *testing.T objects. This functionality is implemented through custom testing framework extensions and is used consistently throughout the test suite for changing working directories during tests.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests. This is implemented through custom testing framework extensions and is used consistently throughout the test suite.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-05-23T19:51:47.091Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1255
File: cmd/describe_affected_test.go:15-15
Timestamp: 2025-05-23T19:51:47.091Z
Learning: In the atmos codebase, t.Chdir() is a valid method call on *testing.T objects and works correctly for changing directories in tests.

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-12-13T00:52:18.278Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-13T00:52:18.278Z
Learning: Adding new CLI command: 1) Create `cmd/[command]/` with CommandProvider interface, 2) Add blank import to `cmd/root.go`: `_ "github.com/cloudposse/atmos/cmd/mycommand"`, 3) Implement in `internal/exec/mycommand.go`, 4) Add tests in `cmd/mycommand/mycommand_test.go`, 5) Create Docusaurus docs in `website/docs/cli/commands/<command>/<subcommand>.mdx`, 6) Build website: `cd website && npm run build`. See `docs/developing-atmos-commands.md` and `docs/prd/command-registry-pattern.md`

Applied to files:

  • cmd/cmd_utils.go
📚 Learning: 2025-02-09T18:43:53.902Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 808
File: pkg/config/loader.go:141-145
Timestamp: 2025-02-09T18:43:53.902Z
Learning: In the Atmos configuration loading process, errors during individual config file loading/merging should be logged but not propagate up to break the entire process. This design choice enables resilient partial configuration loading.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-03-17T18:41:08.831Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 1085
File: pkg/config/imports.go:68-75
Timestamp: 2025-03-17T18:41:08.831Z
Learning: In the Atmos configuration import system, errors during config file merging are logged at debug level and the process continues with other imports rather than failing completely, prioritizing resilience over strict correctness.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-10T17:34:52.568Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/providers/github/oidc.go:96-100
Timestamp: 2025-09-10T17:34:52.568Z
Learning: The ATMOS_ environment variable binding guideline applies to Atmos configuration variables, not external service-required environment variables like GitHub Actions OIDC variables (GITHUB_ACTIONS, ACTIONS_ID_TOKEN_*) which must use their standard names.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-10-23T22:11:41.077Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 727
File: internal/exec/path_utils.go:145-146
Timestamp: 2024-10-23T22:11:41.077Z
Learning: In the `atmos` project, the preference is to print relative paths in log messages instead of full paths.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2025-09-08T01:25:44.958Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain should follow XDG Base Directory Specification like the rest of atmos core, using XDG_CACHE_HOME environment variable when available and falling back to ~/.cache when not set, instead of hardcoding ~/.cache/tools-cache paths.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
📚 Learning: 2024-12-12T15:15:46.457Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: examples/demo-atmos-cli-imports/atmos.yaml:7-7
Timestamp: 2024-12-12T15:15:46.457Z
Learning: In example configuration files, such as `examples/demo-atmos-cli-imports/atmos.yaml`, it's acceptable to use `refs/heads/main` in remote URLs.

Applied to files:

  • website/docs/cli/configuration/configuration.mdx
🧬 Code graph analysis (2)
cmd/working_directory.go (2)
errors/builder.go (1)
  • Build (24-37)
errors/errors.go (3)
  • ErrWorkingDirNotFound (440-440)
  • ErrWorkingDirAccessFailed (442-442)
  • ErrWorkingDirNotDirectory (441-441)
cmd/cmd_utils.go (4)
errors/error_funcs.go (1)
  • CheckErrorPrintAndExit (216-258)
pkg/logger/log.go (1)
  • Debug (24-26)
pkg/utils/shell_utils.go (1)
  • ExecuteShellAndReturnOutput (33-62)
internal/exec/shell_utils.go (1)
  • ExecuteShell (109-142)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (12)
website/docs/cli/configuration/configuration.mdx (3)

45-64: LGTM! Clear parent directory search documentation.

The parent directory search section is well-documented with a practical example. The explanation of how to disable the feature (setting ATMOS_CLI_CONFIG_PATH) is clear and actionable.


249-277: LGTM! Clear .atmos.d discovery documentation.

The .atmos.d discovery section effectively explains the two-tier discovery mechanism:

  1. Git repository root (lower priority)
  2. Configuration directory (higher priority)

The example showing running from repo/components/terraform/vpc/ with discovery from repo/.atmos.d/commands.yaml demonstrates the practical benefit. The precedence order in line 259-260 aligns with the code implementation in pkg/config/load.go.


279-286: LGTM! Helpful guidance on .atmos.d usage vs profiles.

The use cases and tip clearly distinguish when to use .atmos.d/ (local developer settings, dynamically generated config) versus profiles (environment-specific overrides). This helps users make the right architectural choices.

cmd/cmd_utils.go (2)

476-483: LGTM! Clean working directory resolution integration.

The working directory resolution is implemented correctly:

  • Resolves relative paths against atmosConfig.BasePath (as documented)
  • Provides clear error messages with documentation link
  • Logs usage only when WorkingDirectory is specified (avoids noise)
  • Falls back to currentDirPath when empty

This follows the documented behavior and integrates well with the existing command execution flow.


566-607: LGTM! Consistent working directory usage across execution paths.

The resolved workDir is correctly used in both execution contexts:

  • Line 566: ENV var value commands execute with workDir
  • Line 607: Command steps execute with workDir

This ensures that both environment variable resolution commands and step commands honor the working_directory configuration. The integration with u.ExecuteShellAndReturnOutput and e.ExecuteShell is correct based on their signatures in the relevant code snippets.

cmd/working_directory.go (1)

13-48: LGTM! Robust working directory resolution with proper validation.

The resolveWorkingDirectory function is well-implemented:

Path resolution (lines 18-23):

  • Correctly uses filepath.Clean to normalize paths
  • Handles absolute vs relative paths appropriately
  • Relative paths are resolved against basePath as documented

Validation (lines 25-45):

  • Validates directory exists using os.Stat
  • Checks that path is actually a directory (not a file)
  • Uses os.Stat (not os.Lstat), so symlinks to directories work correctly

Error handling:

  • Uses proper sentinel errors from errors/errors.go
  • Provides helpful context (path) and hints in all error cases
  • Clear distinction between not found, access failed, and not a directory

Edge cases handled correctly:

  • Empty string → returns defaultDir
  • Relative paths like ".", "..", "./subdir" → resolved via filepath.Join
  • Absolute paths → used directly after cleaning
  • Symlinks → followed to target (expected behavior)
pkg/config/load.go (6)

22-22: LGTM! Standard import addition.

The import of pkg/utils with alias u follows the codebase's established conventions. This is needed for the u.ProcessTagGitRoot calls in the git root discovery logic.


223-233: LGTM! Git root discovery integration with proper non-fatal handling.

The git root discovery for default config case is well-implemented:

Logic (lines 226-228):

  • Uses u.ProcessTagGitRoot("!repo-root .") to discover git root
  • Validates result is non-empty and not "." (current directory)
  • Proceeds only when valid git root is found

Loading (lines 229-232):

  • Calls mergeDefaultImports(gitRoot, v) to load .atmos.d/ from git root
  • Errors are logged at Trace level but non-fatal
  • This matches the documented "optional" behavior for .atmos.d loading

This enables the key feature: custom commands in .atmos.d/ at repo root work from any subdirectory, even when using default config.


428-557: LGTM! Helpful trace logging for config discovery.

The trace logging additions (lines 428, 452, 479, 540, 557) provide visibility into the configuration discovery process. The consistent message format "Checking for atmos.yaml in " makes it easy to track which paths are being searched. Using log.Trace is appropriate for this level of detail.


844-869: LGTM! Correct precedence for two-tier .atmos.d loading.

The updated mergeDefaultImports implements the documented two-tier loading:

Precedence (lines 860-866):

  1. loadAtmosDFromGitRoot - loads from git root first (lower priority)
  2. loadAtmosDFromDirectory - loads from config dir second (higher priority)

Since Viper merges later values over earlier ones, the config directory's .atmos.d/ correctly overrides the git root's .atmos.d/ on duplicates.

Non-fatal behavior (line 868):
The function returns nil unconditionally, treating all .atmos.d/ loading as optional. This matches the documented behavior and preserves existing semantics (based on learnings that .atmos.d loading should be non-fatal).

The updated comments clearly explain the new behavior and precedence.


873-902: LGTM! Robust git root .atmos.d discovery with proper deduplication.

The loadAtmosDFromGitRoot helper is well-implemented:

Git root discovery (lines 874-877):

  • Uses u.ProcessTagGitRoot to get repository root
  • Returns early if not found or invalid (empty, ".")

Deduplication (lines 879-893):

  • Converts paths to absolute for reliable comparison
  • Handles Windows case-insensitive paths correctly (lines 888-890)
  • Skips loading when git root equals config directory (avoids duplicate loading)

Test isolation (lines 895-898):

  • Respects TEST_EXCLUDE_ATMOS_D for test isolation
  • Returns silently to avoid test output pollution

Loading (lines 900-901):

  • Traces the git root path being checked
  • Delegates to loadAtmosDFromDirectory for actual loading

The function has no return value because .atmos.d loading is optional/non-fatal, which aligns with the documented behavior.


904-922: LGTM! Consistent loading for both atmos.d and .atmos.d.

The loadAtmosDFromDirectory helper correctly loads from both supported directory names:

Dual directory support (lines 907-921):

  • Searches both atmos.d/ and .atmos.d/ subdirectories
  • Uses filepath.Join and filepath.FromSlash for cross-platform paths
  • Creates proper glob patterns (**/*) for recursive search

Error handling:

  • Errors logged at Trace level (lines 910, 918) with path context
  • Non-fatal: loading continues even if one or both directories fail
  • This matches documented "optional" semantics for .atmos.d

Comments:

  • Clear explanation that both directory searches are optional
  • Notes preservation of existing behavior (lines 911-912, 919-920)

This helper is called from both mergeDefaultImports (for config dir) and loadAtmosDFromGitRoot (for git root), ensuring consistent loading behavior.

@aknysh aknysh merged commit 638d1b8 into main Dec 14, 2025
57 checks passed
@aknysh aknysh deleted the feature/dev-3007-add-optional-working_directory-to-workflow-steps branch December 14, 2025 02:43
@github-actions
Copy link

These changes were released in v1.202.0-rc.2.

@github-actions
Copy link

These changes were released in v1.203.0-test.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants