Skip to content

Allow locals to access settings, vars, and env from the same file. Add locals design patterns. Add Atmos YAML functions support in locals#1994

Merged
aknysh merged 31 commits intomainfrom
aknysh/fix-locals-5
Jan 21, 2026
Merged

Allow locals to access settings, vars, and env from the same file. Add locals design patterns. Add Atmos YAML functions support in locals#1994
aknysh merged 31 commits intomainfrom
aknysh/fix-locals-5

Conversation

@aknysh
Copy link
Copy Markdown
Member

@aknysh aknysh commented Jan 19, 2026

what

  • Enable locals to access .settings, .vars, and .env sections from the same YAML file during template resolution
  • Add template context (settings, vars, env) to the locals resolver so locals can reference these sections
  • Only add context to template processing when locals are present (preserving existing behavior for files without locals)
  • Merge section-specific settings/vars/env with global values (not replace) so global keys are preserved
  • Add YAML functions support in locals (!env, !exec, !store, !terraform.state, !terraform.output)
  • Update documentation with error handling, common pitfalls, workarounds for optional values, and YAML functions
  • Add examples/locals example demonstrating the feature
  • Add Locals Design Patterns documentation
  • Add blog posts announcing the enhancements

why

  • The PRD for file-scoped locals explicitly shows examples of locals accessing .vars from the same file
  • YAML functions in locals enable powerful patterns like fetching values from terraform state or environment variables
  • This enables useful patterns like:
    settings:
      substage: dev
    locals:
      domain: '{{ .settings.substage }}.example.com'
  • Cross-file access (from imported files) remains unsupported by design - locals are file-scoped
  • Clear error messages help users understand when template references fail

YAML Functions in Locals

Locals support all Atmos YAML functions for dynamic value resolution:

Function Description Example
!env Environment variables !env API_ENDPOINT
!exec Command execution !exec git rev-parse --short HEAD
!store Store lookups !store secrets/db .password
!terraform.state Terraform state queries !terraform.state vpc .vpc_id
!terraform.output Terraform outputs !terraform.output vpc .vpc_id

Example:

locals:
  # Fetch from environment variable
  api_endpoint: !env API_ENDPOINT
  
  # Combine with Go templates
  api_url: "https://{{ .locals.api_endpoint }}/api/v1"

components:
  terraform:
    myapp:
      vars:
        api_url: "{{ .locals.api_url }}"

Blog Posts

  1. Locals Context Access (2026-01-19-locals-context-access-and-design-patterns.mdx)

    • Enhancement allowing locals to access settings/vars/env from same file
    • File-scoped context explanation
  2. YAML Functions in Locals (2026-01-20-locals-yaml-functions.mdx)

    • Support for !env, !exec, !store, !terraform.state, !terraform.output in locals
    • Examples and use cases

Error Handling Behavior

When a template reference cannot be resolved, Atmos produces a hard error with a clear message rather than silently returning an empty string or passing through the literal template syntax:

Scenario Result
{{ .settings.foo }} when settings doesn't exist Error: map has no entry for key 'settings'
{{ .settings.foo }} when settings exists but no foo Error: map has no entry for key 'foo'
{{ .settings.foo }} when both exist ✅ Resolves to the value

Workarounds for optional values:

locals:
  # Using 'with' for conditional access
  safe_region: '{{ with .settings }}{{ .region }}{{ else }}us-west-2{{ end }}'
  
  # Using index with default
  domain: '{{ index .settings "region" | default "us-west-2" }}.example.com'

Example

A new examples/locals example demonstrates the feature:

cd examples/locals

# See how locals are resolved
atmos describe component myapp -s dev

# View all resolved locals
atmos describe locals myapp -s dev

Output:

vars:
  environment: development
  full_name: acme-development-dev
  name: acme
  tags:
    Environment: development
    ManagedBy: Atmos
    Namespace: acme
    Team: platform

Summary of Changes

Code Changes:

  • pkg/locals/resolver.go:
    • Added templateContext field and WithTemplateContext method to pass settings/vars/env during resolution
    • Added YamlFunctionProcessor callback type and WithYamlFunctionProcessor method for YAML function support
    • Updated resolveString to detect and process YAML functions (strings starting with !)
  • internal/exec/stack_processor_locals.go:
    • Build and pass template context with settings/vars/env from the stack config
    • Added localsResolveOptions struct and createYamlFunctionProcessor for YAML function processing
    • Fixed buildSectionTemplateContext to merge section values with global values (not replace)
    • Added mergeStringAnyMaps helper for shallow merging
  • internal/exec/stack_processor_utils.go:
    • Extract settings/vars/env from raw YAML and add to context only when locals are present
    • Updated to use Atmos YAML unmarshaling for proper custom tag handling
  • errors/errors.go: Added ErrLocalsYamlFunctionFailed sentinel error

