Skip to content

docs(dependencies): document dependencies.components for describe affected - #2391

Merged
Andriy Knysh (aknysh) merged 12 commits into
mainfrom
osterman/describe-affected-deps
May 27, 2026
Merged

Andriy Knysh (aknysh) merged 12 commits into
mainfrom
osterman/describe-affected-deps

Conversation

@osterman

@osterman Erik Osterman (Cloud Posse) (osterman) commented May 5, 2026 •

Copy link
Copy Markdown
Member

what

  • Update atmos describe affected docs to lead with the new dependencies.components (kind: file|folder + path:) format for path-based dependencies; keep a short backward-compat note pointing to legacy settings.depends_on.
  • Convert the dependents example on the describe affected page from settings.depends_on to dependencies.components.
  • Correct the Merge Behavior section in stacks/dependencies/components.mdx: the default is replace, not append; append requires opting in via settings.list_merge_strategy: append. Add an "Opt-in append" subsection and link to the settings reference.
  • Add a migration callout under the schema in stacks/dependencies/components.mdx clarifying that namespace/tenant/environment/stage are not supported in the new format — use a templated stack: instead.
  • Rebalance stacks/dependencies/index.mdx so dependencies.tools and dependencies.components get equal billing in the intro, use cases, and component-dependencies subsection. Remove the duplicate Related Documentation entry and relabel the legacy link as "Legacy settings.depends_on". Add a link to atmos describe affected.
  • Extend the Atmos manifest JSON Schema (website/static/schemas/... and the matching test fixture) so dependencies.components is allowed and validates component, stack, kind, path. Previously rejected by additionalProperties: false.

why

  • The dedicated dependencies.components page existed, but the highest-traffic surface (describe affected) and the JSON Schema still only documented/allowed the legacy settings.depends_on map — driving users to the deprecated format and making the new format fail IDE/SchemaStore validation.
  • The merge-behavior description in stacks/dependencies/components.mdx contradicted the announcement blog and the actual code (internal/exec/describe_dependents_test.go:1093–1154 confirms default = replace, append is opt-in via settings.list_merge_strategy). Users following the docs would have built a wrong mental model of inheritance.
  • The migration story from settings.depends_on (with namespace/tenant/environment/stage) to dependencies.components (with templated stack:) was only discoverable via the migration table at the bottom of the page; surfacing it as a callout reduces confusion for users porting existing configs.

references

  • pkg/schema/dependencies.go — canonical field set for dependencies.components
  • internal/exec/describe_dependents_test.go:1093–1154 — confirms default merge is replace, append requires settings.list_merge_strategy: append
  • website/blog/2026-03-14-dependencies-components.mdx — original announcement
  • Verified: cd website && npm run build succeeds (no broken-link errors)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Dependencies now support four top-level kinds: tools, components, files, and folders. Component-to-component relationships and explicit file/folder watch paths are first-class; describe-affected, describe-dependents, and CI workflows use the expanded surface while legacy formats remain supported.
  • Documentation

    • Guides updated with examples, migration notes, canonical forms, merge semantics, and quick examples for cross-stack and path-based dependencies.
  • Tests

    • Added coverage for the new surfaces, aliasing, deduplication, normalization, and v1/v2 equivalence.

Review Change Stack

…ected

Update docs and JSON Schema to reflect the new `dependencies.components`
format used by `atmos describe affected`, `atmos describe dependents`,
and CI/CD integrations:

- describe-affected: lead with `dependencies.components` + `kind: file|folder`
  in the file/folder reference entries; convert the dependents example to the
  new format; keep a backward-compat note pointing to legacy `settings.depends_on`.
- dependencies/components: correct the Merge Behavior section (default is
  replace, not append; opt into append via `settings.list_merge_strategy`);
  add a migration callout clarifying that `namespace`/`tenant`/`environment`/
  `stage` are unsupported (use templated `stack`).
- dependencies/index: rebalance the intro so `dependencies.tools` and
  `dependencies.components` get equal billing; relabel the duplicate Related
  Documentation entry as Legacy `settings.depends_on`; link to describe affected.
- atmos-manifest schema (website + tests fixture): allow `dependencies.components`
  with `component`, `stack`, `kind`, `path` (was previously rejected by
  `additionalProperties: false`).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@atmos-pro

atmos-pro Bot commented May 5, 2026 •

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@github-actions github-actions Bot added the size/m Medium size PR label May 5, 2026
@osterman Erik Osterman (Cloud Posse) (osterman) added the no-release Do not create a new release (wait for additional code changes) label May 5, 2026
@github-actions

github-actions Bot commented May 5, 2026 •

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai

coderabbitai Bot commented May 5, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9cd36db9-d254-4272-bb78-eeefd3c01195

📥 Commits

Reviewing files that changed from the base of the PR and between c00b18a and 475f90b.

📒 Files selected for processing (3)
  • internal/exec/describe_dependents.go
  • internal/exec/describe_dependents_test.go
  • internal/exec/stack_processor_merge_test.go

📝 Walkthrough

Walkthrough

