Repository navigation
feat: Add structured component dependencies with cross-type and file monitoring - #2193
Conversation
…monitoring Introduce `dependencies.components` format in stack configurations: - ComponentDependency struct with component, stack, kind, and path fields - Cross-type dependencies (terraform can depend on helmfile/packer/plugin) - File/folder watching for external config and source code monitoring - Go template support for dynamic stack references - Dependency inheritance with append merge behavior - Updated describe dependents/affected commands for new dependency format - Test fixtures for inheritance and append merge scenarios - Restructured documentation into dependencies/ directory - Blog post announcing the feature Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Important Cloud Posse Engineering Team Review RequiredThis pull request modifies files that require Cloud Posse's review. Please be patient, and a core maintainer will review your changes. To expedite this process, reach out to us on Slack in the |
Dependency Review✅ No vulnerabilities or license issues found.Scanned FilesNone |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughIntroduces a structured Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/CLI
participant DAC as Describe<br/>Affected
participant Loader as getFileFolder<br/>Dependencies
participant Matcher as Dependency<br/>Checker
participant FS as File System
User->>DAC: Execute "describe affected"
DAC->>Loader: Load dependencies (new or legacy)
alt New Format
Loader->>Loader: Parse dependencies.components -> []ComponentDependency
else Legacy Format
Loader->>Loader: Parse settings.depends_on -> convert to ComponentDependency
Loader-->>Loader: Log deprecation
end
Loader-->>DAC: Return dependencies slice
DAC->>Matcher: Check dependencies against changed files
Matcher->>FS: Match dep.Path (handles file/folder patterns)
alt Match Found
Matcher->>DAC: Mark component as affected
else No Match
Matcher->>DAC: No action
end
DAC-->>User: Return affected components
sequenceDiagram
participant User as User/CLI
participant DDeps as Describe<br/>Dependents
participant Loader as getComponent<br/>Dependencies
participant Matcher as isDependency<br/>Match
participant Output as Dependents<br/>Collector
User->>DDeps: Execute "describe dependents"
DDeps->>Loader: Load component dependencies (new/legacy)
alt New Format
Loader->>Loader: Parse dependencies.components
else Legacy Format
Loader->>Loader: Convert settings.depends_on -> ComponentDependency
Loader-->>Loader: Log deprecation
end
Loader-->>DDeps: Return dependencies slice
loop for each dependency
DDeps->>Matcher: Apply new or legacy matching rules
alt Match
Matcher->>Output: Include dependent component
else No match
Matcher->>Output: Skip
end
end
Output-->>User: Return dependent components
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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 |
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
internal/exec/describe_dependents.go (2)
205-208:⚠️ Potential issue | 🟠 Major
kindis not part of dependent matching yet.Lines 205-208 and 244-256 still key on component name alone, and
isDependencyMatch()only checks stack/context. With the new cross-type feature,terraform/vpcandhelmfile/vpcare distinct targets; right now akind: helmfiledependency can still match the terraformvpc, and a same-named component in another type gets skipped as "self". Please carry the provided component type through this path and compare it todependsOn.Kind(defaulting emptykindto the declaring component type) before matching.Also applies to: 242-256, 416-429
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_dependents.go` around lines 205 - 208, The current dependent-matching logic only compares component names (e.g., stackComponentName vs args.Component) and relies on isDependencyMatch() which ignores target kind; update the flow to carry the provided component type (args.Kind or similar) through the path and use it when skipping and when calling isDependencyMatch(): when reading dependsOn entries treat empty dependsOn.Kind as the declaring component's kind (default to the current stack/component kind), and ensure you compare both name and resolved kind before skipping a "self" match (replace the simple stackComponentName == args.Component check) and before treating a dependency as matching; update references in describe_dependents.go functions that use stackComponentName, args.Component, isDependencyMatch(), and dependsOn.Kind (affecting the matching blocks around those areas) to enforce kind-aware matching.
260-305:⚠️ Potential issue | 🟠 MajorStop after the first match to avoid duplicate dependents.
Once one dependency entry matches, this code appends the dependent but keeps scanning. With append-merge inheritance, the same dependency can legitimately show up in both parent and child stacks, so the same dependent can be emitted more than once.
Suggested fix
if args.IncludeSettings { dependent.Settings = settingsSection } dependents = append(dependents, dependent) + break } } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_dependents.go` around lines 260 - 305, The loop that builds and appends a dependent (creating variable dependent and calling BuildSpaceliftStackNameFromComponentConfig/BuildAtlantisProjectNameFromComponentConfig) continues scanning after appending, causing duplicate dependents; after appending to the dependents slice add a break to stop scanning further matches for that dependency (i.e., exit the current dependency-matching loop immediately after dependents = append(dependents, dependent)) so each dependent is emitted only once.internal/exec/describe_affected_utils_optimized.go (1)
104-127:⚠️ Potential issue | 🟠 MajorResolve dependency paths against the same base as the changed-files index.
Line 122 resolves
dep.Pathusingfilepath.Abs, which anchors relative paths to the process working directory. However,changedFilesIndexnormalizes files relative togitRepoRoot(not the current working directory). This causes a path-matching mismatch when atmos runs from different directories. Additionally, an emptyPathcollapses to the current working directory viaAbs(""), risking over-matches against unrelated changes.The function needs either
gitRepoRootpassed as a parameter to match the indexing strategy, or paths should be resolved againstatmosConfig.BasePath. Also validate and reject empty paths before matching.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_affected_utils_optimized.go` around lines 104 - 127, The code currently resolves dependency paths with filepath.Abs(dep.Path) which anchors relative paths to the process CWD and treats an empty Path as the CWD; change this to resolve dep.Path against the same base used by the changed-files index (pass gitRepoRoot into the routine or use atmosConfig.BasePath) instead of calling filepath.Abs directly, and validate/reject empty dep.Path before building pathPattern (so you don't collapse to CWD); update references around dep.Path, the filepath.Abs call, and pathPattern construction to use the chosen base and add a guard for empty paths.
🧹 Nitpick comments (1)
tests/fixtures/scenarios/dependencies-components-inheritance/components/terraform/mock/main.tf (1)
1-5: Looks good for a test fixture.The mock component is appropriately minimal. The
enabledvariable serves its purpose for testing dependency scenarios.If you want to enhance clarity, consider adding a description to the variable—but it's purely optional for test code.
📝 Optional: Add variable description
# Mock component for testing. variable "enabled" { type = bool default = true + description = "Enable or disable the mock component" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/fixtures/scenarios/dependencies-components-inheritance/components/terraform/mock/main.tf` around lines 1 - 5, The test fixture's variable "enabled" is fine but could be clearer by adding a description; open the Terraform mock file and update the variable "enabled" block to include a description attribute (e.g., description = "Enable mock component for dependency tests") so the variable declaration (variable "enabled") documents its intent while keeping default and type unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/prd/component-dependencies.md`:
- Around line 237-242: Update the failing absolute site routes in the markdown
by replacing the site-rooted URLs with repo-resolvable references or plain text:
change the link targets for "Component Dependencies User Guide"
(/stacks/dependencies/components) and the two "describe" links
(/cli/commands/describe/dependents and /cli/commands/describe/affected) to
either relative repository paths that point to the corresponding docs files
(e.g., a relative path into the docs tree) or convert the links to plain text if
no repo path exists; ensure the link text remains unchanged so readers still see
the same labels while the targets resolve in repo doc validation.
In `@docs/prd/tool-dependencies-integration.md`:
- Line 98: The link "[Component Dependencies
documentation](/stacks/dependencies/components)" is not repo-resolvable from
this doc; replace the absolute path with a relative, repo-resolvable path (for
example change "/stacks/dependencies/components" to the correct relative path to
the components doc from this file) so the docs validation passes; update the
link in the line containing the markdown reference to ensure it points to the
actual file location in the repository.
- Around line 61-70: The PRD still shows the old dependency shape: update the
Dependencies struct and all examples to use the new []ComponentDependency type
instead of []Context and remove legacy fields like stage: prod; specifically
change the Dependencies.Components field to be Components []ComponentDependency
and update sample snippets that drop Components (lines ~197-203) to include the
new ComponentDependency entries using the new keys stack, kind, and path so
examples reflect the current implementation; ensure all occurrences (including
the examples called out around lines 78-86 and 197-203) consistently use
ComponentDependency with stack/kind/path and no legacy stage/context fields.
In `@internal/exec/describe_affected_components.go`:
- Around line 573-587: The code in the block that builds result from
stackComponentSettings.DependsOn drops folder values when a legacy entry
contains both file and folder because it uses "else if"; modify the logic in the
loop that builds result (the code that appends schema.ComponentDependency from
stackComponentSettings.DependsOn) to append a ComponentDependency for the file
when dep.File != "" and also independently append a ComponentDependency for the
folder when dep.Folder != "" (i.e., remove the else-if relationship so both
branches can run), keeping the Kind values "file" and "folder" and Path set to
dep.File/dep.Folder respectively so legacy entries that include both are
preserved.
In `@internal/exec/describe_dependents_test.go`:
- Around line 20-225: The PR is missing unit tests for two resolution paths:
non-default dependency kinds and Go-templated components[].stack values; add two
new t.Run cases in TestGetComponentDependencies (or adjacent tests in
describe_dependents_test.go) that exercise getComponentDependencies and
schema.ComponentDependency: (1) add a fixture where dependencies.components
includes an item with Kind "helmfile" (and Path or Component as appropriate) and
assert IsFile/IsFolder helpers are false and Kind/Path are preserved and the
returned source is dependencySourceDependenciesComponents; (2) add a fixture
where a component's "stack" field is a Go template (e.g., "{{ .ParentStack
}}-prod" or similar) that simulates resolved cross-stack reference (provide a
componentMap representing the post-resolution state with the templated value
resolved across stacks) and assert the resolved Stack value appears in deps and
that edge type (terraform→terraform) is correctly recorded; ensure both tests
call getComponentDependencies and assert on deps length, per-item
Kind/Component/Stack and returned source so these new code paths are covered.
In
`@tests/fixtures/scenarios/dependencies-components-inheritance/stacks/catalog/base.yaml`:
- Around line 1-12: The comment in base.yaml incorrectly states that parent
dependencies "should be inherited by child stacks"; update the comment to
reflect the actual tested behavior used by
TestDescribeDependents_DependenciesComponentsFormat: list-valued dependencies
under components use replace-merge (child lists replace parent lists), so note
that the VPC dependencies in base.yaml are replaced by dev.yaml rather than
appended; update the comment near components -> terraform -> vpc -> dependencies
-> components to explicitly state "replace merge (child replaces parent)
behavior" and mention the related test name for clarity.
In
`@tests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml`:
- Around line 1-2: Update the top comment in the dev.yaml fixture for the
dependencies-components-inheritance scenario to reflect the default replace
merge behavior (not append); change the sentence that currently reads "Tests
that child dependencies are APPENDED to parent dependencies." to indicate that
child dependencies REPLACE parent dependencies, and ensure it matches the
documented behavior in TestDescribeDependents_DependenciesComponentsFormat.
- Around line 20-27: The inline comment above the vpc dependencies is incorrect
about merge behavior; update the comment to state that with the replace merge
strategy the vpc.dependencies block replaces the parent entries from base.yaml
(account-settings, iam-baseline) rather than appending to them, referencing the
vpc key and its dependencies mapping so readers understand the actual replace
semantics.
In `@website/blog/2026-01-02-dependencies-components.mdx`:
- Line 40: The doc line "Inheritance: Dependencies are appended during stack
inheritance (not replaced)" is misleading; update the "Inheritance" sentence to
state that dependencies default to the replace strategy during stack inheritance
and are only appended when explicitly configured via list_merge_strategy:
append, e.g., change the wording under the "Inheritance" heading to mention the
default replace behavior and call out the explicit list_merge_strategy: append
option for appending dependencies.
In `@website/docs/stacks/dependencies/components.mdx`:
- Around line 260-271: The example JSON in the docs still uses the legacy
affected value "stack.settings.depends_on.folder"; update the JSON example so
the affected field uses the new plain-reason format (e.g., change the subnet
entry's "affected" value to "folder" and any similar legacy strings to "file" or
"folder" as appropriate), verify the example shows both possible plain values if
relevant, and ensure the doc now matches the CLI output for the
"component"/"subnet" example.
In `@website/docs/stacks/dependencies/index.mdx`:
- Line 220: The sentence overstates behavior—change the claim about
"dependencies.components" so it is scoped to only the flows that support
dependency metadata (e.g., commands and integrations that consume dependency
info). Locate the sentence referencing "dependencies.components" and replace it
with a scoped version that notes it controls execution order only for supported
flows (such as commands and integrations that read dependency metadata) and does
not imply a universal guarantee.
In `@website/docs/stacks/settings/depends_on.mdx`:
- Around line 19-25: The example under dependencies.components uses the
deprecated selector field "stage" — update the snippet to use the new selector
key "stack" instead (i.e., replace any occurrence of "stage: prod" with "stack:
prod") so the documentation example matches the new dependencies.components
schema; look for the YAML block showing dependencies.components and ensure the
selector uses "stack" in the component entry.
In `@website/docs/stacks/settings/index.mdx`:
- Line 161: The subsection currently teaches the legacy config key
settings.depends_on but links to the new dependencies.components page, which is
contradictory; either move the concrete examples and sample YAML from this
subsection into the new dependencies.components documentation and update this
page to reference that new examples section, or explicitly mark this subsection
as “Legacy: settings.depends_on” and change the link to point to the legacy
documentation for settings (not dependencies.components); update any example
headings and text to reference the correct symbol (settings.depends_on or
dependencies.components) so CLI docs and website examples remain in sync.
---
Outside diff comments:
In `@internal/exec/describe_affected_utils_optimized.go`:
- Around line 104-127: The code currently resolves dependency paths with
filepath.Abs(dep.Path) which anchors relative paths to the process CWD and
treats an empty Path as the CWD; change this to resolve dep.Path against the
same base used by the changed-files index (pass gitRepoRoot into the routine or
use atmosConfig.BasePath) instead of calling filepath.Abs directly, and
validate/reject empty dep.Path before building pathPattern (so you don't
collapse to CWD); update references around dep.Path, the filepath.Abs call, and
pathPattern construction to use the chosen base and add a guard for empty paths.
In `@internal/exec/describe_dependents.go`:
- Around line 205-208: The current dependent-matching logic only compares
component names (e.g., stackComponentName vs args.Component) and relies on
isDependencyMatch() which ignores target kind; update the flow to carry the
provided component type (args.Kind or similar) through the path and use it when
skipping and when calling isDependencyMatch(): when reading dependsOn entries
treat empty dependsOn.Kind as the declaring component's kind (default to the
current stack/component kind), and ensure you compare both name and resolved
kind before skipping a "self" match (replace the simple stackComponentName ==
args.Component check) and before treating a dependency as matching; update
references in describe_dependents.go functions that use stackComponentName,
args.Component, isDependencyMatch(), and dependsOn.Kind (affecting the matching
blocks around those areas) to enforce kind-aware matching.
- Around line 260-305: The loop that builds and appends a dependent (creating
variable dependent and calling
BuildSpaceliftStackNameFromComponentConfig/BuildAtlantisProjectNameFromComponentConfig)
continues scanning after appending, causing duplicate dependents; after
appending to the dependents slice add a break to stop scanning further matches
for that dependency (i.e., exit the current dependency-matching loop immediately
after dependents = append(dependents, dependent)) so each dependent is emitted
only once.
---
Nitpick comments:
In
`@tests/fixtures/scenarios/dependencies-components-inheritance/components/terraform/mock/main.tf`:
- Around line 1-5: The test fixture's variable "enabled" is fine but could be
clearer by adding a description; open the Terraform mock file and update the
variable "enabled" block to include a description attribute (e.g., description =
"Enable mock component for dependency tests") so the variable declaration
(variable "enabled") documents its intent while keeping default and type
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 442dcd62-6b59-4cfa-b8e9-b06a2da3bb74
📒 Files selected for processing (29)
docs/prd/component-dependencies.mddocs/prd/tool-dependencies-integration.mdinternal/exec/describe_affected_components.gointernal/exec/describe_affected_optimizations_test.gointernal/exec/describe_affected_utils_2_test.gointernal/exec/describe_affected_utils_optimized.gointernal/exec/describe_dependents.gointernal/exec/describe_dependents_test.gopkg/schema/dependencies.gotests/fixtures/scenarios/dependencies-components-inheritance-append/atmos.yamltests/fixtures/scenarios/dependencies-components-inheritance-append/components/terraform/mock/main.tftests/fixtures/scenarios/dependencies-components-inheritance-append/stacks/catalog/base.yamltests/fixtures/scenarios/dependencies-components-inheritance-append/stacks/deploy/dev.yamltests/fixtures/scenarios/dependencies-components-inheritance/atmos.yamltests/fixtures/scenarios/dependencies-components-inheritance/components/terraform/mock/main.tftests/fixtures/scenarios/dependencies-components-inheritance/stacks/catalog/base.yamltests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yamlwebsite/blog/2026-01-02-dependencies-components.mdxwebsite/docs/cli/commands/toolchain/registry/_category_.jsonwebsite/docs/deploy/deploy.mdxwebsite/docs/learn/next-steps.mdxwebsite/docs/stacks/dependencies/_category_.jsonwebsite/docs/stacks/dependencies/components.mdxwebsite/docs/stacks/dependencies/index.mdxwebsite/docs/stacks/settings/depends_on.mdxwebsite/docs/stacks/settings/index.mdxwebsite/docs/stacks/stacks.mdxwebsite/docusaurus.config.jswebsite/src/data/roadmap.js
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2193 +/- ##
==========================================
+ Coverage 77.35% 77.40% +0.05%
==========================================
Files 961 962 +1
Lines 91169 91239 +70
==========================================
+ Hits 70524 70627 +103
+ Misses 16564 16536 -28
+ Partials 4081 4076 -5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Fix else-if bug in legacy dependency conversion that dropped folder entries when both file and folder were present. Correct documentation to reflect replace merge as default behavior (not append). Update PRD links to be repo-resolvable, fix legacy field names (stage→stack), and update blog post date. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
website/docs/stacks/dependencies/index.mdx (1)
259-263:⚠️ Potential issue | 🟡 MinorDisambiguate the two “Component Dependencies” links in Related Documentation.
Both entries use the same title but point to different pages (new vs legacy), which is easy to misread.
Suggested fix
- [Component Dependencies](/stacks/dependencies/components) - Detailed component dependency configuration - [Toolchain Management](/cli/commands/toolchain/usage) - Installing and managing CLI tools - [Toolchain Configuration](/cli/configuration/toolchain/) - Configuring toolchain behavior -- [Component Dependencies](/stacks/settings/depends_on) - Configure dependencies between components +- [Legacy `settings.depends_on`](/stacks/settings/depends_on) - Configure dependencies between components (legacy format) - [YAML Functions](/functions/yaml) - Using `!terraform.output` and other functions for cross-component dependenciesAs per coding guidelines, “Keep CLI documentation and website documentation in sync and document new features on the website with examples and use cases.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/docs/stacks/dependencies/index.mdx` around lines 259 - 263, Two identical link labels "[Component Dependencies]" in the Related Documentation section are ambiguous; change the link text to disambiguate the two targets—e.g., rename the first "[Component Dependencies](/stacks/dependencies/components)" to "Component Dependencies (new components)" or "Component Dependencies — Components" and rename the second "[Component Dependencies](/stacks/settings/depends_on)" to "Component Dependencies (legacy/settings)" or "Component Dependencies — Settings/depends_on" so readers can tell them apart while leaving the hrefs unchanged; update only the link labels in the file index.mdx where the two duplicate "[Component Dependencies]" entries appear.internal/exec/describe_affected_components.go (1)
190-199:⚠️ Potential issue | 🟠 Major
dependencies.componentschecks are skipped whensettingsis missing.In these blocks, dependency processing only runs inside
if settingsSection .... Components that definedependencies.componentsbut have nosettingsblock will never run file/folder dependency checks, sodescribe affectedcan miss valid changes.Suggested fix
@@ - if settingsSection, ok := componentSection[cfg.SettingsSectionName].(map[string]any); ok { - err := checkSettingsAndDependenciesIndexed( - &affected, atmosConfig, componentName, stackName, cfg.TerraformComponentType, - &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, - includeSpaceliftAdminStacks, includeSettings, - ) - if err != nil { - return nil, err - } - } + settingsSection, _ := componentSection[cfg.SettingsSectionName].(map[string]any) + err := checkSettingsAndDependenciesIndexed( + &affected, atmosConfig, componentName, stackName, cfg.TerraformComponentType, + &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, + includeSpaceliftAdminStacks, includeSettings, + ) + if err != nil { + return nil, err + } @@ - if settingsSection, ok := componentSection[cfg.SettingsSectionName].(map[string]any); ok { - err := checkSettingsAndDependenciesIndexed( - &affected, atmosConfig, componentName, stackName, cfg.HelmfileComponentType, - &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, - includeSpaceliftAdminStacks, includeSettings, - ) - if err != nil { - return nil, err - } - } + settingsSection, _ := componentSection[cfg.SettingsSectionName].(map[string]any) + err := checkSettingsAndDependenciesIndexed( + &affected, atmosConfig, componentName, stackName, cfg.HelmfileComponentType, + &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, + includeSpaceliftAdminStacks, includeSettings, + ) + if err != nil { + return nil, err + } @@ - if settingsSection, ok := componentSection[cfg.SettingsSectionName].(map[string]any); ok { - err := checkSettingsAndDependenciesIndexed( - &affected, atmosConfig, componentName, stackName, cfg.PackerComponentType, - &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, - includeSpaceliftAdminStacks, includeSettings, - ) - if err != nil { - return nil, err - } - } + settingsSection, _ := componentSection[cfg.SettingsSectionName].(map[string]any) + err := checkSettingsAndDependenciesIndexed( + &affected, atmosConfig, componentName, stackName, cfg.PackerComponentType, + &componentSection, settingsSection, remoteStacks, currentStacks, filesIndex, + includeSpaceliftAdminStacks, includeSettings, + ) + if err != nil { + return nil, err + } @@ func checkSettingsAndDependenciesIndexed( @@ ) error { // Check settings section changes. - if !isEqual(remoteStacks, stackName, componentType, componentName, settingsSection, cfg.SettingsSectionName) { + if settingsSection != nil && !isEqual(remoteStacks, stackName, componentType, componentName, settingsSection, cfg.SettingsSectionName) { err := addAffectedComponent(affected, atmosConfig, componentName, stackName, componentType, componentSection, affectedReasonStackSettings, includeSpaceliftAdminStacks, currentStacks, includeSettings) if err != nil { return err }Also applies to: 300-309, 410-419
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_affected_components.go` around lines 190 - 199, The dependency checks are only executed when a settings block exists because the call to checkSettingsAndDependenciesIndexed is nested under if settingsSection ...; update the logic so dependency processing runs even when settings is absent: extract the dependencies map (dependencies.components) from componentSection and call the dependency-checking routine (reuse or refactor checkSettingsAndDependenciesIndexed into a separate function for pure dependency checks, or call it with a nil/empty settingsSection) for componentName/stackName/ cfg.TerraformComponentType using remoteStacks/currentStacks/filesIndex/includeSpaceliftAdminStacks/includeSettings as before; apply the same change to the other analogous blocks that call checkSettingsAndDependenciesIndexed so components without settings still get their file/folder dependency checks.
♻️ Duplicate comments (1)
tests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml (1)
20-20:⚠️ Potential issue | 🟡 MinorUpdate Line 20 comment to match replace behavior.
Line 20 still says VPC “inherits … AND adds,” which contradicts the replace semantics documented in this scenario.
Suggested wording fix
- # VPC inherits base dependencies AND adds its own. + # VPC defines its own dependencies; parent entries are replaced.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml` at line 20, Update the comment on Line 20 referencing "VPC inherits base dependencies AND adds its own" to reflect the replace semantics for this scenario: change the wording to state that the VPC replaces the base dependencies (does not inherit them) and specify any VPC-specific dependencies it defines, e.g., "VPC replaces base dependencies with its own" or "VPC uses replace semantics — it does not inherit base dependencies; it defines its own." Ensure the comment mentions "replace semantics" and "VPC" so readers understand the behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/prd/component-dependencies.md`:
- Around line 167-181: The helper methods IsFileDependency, IsFolderDependency,
and IsComponentDependency are declared with value receivers but the
ComponentDependency type uses pointer receivers elsewhere; change each method
signature to use a pointer receiver (e.g., func (d *ComponentDependency)
IsFileDependency() bool etc.) so the receivers match the implementations and
calls that expect pointer semantics, keeping the method bodies unchanged.
- Around line 134-135: The sentence incorrectly ties the append merge behavior
of dependencies.components to list_merge_strategy: append; update the wording so
it states that dependencies.components uses append-merge by design (child stacks
add their dependencies to parent dependencies) regardless of list_merge_strategy
in atmos.yaml, and remove or rephrase any implication that list_merge_strategy
controls this behavior; reference symbols: dependencies.components,
list_merge_strategy, atmos.yaml, and ensure the doc explains that this
dependency-merge semantics is intentional and documented elsewhere in the PR.
---
Outside diff comments:
In `@internal/exec/describe_affected_components.go`:
- Around line 190-199: The dependency checks are only executed when a settings
block exists because the call to checkSettingsAndDependenciesIndexed is nested
under if settingsSection ...; update the logic so dependency processing runs
even when settings is absent: extract the dependencies map
(dependencies.components) from componentSection and call the dependency-checking
routine (reuse or refactor checkSettingsAndDependenciesIndexed into a separate
function for pure dependency checks, or call it with a nil/empty
settingsSection) for componentName/stackName/ cfg.TerraformComponentType using
remoteStacks/currentStacks/filesIndex/includeSpaceliftAdminStacks/includeSettings
as before; apply the same change to the other analogous blocks that call
checkSettingsAndDependenciesIndexed so components without settings still get
their file/folder dependency checks.
In `@website/docs/stacks/dependencies/index.mdx`:
- Around line 259-263: Two identical link labels "[Component Dependencies]" in
the Related Documentation section are ambiguous; change the link text to
disambiguate the two targets—e.g., rename the first "[Component
Dependencies](/stacks/dependencies/components)" to "Component Dependencies (new
components)" or "Component Dependencies — Components" and rename the second
"[Component Dependencies](/stacks/settings/depends_on)" to "Component
Dependencies (legacy/settings)" or "Component Dependencies —
Settings/depends_on" so readers can tell them apart while leaving the hrefs
unchanged; update only the link labels in the file index.mdx where the two
duplicate "[Component Dependencies]" entries appear.
---
Duplicate comments:
In
`@tests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml`:
- Line 20: Update the comment on Line 20 referencing "VPC inherits base
dependencies AND adds its own" to reflect the replace semantics for this
scenario: change the wording to state that the VPC replaces the base
dependencies (does not inherit them) and specify any VPC-specific dependencies
it defines, e.g., "VPC replaces base dependencies with its own" or "VPC uses
replace semantics — it does not inherit base dependencies; it defines its own."
Ensure the comment mentions "replace semantics" and "VPC" so readers understand
the behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5698cd83-17f2-4194-be7f-b1908e706225
📒 Files selected for processing (10)
docs/prd/component-dependencies.mddocs/prd/tool-dependencies-integration.mdinternal/exec/describe_affected_components.gotests/fixtures/scenarios/dependencies-components-inheritance/stacks/catalog/base.yamltests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yamlwebsite/blog/2026-03-14-dependencies-components.mdxwebsite/docs/stacks/dependencies/components.mdxwebsite/docs/stacks/dependencies/index.mdxwebsite/docs/stacks/settings/depends_on.mdxwebsite/docs/stacks/settings/index.mdx
✅ Files skipped from review due to trivial changes (1)
- website/blog/2026-03-14-dependencies-components.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/fixtures/scenarios/dependencies-components-inheritance/stacks/catalog/base.yaml
… dependencies Fix fixture comment to match replace merge semantics, fix PRD pointer receiver signatures, and add comprehensive tests for dependency matching, context conversion, and file/folder change detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add helmfile component (nginx) that depends on terraform VPC to test
cross-type dependency resolution. Add eks component with templated
stack reference ({{ .vars.stage }}) to test Go template evaluation
in dependency declarations. Both paths are now covered by the
DependenciesComponentsFormat integration test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
docs/prd/component-dependencies.md (1)
134-135:⚠️ Potential issue | 🟡 MinorMerge semantics wording is currently incorrect.
Line 134 ties append behavior to
list_merge_strategy: append, but this feature is documented and implemented as append-merge by design fordependencies.components. Please remove the conditional wording so users don’t misconfigure inheritance behavior.Suggested doc fix
-`dependencies.components` uses **append merge** behavior when `list_merge_strategy: append` is configured in `atmos.yaml`. Child stacks add their dependencies to parent dependencies. +`dependencies.components` uses **append merge** behavior by design. Child stacks add their dependencies to parent dependencies.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/prd/component-dependencies.md` around lines 134 - 135, The wording incorrectly ties append behavior of dependencies.components to the presence of list_merge_strategy: append; update the text so it states that dependencies.components uses append-merge by design (always inheriting child stack entries into parent) and remove the conditional/“when list_merge_strategy: append” phrasing; ensure references to dependencies.components and list_merge_strategy: append remain for context but do not imply that the append-merge behavior is configurable.
🧹 Nitpick comments (4)
internal/exec/describe_affected_utils_2_test.go (1)
720-725: Tighten unchanged-path assertions to prevent metadata leakage.When
expectChangedis false, also assert emptychangedTypeandchangedPath. This catches regressions where the function reports stale match metadata even when no change is detected.Proposed test hardening
require.NoError(t, err) assert.Equal(t, tt.expectChanged, changed) if tt.expectChanged { assert.Equal(t, tt.expectChangedType, changedType) assert.Equal(t, tt.expectChangedPath, changedPath) + } else { + assert.Empty(t, changedType) + assert.Empty(t, changedPath) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_affected_utils_2_test.go` around lines 720 - 725, Tighten the test assertions in internal/exec/describe_affected_utils_2_test.go so that when tt.expectChanged is false you also assert that changedType and changedPath are empty; in the existing block that checks require.NoError(t, err) and assert.Equal(t, tt.expectChanged, changed), add assertions for empty strings (or nil/zero values as appropriate) for changedType and changedPath to ensure no stale match metadata is returned by the function under test.pkg/schema/dependencies_test.go (2)
100-104: Coverpluginkind inIsComponentDependencytests.The PR adds cross-type support including plugin dependencies; this path should be asserted here too.
Diff suggestion
{ name: "packer kind returns true", dep: ComponentDependency{Kind: "packer", Component: "ami"}, expected: true, }, + { + name: "plugin kind returns true", + dep: ComponentDependency{Kind: "plugin", Component: "custom"}, + expected: true, + }, { name: "file kind returns false", dep: ComponentDependency{Kind: "file", Path: "config.json"}, expected: false, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/schema/dependencies_test.go` around lines 100 - 104, Add a test case covering plugin-kind dependencies in the existing IsComponentDependency tests: in pkg/schema/dependencies_test.go add an entry similar to the existing "packer kind returns true" case but with dep: ComponentDependency{Kind: "plugin", Component: "some-plugin"} and expected: true so that IsComponentDependency (and the ComponentDependency type) is asserted to return true for Kind == "plugin".
15-35: Add empty-path boundary cases forfileandfolderkinds.Right now, all
file/folderscenarios include a populated path. Add empty-path cases to lock down classifier behavior for malformed entries.As per coding guidelines "Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages."Diff suggestion
func TestComponentDependency_IsFileDependency(t *testing.T) { tests := []struct { name string dep ComponentDependency expected bool }{ { name: "file kind returns true", dep: ComponentDependency{Kind: "file", Path: "config.json"}, expected: true, }, + { + name: "file kind without path returns false", + dep: ComponentDependency{Kind: "file"}, + expected: false, + }, { name: "folder kind returns false", dep: ComponentDependency{Kind: "folder", Path: "src/"}, expected: false, }, @@ func TestComponentDependency_IsFolderDependency(t *testing.T) { tests := []struct { name string dep ComponentDependency expected bool }{ { name: "folder kind returns true", dep: ComponentDependency{Kind: "folder", Path: "src/lambda"}, expected: true, }, + { + name: "folder kind without path returns false", + dep: ComponentDependency{Kind: "folder"}, + expected: false, + }, { name: "file kind returns false", dep: ComponentDependency{Kind: "file", Path: "config.json"}, expected: false, },Also applies to: 50-70
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/schema/dependencies_test.go` around lines 15 - 35, Add boundary unit tests for empty Path values: in the existing test table (in pkg/schema/dependencies_test.go) add two cases using the ComponentDependency struct — one with Kind: "file" and Path: "" and one with Kind: "folder" and Path: "" — and assert the classifier returns false for both; ensure these entries follow the same table-driven format as the other cases so they exercise the file/folder validation logic in the same test function.internal/exec/describe_dependents_test.go (1)
140-160: File/folder Kind coverage is good; consider adding cross-type Kind test.The unit test covers
kind: "file"andkind: "folder"well. Per PR objectives,kindalso enables cross-type dependencies (e.g.,kind: "helmfile"). While the integration test at line 1027 validates this via fixtures, adding a unit test case here would directly verifygetComponentDependenciesparsing for cross-type kinds.Example addition:
map[string]any{"component": "chart", "kind": "helmfile"},This is optional since integration tests do cover the behavior.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/exec/describe_dependents_test.go` around lines 140 - 160, Add a unit subcase to the test that ensures getComponentDependencies parses cross-type kinds: extend the componentMap in the t.Run block to include an entry like map[string]any{"component":"chart","kind":"helmfile"}, call getComponentDependencies (same as existing), assert source equals dependencySourceDependenciesComponents, then assert the returned deps includes an entry with Component=="chart" and Kind=="helmfile" (and any relevant Path if applicable); this verifies the parser handles non-file/folder kinds alongside existing vpc/file/folder assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/prd/component-dependencies.md`:
- Line 198: Update the numbered list item text "3. Supports legacy
`file`/`folder` fields for backward compatibility" to include a trailing period
so it reads "3. Supports legacy `file`/`folder` fields for backward
compatibility." — edit the line in docs/prd/component-dependencies.md where that
exact list item appears.
---
Duplicate comments:
In `@docs/prd/component-dependencies.md`:
- Around line 134-135: The wording incorrectly ties append behavior of
dependencies.components to the presence of list_merge_strategy: append; update
the text so it states that dependencies.components uses append-merge by design
(always inheriting child stack entries into parent) and remove the
conditional/“when list_merge_strategy: append” phrasing; ensure references to
dependencies.components and list_merge_strategy: append remain for context but
do not imply that the append-merge behavior is configurable.
---
Nitpick comments:
In `@internal/exec/describe_affected_utils_2_test.go`:
- Around line 720-725: Tighten the test assertions in
internal/exec/describe_affected_utils_2_test.go so that when tt.expectChanged is
false you also assert that changedType and changedPath are empty; in the
existing block that checks require.NoError(t, err) and assert.Equal(t,
tt.expectChanged, changed), add assertions for empty strings (or nil/zero values
as appropriate) for changedType and changedPath to ensure no stale match
metadata is returned by the function under test.
In `@internal/exec/describe_dependents_test.go`:
- Around line 140-160: Add a unit subcase to the test that ensures
getComponentDependencies parses cross-type kinds: extend the componentMap in the
t.Run block to include an entry like
map[string]any{"component":"chart","kind":"helmfile"}, call
getComponentDependencies (same as existing), assert source equals
dependencySourceDependenciesComponents, then assert the returned deps includes
an entry with Component=="chart" and Kind=="helmfile" (and any relevant Path if
applicable); this verifies the parser handles non-file/folder kinds alongside
existing vpc/file/folder assertions.
In `@pkg/schema/dependencies_test.go`:
- Around line 100-104: Add a test case covering plugin-kind dependencies in the
existing IsComponentDependency tests: in pkg/schema/dependencies_test.go add an
entry similar to the existing "packer kind returns true" case but with dep:
ComponentDependency{Kind: "plugin", Component: "some-plugin"} and expected: true
so that IsComponentDependency (and the ComponentDependency type) is asserted to
return true for Kind == "plugin".
- Around line 15-35: Add boundary unit tests for empty Path values: in the
existing test table (in pkg/schema/dependencies_test.go) add two cases using the
ComponentDependency struct — one with Kind: "file" and Path: "" and one with
Kind: "folder" and Path: "" — and assert the classifier returns false for both;
ensure these entries follow the same table-driven format as the other cases so
they exercise the file/folder validation logic in the same test function.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6fb8567c-c1e3-4bd0-b657-7e9a24bf77a4
📒 Files selected for processing (7)
docs/prd/component-dependencies.mdinternal/exec/describe_affected_utils_2_test.gointernal/exec/describe_dependents_test.gopkg/schema/dependencies_test.gotests/fixtures/scenarios/dependencies-components-inheritance/atmos.yamltests/fixtures/scenarios/dependencies-components-inheritance/components/helmfile/mock/helmfile.yamltests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml
✅ Files skipped from review due to trivial changes (1)
- tests/fixtures/scenarios/dependencies-components-inheritance/components/helmfile/mock/helmfile.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/fixtures/scenarios/dependencies-components-inheritance/stacks/deploy/dev.yaml
Add plugin kind test case, empty-path boundary cases for file/folder classifiers, cross-type helmfile kind unit test for getComponentDependencies, tighten empty-deps metadata assertions, and fix PRD terminal punctuation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Warning Release Documentation RequiredThis PR is labeled
|
|
These changes were released in v1.210.0-rc.0. |
|
These changes were released in v1.210.0-test.25. |
…tion guide Step 3 of the migration workflow still mapped mock_outputs to the YQ // "default" pattern, contradicting the mocks:/--use-mocks mapping documented a few paragraphs earlier. Quotes the YQ default expressions for consistency with atmos-yaml-functions/SKILL.md and atmos-components/SKILL.md. dag-concurrent-execution.md had two more self-contradictions: the Subprocess Execution section still described the os.Stdout race that Phase 1 already fixed (terraform_plan_diff.go now captures via bytes.Buffer), and the Resolved Questions section claimed cross-type dependency syntax was "solved by PR #2193" — traced the code and found pkg/scheduler/adapters/terraform.go explicitly skips any dependency whose kind isn't "terraform", so the kind field is schema-parseable but not yet consumed by the scheduler; corrected to match the already-accurate Phase 3 status. terragrunt.mdx's list-affected example claimed to compare against main by default without passing --ref; list affected has no --base flag (unlike describe affected), so made the comparison explicit with --ref main instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…dposse#2878) * docs(prd): correct stale status headers found during Terragrunt migration research Checkpoint before syncing this branch with origin/main — these fixes were made against an older snapshot and will likely need rework once current upstream content is merged in. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(migration): add Terragrunt migration skill reference and correct stale PRD statuses Adds the atmos-migration skill's Terragrunt reference (classic and Stacks patterns, concept mapping, migration workflow), hands-on-validated against a real Terragrunt Stacks example run end to end on the floci/aws emulator. Corrects four PRD status headers that had gone stale relative to shipped code, fixes pre-existing EditorConfig indentation violations the commit hook surfaced in two of those files, and documents the mocks/--use-mocks feature in the website Terragrunt migration guide as the direct equivalent of mock_outputs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(docs): use clean !terraform.state syntax and fix EditorConfig indentation CI caught two real issues in the new Terragrunt migration reference: - Two examples used the legacy doubled-double-quote YQ escaping (!terraform.state x ".field // ""default""") instead of the clean current syntax (!terraform.state x .field // "default"), which scripts/check- terraform-example-syntax.sh flags outside its designated compatibility fixtures. - The "Migration Workflow" numbered list used 3-space continuation indentation, not a multiple of the repo's 2-space EditorConfig setting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(docs): address CodeRabbit findings and field-test gaps on Terragrunt migration guide Reconciles PRD status claims that contradicted themselves (dag-concurrent-execution.md Phase 3 is only partially shipped, not fully; custom-hooks.md's relative "today" date), completes the from-terragrunt.md 5-level merge listing, and fixes a hallucinated `settings.terraform.provider_overrides` key found via hands-on field testing. Also recommends `atmos list affected` over `atmos describe affected` for human-run migration comparisons (table output vs. a wall of YAML), notes both diff committed trees only, and updates the Change Tracking table to the current `dependencies.files`/`folders` syntax instead of the legacy inline `kind: file`/`kind: folder` form. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(docs): resolve second CodeRabbit review round on Terragrunt migration guide Step 3 of the migration workflow still mapped mock_outputs to the YQ // "default" pattern, contradicting the mocks:/--use-mocks mapping documented a few paragraphs earlier. Quotes the YQ default expressions for consistency with atmos-yaml-functions/SKILL.md and atmos-components/SKILL.md. dag-concurrent-execution.md had two more self-contradictions: the Subprocess Execution section still described the os.Stdout race that Phase 1 already fixed (terraform_plan_diff.go now captures via bytes.Buffer), and the Resolved Questions section claimed cross-type dependency syntax was "solved by PR cloudposse#2193" — traced the code and found pkg/scheduler/adapters/terraform.go explicitly skips any dependency whose kind isn't "terraform", so the kind field is schema-parseable but not yet consumed by the scheduler; corrected to match the already-accurate Phase 3 status. terragrunt.mdx's list-affected example claimed to compare against main by default without passing --ref; list affected has no --base flag (unlike describe affected), so made the comparison explicit with --ref main instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore: trigger CI re-run * fix(mocks): correct provenance rendering, error wording, and // default parity A field test of --use-mocks found `describe component` silently rendering empty output whenever a component's provenance path wasn't matched due to an unnormalized lookup, a mock-output error that mislabeled the output name as a component name, and a YQ `//` default that only rescued a missing key inside a declared `mocks` map, not a component with no `mocks` section at all -- inconsistent with how `//` already rescues real state. Also cross-references the mocks:/--use-mocks feature from the docs pages and skill most likely to be read first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * test(snapshots): regenerate describe_component golden snapshots after provenance fix The filterEmptySections fix (6c22503) corrected describe_component to stop silently dropping real sections (backend, metadata, env, overrides) that lack a stack-root section of the same name. CI caught the resulting golden snapshot drift on both linux and macos; regenerated via `-regenerate-snapshots` per CLAUDE.md, verified the diffs only add the previously-hidden, now-correct content. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(provenance): address CodeRabbit review on PR cloudposse#2878 Add periods to the rendering-constant comments (godot's inline-comment scope missed these, but CLAUDE.md's comment convention still applies), and cover the array-element provenance path (vars[0].foo) alongside the already-tested dot-nested form. The trailing-period finding on ErrTerraformMockOutputNotDeclared was already resolved by an earlier commit in this PR — no change needed there. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(test): widen RunSession timeouts to fix Windows CI flake Acceptance Tests (windows, shard 4/10) failed with ErrWaitTimeout in TestRunSessionExecutesScriptedShellActions and TestRunSessionAppliesDirectoryAndEnvironment: the write->echo->match round trip against a spawned child (no PTY on Windows, unlike session_unix.go) never completed within the 2s wait/3s context budget. Widened both to 8s/15s across all four RunSession-based tests; no production code changed since static review found no concrete pipe-wiring bug. Not reproduced locally (no Windows environment available) — documented in docs/fixes/ per this repo's convention for unconfirmed Windows-only CI fixes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(fixes): address CodeRabbit findings on PR cloudposse#2878 - Add a text language tag to the failure-output fenced block (markdownlint MD040). - Correct the documented timeout values to match what actually shipped after merge-conflict resolution: 10s per wait (not 8s), and 25s outer context for TestRunSessionAppliesDirectoryAndEnvironment's two sequential waits (not 15s) — the outer context must exceed the sum of sequential wait timeouts, not just one of them, per waitForOutput's ctx.Done()-vs-deadline-timer race. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(fixes): document CI exit-code test failure as a registry network flake Acceptance Tests (linux, shard 9/10) failed TestCLICommands/atmos_exit_code_should_be_same_as_command_exit_code_(2) with "Expected exit code 2, got 1". The real cause was tofu init timing out reaching registry.opentofu.org (context deadline exceeded) before any plan could run -- confirmed the fixture has no registry-mirror config to regress, and the sibling (0)/(1) exit-code cases in the same file passed. No code change: there's nothing in this repo that fixes a transient outage on a public third-party registry, and loosening the exit-code assertion would mask a real CLI exit-code-propagation regression if one ever occurs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(ci): don't fail test-required/k3s-required on a cancelled run All five attached failure logs (Acceptance Tests linux/macos/windows, [k3s] demo-helmfile, Build windows) traced to one event: workflow run 33394180592 on this PR was cancelled (confirmed via gh api), not failed. The test/k3s matrix jobs were skipped as a result, but the -required gate jobs (if: always()) still ran and misreported the cancellation as a hard failure ("expected 10 shard jobs, found 0" / "k3s matrix result was 'skipped'"). needs.test.result and needs.k3s.result both report "skipped" for a genuine upstream failure and for a whole-run cancellation alike, so they can't distinguish the two - cancelled() can, and is the fix. It's only valid in an if:, not inside a run: script (caught by actionlint), so both gates get a "Skip verification" step under if: cancelled() plus if: !cancelled() on their existing check steps, leaving the fail-loudly-on-genuine-anomalies logic untouched for real failures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * [autocommit] formatting fixes * fix(ci): pin cuelang.org/go's NOTICE URL to a deterministic override Review Dependency Licenses failed: NOTICE had "URL: Unknown" for cuelang.org/go, but a fresh generate-notice.sh run resolved a real URL, tripping the out-of-date check. Root cause was a race, not one bad run: this branch's merge commit already had the correct URL, but a subsequent [autocommit] formatting fixes commit (atmos-pro[bot]) regenerated NOTICE under a network condition where go-licenses' live resolution for cuelang.org/go failed, silently reverting it to "Unknown" and committing that regression - exactly the oscillation scripts/generate-notice.sh's REPO_OVERRIDES mechanism exists to prevent for modules go-licenses can't resolve reliably, cuelang.org/go just wasn't in the list yet. Added it (repo github.com/cue-lang/cue, no tag prefix, LICENSE path), which reconstructs the exact URL CI itself resolved (https://github.com/cue-lang/cue/blob/v0.16.1/LICENSE) from go.mod's pinned v0.16.1 with no network dependency, and applied that one-line NOTICE fix by hand: a local generate-notice.sh run silently produced a truncated 102-dependency report (vs. CI's 643) with 0 Apache-2.0/BSD licenses found, consistent with this machine lacking a Linux-targeting C cross-compiler for CGO_ENABLED=1 GOOS=linux GOARCH=amd64 - so that broken local output was discarded rather than committed, and the NOTICE line was hand-verified against the override's own URL-construction formula and go.mod's version instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(ci): retry go install go-licenses on transient sum.golang.org failures Review Dependency Licenses failed installing go-licenses@v1.6.0: a mid-stream HTTP/2 reset (stream ID 1155; INTERNAL_ERROR) reading sum.golang.org during go install's go.sum verification, unrelated to any actual dependency problem and unrelated to the immediately preceding commit on this branch (confirmed via gh api against head_sha 5ac5d97, which only touched an unrelated NOTICE URL override). Same failure class already fixed once for go mod download (docs/fixes/2026-08-25-build-atmos-go-mod-download-retry.md, later ported to magefiles/build.go's runGoModDownload) - just hit a different network call (go install's dependency-graph resolution) in a different script. Wrapped generate-notice.sh's bare go install in the same 3-attempt/15s-backoff until loop, matching .github/actions/download-artifact-retry's convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(docs): replace a literal tab with spaces in a fix-log fenced block Run pre-commit hooks failed atmos-validate-editorconfig: a fenced code block in docs/fixes/2026-08-31-notice-go-licenses-install-retry.md quoted a Go toolchain error message verbatim, including its original tab-indented continuation line - violating this repo's *.md indent_style=space rule. Replaced the literal tab with two spaces (matching indent_size=2), content otherwise unchanged. Scanned every other 2026-08-31 fix-log doc added this session for the same issue; none found. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(blog): bump terraform-component-mocks date to when its content changed fix(mocks) commit 6c22503 edited this post's body (the // default behavior clarification) on 2026-08-06, but the post kept displaying/sorting under its original 2026-07-15 publish date since Docusaurus has no separate date. Added an explicit date: frontmatter override for the edit date, matching this repo's existing convention for date overrides (e.g. 2026-01-02-unified-task-runner.mdx). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(security): remediate 4 Dependabot alerts - google.golang.org/grpc v1.82.1 -> v1.83.1 (go get + go mod tidy), bumping compatible transitive deps - website pnpm overrides: browserslist -> ^4.28.7, postcss-selector-parser (^6.0.11 and ^6.0.16 requesters) -> ^6.1.3 - regenerate NOTICE to reflect the grpc bump Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(fixes): document atmos_vendor_pull DNS-resolution CI flake Acceptance Tests (macos, shard 4/10) failed with "tty did not match pattern \"Vendored 3 components\"" because git itself could not resolve github.com on the runner (OS-level resolver failure, corroborated by the same job's Harden Runner network log) -- not a code regression. No code change; re-running the job is expected to pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: address CodeRabbit review findings on mocks docs, fix-logs, and noticegen tests - agent-skills/skills/atmos-migration/references/from-terragrunt.md: correct the mock_outputs -> mocks migration guidance -- Terragrunt scopes mock_outputs per dependency consumer, Atmos scopes mocks per producer component (shared by every consumer). Document that a shared mock value only works when every consumer agrees on it, and that a genuinely different per-consumer value needs its own producer component instance. - docs/fixes/2026-08-31-notice-go-licenses-install-retry.md: the retry loop now lives in tools/noticegen/report.go's ensureGoLicenses (tested in tools/noticegen/report_test.go), not scripts/generate-notice.sh, which was deleted when the NOTICE generator was rewritten as a Go tool. Updated the title, Context, Changes, and Validation sections accordingly. - docs/fixes/2026-08-31-required-check-gates-fail-on-cancelled-run.md: reworded "passing (all-steps-skipped) job" to "a passing job whose verification steps are skipped" -- the explicit Skip verification step still runs, so the job isn't literally all-skipped. - tools/noticegen/report.go: extracted lookPathGoLicenses as a package-level var (previously a direct exec.LookPath call inside ensureGoLicenses) so tests can force the "not found" branch deterministically. - tools/noticegen/report_test.go: both retry tests now inject lookPathGoLicenses to return exec.ErrNotFound, instead of relying on the real PATH not already containing go-licenses -- which it may, e.g. from a prior local run, silently skipping runGoInstall and making the retry assertions vacuous. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: address CodeRabbit findings on SKILL.md link casing and vendor-pull fix-log wording - agent-skills/skills/atmos-migration/SKILL.md: lowercase the from-terragrunt.md reference link's display text to match the actual lowercase repo path and the style of the overview section's own link. - docs/fixes/2026-09-02-vendor-pull-dns-resolution-flake.md: correct the fixture description -- tests/fixtures/scenarios/vendor/vendor.yaml exercises a local file:// source and a git::https:// source, not an OCI source or a separate plain-HTTPS source. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(security): remediate 3 Dependabot/CodeQL alerts - golang.org/x/crypto v0.55.0 -> v0.56.0 (go get + go mod tidy), fixing two govulncheck alerts (GO-2026-6354, GO-2026-6355): a malicious SSH peer could deadlock a connection via crafted channel messages (golang.org/x/crypto/ssh). No direct callers in this repo beyond pkg/store/providers/github_actions_client.go; verified via go build and pkg/store/... tests. - website pnpm override: fast-uri@^3 -> ^3.1.6 (patched; published 10 days ago, clears this repo's 7-day minimum-release-age cooldown). - regenerate NOTICE to reflect the x/crypto bump. qs (Dependabot cloudposse#283/cloudposse#284, patched at 6.16.0) is intentionally NOT bumped: 6.16.0 was published 4 days ago, still inside website/.npmrc's 7-day minimum-release-age cooldown -- forcing it in via minimumReleaseAgeExclude would defeat the cooldown's purpose. Will pick it up once it clears. browserslist (cloudposse#281/cloudposse#282) and postcss-selector-parser (cloudposse#280) are already fixed on this branch from an earlier commit; GitHub just hasn't re-scanned yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(ci): whitelist go.googlesource.com/go.dev/pkg.go.dev for CodeQL Go jobs StepSecurity's blocked-call detections (analyzed via the stepsecurity MCP server) showed the analyze and govulncheck jobs' harden-runner egress policies blocking go.googlesource.com, go.dev, and pkg.go.dev during Go module/toolchain resolution -- both are trusted Go project domains (GOTOOLCHAIN auto-download and go-getter's git-host fallback path). go.googlesource.com was already allowed for govulncheck but missing from analyze; go.dev and pkg.go.dev were missing from both. Also removed a duplicate storage.googleapis.com entry in analyze's list. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: atmos-pro[bot] <173522224+atmos-pro[bot]@users.noreply.github.com> Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
what
dependencies.componentsformat in stack configurations for declaring explicit component dependenciesComponentDependencystruct withcomponent,stack,kind, andpathfieldskindfield)kind: file/kind: folder)describe dependentsanddescribe affectedcommands to resolve dependencies from the new formatdependencies.mdxintodependencies/directory with dedicated component dependencies pagewhy
settings.depends_onformat is limited: it uses a map with numeric keys, requires separate namespace/tenant/environment/stage fields instead of stack templates, and mixes file/folder tracking with component dependencieskind: file+pathvs legacyfilefield){{ .vars.tenant }}-{{ .vars.environment }}-prod) provide a more flexible and readable way to reference cross-stack dependenciesdependencies.components: [...]) is more intuitive than the map-basedsettings.depends_onformatsettings.depends_oncontinues to work for backward compatibilityreferences
docs/prd/component-dependencies.mdwebsite/blog/2026-01-02-dependencies-components.mdx/stacks/dependencies/componentsSummary by CodeRabbit
New Features
Documentation
Tests
Deprecation