Test Changes:

  • Added new integration tests: TestLocalsSettingsAccessSameFile, TestLocalsSettingsAccessDescribeStacks, TestLocalsSettingsAccessNotCrossFile
  • Added test fixture tests/fixtures/scenarios/locals-settings-access/ demonstrating same-file access
  • Added test fixture tests/fixtures/scenarios/locals-settings-cross-file/ demonstrating cross-file access error
  • Added advanced tests: TestLocalsNestedSettingsAccess, TestLocalsEnvironmentVariableAccess, TestLocalsHelmfileSectionLocals
  • Added test fixture tests/fixtures/scenarios/locals-advanced/ for nested values and helmfile section locals
  • Converted context-access unit tests to table-driven format (TestExtractLocalsFromRawYAML_ContextAccess)
  • Added unit tests for merge behavior (TestMergeStringAnyMaps, TestBuildSectionTemplateContext_MergesBehavior)
  • Added TestLocalsWithYamlFunctionsEnv for YAML functions in locals
  • Added test fixture tests/fixtures/scenarios/locals-yaml-functions/ for YAML function testing

Documentation Changes:

  • Added "Accessing Other Sections" section explaining what template context is available
  • Added "Processing Order" section explaining why cross-file access doesn't work
  • Added "Component-Level Locals" section with inheritance from base components
  • Added "Scope Merging for Settings and Vars" section explaining merge behavior
  • Added "Debugging Locals" section with troubleshooting guidance
  • Added "YAML Functions in Locals" section with examples for !env, !exec, !store, !terraform.state, !terraform.output
  • Added "Error Handling" section with:
    • Unresolved template reference behavior (produces error, not empty string)
    • Common error scenarios table
    • Handling optional values with Go template conditionals
    • Cross-file access error explanation and solutions
  • Updated "Locals vs Vars" comparison table with "Cross-File Access" row
  • Added best practice for using vars for cross-file sharing

Blog Posts Added:

  • website/blog/2026-01-19-locals-context-access-and-design-patterns.mdx
  • website/blog/2026-01-20-locals-yaml-functions.mdx

Example Added:

  • examples/locals/ - Minimal example demonstrating locals feature:
    • Basic locals and dependency resolution
    • Accessing settings/vars from same file
    • Building computed values (name_prefix, full_name, tags)
    • File-scoped isolation between dev and prod stacks

Dependency Updates:

  • Updated google.golang.org/api from retracted v0.258.0 to v0.260.0

Summary by CodeRabbit

  • New Features

    • Locals now access .settings, .vars, and .env from the same file during resolution
    • YAML function support in locals (e.g., !env, !exec, !store, !terraform.state, !terraform.output)
  • Documentation

    • Major docs and blog updates with processing diagrams, examples, guidance, and warnings
  • Tests

    • Extensive new tests and fixtures covering locals scope, YAML functions, env access, cross-file cases, and edge conditions
  • Examples

    • New examples demonstrating locals usage and try-it workflows
  • Chores

    • Multiple dependency patch bumps and NOTICE license URL updates

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

@aknysh aknysh added the patch A minor, backward compatible change label Jan 19, 2026
@aknysh aknysh requested review from a team as code owners January 19, 2026 01:19
@aknysh aknysh added the patch A minor, backward compatible change label Jan 19, 2026
@github-actions github-actions bot added the size/l Large size PR label Jan 19, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 19, 2026

Important

Cloud Posse Engineering Team Review Required

This 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 #pr-reviews channel.

@mergify mergify bot added the needs-cloudposse Needs Cloud Posse assistance label Jan 19, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 19, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

  • go.mod

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

Threads a per-file template context through locals extraction/resolution, adds pluggable YAML-function processing into the locals resolver, updates signatures and error handling, and expands tests, fixtures, examples, and docs. Dependency NOTICE/go.mod entries were bumped.

Changes