The PR expands the Atmos manifest dependencies into four sibling keys: tools, components, files, and folders; adds schema definitions and fixtures, extends the ComponentDependency model and normalization, updates parsing to handle v2 and legacy forms, adds tests, and revises docs and examples.

Changes

Dependencies schema, parsing, docs, and tests

Layer / File(s) Summary
Data Shape
tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
dependencies description updated and now exposes tools, components, files, and folders; added dependencies_components, dependencies_files, dependencies_folders, and dependencies_component_entry definitions.
Public static schema
website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
Static website schema updated to add dependencies_components, dependencies_component_entry, dependencies_files, and dependencies_folders with validation rules (name/component or legacy kind/path).
Docs, CLI, and PRD
website/docs/..., docs/prd/component-dependencies.md
Docs and CLI examples updated to describe four-key model, canonical and legacy formats, migration notes, merge semantics, and dependencies.files/folders usage.
Core Model & Validation
pkg/schema/dependencies.go, pkg/schema/dependencies_test.go
ComponentDependency gains Name alias; added sentinel errors ErrComponentDependencyNameConflict, ErrComponentDependencyMissingPath; helper methods IsFileDependency, IsFolderDependency, IsComponentDependency; Normalize logic and unit tests for aliasing, siblings mirroring, dedupe, and error cases.
Runtime Parsing / Helpers
internal/exec/describe_affected_components.go, internal/exec/describe_dependents.go
Parsing unified to decode schema.Dependencies, call Normalize(), filter component vs path entries, add getFileFolderDependenciesFromNewFormat, filterComponentDependencies, and hasDependencyEntries helpers; legacy settings.depends_on fallback retained.
Unit & Integration Tests
internal/exec/describe_affected_utils_2_test.go, internal/exec/describe_dependents_test.go, internal/exec/stack_processor_merge_test.go
Tests added/extended for dependencies.files/folders, name alias handling, v1/v2 equivalence, deduplication across inline+siblings, fallback behavior, and list merge semantics (replace vs append).

Sequence Diagram(s)

(Skipped.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • cloudposse/atmos#2193: Implements the same structured component dependencies (components + files/folders), normalization, and updates to describe logic and docs — directly related.

Suggested reviewers

  • aknysh
  • milldr
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: documenting dependencies.components for describe affected across documentation, schemas, and code updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch osterman/describe-affected-deps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
website/docs/stacks/dependencies/components.mdx (1)

339-344: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Merge behavior row is now inconsistent with the updated section above.

Line 342 still says dependencies.components uses append merge, but Line 160 now documents default replace (append is opt-in). Please align the table row to avoid contradictory guidance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/docs/stacks/dependencies/components.mdx` around lines 339 - 344,
Update the Merge behavior cell for `dependencies.components` in the table so it
matches the updated section above: change the current "Append (simple)" to
reflect the new default replace behavior with append as opt-in (e.g., "Default
replace (append opt-in)"). Edit the row that references
`dependencies.components` (the table header uses `settings.depends_on` vs
`dependencies.components`) so the Merge behavior entry is consistent with the
documentation text about default replace and optional append.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json`:
- Around line 1565-1588: The schema currently allows empty/invalid dependency
objects; update dependencies_component_entry to enforce valid shapes by
replacing the loose properties-only definition with a oneOf containing two
variants: (1) a "component dependency" schema that requires "component"
(string), allows optional "stack" and "kind", and explicitly forbids "kind"
being "file" or "folder" (use not + enum), and disallows "path"; and (2) a "path
dependency" schema that requires "path" (string) and requires "kind" to be one
of ["file","folder"], and disallows "component" and "stack"; keep
additionalProperties: false. Use the existing symbol names
dependencies_component_entry and property names component, stack, kind, path to
locate where to apply the change.

---

Outside diff comments:
In `@website/docs/stacks/dependencies/components.mdx`:
- Around line 339-344: Update the Merge behavior cell for
`dependencies.components` in the table so it matches the updated section above:
change the current "Append (simple)" to reflect the new default replace behavior
with append as opt-in (e.g., "Default replace (append opt-in)"). Edit the row
that references `dependencies.components` (the table header uses
`settings.depends_on` vs `dependencies.components`) so the Merge behavior entry
is consistent with the documentation text about default replace and optional
append.
🪄 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: a86437e3-0866-4792-bfea-d178aa16f6e9

📥 Commits

Reviewing files that changed from the base of the PR and between acc1016 and 2941eca.

📒 Files selected for processing (5)
  • tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
  • website/docs/cli/commands/describe/describe-affected.mdx
  • website/docs/stacks/dependencies/components.mdx
  • website/docs/stacks/dependencies/index.mdx
  • website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json

Comment thread website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
atmos-pro[bot]
atmos-pro Bot previously approved these changes May 5, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

Address CodeRabbit feedback: `dependencies_component_entry` previously allowed
empty objects and other invalid combinations. Add an `anyOf` constraint
requiring either:

- `component` (component-to-component dependency), or
- `kind: file|folder` + `path` (path-based dependency).

Validated against 10 positive/negative cases with `jsonschema` (Draft 2020-12);
matches the field semantics in `pkg/schema/dependencies.go`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 5, 2026
atmos-pro[bot]
atmos-pro Bot previously approved these changes May 5, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

@codecov

codecov Bot commented May 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.28571% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.58%. Comparing base (3bc31f2) to head (475f90b).

Files with missing lines Patch % Lines
internal/exec/describe_affected_components.go 0.00% 3 Missing and 4 partials ⚠️
internal/exec/describe_dependents.go 80.00% 3 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2391      +/-   ##
==========================================
+ Coverage   78.54%   78.58%   +0.03%     
==========================================
  Files        1144     1144              
  Lines      109879   109984     +105     
==========================================
+ Hits        86304    86426     +122     
+ Misses      18787    18763      -24     
- Partials     4788     4795       +7     
Flag Coverage Δ
unittests 78.58% <89.28%> (+0.03%) ⬆️

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

Files with missing lines Coverage Δ
pkg/schema/dependencies.go 100.00% <100.00%> (ø)
internal/exec/describe_dependents.go 92.78% <80.00%> (-1.13%) ⬇️
internal/exec/describe_affected_components.go 63.93% <0.00%> (-1.07%) ⬇️

... and 5 files with indirect coverage changes

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

… keys)

Reconciles design smells from the v1.210.0 dependencies.components shape
without breaking existing configurations:

- `name:` is now the canonical, preferred alias for `component:` inside
  `dependencies.components[]` entries.
- `dependencies.files` and `dependencies.folders` are new sibling keys
  for path-based dependencies, replacing the awkward inline
  `kind: file` / `kind: folder` entries inside `components[]`.

A new `Dependencies.Normalize()` method reconciles both surfaces into a
single internal representation: `name → component` alias resolution
(with conflict error), and bidirectional mirroring between the typed
`Files`/`Folders` slices and `Components[]` so downstream filters keep
working unchanged.

JSON manifest schemas, user docs, and the PRD are updated. Legacy
`kind: file/folder` and `component:` shapes still parse and behave
identically; docs mark them as legacy and point to the canonical
sibling keys.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (7)
pkg/schema/dependencies_test.go (2)

258-269: 💤 Low value

Optional: tighten this dedup test by also asserting on Components.

The current assertion only verifies d.Files is deduped, but the real risk is d.Components accumulating duplicate (kind, path) entries — see the related comment in pkg/schema/dependencies.go. An assertion here would catch any regression in the mirror step.

♻️ Suggested addition
 		require.NoError(t, d.Normalize())
 
 		// Files should appear exactly once in the typed view.
 		assert.Equal(t, []string{"configs/shared.json"}, d.Files)
+
+		// Components should also contain exactly one entry for the shared path,
+		// not one from the inline shape plus one mirrored from the sibling key.
+		fileEntries := 0
+		for _, c := range d.Components {
+			if c.IsFileDependency() && c.Path == "configs/shared.json" {
+				fileEntries++
+			}
+		}
+		assert.Equal(t, 1, fileEntries, "duplicate (kind,path) entries in Components")
 	})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/schema/dependencies_test.go` around lines 258 - 269, The test for
deduping should also assert that the Components slice is deduped: after creating
the Dependencies with Files and Components and calling d.Normalize(), add an
assertion that d.Components equals []ComponentDependency{{Kind: "file", Path:
"configs/shared.json"}} (or the canonical single entry) so the mirror step in
Dependencies.Normalize() doesn't produce duplicate (Kind, Path) entries;
reference the Dependencies struct, the Components field and the
ComponentDependency type when updating the test.

141-294: ⚡ Quick win

Suggestion: add an idempotency test for Normalize.

A round-trip test (Normalize twice in a row, assert state is unchanged the second time) would lock in the contract that callers can safely re-normalize after a merge. Today this would fail on Components duplication — see the companion comment on pkg/schema/dependencies.go.

♻️ Sketch
t.Run("Normalize is idempotent", func(t *testing.T) {
    d := &Dependencies{
        Components: []ComponentDependency{{Name: "vpc"}},
        Files:      []string{"configs/lambda.json"},
        Folders:    []string{"src/handler"},
    }
    require.NoError(t, d.Normalize())
    snapshot := *d // shallow copy of slices is fine; we compare contents below
    componentsBefore := append([]ComponentDependency(nil), d.Components...)
    filesBefore := append([]string(nil), d.Files...)
    foldersBefore := append([]string(nil), d.Folders...)

    require.NoError(t, d.Normalize())
    assert.Equal(t, componentsBefore, d.Components, "Components must not change on second Normalize")
    assert.Equal(t, filesBefore, d.Files)
    assert.Equal(t, foldersBefore, d.Folders)
    _ = snapshot
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/schema/dependencies_test.go` around lines 141 - 294, Add an idempotency
unit test that calls Dependencies.Normalize() twice and asserts the second call
does not change Dependencies state: create a Dependencies value (use Components
with Name "vpc" and Files/Folders like "configs/lambda.json"/"src/handler"),
call d.Normalize(), copy slices into componentsBefore/filesBefore/foldersBefore,
call d.Normalize() again and assert Components, Files, and Folders equal their
"before" copies; reference the Normalize method and types Dependencies and
ComponentDependency in the test to locate where to add it in
pkg/schema/dependencies_test.go.
docs/prd/component-dependencies.md (1)

132-151: 💤 Low value

Minor: PRD merge-behavior section doesn't call out the default, unlike components.mdx.

The user-facing page (website/docs/stacks/dependencies/components.mdx line 174) now correctly states "By default, dependencies.components uses replace merge behavior… To opt into append-merge behavior, set settings.list_merge_strategy: append." This PRD section is technically correct (it qualifies append-merge as conditional on the setting) but doesn't state the default, and the worked example below showing both deps merging will read as "the way it works" to a quick reader. Worth a one-line tweak so the two docs match.

♻️ Suggested wording
 ### Merge Behavior
 
-`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 **replace merge** by default — a child stack's list replaces the parent's. To opt in to append-merge (child dependencies extend the parent's list), set `settings.list_merge_strategy: append` in `atmos.yaml`.
+
+The example below assumes `list_merge_strategy: append` is enabled.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/prd/component-dependencies.md` around lines 132 - 151, The PRD's "Merge
Behavior" section omits the default merge behavior; update the paragraph to
state that dependencies.components defaults to "replace merge" and only uses
append merge when settings.list_merge_strategy: append is set—mention the
specific symbols dependencies.components and settings.list_merge_strategy so
readers know where to change the behavior and align this doc with
components.mdx.
website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json (2)

1571-1604: ⚡ Quick win

Tighten path entries with minLength: 1 to catch empty strings at validate time.

dependencies.files and dependencies.folders accept any string today, including "". The Go normalizer in pkg/schema/dependencies.go silently skips empty paths during sibling mirroring, so the user gets no signal that their YAML is wrong (e.g., a stray template result). A minLength: 1 on the items moves that error to schema validation, where it belongs.

♻️ Proposed change
     "dependencies_files": {
       …
       "oneOf": [
         { "type": "string", "pattern": "^!include" },
         {
           "type": "array",
           "items": {
             "type": "string",
+            "minLength": 1,
             "description": "File path (relative to the repository root). Changes to this file mark the declaring component as affected."
           }
         }
       ]
     },
     "dependencies_folders": {
       …
       "oneOf": [
         { "type": "string", "pattern": "^!include" },
         {
           "type": "array",
           "items": {
             "type": "string",
+            "minLength": 1,
             "description": "Folder path (relative to the repository root). Changes to any file under this folder mark the declaring component as affected."
           }
         }
       ]
     },

Apply the same to the matching fixture under tests/fixtures/schemas/....

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json` around
lines 1571 - 1604, Add "minLength: 1" to the string items for both
"dependencies_files" and "dependencies_folders" schemas so empty strings are
rejected at validation time; update the "items" object under each schema's array
branch (the item with "type": "string") to include minLength: 1, and apply the
same change to the corresponding test fixture schema(s) under
tests/fixtures/schemas to ensure tests reflect the tightened validation.

1631-1646: ⚖️ Poor tradeoff

Schema edge case: anyOf permits { name, kind: file, path } which the Go side would mishandle.

The current anyOf structure allows an entry to satisfy the name-required branch while also carrying kind: file + path. When both are present, the Go code's IsFileDependency() check (Kind-based discrimination) wins: the entry is treated as a file dependency, Name gets resolved into Component, and the Component ends up orphaned.

This pattern isn't used anywhere in existing fixtures or examples, but it could emerge from generated or templated YAML. If you want to enforce true mutual exclusion, switch to oneOf and add not constraints to the component branches. Worth verifying first—it's a stricter validation that could break edge-case manifests in the wild.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json` around
lines 1631 - 1646, The anyOf validation allows entries with both "name" and
"kind":"file"/"path" which the Go IsFileDependency() logic will treat as a file
and orphan the Name/Component; change the schema's anyOf to oneOf and tighten
branches: make the "name" branch forbid "kind" and "path" (use a "not" with
required ["kind","path"] or explicit "properties" with "not"), likewise make the
"component" branch forbid "kind" and "path", and keep the file/folder branch
requiring "kind" and "path" with kind enum ["file","folder"]; ensure these
constraints reference the same JSON object that currently uses anyOf so Name and
Component cannot co-exist with kind/path.
website/docs/stacks/dependencies/components.mdx (1)

134-145: 💤 Low value

Minor: align example folder paths across the page.

This block uses src/lambda/my-function while the lower "How It Works" example at line 247–248 and elsewhere on the page uses src/lambda/handler. Picking one path makes the doc easier to scan, but no functional impact.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/docs/stacks/dependencies/components.mdx` around lines 134 - 145, The
example uses inconsistent folder paths: change the folders entry that currently
lists "src/lambda/my-function" to the same path used elsewhere
("src/lambda/handler") so examples are consistent; update that "folders" example
(and any other occurrences of "src/lambda/my-function") to "src/lambda/handler"
within the document so the "folders" example, the "How It Works" example, and
other references match.
tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json (1)

1631-1645: 💤 Low value

Schema permissively allows mixing name/component with legacy kind: file|folder + path.

The anyOf structure accepts an entry like { name: vpc, kind: file, path: foo } because the first branch matches on name alone. The normalizer promotes name to component and doesn't reject the mixed style—it normalizes without validating mutual exclusivity.

If the intent is to keep component-style and path-based forms distinct, consider using oneOf with explicit exclusion constraints in the schema, or add runtime validation in normalizeComponentEntries() to reject mixed entries. Since backward compatibility is a stated goal (legacy path-based entries are supported), the current permissive approach aligns with that intent, though it risks accidental mixing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json` around
lines 1631 - 1645, The schema's anyOf allows mixed-style entries (e.g., {name,
kind, path}) which slips through normalization; either make the schema enforce
exclusivity by replacing the anyOf with oneOf and explicit exclusion clauses for
the branches (ensure branches: {required: ["name"], not: {required:
["kind","path"]}}, {required: ["component"], not: {required: ["kind","path"]}},
and the legacy branch {required: ["kind","path"], properties.kind.enum contains
["file","folder"]}) or add runtime validation in normalizeComponentEntries() to
detect and reject objects that contain both component-style keys ("name" or
"component") and legacy keys ("kind" or "path") before normalizing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/exec/describe_affected_components.go`:
- Around line 544-559: Replace the duplicate fast-path check in
describe_affected_components.go with a call to the existing hasDependencyEntries
helper (from describe_dependents.go) to keep logic centralized, then when
calling deps.Normalize() on the decoded deps variable, change the log.Debug call
to log.Warn and include the returned error in the warning message so Normalize
failures are surfaced (e.g., "failed to normalize dependencies section" + err)
rather than silently dropping file/folder deps.

In `@internal/exec/describe_dependents.go`:
- Around line 471-481: The Normalize error on deps.Normalize() is currently
debug-logged and swallowed, causing silent partial normalization; change
getComponentDependencies to return an error (update its signature and all
callers) and, when deps.Normalize() returns normErr, return that error (or at
minimum log it at Error/Warn level) instead of just log.Debug so misconfigured
stacks fail loudly; ensure callers handle the propagated error and that the
behavior references deps.Normalize() and getComponentDependencies.

In `@pkg/schema/dependencies.go`:
- Around line 133-176: Normalize is not idempotent because
mirrorSiblingsIntoComponents blindly appends synthetic ComponentDependency
entries for Files/Folders causing duplicates; modify
mirrorSiblingsIntoComponents to first build a set/map of existing (kind, path)
pairs from d.Components and only append a new ComponentDependency{Kind:
dependencyKindFile / dependencyKindFolder, Path: p} when that (kind,path) is not
already present, marking it in the map as you append; keep using the same
symbols (Normalize, mirrorSiblingsIntoComponents, d.Components, d.Files,
d.Folders, ComponentDependency, dependencyKindFile, dependencyKindFolder) so
repeated Normalize calls do not produce duplicate entries.

In `@website/docs/stacks/dependencies/components.mdx`:
- Around line 210-223: The tip currently lists valid list_merge_strategy values
but omits "append"; update the tip text in components.mdx to list "replace"
(default), "append", and "merge" so it matches the settings reference and
example; specifically edit the tip under the example that mentions Other valid
`list_merge_strategy` values to include `append`, keeping the reference link to
[`settings` reference] intact and ensuring `list_merge_strategy` is spelled
exactly as shown in the diff.

In `@website/docs/stacks/dependencies/index.mdx`:
- Line 14: The sentence incorrectly groups `components`, `files`, and `folders`
as all defining ordering; update the paragraph so it clearly states that `tools`
pins CLI versions and `components` controls ordering between Atmos components,
while `files` and `folders` are only watch-paths consumed by `atmos describe
affected` and CI/CD integrations (they do not affect execution order); use the
keys `tools`, `components`, `files`, and `folders` in the revised text to make
roles explicit.
- Around line 264-266: Update the documentation note "Legacy inline shape" to
remove or correct the incorrect release reference to v1.210.0: either delete the
"shipped in v1.210.0" clause or replace it with the accurate release/planned
version and optionally cite the correct commit/PR, and make sure the text still
points readers to the newer keys `dependencies.files` and `dependencies.folders`
as replacements for the inline `dependencies.components[]` `kind: file` / `kind:
folder` shape (refer to the block labeled "Legacy inline shape" and the
`dependencies.components[]` wording when applying the change).

---

Nitpick comments:
In `@docs/prd/component-dependencies.md`:
- Around line 132-151: The PRD's "Merge Behavior" section omits the default
merge behavior; update the paragraph to state that dependencies.components
defaults to "replace merge" and only uses append merge when
settings.list_merge_strategy: append is set—mention the specific symbols
dependencies.components and settings.list_merge_strategy so readers know where
to change the behavior and align this doc with components.mdx.

In `@pkg/schema/dependencies_test.go`:
- Around line 258-269: The test for deduping should also assert that the
Components slice is deduped: after creating the Dependencies with Files and
Components and calling d.Normalize(), add an assertion that d.Components equals
[]ComponentDependency{{Kind: "file", Path: "configs/shared.json"}} (or the
canonical single entry) so the mirror step in Dependencies.Normalize() doesn't
produce duplicate (Kind, Path) entries; reference the Dependencies struct, the
Components field and the ComponentDependency type when updating the test.
- Around line 141-294: Add an idempotency unit test that calls
Dependencies.Normalize() twice and asserts the second call does not change
Dependencies state: create a Dependencies value (use Components with Name "vpc"
and Files/Folders like "configs/lambda.json"/"src/handler"), call d.Normalize(),
copy slices into componentsBefore/filesBefore/foldersBefore, call d.Normalize()
again and assert Components, Files, and Folders equal their "before" copies;
reference the Normalize method and types Dependencies and ComponentDependency in
the test to locate where to add it in pkg/schema/dependencies_test.go.

In `@tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json`:
- Around line 1631-1645: The schema's anyOf allows mixed-style entries (e.g.,
{name, kind, path}) which slips through normalization; either make the schema
enforce exclusivity by replacing the anyOf with oneOf and explicit exclusion
clauses for the branches (ensure branches: {required: ["name"], not: {required:
["kind","path"]}}, {required: ["component"], not: {required: ["kind","path"]}},
and the legacy branch {required: ["kind","path"], properties.kind.enum contains
["file","folder"]}) or add runtime validation in normalizeComponentEntries() to
detect and reject objects that contain both component-style keys ("name" or
"component") and legacy keys ("kind" or "path") before normalizing.

In `@website/docs/stacks/dependencies/components.mdx`:
- Around line 134-145: The example uses inconsistent folder paths: change the
folders entry that currently lists "src/lambda/my-function" to the same path
used elsewhere ("src/lambda/handler") so examples are consistent; update that
"folders" example (and any other occurrences of "src/lambda/my-function") to
"src/lambda/handler" within the document so the "folders" example, the "How It
Works" example, and other references match.

In `@website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json`:
- Around line 1571-1604: Add "minLength: 1" to the string items for both
"dependencies_files" and "dependencies_folders" schemas so empty strings are
rejected at validation time; update the "items" object under each schema's array
branch (the item with "type": "string") to include minLength: 1, and apply the
same change to the corresponding test fixture schema(s) under
tests/fixtures/schemas to ensure tests reflect the tightened validation.
- Around line 1631-1646: The anyOf validation allows entries with both "name"
and "kind":"file"/"path" which the Go IsFileDependency() logic will treat as a
file and orphan the Name/Component; change the schema's anyOf to oneOf and
tighten branches: make the "name" branch forbid "kind" and "path" (use a "not"
with required ["kind","path"] or explicit "properties" with "not"), likewise
make the "component" branch forbid "kind" and "path", and keep the file/folder
branch requiring "kind" and "path" with kind enum ["file","folder"]; ensure
these constraints reference the same JSON object that currently uses anyOf so
Name and Component cannot co-exist with kind/path.
🪄 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: ed08c609-ea1e-4fbd-b7ef-37362754e536

📥 Commits

Reviewing files that changed from the base of the PR and between 4905336 and 76608c1.

📒 Files selected for processing (11)
  • docs/prd/component-dependencies.md
  • internal/exec/describe_affected_components.go
  • internal/exec/describe_affected_utils_2_test.go
  • internal/exec/describe_dependents.go
  • pkg/schema/dependencies.go
  • pkg/schema/dependencies_test.go
  • tests/fixtures/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
  • website/docs/cli/commands/describe/describe-affected.mdx
  • website/docs/stacks/dependencies/components.mdx
  • website/docs/stacks/dependencies/index.mdx
  • website/static/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/docs/cli/commands/describe/describe-affected.mdx

Comment thread internal/exec/describe_affected_components.go
Comment thread internal/exec/describe_dependents.go
Comment thread pkg/schema/dependencies.go
Comment thread website/docs/stacks/dependencies/components.mdx
Comment thread website/docs/stacks/dependencies/index.mdx Outdated
Comment thread website/docs/stacks/dependencies/index.mdx
atmos-pro[bot]
atmos-pro Bot previously approved these changes May 5, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
internal/exec/describe_affected_components.go (1)

549-559: ⚡ Quick win

Decode-error branch should log too, mirroring the Normalize branch.

Same shape concern as in describe_dependents.go: a mapstructure.Decode failure silently returns nil, which in this hot path means all file/folder deps for the component get dropped without a peep — only the Normalize failure now warns. Adding a log.Warn on the decode error path keeps both sibling failures visible at the same level.

♻️ Suggested log on decode failure
 	var deps schema.Dependencies
-	if err := mapstructure.Decode(depsSection, &deps); err != nil {
-		return nil
-	}
+	if err := mapstructure.Decode(depsSection, &deps); err != nil {
+		log.Warn("invalid dependencies section; file/folder deps may be silently ignored", "error", err)
+		return nil
+	}
 	if err := deps.Normalize(); err != nil {
 		log.Warn("invalid dependencies section; file/folder deps may be silently ignored", "error", err)
 		return nil
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/exec/describe_affected_components.go` around lines 549 - 559, The
mapstructure.Decode failure for depsSection currently returns nil silently; add
a warning log similar to the Normalize branch so decode errors are visible. In
the block where mapstructure.Decode(depsSection, &deps) returns err, call
log.Warn with a descriptive message (e.g., "invalid dependencies section; decode
failed") and include the error (err) as a field, then continue to return nil as
before; keep the existing deps.Normalize check and its log.Warn intact. Ensure
you reference mapstructure.Decode, schema.Dependencies/deps, depsSection, and
log.Warn when making the change.
pkg/schema/dependencies_test.go (1)

141-306: 💤 Low value

Comprehensive coverage of the new normalization paths.

Good split between name-alias scenarios and the files/folders mirroring scenarios, and the idempotence test (lines 295–305) directly nails the duplication concern from the earlier review round. One small follow-up if you want to widen the safety net later: the idempotence test only re-checks d.Components; consider also asserting d.Files/d.Folders are stable across the second Normalize call so a future regression in backfillTypedSlicesFromInline would also fail.

♻️ Optional tweak to also assert typed slices stay stable
 	t.Run("is idempotent — calling twice produces the same result", func(t *testing.T) {
 		d := &Dependencies{
 			Components: []ComponentDependency{{Component: "vpc"}},
 			Files:      []string{"configs/lambda.json"},
 			Folders:    []string{"src/handler"},
 		}
 		require.NoError(t, d.Normalize())
 		first := append([]ComponentDependency(nil), d.Components...)
+		firstFiles := append([]string(nil), d.Files...)
+		firstFolders := append([]string(nil), d.Folders...)
 		require.NoError(t, d.Normalize())
 		assert.Equal(t, first, d.Components, "second Normalize must not append duplicates")
+		assert.Equal(t, firstFiles, d.Files, "Files must be stable across Normalize calls")
+		assert.Equal(t, firstFolders, d.Folders, "Folders must be stable across Normalize calls")
 	})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/schema/dependencies_test.go` around lines 141 - 306, The idempotence
subtest in TestDependencies_Normalize_FilesFoldersSiblings only checks that
d.Components is unchanged after a second call to Normalize; extend the test to
also capture and assert that d.Files and d.Folders remain identical before and
after the second Normalize to guard against regressions in
backfillTypedSlicesFromInline (use the same pattern used for Components: copy
the slices into local variables, call d.Normalize() again, and assert equality
against the originals).
internal/exec/describe_dependents.go (1)

468-481: ⚡ Quick win

Decode error path is silently swallowed.

If mapstructure.Decode(depsSection, &deps) fails (e.g., a user types dependencies.components: "vpc" as a string instead of a list), the err == nil guard silently falls through to the legacy settings.depends_on path with no signal to the user. The companion Normalize failure now warns — this branch should match for consistency and so config typos in the new format don't masquerade as "no dependencies declared".

♻️ Suggested log on decode failure
 		if hasDependencyEntries(depsSection) {
 			var deps schema.Dependencies
-			if err := mapstructure.Decode(depsSection, &deps); err == nil {
+			if err := mapstructure.Decode(depsSection, &deps); err != nil {
+				log.Warn("invalid dependencies section; entries may be silently ignored", "error", err)
+			} else {
 				if normErr := deps.Normalize(); normErr != nil {
 					log.Warn("invalid dependencies section; entries may be silently ignored", "error", normErr)
 				}
 				if len(deps.Components) > 0 {
 					return deps.Components, settingsSection, dependencySourceDependenciesComponents
 				}
 			}
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/exec/describe_dependents.go` around lines 468 - 481, The current
branch ignores errors from mapstructure.Decode when parsing depsSection,
allowing malformed new-format dependencies to silently fall through to the
legacy settings.depends_on path; update the block that calls
mapstructure.Decode(depsSection, &deps) (in the code handling
componentMap[cfg.DependenciesSectionName]) so that on a non-nil err you log a
clear warning/error (including the decode error) and return/stop processing this
branch (so it does not fall back to settings.depends_on), keeping the existing
Normalize() warning behavior for normalization errors; reference symbols:
componentMap, cfg.DependenciesSectionName, hasDependencyEntries,
mapstructure.Decode, deps (schema.Dependencies), deps.Normalize,
dependencySourceDependenciesComponents, settingsSection.
internal/exec/describe_affected_utils_2_test.go (1)

617-713: 💤 Low value

Solid v2 surface coverage with the right equivalence and dedup checks.

The v1↔v2 equivalence subtest plus the dedup-by-path subtest are exactly what this surface needed. Optional follow-up if/when you have spare cycles: a precedence test where the v2 sibling keys (files/folders) coexist with a populated settings.depends_on would close the symmetry with the existing "prefers dependencies.components over settings.depends_on" case (line 572).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/exec/describe_affected_utils_2_test.go` around lines 617 - 713, Add
a new unit test that verifies precedence when v2 sibling keys
("files"/"folders") coexist with a populated settings.depends_on: construct a
componentSection (or component map) that includes both "dependencies": {"files":
[...], "folders": [...]} and a "settings": {"depends_on": [...] } entry (where
depends_on contains entries that would also map to file/folder deps), call
getFileFolderDependencies and assert that only the v2 sibling keys produce
file/folder dependencies (i.e., settings.depends_on is ignored for file/folder
resolution); use the same assertion patterns as nearby tests
(require.Len/assert.ElementsMatch/assert.Equal) and reference
getFileFolderDependencies, "files"/"folders", and "settings.depends_on" to
locate the correct behavior to test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/docs/stacks/dependencies/index.mdx`:
- Line 239: The example in the dependencies.components block uses the old key
"name" (line showing "- name: vpc") which doesn't match the v2 manifest shape;
update the example to use "component: vpc" and ensure any sibling examples
follow the v2 keys ("component", "stack", "kind", "path") so the docs reflect
the new schema used by dependencies.components.

---

Nitpick comments:
In `@internal/exec/describe_affected_components.go`:
- Around line 549-559: The mapstructure.Decode failure for depsSection currently
returns nil silently; add a warning log similar to the Normalize branch so
decode errors are visible. In the block where mapstructure.Decode(depsSection,
&deps) returns err, call log.Warn with a descriptive message (e.g., "invalid
dependencies section; decode failed") and include the error (err) as a field,
then continue to return nil as before; keep the existing deps.Normalize check
and its log.Warn intact. Ensure you reference mapstructure.Decode,
schema.Dependencies/deps, depsSection, and log.Warn when making the change.

In `@internal/exec/describe_affected_utils_2_test.go`:
- Around line 617-713: Add a new unit test that verifies precedence when v2
sibling keys ("files"/"folders") coexist with a populated settings.depends_on:
construct a componentSection (or component map) that includes both
"dependencies": {"files": [...], "folders": [...]} and a "settings":
{"depends_on": [...] } entry (where depends_on contains entries that would also
map to file/folder deps), call getFileFolderDependencies and assert that only
the v2 sibling keys produce file/folder dependencies (i.e., settings.depends_on
is ignored for file/folder resolution); use the same assertion patterns as
nearby tests (require.Len/assert.ElementsMatch/assert.Equal) and reference
getFileFolderDependencies, "files"/"folders", and "settings.depends_on" to
locate the correct behavior to test.

In `@internal/exec/describe_dependents.go`:
- Around line 468-481: The current branch ignores errors from
mapstructure.Decode when parsing depsSection, allowing malformed new-format
dependencies to silently fall through to the legacy settings.depends_on path;
update the block that calls mapstructure.Decode(depsSection, &deps) (in the code
handling componentMap[cfg.DependenciesSectionName]) so that on a non-nil err you
log a clear warning/error (including the decode error) and return/stop
processing this branch (so it does not fall back to settings.depends_on),
keeping the existing Normalize() warning behavior for normalization errors;
reference symbols: componentMap, cfg.DependenciesSectionName,
hasDependencyEntries, mapstructure.Decode, deps (schema.Dependencies),
deps.Normalize, dependencySourceDependenciesComponents, settingsSection.

In `@pkg/schema/dependencies_test.go`:
- Around line 141-306: The idempotence subtest in
TestDependencies_Normalize_FilesFoldersSiblings only checks that d.Components is
unchanged after a second call to Normalize; extend the test to also capture and
assert that d.Files and d.Folders remain identical before and after the second
Normalize to guard against regressions in backfillTypedSlicesFromInline (use the
same pattern used for Components: copy the slices into local variables, call
d.Normalize() again, and assert equality against the originals).
🪄 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: d72602b2-5ebe-444e-b6db-eb8881408fe3

📥 Commits

Reviewing files that changed from the base of the PR and between 76608c1 and d73c905.

📒 Files selected for processing (7)
  • internal/exec/describe_affected_components.go
  • internal/exec/describe_affected_utils_2_test.go
  • internal/exec/describe_dependents.go
  • pkg/schema/dependencies.go
  • pkg/schema/dependencies_test.go
  • website/docs/stacks/dependencies/components.mdx
  • website/docs/stacks/dependencies/index.mdx

Comment thread website/docs/stacks/dependencies/index.mdx Outdated
atmos-pro[bot]
atmos-pro Bot previously approved these changes May 5, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

atmos-pro[bot]
atmos-pro Bot previously approved these changes May 6, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

atmos-pro[bot]
atmos-pro Bot previously approved these changes May 6, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 6, 2026
atmos-pro[bot]
atmos-pro Bot previously approved these changes May 9, 2026

@atmos-pro atmos-pro Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There were no affected stacks, therefore this is approved by Atmos Pro.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 25, 2026
@aknysh
Andriy Knysh (aknysh) merged commit 0a1d3ad into main May 27, 2026
60 checks passed
@aknysh
Andriy Knysh (aknysh) deleted the osterman/describe-affected-deps branch May 27, 2026 01:43
@atmos-pro

atmos-pro Bot commented May 27, 2026 •

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@github-actions

Copy link
Copy Markdown

These changes were released in v1.220.0-rc.4.

This branch was successfully deployed

1 active deployment
preview — 475f90ba Deployed May 27, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/l Large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants