feat: Make workflow --file flag optional with auto-discovery#1800
feat: Make workflow --file flag optional with auto-discovery#1800
Conversation
📝 WalkthroughWalkthroughThis refactors the workflow command architecture by migrating from a monolithic implementation to a provider-based pattern under Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as CLI Handler
participant Discovery as Workflow Discovery
participant Config as Atmos Config
participant Selection as Interactive Selector
User->>CLI: atmos workflow my-workflow
CLI->>CLI: --file not provided?
alt Auto-Discovery Enabled
CLI->>Discovery: findWorkflowAcrossFiles("my-workflow")
Discovery->>Config: Load AtmosConfiguration
Discovery->>Discovery: Scan workflow base path
Discovery->>Discovery: Match workflows by name
Discovery-->>CLI: WorkflowMatch[] (results)
alt Single Match Found
CLI->>CLI: Auto-select matched file
CLI->>CLI: Execute workflow
else Multiple Matches Found
alt TTY Interactive
CLI->>Selection: promptForWorkflowFile(matches)
Selection->>User: Present selection menu
User->>Selection: Select workflow file
Selection-->>CLI: Selected file path
CLI->>CLI: Execute workflow
else CI/Non-TTY
CLI->>CLI: Error: Multiple matches
CLI->>User: List matching files
end
else No Matches
CLI->>CLI: Error: No workflows found
CLI->>User: List available workflows
end
else --file Provided
CLI->>CLI: Use explicit file
CLI->>CLI: Execute workflow
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (3)website/**📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
Files:
website/**/*.mdx📄 CodeRabbit inference engine (CLAUDE.md)
Files:
website/blog/**/*.mdx📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (5)📓 Common learnings📚 Learning: 2025-12-10T23:12:15.768ZApplied to files:
📚 Learning: 2025-06-02T14:12:02.710ZApplied to files:
📚 Learning: 2025-12-10T23:12:15.768ZApplied to files:
📚 Learning: 2025-12-10T23:12:15.768ZApplied to files:
🪛 LanguageToolwebsite/blog/2025-11-18-workflow-file-auto-discovery.mdx[grammar] ~56-~56: Please add a punctuation mark at the end of paragraph. (PUNCTUATION_PARAGRAPH_END) [typographical] ~170-~170: To join two clauses or introduce examples, consider using an em dash. (DASH_RULE) [grammar] ~170-~170: Please add a punctuation mark at the end of paragraph. (PUNCTUATION_PARAGRAPH_END) ⏰ 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)
🔇 Additional comments (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
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. |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
|
Warning Changelog Entry RequiredThis PR is labeled Action needed: Add a new blog post in Example filename: Alternatively: If this change doesn't require a changelog entry, remove the |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1800 +/- ##
==========================================
+ Coverage 73.09% 73.27% +0.17%
==========================================
Files 550 551 +1
Lines 53208 53458 +250
==========================================
+ Hits 38893 39170 +277
+ Misses 11457 11443 -14
+ Partials 2858 2845 -13
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (9)
website/blog/2025-11-18-workflow-file-auto-discovery.md (1)
72-110: Consider calling out non-interactive (CI) behavior when duplicates exist.You explain that duplicate workflow names trigger an interactive selector, but in non-TTY contexts (e.g., CI) selection will fail and require
--file. Adding a short note under “How It Works” or “Backward Compatibility” that non-interactive runs error on duplicates and must pass--filewould make the behavior clearer for CI users.cmd/workflow/utils.go (2)
54-56: Fix godot-style comment punctuation.The first line of the multi-line comment above
identityFlagCompletiondoes not end with a period, which will trip the godot linter.You can tweak it to something like:
-// identityFlagCompletion provides shell completion for identity flags by fetching -// available identities from the Atmos configuration. +// identityFlagCompletion provides shell completion for identity flags by fetching. +// Available identities from the Atmos configuration.or otherwise ensure each
//line ends with a period.
28-35: Optional: consider prefix-filtering completion results usingtoComplete.All three completion functions currently return the full set of candidates, ignoring the
toCompleteprefix. That’s safe, but lightly filtering on the client side can reduce noise for users with many stacks/identities/workflows and shouldn’t affect correctness.For example:
-import ( - "sort" +import ( + "sort" + "strings" @@ func stackFlagCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ - return output, cobra.ShellCompDirectiveNoFileComp + if toComplete == "" { + return output, cobra.ShellCompDirectiveNoFileComp + } + + var filtered []string + for _, s := range output { + if strings.HasPrefix(s, toComplete) { + filtered = append(filtered, s) + } + } + return filtered, cobra.ShellCompDirectiveNoFileComp @@ func identityFlagCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ - return identities, cobra.ShellCompDirectiveNoFileComp + if toComplete == "" { + return identities, cobra.ShellCompDirectiveNoFileComp + } + + var filtered []string + for _, id := range identities { + if strings.HasPrefix(id, toComplete) { + filtered = append(filtered, id) + } + } + return filtered, cobra.ShellCompDirectiveNoFileComp @@ func workflowNameCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ - return completions, cobra.ShellCompDirectiveNoFileComp + if toComplete == "" { + return completions, cobra.ShellCompDirectiveNoFileComp + } + + var filtered []string + for _, c := range completions { + // Match on the value before the tab (workflow name). + if name, _, ok := strings.Cut(c, "\t"); ok { + if strings.HasPrefix(name, toComplete) { + filtered = append(filtered, c) + } + } + } + return filtered, cobra.ShellCompDirectiveNoFileCompFeel free to adjust matching semantics (case sensitivity, etc.) to align with other completions in the repo.
Also applies to: 56-72, 85-120
internal/exec/workflow_test.go (1)
384-417: Optional: factor out repeatedstacksPath/env wiring in these subtests.Several subtests repeat the same
stacksPath+t.Setenvboilerplate before callingcreateWorkflowCmdandExecuteWorkflowCmd. If this file grows further, consider a small helper (e.g.,setupWorkflowTestEnv(t *testing.T) *cobra.Command) to centralize that setup and reduce duplication, but it’s not urgent.cmd/workflow/utils_test.go (2)
45-54: Consider adding explicit assertions or documenting intent.Lines 50-53 discard both
errandresults. If the intent is just "doesn't panic," add a brief comment. If fixtures should return valid stacks, assert on the results.- // May error if the fixtures don't have valid stacks configured. - // The important thing is that the function runs without panicking. - _ = err - _ = results + // Validates function executes without panicking. + // Fixtures may not have valid stacks configured; error handling is acceptable. + assert.True(t, err == nil || err != nil, "function should complete without panic")
276-284: Conditional assertion may mask test failures.If
resultsis empty, the assertions inside theifblock are skipped, and the test passes. Consider asserting unconditionally:assert.Equal(t, cobra.ShellCompDirectiveNoFileComp, directive) - if len(results) > 0 { - assert.Len(t, results, 2) - // Should have both entries with different file contexts. - assert.Contains(t, results, "deploy\tfile1.yaml") - assert.Contains(t, results, "deploy\tfile2.yaml") - } + require.Len(t, results, 2, "expected both workflow files to be discovered") + assert.Contains(t, results, "deploy\tfile1.yaml") + assert.Contains(t, results, "deploy\tfile2.yaml")cmd/workflow/workflow.go (2)
129-133: Unusedoptsparameter.
WorkflowOptionsis parsed from flags on lines 58-65 but passed as_(unused) toexecuteWorkflowWithOptions. Either integrate the options or simplify by removing the parsing step.-func executeWorkflowWithOptions(cmd *cobra.Command, args []string, _ *WorkflowOptions) error { +func executeWorkflowWithOptions(cmd *cobra.Command, args []string, opts *WorkflowOptions) error { + // TODO: Use opts directly instead of re-parsing flags in ExecuteWorkflowCmd return e.ExecuteWorkflowCmd(cmd, args) }
135-141: Redundant help handling.Cobra handles
--helpand-hautomatically. This function would also match a workflow literally namedhelp. Consider removing unless there's a specific use case.-// handleHelpRequest handles the help request for the workflow command. -func handleHelpRequest(cmd *cobra.Command, args []string) { - // Check if help is requested. - if len(args) > 0 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h") { - _ = cmd.Help() - } -}internal/exec/workflow_utils.go (1)
459-462: TTY check is redundant but defensive.The caller in
workflow.goalready checks TTY/CI status before calling this function. The duplicate check here is harmless but adds unnecessary code. Consider documenting the precondition or removing the check.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 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.
📒 Files selected for processing (2)
internal/exec/workflow_utils.go(10 hunks)tests/test-cases/workflows.yaml(9 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
tests/test-cases/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER modify tests/test-cases/ or tests/testdata/ unless explicitly instructed. Golden snapshots are sensitive to minor changes.
Files:
tests/test-cases/workflows.yaml
**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.go: Use functional options pattern to avoid functions with many parameters. Define Option functions that modify a Config struct and pass variadic options to New functions.
Use context.Context for cancellation signals, deadlines/timeouts, and request-scoped values (trace IDs). Context should be first parameter in functions that accept it. DO NOT use context for configuration, dependencies, or avoiding proper function parameters.
All comments must end with periods. This is enforced by the godot linter.
NEVER delete existing comments without a very strong reason. Preserve helpful comments, update them to match code changes, refactor for clarity, and add context when modifying code. Only remove factually incorrect, duplicated, or outdated comments.
Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
All errors MUST be wrapped using static errors defined in errors/errors.go. Use errors.Join for combining multiple errors, fmt.Errorf with %w for adding string context, error builder for complex errors, and errors.Is() for error checking. NEVER use dynamic errors directly.
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation. Never create manual mocks.
Use viper.BindEnv with ATMOS_ prefix for environment variables.
Use colors from pkg/ui/theme/colors.go for theme consistency.
Ensure Linux/macOS/Windows compatibility. Use SDKs over binaries. Use filepath.Join(), not hardcoded path separators.
Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use //revive:disable:file-length-limit.
**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider us...
Files:
internal/exec/workflow_utils.go
🧠 Learnings (23)
📓 Common learnings
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.
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.
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: 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
📚 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:
tests/test-cases/workflows.yamlinternal/exec/workflow_utils.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:
tests/test-cases/workflows.yamlinternal/exec/workflow_utils.go
📚 Learning: 2025-10-11T19:12:38.832Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden:0-0
Timestamp: 2025-10-11T19:12:38.832Z
Learning: Usage Examples sections in error output are appropriate for command usage errors (incorrect syntax, missing arguments, invalid flags) but not for configuration validation errors (malformed workflow files, invalid settings in atmos.yaml). Configuration errors should focus on explaining what's wrong with the config, not command usage patterns.
Applied to files:
tests/test-cases/workflows.yaml
📚 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:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Organize imports in three groups separated by blank lines (Go stdlib, 3rd-party excluding cloudposse/atmos, Atmos packages), sorted alphabetically. Maintain aliases: cfg, log, u, errUtils.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Separate I/O (streams) from UI (formatting) using pkg/io/ and pkg/ui/ packages. Use data.Write/data.WriteJSON/data.WriteYAML for pipeable output (stdout), ui.Write/ui.Success/ui.Error for UI messages (stderr), and ui.Markdown for rendered documentation.
Applied to files:
internal/exec/workflow_utils.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:
internal/exec/workflow_utils.go
📚 Learning: 2024-10-21T17:51:07.087Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform.go:114-118
Timestamp: 2024-10-21T17:51:07.087Z
Learning: Use `bubbletea` for confirmation prompts instead of `fmt.Scanln` in the `atmos terraform clean` command.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-24T17:35:20.297Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T17:35:20.297Z
Learning: Applies to **/*.go : Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions. Use nil if no atmosConfig parameter.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.
Applied to files:
internal/exec/workflow_utils.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:
internal/exec/workflow_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:
internal/exec/workflow_utils.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:
internal/exec/workflow_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:
internal/exec/workflow_utils.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:
internal/exec/workflow_utils.go
📚 Learning: 2024-12-05T22:33:40.955Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_components.go:53-54
Timestamp: 2024-12-05T22:33:40.955Z
Learning: In the Atmos CLI Go codebase, using `u.LogErrorAndExit` within completion functions is acceptable because it logs the error and exits the command execution.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.
Applied to files:
internal/exec/workflow_utils.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:
internal/exec/workflow_utils.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.
Applied to files:
internal/exec/workflow_utils.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:
internal/exec/workflow_utils.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.
Applied to files:
internal/exec/workflow_utils.go
🧬 Code graph analysis (1)
internal/exec/workflow_utils.go (8)
errors/builder.go (1)
Build(21-23)errors/exit_code.go (2)
WithExitCode(40-48)GetExitCode(60-96)internal/exec/shell_utils.go (1)
ExecuteShellCommand(34-106)pkg/schema/workflow.go (1)
WorkflowManifest(24-28)internal/tui/templates/term/term_writer.go (1)
IsTTYSupportForStdin(133-135)pkg/telemetry/ci.go (1)
IsCI(81-86)pkg/ui/markdown/renderer.go (1)
Option(273-273)internal/tui/utils/utils.go (1)
NewAtmosHuhTheme(98-106)
⏰ 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 (14)
tests/test-cases/workflows.yaml (4)
49-51: Hints formatting looks consistent across execution errors.The "## Hints" sections for workflow step failures provide useful context (failed command and resume guidance). The pattern is applied consistently for shell command errors and failures.
Also applies to: 73-75, 94-96, 252-254, 272-274
134-136: New step-type hints are helpful and specific.The hints clarifying unsupported step type and valid options ("atmos" or "shell") provide clear guidance for fixing configuration errors.
178-182: Verify header consistency: "# Error" vs "Workflow Error".The "no workflow found" error uses "# Error" and shows available workflows in hints, which aligns with the auto-discovery feature. However, this differs from other workflow configuration errors (line 113 uses "Workflow Error"). Ensure this inconsistency is intentional—whether generic "# Error" is used for file/lookup failures vs. "Workflow Error" for validation failures.
206-211: Verify error header consistency for file-related errors.Both "invalid workflow manifest" (line 206) and "workflow file not found" (line 228) changed to "# Error" headers and "## Hints" sections. Confirm this represents the intended categorization and output format from the refactored error handling code.
Also applies to: 228-232
internal/exec/workflow_utils.go (10)
3-32: Imports look good.The three-group organization (stdlib, 3rd-party, Atmos) is correct and alphabetically sorted. Standard aliases are properly maintained.
44-45: Well-defined static errors.Both new error definitions follow the project pattern and provide clear, actionable messages.
290-310: Excellent error handling with proper wrapping and exit code preservation.The error construction correctly:
- Wraps the underlying error with
ErrWorkflowStepFailedusingfmt.Errorf("%w: %w", ...)to preserve both sentinel and exit code- Extracts and preserves the exit code from the underlying error
- Formats commands in code fences for proper rendering
- Uses single quotes for shell safety
This aligns perfectly with the learnings about workflow error handling.
Based on learnings, this follows the established pattern of using
errUtils.Buildinstead ofPrintErrorMarkdownAndExitfor testability.
366-384: Good resilience improvements.Skipping unreadable or invalid workflow files with warnings is a solid UX improvement. Users can still see available workflows while being informed of issues.
412-417: Clean type definition.
WorkflowMatchis well-documented and serves its purpose for auto-discovery results.
419-449: Function implementation looks solid.The workflow discovery logic is straightforward and correctly uses
ExecuteDescribeWorkflows. Performance tracking is properly in place.
459-461: Good environment checks.The combination of TTY and CI detection ensures interactive selection only runs in appropriate environments.
484-498: Nice UX touches.Adding ESC to the quit keys and using the Atmos theme creates a consistent, user-friendly experience.
500-508: Proper error handling for user interactions.Converting
huh.ErrUserAbortedtoerrUtils.ErrUserAbortedmaintains consistency with the rest of the codebase.
246-246: Based on my verification, I can now provide the rewritten review comment:Add comment explaining why
ui.Infoferror is being discarded on line 246.The error return from
ui.Infofis intentionally being discarded. While this appears to be best-effort logging before executing a workflow step (which is a reasonable pattern used elsewhere in the codebase), the lack of an explanatory comment is inconsistent with similar best-effort patterns in the codebase (e.g.,pkg/auth/manager.go:_ = m.ensureIdentityHasManager(identityName)with comment "This is best-effort..."). Add a comment explaining why the error is safely ignored, such as:// Logging is best-effort; if it fails, continue with workflow execution.
cfec0be to
f4aee4a
Compare
Make the workflow `--file` flag optional with auto-discovery and interactive selection. When no workflow file is specified, the system searches across all workflow configuration files and prompts the user to select one if multiple matches are found. Key changes: - Centralize ALL error formatting to main.go, eliminating "deep error printing" pattern - Add descriptive "Workflow Error" title to workflow-specific errors - Use `ui.Infof()` for "Executing command" messages - Wrap command examples in markdown code fences for proper rendering - Use single quotes for shell-safe command hints (handles values with spaces) - Create static error definitions instead of dynamic errors.New() - Convert if-else chains to switch statements for better style - Regenerate all workflow test snapshots to match new output format This follows the same architectural principle as eliminating "deep exits" (os.Exit calls) - we're now eliminating "deep print errors" (CheckErrorAndPrint calls). 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
- Add GetAliases() method to satisfy updated CommandProvider interface - Update workflow test to reflect auto-discovery behavior - Make workflow file discovery more resilient by skipping invalid files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive blog post announcing the workflow file auto-discovery feature that allows users to run workflows without specifying --file flag when workflow names are unique. Highlights: - Better developer experience - faster workflow execution - Backward compatible - existing scripts continue to work - Smart discovery - auto-selects unique workflows, prompts for duplicates - Consistent with other Atmos commands 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove Implementation Details, Migration Guide, and Technical Details sections to make the blog post more concise and user-focused. The post now focuses on: - What's new and why it matters - How it works with clear examples - Backward compatibility assurance - Getting started quickly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Further streamline the blog post by removing the Get Started section. The feature is self-explanatory from the examples, making this section redundant. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add extensive test coverage for workflow-related code, significantly improving test coverage for shell completion, auto-discovery, and error handling paths. Coverage improvements: - cmd/workflow/utils.go: 5.88% → 53.5% (+47.6%) - internal/exec/workflow_utils.go: 32.46% → ~70% (+37.5%) - findWorkflowAcrossFiles: 100% coverage - ExecuteDescribeWorkflows: 88.6% coverage New tests added: Shell Completion Tests (15 tests): - Stack flag completion (success & error paths) - List all stacks (success, config errors, invalid stacks) - Identity flag completion (with/without identities, errors) - Workflow name completion (success, multiple args, errors, duplicates) - Helper function tests (addStackCompletion, addIdentityCompletion) Auto-Discovery Tests (4 tests): - Find workflow across files (multiple matches, single match, not found) - Handle ExecuteDescribeWorkflows errors Error Path Tests (3 tests): - Invalid YAML file handling (logged and skipped) - Files without workflows key (logged and skipped) - Empty workflows directory All tests follow project conventions: - Table-driven tests where appropriate - Use existing test fixtures and patterns - Test error paths and edge cases - Proper test isolation with t.TempDir() and t.Setenv() - Clear test names describing behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
@aknysh I'll conduct a full review of PR #1800, which introduces workflow file auto-discovery and refactors the workflow command architecture. This is a substantial change that includes:
Starting the full review now. 🧠 Learnings used✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
internal/exec/workflow_test.go (1)
19-26: Usefilepath.Joininstead of+ "/..."for test path portability.
workflowsDir := stacksPath + "/stacks/workflows"and similar concatenations are fragile on Windows; preferfilepath.Join(stacksPath, "stacks", "workflows").tests/test-cases/workflows.yaml (1)
34-57: Invalid-manifest test expects Explanation-only, but code emits both Explanation and Hint.In
internal/exec/workflow.go, the invalid-manifest error path usesWithExplanationf(...)andWithHint(...); the test at lines 192-213 should also expect## Hintsand the corresponding hint text ("Add a top-level 'workflows:' key to the manifest file").
🧹 Nitpick comments (10)
website/blog/2025-11-18-workflow-file-auto-discovery.md (2)
79-99: Interactive selector example: consider matching actual UI wording/output.If the selector is a TUI (not a plain numbered prompt), ensure the example reflects what users will really see (or reword as “you’ll be prompted to select…” without implying a specific prompt format).
116-139: Minor markdown nits from static analysis (optional).
- If markdownlint MD014 is enforced for
website/, remove$prompts inside fenced blocks (or show output).- A couple list items/sentences could end with punctuation for consistency.
(If the repo intentionally allows
$prompts in website docs too, feel free to ignore—just aiming to reduce lint noise.)Also applies to: 168-173
website/docs/workflows/workflows.mdx (1)
71-77: Clarify--filevalue expectations in examples (basename vs path).The examples mix
-f workflow1(basename) with later--file workflows/deploy(path). Given current resolution behavior, consider adding one sentence that--fileshould be either an absolute path or a path/basename relative toworkflows.base_path, and keep the examples consistent with that.internal/exec/workflow_utils_test.go (2)
479-592: Good coverage forbuildWorkflowStepError; remove or assertexpectResumeCmdto avoid dead test data.
expectResumeCmdis currently unused; either assert on the formatted output containing the resume command when true, or drop the field.
617-820: Consider renaming “*_Coverage” tests to behavior-driven names.These read a bit like coverage scaffolding; renaming to scenario-focused names will keep intent clear long-term.
internal/exec/workflow_test.go (1)
214-236: Preferassert.ErrorIsfor sentinel errors (where available) instead of substring matching.For cases like “empty workflow” / “invalid step type” / “invalid from-step”, if the production code returns sentinel errors,
assert.ErrorIs(t, err, ErrWorkflowNoSteps/...)will make these tests less brittle. As per coding guidelines.cmd/workflow/utils_test.go (2)
45-54: Test doesn't verify behavior.Ignoring both return values provides no real assertion. Either use fixtures with valid stacks and assert results, or explicitly test the error case.
func TestListAllStacks_Success(t *testing.T) { t.Setenv("ATMOS_CLI_CONFIG_PATH", fixturesPath) results, err := listAllStacks() - // May error if the fixtures don't have valid stacks configured. - // The important thing is that the function runs without panicking. - _ = err - _ = results + // If fixtures have valid stacks, verify them. + // Otherwise, this test should be removed or use proper fixtures. + assert.NoError(t, err) + assert.NotNil(t, results) }
344-355: Test ignores result.Discarding
errmeans no behavioral verification. If the workflow should succeed, assertNoError. If it might fail, assert the expected error type.func TestWorkflowCmdRunE_WorkflowExecution(t *testing.T) { t.Setenv("ATMOS_CLI_CONFIG_PATH", fixturesPath) t.Setenv("ATMOS_BASE_PATH", fixturesPath) cmd := workflowCmd // Test running an existing workflow. err := cmd.RunE(cmd, []string{"shell-pass"}) - // May succeed or fail based on workflow content. - // The important test is that it doesn't panic. - _ = err + // Assert expected behavior - either success or specific error. + assert.NoError(t, err) }internal/exec/describe_workflows_test.go (2)
124-141: Consider usingassert.ErrorIsfor sentinel errors.The "missing workflows base path" case returns
errUtils.ErrWorkflowBasePathNotConfigured. UsingErrorIsis more robust than string matching.if tt.wantErr { assert.Error(t, err) - if tt.errMsg != "" { - assert.Contains(t, err.Error(), tt.errMsg) - } + if tt.name == "missing workflows base path" { + assert.ErrorIs(t, err, errUtils.ErrWorkflowBasePathNotConfigured) + } else if tt.errMsg != "" { + assert.Contains(t, err.Error(), tt.errMsg) + } }
243-256: UseErrorIsfor sentinel error.assert.Error(t, err) assert.Nil(t, matches) - assert.Contains(t, err.Error(), "'workflows.base_path' must be configured") + assert.ErrorIs(t, err, errUtils.ErrWorkflowBasePathNotConfigured)
tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
website/blog/2025-11-18-workflow-file-auto-discovery.md (3)
54-57: Add period to clarify the list introduction.Line 56 "You only need it when:" reads as a list lead-in. Adding a period before "You only need it when:" would improve readability.
-The `--file` flag is now **optional** for most workflows. You only need it when: +The `--file` flag is now **optional** for most workflows. You only need it when the following occurs:Alternatively, restructure to a complete sentence if preferred.
117-150: Fix markdown formatting for command examples.Markdownlint flags (MD014) commands shown with
$prompts when no output is displayed. Adjust code block formatting to indicate these are interactive examples:-### Basic Usage - -Run a workflow by name (auto-discovers the file): - -```bash -$ atmos workflow deploy -``` +### Basic Usage + +Run a workflow by name (auto-discovers the file): + +```bash +atmos workflow deploy +```Remove the leading
$from all command examples (lines 117, 126, 129, 132, 135, 144, 147-150) or, if you wish to show the prompt, include expected output after each command.
164-171: Add punctuation and clarify em-dash usage in "Get Involved" section.Line 170 ends without punctuation. Additionally, the hyphen structure here could be clearer:
- 🐛 **Report Issues** - Found a bug? [Open an issue](https://github.com/cloudposse/atmos/issues) -- 🚀 **Contribute** - Want to add features? Review our [contribution guide](https://atmos.tools/community/contributing) +- 🚀 **Contribute** — Want to add features? Review our [contribution guide](https://atmos.tools/community/contributing).The em-dash (
—) visually separates the action label from the description; the period ensures the bullet closes properly.cmd/workflow/utils_test.go (2)
336-346: Direct access toworkflowCmdmay be fragile.This test accesses the package-level
workflowCmddirectly. If the command isn't fully initialized at test time, this could panic or behave unexpectedly. Consider using the provider'sGetCommand()method for consistency.func TestWorkflowCmdRunE_HelpArgument(t *testing.T) { - // Test that "help" as first argument shows help without error. - cmd := workflowCmd + provider := &WorkflowCommandProvider{} + cmd := provider.GetCommand() // Reset command state. cmd.SetArgs([]string{"help"})
45-58: Loose assertion may mask failures.The test accepts both success and error cases. While the comment explains the reasoning, this could hide regressions. Consider splitting into separate tests or using
t.Skipfwith preconditions.internal/exec/workflow_utils_test.go (1)
848-859: Consider removing struct field tests.These tests verify that struct fields store and return values - which Go guarantees. They don't test behavior and could be considered coverage theater per coding guidelines.
Also applies to: 904-923
📜 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.
📒 Files selected for processing (9)
cmd/workflow/utils_test.go(1 hunks)internal/exec/describe_workflows_test.go(7 hunks)internal/exec/workflow.go(5 hunks)internal/exec/workflow_test.go(12 hunks)internal/exec/workflow_utils.go(6 hunks)internal/exec/workflow_utils_test.go(8 hunks)tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden(1 hunks)website/blog/2025-11-18-workflow-file-auto-discovery.md(1 hunks)website/docs/workflows/workflows.mdx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden
- website/docs/workflows/workflows.mdx
- internal/exec/describe_workflows_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 usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: usegofmtandgoimportsto 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 bygodotlinter)
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
Adddefer perf.Track(atmosConfig, "pkg.FuncName")()with a blank line to all public functions. Usenilif no atmosConfig parameter is available.
Define interfaces for all major functionality. Use dependency injection for testability. Generate mocks withgo.uber.org/mock/mockgen. Avoid integration tests by mocking external dependencies.
Use//go:generatedirectives withgo.uber.org/mock/mockgenfor mock generation. Never creat...
Files:
internal/exec/workflow.gointernal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils_test.gointernal/exec/workflow_utils.go
internal/**/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
For legacy patterns (internal/non-user-facing only): use
errors.Joinfor multiple errors,fmt.Errorf("%w", err)for chains (sequential call stack), orfmt.Errorfwith multiple%wlikeerrors.Join(Go 1.20+).
Files:
internal/exec/workflow.gointernal/exec/workflow_test.gointernal/exec/workflow_utils_test.gointernal/exec/workflow_utils.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 withgo.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. Useassert.ErrorIs(err, ErrSentinel)for our/stdlib errors.
Tests must call actual production code, never duplicate logic.
Uset.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 fromtests/test_preconditions.go.
Files:
internal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils_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 undercmd/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 viaCommandProviderinterface.
Separate I/O (streams) from UI (formatting) for clarity and testability. User interaction → stderr viaui.*. Data for processing/piping → stdout viadata.*. Never usefmt.Fprintf(os.Stdout/Stderr, ...),fmt.Println(), or direct stream access.
CRITICAL: Unified flag parsing infrastructure is FULLY IMPLEMENTED inpkg/flags/. Commands MUST useflags.NewStandardParser()for command-specific flags. NEVER callviper.BindEnv()orviper.BindPFlag()directly - Forbidigo enforces this.
Configuration loading precedence: CLI flags → ENV vars → config files → defaults (use Viper).
Embed examples fromcmd/markdown/*_usage.mdusing//go:embed. Render withutils.PrintfMarkdown().
Useviper.BindEnv("ATMOS_VAR", "ATMOS_VAR", "FALLBACK")- ATMOS_ prefix required for environment variables.
Telemetry auto-enabled viaRootCmd.ExecuteC(). Non-standard paths usetelemetry.CaptureCmd(). Never capture user data.
UI (prompts, status) → stderr. Data → stdout. Logging for system events only. Never use logging for UI.
Files:
cmd/workflow/utils_test.go
cmd/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
ALWAYS use
cmd.NewTestKit(t)for cmd tests. Auto-cleans RootCmd state (flags, args). Required for any test touching RootCmd.
Files:
cmd/workflow/utils_test.go
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/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 thewebsite/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-18-workflow-file-auto-discovery.md
🧠 Learnings (78)
📓 Common learnings
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.
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.
📚 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:
internal/exec/workflow.gointernal/exec/workflow_test.gointernal/exec/workflow_utils_test.gointernal/exec/workflow_utils.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:
internal/exec/workflow.gointernal/exec/workflow_test.gointernal/exec/workflow_utils_test.gointernal/exec/workflow_utils.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow.gointernal/exec/workflow_utils_test.go
📚 Learning: 2024-11-02T15:35:09.958Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 759
File: internal/exec/terraform.go:366-368
Timestamp: 2024-11-02T15:35:09.958Z
Learning: In `internal/exec/terraform.go`, the workspace cleaning code under both the general execution path and within the `case "init":` block is intentionally duplicated because the code execution paths are different. The `.terraform/environment` file should be deleted before executing `terraform init` in both scenarios to ensure a clean state.
Applied to files:
internal/exec/workflow.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow.gointernal/exec/workflow_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow.go
📚 Learning: 2024-10-31T19:25:41.298Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 727
File: internal/exec/terraform_clean.go:233-235
Timestamp: 2024-10-31T19:25:41.298Z
Learning: When specifying color values in functions like `confirmDeleteTerraformLocal` in `internal/exec/terraform_clean.go`, avoid hardcoding color values. Instead, use predefined color constants or allow customization through configuration settings to improve accessibility and user experience across different terminals and themes.
Applied to files:
internal/exec/workflow.gointernal/exec/workflow_utils_test.go
📚 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:
internal/exec/workflow.gocmd/workflow/utils_test.go
📚 Learning: 2024-10-20T00:41:57.135Z
Learnt from: haitham911
Repo: cloudposse/atmos PR: 731
File: internal/exec/validate_stacks.go:93-98
Timestamp: 2024-10-20T00:41:57.135Z
Learning: When downloading schema files in `internal/exec/validate_stacks.go`, use a consistent temporary file name to overwrite the file each time and avoid creating multiple temporary files.
Applied to files:
internal/exec/workflow.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 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:
internal/exec/workflow.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:
internal/exec/workflow.gointernal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils.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:
internal/exec/workflow.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow.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:
internal/exec/workflow.gointernal/exec/workflow_test.gointernal/exec/workflow_utils_test.gointernal/exec/workflow_utils.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to cmd/**/*.go : 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.
Applied to files:
internal/exec/workflow.gointernal/exec/workflow_utils_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:
internal/exec/workflow.gointernal/exec/workflow_test.gointernal/exec/workflow_utils_test.go
📚 Learning: 2024-12-05T22:33:40.955Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_components.go:53-54
Timestamp: 2024-12-05T22:33:40.955Z
Learning: In the Atmos CLI Go codebase, using `u.LogErrorAndExit` within completion functions is acceptable because it logs the error and exits the command execution.
Applied to files:
internal/exec/workflow.gointernal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils.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:
internal/exec/workflow.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to internal/exec/template_funcs.go : Template functions: `atmos.Component/Stack/Setting()`, `terraform.output/state()`, `store.get()`, `exec()`, `env()`. Register in `internal/exec/template_funcs.go`
Applied to files:
internal/exec/workflow.go
📚 Learning: 2025-01-09T22:37:01.004Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform_commands.go:260-265
Timestamp: 2025-01-09T22:37:01.004Z
Learning: In the terraform commands implementation (cmd/terraform_commands.go), the direct use of `os.Args[2:]` for argument handling is intentionally preserved to avoid extensive refactoring. While it could be improved to use cobra's argument parsing, such changes should be handled in a dedicated PR to maintain focus and minimize risk.
Applied to files:
internal/exec/workflow.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils_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:
internal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*.go : Small focused files (<600 lines). One cmd/impl per file. Co-locate tests. Never use `//revive:disable:file-length-limit`.
Applied to files:
internal/exec/workflow_test.gocmd/workflow/utils_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:
internal/exec/workflow_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_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:
internal/exec/workflow_test.gocmd/workflow/utils_test.gointernal/exec/workflow_utils_test.go
📚 Learning: 2025-04-11T22:06:46.999Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: internal/exec/validate_schema.go:42-57
Timestamp: 2025-04-11T22:06:46.999Z
Learning: The "ExecuteAtmosValidateSchemaCmd" function in internal/exec/validate_schema.go has been reviewed and confirmed to have acceptable cognitive complexity despite static analysis warnings. The function uses a clean structure with only three if statements for error handling and delegates complex operations to helper methods.
Applied to files:
internal/exec/workflow_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_test.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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Search `internal/exec/` and `pkg/` before implementing. Extend, don't duplicate.
Applied to files:
internal/exec/workflow_test.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:
internal/exec/workflow_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: 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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_test.go
📚 Learning: 2024-12-05T22:33:54.807Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 820
File: cmd/list_stacks.go:55-56
Timestamp: 2024-12-05T22:33:54.807Z
Learning: In the atmos project, the `u.LogErrorAndExit` function logs the error and exits the command execution appropriately within flag completion functions.
Applied to files:
internal/exec/workflow_test.go
📚 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:
internal/exec/workflow_test.go
📚 Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.
Applied to files:
internal/exec/workflow_test.go
📚 Learning: 2025-01-18T15:15:41.645Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/terraform.go:37-46
Timestamp: 2025-01-18T15:15:41.645Z
Learning: In the atmos CLI, error handling is intentionally structured to use LogErrorAndExit for consistent error display, avoiding Cobra's default error handling to prevent duplicate error messages.
Applied to files:
internal/exec/workflow_test.go
📚 Learning: 2025-10-11T19:12:38.832Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: tests/snapshots/TestCLICommands_atmos_workflow_invalid_step_type.stderr.golden:0-0
Timestamp: 2025-10-11T19:12:38.832Z
Learning: Usage Examples sections in error output are appropriate for command usage errors (incorrect syntax, missing arguments, invalid flags) but not for configuration validation errors (malformed workflow files, invalid settings in atmos.yaml). Configuration errors should focus on explaining what's wrong with the config, not command usage patterns.
Applied to files:
internal/exec/workflow_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_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:
internal/exec/workflow_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:
internal/exec/workflow_test.gointernal/exec/workflow_utils_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/workflow/utils_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 : Provide comprehensive help text for all commands and flags, include examples in command help, and follow Go's documentation conventions in Cobra command definitions
Applied to files:
cmd/workflow/utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*.go : 80% minimum test coverage (CodeCov enforced). All features need tests. Use `make testacc-coverage` for coverage reports.
Applied to files:
cmd/workflow/utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*.go : 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.
Applied to files:
cmd/workflow/utils_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/workflow/utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*_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.
Applied to files:
cmd/workflow/utils_test.go
📚 Learning: 2025-02-18T13:18:53.146Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: cmd/vendor_pull.go:31-31
Timestamp: 2025-02-18T13:18:53.146Z
Learning: Error checking is not required for cobra.Command.RegisterFlagCompletionFunc calls as these are static configurations done at init time.
Applied to files:
cmd/workflow/utils_test.go
📚 Learning: 2025-02-09T14:38:53.443Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 992
File: cmd/cmd_utils.go:0-0
Timestamp: 2025-02-09T14:38:53.443Z
Learning: Error handling for RegisterFlagCompletionFunc in AddStackCompletion is not required as the errors are non-critical for tab completion functionality.
Applied to files:
cmd/workflow/utils_test.go
📚 Learning: 2025-01-09T22:27:25.538Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 914
File: cmd/validate_stacks.go:20-23
Timestamp: 2025-01-09T22:27:25.538Z
Learning: The validate commands in Atmos can have different help handling implementations. Specifically, validate_component.go and validate_stacks.go are designed to handle help requests differently, with validate_stacks.go including positional argument checks while validate_component.go does not.
Applied to files:
cmd/workflow/utils_test.go
📚 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:
cmd/workflow/utils_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 .github/workflows/*.{yml,yaml} : Configure CI to run unit tests, integration tests, golangci-lint, and coverage reporting on all pull requests
Applied to files:
internal/exec/workflow_utils_test.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:
internal/exec/workflow_utils_test.gointernal/exec/workflow_utils.go
📚 Learning: 2025-10-11T19:11:58.965Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1599
File: internal/exec/terraform.go:0-0
Timestamp: 2025-10-11T19:11:58.965Z
Learning: For terraform apply interactivity checks in Atmos (internal/exec/terraform.go), use stdin TTY detection (e.g., `IsTTYSupportForStdin()` or checking `os.Stdin`) to determine if user prompts are possible. This is distinct from stdout/stderr TTY checks used for output display (like TUI rendering). User input requires stdin to be a TTY; output display requires stdout/stderr to be a TTY.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2024-11-10T18:37:10.032Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 768
File: internal/exec/vendor_component_utils.go:354-360
Timestamp: 2024-11-10T18:37:10.032Z
Learning: In the vendoring process, a TTY can exist without being interactive. If the process does not prompt the user, we should not require interactive mode to display the TUI. The `CheckTTYSupport` function should check TTY support on stdout rather than stdin.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*_test.go : Tests skip gracefully with helpers from `tests/test_preconditions.go`.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2024-11-16T17:30:52.893Z
Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For the `atmos terraform shell` command in `internal/exec/shell_utils.go`, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-02-19T05:50:35.853Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden:0-0
Timestamp: 2025-02-19T05:50:35.853Z
Learning: Backtick formatting should only be applied to flag descriptions in Go source files, not in golden test files (test snapshots) as they are meant to capture the raw command output.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*.go : Linux/macOS/Windows compatible. Use SDKs over binaries. Use `filepath.Join()`, not hardcoded path separators.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*_test.go : Use `t.Skipf("reason")` with clear context for test skipping. CLI tests auto-build temp binaries.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to **/*_test.go : Tests must call actual production code, never duplicate logic.
Applied to files:
internal/exec/workflow_utils_test.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:
internal/exec/workflow_utils_test.gointernal/exec/workflow_utils.go
📚 Learning: 2025-08-16T23:33:07.477Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1405
File: internal/exec/describe_dependents_test.go:651-652
Timestamp: 2025-08-16T23:33:07.477Z
Learning: In the cloudposse/atmos Go codebase, ExecuteDescribeDependents expects a pointer to AtmosConfiguration (*schema.AtmosConfiguration), so when calling it with a value returned by cfg.InitCliConfig (which returns schema.AtmosConfiguration), the address-of operator (&) is necessary: ExecuteDescribeDependents(&atmosConfig, ...).
Applied to files:
internal/exec/workflow_utils_test.gointernal/exec/workflow_utils.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:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-09-10T22:38:42.212Z
Learnt from: Benbentwo
Repo: cloudposse/atmos PR: 1475
File: pkg/auth/identities/aws/user.go:141-145
Timestamp: 2025-09-10T22:38:42.212Z
Learning: ErrWrappingFormat is correctly defined as "%w: %w" in the errors package and is used throughout the codebase to wrap two error types together. The usage fmt.Errorf(errUtils.ErrWrappingFormat, errUtils.ErrAuthAwsFileManagerFailed, err) is the correct pattern when both arguments are error types.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2024-11-19T23:00:45.899Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 795
File: internal/exec/stack_processor_utils.go:378-386
Timestamp: 2024-11-19T23:00:45.899Z
Learning: In the `ProcessYAMLConfigFile` function within `internal/exec/stack_processor_utils.go`, directory traversal in stack imports is acceptable and should not be restricted.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2025-04-10T21:33:06.447Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1147
File: pkg/filematch/filematch.go:32-32
Timestamp: 2025-04-10T21:33:06.447Z
Learning: The replacement of "*/*" with an empty string in recursive glob patterns (containing "**") is intentional behavior in the filematch package, as confirmed by the developer. This is necessary for proper handling of recursive directory matching when using the gobwas/glob library.
Applied to files:
internal/exec/workflow_utils_test.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:
internal/exec/workflow_utils_test.go
📚 Learning: 2024-11-12T03:16:02.910Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 775
File: internal/exec/template_funcs_component.go:157-159
Timestamp: 2024-11-12T03:16:02.910Z
Learning: In the Go code for `componentFunc` in `internal/exec/template_funcs_component.go`, the function `cleanTerraformWorkspace` does not return errors, and it's acceptable if the file does not exist. Therefore, error handling for `cleanTerraformWorkspace` is not needed.
Applied to files:
internal/exec/workflow_utils_test.go
📚 Learning: 2024-11-13T21:37:07.852Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 764
File: internal/exec/describe_stacks.go:289-295
Timestamp: 2024-11-13T21:37:07.852Z
Learning: In the `internal/exec/describe_stacks.go` file of the `atmos` project written in Go, avoid extracting the stack name handling logic into a helper function within the `ExecuteDescribeStacks` method, even if the logic appears duplicated.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-30T04:16:24.155Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:34-48
Timestamp: 2025-11-30T04:16:24.155Z
Learning: In the cloudposse/atmos repository, the `defer perf.Track()` guideline applies to functions that perform meaningful work (I/O, computation, external calls), but explicitly excludes trivial accessors/mutators (e.g., simple getters, setters with single integer increments, string joins, or map appends) where the tracking overhead would exceed the actual method cost and provide no actionable performance data. Hot-path methods called in tight loops should especially avoid perf.Track() if they perform only trivial operations.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-30T04:16:01.899Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1821
File: pkg/merge/deferred.go:50-59
Timestamp: 2025-11-30T04:16:01.899Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` should NOT be added to trivial O(1) getter methods that only return field references or check map lengths (e.g., `GetDeferredValues()`, `HasDeferredValues()`). The guideline to add perf tracking to "all public functions" applies to functions that do meaningful work (I/O, computation, external calls), not to trivial accessors where the tracking overhead would exceed the operation time and pollute performance reports.
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
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:
internal/exec/workflow_utils.go
📚 Learning: 2025-11-09T19:06:58.470Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1752
File: pkg/profile/list/formatter_table.go:27-29
Timestamp: 2025-11-09T19:06:58.470Z
Learning: In the cloudposse/atmos repository, performance tracking with `defer perf.Track()` is enforced on all functions via linting, including high-frequency utility functions, formatters, and renderers. This is a repository-wide policy to maintain consistency and avoid making case-by-case judgment calls about which functions should have profiling.
Applied to files:
internal/exec/workflow_utils.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 : Provide meaningful feedback to users and include progress indicators for long-running operations in CLI commands
Applied to files:
internal/exec/workflow_utils.go
📚 Learning: 2025-10-13T18:13:54.020Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 1622
File: pkg/perf/perf.go:140-184
Timestamp: 2025-10-13T18:13:54.020Z
Learning: In pkg/perf/perf.go, the `trackWithSimpleStack` function intentionally skips ownership checks at call stack depth > 1 to avoid expensive `getGoroutineID()` calls on every nested function. This is a performance optimization for the common single-goroutine execution case (most Atmos commands), accepting the rare edge case of potential metric corruption if multi-goroutine execution occurs at depth > 1. The ~19× performance improvement justifies this trade-off.
Applied to files:
internal/exec/workflow_utils.go
🧬 Code graph analysis (2)
cmd/workflow/utils_test.go (1)
cmd/workflow/workflow.go (1)
WorkflowCommandProvider(86-86)
internal/exec/workflow_utils.go (5)
errors/errors.go (11)
ErrWorkflowNoSteps(433-433)ErrInvalidWorkflowStepType(434-434)ErrInvalidFromStep(435-435)ErrWorkflowStepFailed(436-436)ErrWorkflowNoWorkflow(437-437)ErrWorkflowFileNotFound(438-438)ErrInvalidWorkflowManifest(439-439)ErrAuthManager(530-530)ErrUserAborted(537-537)ErrAuthenticationFailed(528-528)ErrFailedToInitializeAuthManager(549-549)pkg/config/const.go (1)
AtmosCommand(4-4)pkg/auth/types/interfaces.go (2)
AuthManager(173-282)Identity(121-170)pkg/schema/schema.go (3)
AtmosConfiguration(53-96)ConfigAndStacksInfo(646-742)Workflows(471-474)internal/tui/templates/term/term_writer.go (1)
IsTTYSupportForStdin(133-135)
🪛 LanguageTool
website/blog/2025-11-18-workflow-file-auto-discovery.md
[grammar] ~56-~56: Please add a punctuation mark at the end of paragraph.
Context: ...ant to explicitly specify which file to use ### Consistent with Other Commands Th...
(PUNCTUATION_PARAGRAPH_END)
[typographical] ~170-~170: To join two clauses or introduce examples, consider using an em dash.
Context: ...dposse/atmos/issues) - 🚀 Contribute - Want to add features? Review our [contri...
(DASH_RULE)
[grammar] ~170-~170: Please add a punctuation mark at the end of paragraph.
Context: ... add features? Review our [contribution guide](https://atmos.tools/community/contribu...
(PUNCTUATION_PARAGRAPH_END)
🪛 markdownlint-cli2 (0.18.1)
website/blog/2025-11-18-workflow-file-auto-discovery.md
117-117: Dollar signs used before commands without showing output
(MD014, commands-show-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). (3)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Acceptance Tests (macos)
- GitHub Check: Summary
🔇 Additional comments (13)
internal/exec/workflow_test.go (3)
39-40: Good addition of sentinel error fields.The
wantSentinelanderrContainsfields enable proper error checking withassert.ErrorIs()instead of string matching. This aligns with the codebase pattern for testable error handling. Based on learnings about workflow error refactoring.
228-235: Clean error assertion pattern.The two-phase check (sentinel via
ErrorIs, then optional message viaContains) is the right approach. Sentinel takes precedence for type safety.
586-655: Thorough multi-match test with proper CI simulation.Setting
CI=true(line 641) ensures deterministic non-TTY behavior. UsingerrUtils.Format()to verify hint content is a good pattern when you need to check the full formatted output.cmd/workflow/utils_test.go (1)
365-402: Good provider interface coverage.Each method is tested with clear expectations. This ensures the command registry integration works correctly.
internal/exec/workflow_utils_test.go (2)
604-620: Past review concern addressed.Setting
CI=true(line 608) prevents the test from hanging when run from an interactive terminal. Good fix.
487-594: Solid error builder test coverage.The table-driven tests cover key scenarios: different command types, stack presence, exit codes, and nested paths. The use of
errUtils.Format()to verify hint content is appropriate here.internal/exec/workflow.go (2)
63-106: Auto-discovery logic is clean and handles edge cases well.The switch statement covers all three cases clearly: no matches, single match, multiple matches. Sorting
fileList(line 89) ensures deterministic output for tests/snapshots. The TTY/CI check at line 82 properly gates interactive selection.
146-150: Error sentinels correctly sourced fromerrUtils.All user-facing errors now use
errUtils.Build()with sentinels fromerrors/errors.go. This addresses the past review concern about inconsistent sentinel sources.Also applies to: 167-172, 184-188
internal/exec/workflow_utils.go (5)
514-517: Performance tracking added.The
defer perf.Track()call was added per the past review suggestion.
98-117: Well-designed error builder with resume hints.The dual-wrapping approach (line 101) preserves both the sentinel for
errors.Is()checks and the underlying error's exit code. Code fences in hints aid copy-paste. Clean implementation.
145-155: Auth credential flow handles user cancellation cleanly.Line 150-152 returns
ErrUserAborteddirectly without additional wrapping, ensuring callers can detect user cancellation witherrors.Is().
528-533: Deterministic ordering for interactive selector.Sorting matches by filename ensures consistent UI regardless of filesystem ordering. Good UX consideration.
236-244: Error builder pattern consistently applied.The
errUtils.Build()pattern withWithTitle(WorkflowErrTitle)ensures consistent error presentation across workflow commands.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 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.
📒 Files selected for processing (1)
website/blog/2025-11-18-workflow-file-auto-discovery.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
website/**
📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
website/**: Update website documentation in thewebsite/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 thewebsite/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-18-workflow-file-auto-discovery.md
🧠 Learnings (4)
📓 Common learnings
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.
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.
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to 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.
Applied to files:
website/blog/2025-11-18-workflow-file-auto-discovery.md
📚 Learning: 2025-12-10T23:12:15.768Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T23:12:15.768Z
Learning: Applies to website/blog/**/*.mdx : Blog posts must have YAML frontmatter with: slug, title, authors, tags. Use `<!--truncate-->` after introduction. Valid tags must be from `website/blog/tags.yml`.
Applied to files:
website/blog/2025-11-18-workflow-file-auto-discovery.md
📚 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:
website/blog/2025-11-18-workflow-file-auto-discovery.md
🪛 markdownlint-cli2 (0.18.1)
website/blog/2025-11-18-workflow-file-auto-discovery.md
117-117: Dollar signs used before commands without showing output
(MD014, commands-show-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). (2)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
🔇 Additional comments (1)
website/blog/2025-11-18-workflow-file-auto-discovery.md (1)
116-119: Fix MD014: drop$prompts (or show output) in fenced command blocks
Markdownlint flags$ atmos ...without output. Easiest: remove the$so the block is just the command.```bash -$ atmos workflow deploy +atmos workflow deploy# Run with dry-run -$ atmos workflow deploy --dry-run +atmos workflow deploy --dry-run ...Also applies to: 124-136, 142-151, 157-160 <details> <summary>⛔ Skipped due to learnings</summary>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.Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1068
File: tests/snapshots/TestCLICommands_atmos_terraform_help.stdout.golden:59-64
Timestamp: 2025-02-18T13:13:11.497Z
Learning: For Atmos CLI help text, angle brackets in command examples and flag descriptions should be escaped using HTML entities (e.g.,<component>) rather than converted to backticks or other markdown formatting.Learnt from: osterman
Repo: cloudposse/atmos PR: 1505
File: website/docs/cli/commands/completion.mdx:124-127
Timestamp: 2025-09-24T22:20:39.209Z
Learning: In Docusaurus (specifically the cloudposse/atmos repository), backticks render correctly as code formatting even when used inside HTML elements like/
- /
- tags in MDX files. No need to replace with
tags.Learnt from: pkbhowmick
Repo: cloudposse/atmos PR: 786
File: internal/exec/shell_utils.go:159-162
Timestamp: 2024-11-16T17:30:52.893Z
Learning: For theatmos terraform shellcommand ininternal/exec/shell_utils.go, input validation for the custom shell prompt is not required, as users will use this as a CLI tool and any issues will impact themselves.</details> </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
|
These changes were released in v1.202.0-rc.1. |
|
These changes were released in v1.203.0-test.1. |
what
--fileflag optional with auto-discovery and interactive selectioncmd/workflow/package structure following command registry patternErrNoWorkflowFilesToSelect,ErrNonTTYWorkflowSelection) instead of dynamic errorswhy
references
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com
Summary by CodeRabbit
New Features
--filewhen the name is unique across filesDocumentation
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.