Cohort / File(s) Summary
Dependency Updates
NOTICE, go.mod
Bumped multiple module versions and updated NOTICE URLs to newer patch releases.
Locals Stack Processing
internal/exec/stack_processor_locals.go
Threaded templateContext and currentStack through locals extraction; added buildTemplateContextFromConfig, buildSectionTemplateContext, mergeStringAnyMaps, and updated public signatures.
Locals Utils & Result Struct
internal/exec/stack_processor_utils.go
Introduced extractLocalsResult (locals, settings, vars, env, hasLocals); extractLocalsFromRawYAML returns structured result and populates template context.
Resolver Enhancements
pkg/locals/resolver.go
Added YamlFunctionProcessor type; WithTemplateContext and WithYamlFunctionProcessor methods; resolver now runs YAML-function processor before templating and merges templateContext.
Error Handling
errors/errors.go
Added sentinel ErrLocalsYamlFunctionFailed for YAML-function processing failures.
Process/Describe Wiring
internal/exec/describe_locals.go
ProcessStackLocals signature updated to accept stackName; call sites updated.
Tests: Unit & Integration
internal/exec/*_test.go, pkg/locals/resolver_test.go, tests/cli_locals_test.go
Updated tests for new signatures/result shapes; added tests for merge helpers, template-context interactions, YAML functions, and extensive CLI/local scenarios.
Test Fixtures
tests/fixtures/scenarios/locals-*/*
Added fixtures for same-file settings access, cross-file restrictions, advanced locals, YAML functions, env tests, and supporting component mock files.
Examples
examples/locals/*
New example project and README demonstrating file-scoped locals, computed values, and component usage.
Docs & Blog
website/docs/stacks/locals.mdx, website/docs/design-patterns/*, website/blog/*
Substantially expanded locals documentation and added blog posts describing context rules and YAML functions in locals.
Snapshots & Minor
tests/snapshots/*
Minor snapshot/golden updates and whitespace fixes.

Sequence Diagram(s)

sequenceDiagram
    participant Processor as Stack Processor
    participant StackUtil as Stack Utils
    participant Locals as Locals Extractor
    participant Resolver as Template Resolver
    participant Output as Resolved Values

    Processor->>StackUtil: extractAndAddLocalsToContext(rawYAML, filePath)
    StackUtil->>Locals: extractLocalsFromRawYAML(yamlContent)
    Locals->>Locals: parse locals, settings, vars, env -> extractLocalsResult
    Locals-->>StackUtil: return extractLocalsResult
    StackUtil->>Processor: inject extractLocalsResult into templateContext
    Processor->>Processor: buildSectionTemplateContext(globalContext, sectionOverrides)
    Processor->>Resolver: NewResolver().WithTemplateContext(mergedContext).WithYamlFunctionProcessor(processor)
    Resolver->>Resolver: if YAML-function tag -> call yamlFunctionProcessor(value)
    Resolver->>Resolver: render templates with mergedContext (locals take precedence)
    Resolver-->>Output: final resolved locals/vars for components
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • osterman
  • Benbentwo
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: allowing locals to access settings/vars/env from the same file, adding design patterns, and supporting YAML functions in locals.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/fix-locals-5

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.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 19, 2026

Codecov Report

❌ Patch coverage is 94.85294% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.97%. Comparing base (1eeae7d) to head (88ea727).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/exec/stack_processor_utils.go 88.57% 2 Missing and 2 partials ⚠️
internal/exec/stack_processor_locals.go 95.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1994      +/-   ##
==========================================
+ Coverage   74.93%   74.97%   +0.04%     
==========================================
  Files         775      775              
  Lines       71355    71464     +109     
==========================================
+ Hits        53471    53582     +111     
  Misses      14398    14398              
+ Partials     3486     3484       -2     
Flag Coverage Δ
unittests 74.97% <94.85%> (+0.04%) ⬆️

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

Files with missing lines Coverage Δ
errors/errors.go 100.00% <ø> (ø)
internal/exec/describe_locals.go 89.36% <100.00%> (ø)
pkg/locals/resolver.go 93.86% <100.00%> (+0.85%) ⬆️
internal/exec/stack_processor_locals.go 98.19% <95.00%> (-1.81%) ⬇️
internal/exec/stack_processor_utils.go 79.70% <88.57%> (-0.44%) ⬇️

... 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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

This PR extends the locals resolution pipeline to support file-scoped template context, enabling locals to reference .settings, .vars, and .env from the same file during template processing. It introduces templateContext propagation through the stack processor and locals resolver, adds a new helper type for extracting multiple context sections, and bumps the doublestar dependency to v4.9.2.

Changes

Cohort / File(s) Summary
Dependency Updates
NOTICE, go.mod
Bump bmatcuk/doublestar/v4 from v4.9.1 to v4.9.2
Stack Processor Locals
internal/exec/stack_processor_locals.go
Add templateContext parameter to ExtractAndResolveLocals, resolveLocalsWithDependencies, and ResolveComponentLocals. Introduce buildTemplateContextFromConfig and buildSectionTemplateContext helpers to construct and propagate context from stack config. Thread context through resolution flow for terraform, helmfile, and packer sections.
Stack Processor Utilities
internal/exec/stack_processor_utils.go
Introduce extractLocalsResult struct to group locals, settings, vars, and env. Update extractLocalsFromRawYAML to return pointer to extractLocalsResult. Enhance extractAndAddLocalsToContext to populate template context with settings, vars, and env from the extraction result.
Locals Resolver
pkg/locals/resolver.go
Add templateContext field and WithTemplateContext() method for method chaining. Merge per-file templateContext with resolved locals during resolution, giving precedence to resolved locals. Enhance error reporting to include available context keys.
Stack Processor Tests
internal/exec/stack_processor_locals_test.go
Update all call sites of ExtractAndResolveLocals and ResolveComponentLocals to pass templateContext parameter (nil in tests).
Stack Processor Utils Tests
internal/exec/stack_processor_utils_test.go
Adjust assertions to access result.locals instead of direct result map. Add new test cases: SettingsAccess, VarsAccess, EnvAccess, CombinedContextAccess validating cross-context access within the same file.
Integration Tests
tests/cli_locals_test.go
Add Settings Access Tests group validating file-scoped local access to .settings, .vars, .env. Include same-file access, describe-stacks flow, and cross-file access restriction tests.
Test Fixtures
tests/fixtures/scenarios/locals-settings-access/*
Add new scenario directory with atmos.yaml config, mock Terraform module (main.tf), stack manifests (test-same-file.yaml, test.yaml), mixin (sandbox-dev.yaml), and catalog component demonstrating locals accessing .settings from the same file.
Documentation
website/docs/stacks/locals.mdx
Expand with Processing Order section, dependency resolution details, Accessing Other Sections guidance, and Same-File Access warning. Update Locals vs Vars comparison table to clarify file-scoped behavior and cross-file limitations. Add best practices for using vars for cross-file sharing.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Stack Processor
    participant Extractor as Utils (extractLocalsFromRawYAML)
    participant Resolver as Locals Resolver
    participant TemplateEngine as Template Engine

    Client->>Extractor: Extract locals, settings, vars, env from YAML
    Extractor-->>Client: Return extractLocalsResult

    Client->>Client: Build templateContext from config + extracted sections

    Client->>Resolver: ResolveComponentLocals with templateContext

    Resolver->>Resolver: Set templateContext via WithTemplateContext()

    loop Resolve each local with dependencies
        Resolver->>TemplateEngine: Execute template with merged context<br/>(locals + settings + vars + env)
        TemplateEngine-->>Resolver: Resolved value
    end

    Resolver->>Resolver: Merge resolved locals with templateContext<br/>(locals take precedence)

    Resolver-->>Client: Fully resolved locals map
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #1939: Implements the same file-scoped locals extraction/resolution and threadable templateContext changes with extensive test and documentation updates.
  • PR #1883: Extends file-scoped locals by adding templateContext propagation (WithTemplateContext method, resolver changes, and signature updates).
  • PR #1485: Modifies template processing and context handling in stack_processor_utils.go affecting when and how templates are processed.

Suggested reviewers

  • osterman
  • aknysh
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 74.47% 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 clearly describes the main change: enabling locals to access settings, vars, and env from the same file.
Linked Issues check ✅ Passed All requirements from issue #1991 are met: locals can now access .settings from the same file; tests verify same-file access and cross-file restriction; docs clarified.
Out of Scope Changes check ✅ Passed All changes align with the PR objective: resolver context handling, stack processor threading, utils extraction, tests, fixtures, and docs all support file-scoped template context access.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/fix-locals-5

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

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@internal/exec/stack_processor_locals.go`:
- Around line 186-211: buildSectionTemplateContext currently replaces the entire
.settings/.vars/.env maps when a section provides them, losing global keys;
change it to shallow-merge the section maps onto the existing global maps
instead. In buildSectionTemplateContext, for each of cfg.SettingsSectionName,
cfg.VarsSectionName, and cfg.EnvSectionName: if the section map exists, get the
existing map from context (if any, ensure it's a map[string]any), copy its
key/value pairs into a new map, then copy/overwrite with keys from the section
map and assign that merged map back to context[...] so section keys override but
unspecified global keys remain. Use the function name
buildSectionTemplateContext and the symbols cfg.SettingsSectionName,
cfg.VarsSectionName, cfg.EnvSectionName to locate where to apply the merge.

In `@NOTICE`:
- Around line 1075-1077: The NOTICE file was edited manually; instead regenerate
it by running the provided script and committing the generated output: execute
./scripts/generate-notice.sh (or the repository's canonical generation command),
verify the NOTICE changes are as expected, and commit the updated NOTICE rather
than making manual edits—do not edit NOTICE by hand going forward.
🧹 Nitpick comments (2)
tests/cli_locals_test.go (1)

900-935: Consider strengthening the cross-file test assertion.

This test verifies that cross-file access doesn't cause errors, but it doesn't explicitly verify that the cross-file pattern fails as expected. The test passes as long as test-same-file works, but doesn't validate that a template referencing imported settings would produce <no value> or an error.

For stronger coverage, consider adding a test case that explicitly attempts cross-file settings access and verifies the expected failure mode.

internal/exec/stack_processor_utils_test.go (1)

1726-1818: Consider table-driving the new context-access cases.

The settings/vars/env/combined tests share the same setup and assertion pattern; a table-driven test would reduce duplication and make it easier to add cases. As per coding guidelines.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
internal/exec/stack_processor_utils.go (1)

116-174: Prevent parent .settings/.vars/.env from leaking into imported files.

Only locals are cleared from context, so settings/vars/env from a parent file can persist into imports and trigger template processing or cross-file access unexpectedly. Clear these keys alongside locals to preserve file-scoped behavior.

Suggested fix
 if context != nil {
     delete(context, "locals")
+    delete(context, cfg.SettingsSectionName)
+    delete(context, cfg.VarsSectionName)
+    delete(context, cfg.EnvSectionName)
 }
🤖 Fix all issues with AI agents
In `@NOTICE`:
- Around line 1075-1077: The NOTICE file was modified manually and is out of
date; regenerate it using the project's generation script instead of editing
NOTICE directly: run ./scripts/generate-notice.sh to produce an updated NOTICE,
review and commit the generated output, and remove any manual changes
referencing entries like "github.com/bmatcuk/doublestar/v4" so CI will pass.

In `@website/docs/stacks/locals.mdx`:
- Line 229: The sentence "This architecture ensures that locals resolution is
fast, predictable, and free of cross-file dependencies" is missing a terminal
period; update the sentence in locals.mdx (the line containing that exact text)
to end with a period so it reads "...dependencies." to maintain consistent
punctuation.
🧹 Nitpick comments (1)
tests/cli_locals_test.go (1)

900-935: Consider strengthening the cross-file access test.

The test comment mentions that cross-file access "would fail or return <no value>", but the assertions only verify that same-file access works. For stronger validation of the file-scoped design, consider adding a fixture that explicitly attempts cross-file settings access and asserting the expected failure behavior (similar to TestLocalsNotInherited which checks for <no value>).

That said, if the intent is just to confirm the happy path works while cross-file scenarios are covered elsewhere, this is fine as-is.

@aknysh aknysh requested a review from osterman January 19, 2026 03:59
@github-actions github-actions bot added size/xl Extra large size PR and removed size/l Large size PR labels Jan 19, 2026
@mergify
Copy link
Copy Markdown

mergify bot commented Jan 19, 2026

Warning

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

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

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

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 19, 2026
@github-actions
Copy link
Copy Markdown

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@internal/exec/stack_processor_locals.go`:
- Around line 112-126: The YAML function processor in
createYamlFunctionProcessor currently returns raw errors and nil for missing
keys; update it to wrap any returned error and the missing-_value case with the
sentinel error defined in errors/errors.go (use the package-level sentinel, e.g.
errors.ErrSentinel), e.g., when ProcessCustomYamlTags returns err wrap it with
fmt.Errorf("%w: %v", errors.ErrSentinel, err) and when "_value" is absent return
errors.ErrSentinel (or wrap a descriptive message with the sentinel) from
createYamlFunctionProcessor so all failures conform to the project's
error-wrapping guideline.

In `@internal/exec/stack_processor_utils.go`:
- Around line 155-160: The code currently returns early when
len(extractResult.locals) == 0, which skips template context setup even if a
locals: {} section existed; change the logic to detect presence of the locals
section rather than its resolved size by adding a boolean flag on the extraction
result (e.g., ExtractResult.LocalsDeclared or a method like
ExtractResult.HasLocalsField) and use that here (and consistently in
ProcessBaseStackConfig) to decide whether to enable template processing; update
the extractor that populates extractResult to set this flag when the locals
block is present so template context is created even when resolve yields an
empty map.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@pkg/locals/resolver.go`:
- Around line 466-470: Replace the raw fmt.Errorf return in the locals resolver
with a wrapped sentinel error so callers can errors.Is() it; import and use the
package-level sentinel (e.g., errors.ErrLocalResolution or add that sentinel in
errors/errors.go if missing) and wrap the detailed fmt.Errorf message with
fmt.Errorf("%w: ...", errors.ErrLocalResolution, ...) while keeping the existing
context (use r.getAvailableLocals(), r.getAvailableContext(), localName,
r.filePath and the original err) so the returned error both preserves details
and matches the static sentinel.

In `@tests/cli_locals_test.go`:
- Around line 1092-1093: Update the comment describing the output of
ExecuteDescribeLocals to accurately reflect that it returns root-level locals
plus per-section locals (terraform, helmfile, packer) rather than a components.*
tree; locate the comment near the test for ExecuteDescribeLocals in
cli_locals_test.go and replace the incorrect
"components.terraform.<component>.locals" description with a note that the
structure includes a top-level "locals:" and separate "terraform:", "helmfile:",
and "packer:" sections containing their respective locals.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 21, 2026
osterman and others added 2 commits January 20, 2026 19:45
- Reduced stacks/locals.mdx from 827 to 331 lines (60% cut)
- Consolidated Configuration Scopes (3 examples → 1 comprehensive example)
- Moved Processing Order diagram to <details> block ("How does processing work?")
- Deleted redundant "Complete Example" section, rely on "Try It" embed instead
- Removed duplicate explanations of file-scoped isolation across sections
- Moved debugging output examples to <details> block
- Condensed error handling section and best practices
- Removed "Scope Merging", "Limitations", "When to Use Each" sections as redundant

- Reduced examples/locals/README.md from 155 to 35 lines (77% cut)
- Aligned with standard example README pattern (demo-stacks/README.md style)
- Removed 60-line "Example Output" section
- Removed 40-line "Key Concepts" section duplicating main docs
- Fixed broken documentation link (/core-concepts/stacks/locals → /stacks/locals)

Locals is a minor feature with key gotchas. Documentation now appropriately sized.

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@website/docs/stacks/locals.mdx`:
- Around line 167-169: Update the Docusaurus admonition title syntax by
replacing the bracketed title token ":::warning[Same-File Access Only]" with the
inline form ":::warning Same-File Access Only" so the admonition type and title
are separated by a space; locate the admonition that currently reads
":::warning[Same-File Access Only]" in locals.mdx and change it to the inline
title format for proper rendering.

@aknysh aknysh merged commit 2f95f4a into main Jan 21, 2026
58 checks passed
@aknysh aknysh deleted the aknysh/fix-locals-5 branch January 21, 2026 03:03
@mergify mergify bot removed the needs-cloudposse Needs Cloud Posse assistance label Jan 21, 2026
@github-actions
Copy link
Copy Markdown

Warning

Release Documentation Required

This PR is labeled minor or major and requires documentation updates:

  • Changelog entry - Add a blog post in website/blog/YYYY-MM-DD-feature-name.mdx
  • Roadmap update - Update website/src/data/roadmap.js with the new milestone

Alternatively: If this change doesn't require release documentation, remove the minor or major label.

@github-actions
Copy link
Copy Markdown

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

aknysh added a commit that referenced this pull request Jan 28, 2026
Issue: #2032

After PR #1994, settings could no longer reference locals (regression from
1.204). This adds template processing for settings, vars, and env sections
after locals are resolved, enabling bidirectional references between all
sections.

The fix ensures:
- Locals can reference settings (resolved during locals processing)
- Settings can reference locals (new template processing step)
- Vars can reference both locals and processed settings
- Env can reference locals, processed settings, and processed vars

Added processTemplatesInSection() helper and comprehensive tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants