Add core git YAML functions @osterman (#2537)
## what- Add core Git YAML functions:
!git.root,!git.sha,!git.branch, and!git.ref. - Resolve Git metadata through
pkg/git, withpkg/utilslimited to compatibility shims and YAML tag registration. - Wire Git tag resolution through config preprocessing, stack/component YAML processing, and function registry metadata.
- Add a changelog post and roadmap milestone for the new Git YAML functions.
why
- Allow dev stack/component source versions to pin to the current Git SHA via
!git.ref. - Keep prod pins explicit while giving dev environments PR-aware source refs.
- Avoid expanding
pkg/utilsby placing Git behavior in the self-contained Git package.
references
- n/a
Summary by CodeRabbit
-
New Features
- Added Git YAML tags (!git.root / !repo-root, !git.sha, !git.ref, !git.branch) to resolve repo root, commit SHA/ref, and branch in configs and stacks; !git.ref can pin source versions.
-
Refactor
- Centralized git tag resolution for consistent behavior, alias support, unified fallbacks, and clearer error handling.
-
Tests
- Expanded coverage for tag resolution, fallbacks, detached‑HEAD behavior, and real-repo scenarios.
-
Documentation
- Updated blog post and roadmap with examples and usage notes.
🚀 Enhancements
Fix templated store hook execution @osterman (#2539)
## what- Render hook execution fields only after a hook matches the current event and skip filters.
- Preserve static hook discovery/preflight while supporting
!templateand bare Go templates in store hook names, output keys, and output values. - Add regression tests for templated store hooks and non-matching hooks with invalid execution-only templates.
why
- Fixes a regression where templated
store-outputs.namevalues were used literally, causing store lookup failures. - Keeps pre-auth hook discovery safe while allowing execution-time hook fields to use the fully available component context.
- Prevents future regressions for both YAML function and bare Go template forms.
references
- Closes #2538
Summary by CodeRabbit
-
New Features
- Hooks now resolve execution-time templates and custom YAML functions, supporting nested templating, rendering into hook execution fields, stronger type validation, and clearer hook-specific error messages.
-
Tests
- Added tests for template rendering, YAML-function evaluation, nested value processing, error cases, and store-hook execution behavior.
fix(auth): normalize override keys to uppercase in filterAtmosOverrides (#2349) @thejrose1984 (#2541)
## what- Uppercase the override key before the prefix check (and in the returned map) inside
pkg/auth/manager_env_overrides.go:filterAtmosOverrides. - Add regression test cases in
TestFilterAtmosOverridescovering Viper-lowercased keys, mixed-case keys, and mixed atmos/non-atmos casings.
why
filterAtmosOverrides did a case-sensitive strings.HasPrefix(k, \"ATMOS_\"). The function's documented contract was "only keys with the ATMOS_* prefix" — but in production the only realistic source of its input map is an MCP server env: block in atmos.yaml / .atmos.d/mcp.yaml, which Viper loads with all map keys lowercased.
This is the same Viper-lowercasing pitfall already documented and handled on a sibling code path by pkg/mcp/client/mcpconfig.go:copyEnv (the CLI-provider pass-through that writes config files for Claude Code / Codex / Gemini). That fix wasn't applied to the auth code path, so an authored:
mcp:
servers:
atmos:
command: atmos
args: [\"mcp\", \"start\"]
env:
ATMOS_PROFILE: managers
identity: core-root/terraformreached filterAtmosOverrides as {\"atmos_profile\": \"managers\"}, was silently dropped, and the auth manager was rebuilt against the default profile. Identity resolution then surfaced as:
✗ Server failed to start
Error: MCP server failed to start: atmos: auth setup failed for \"atmos\": identity not found: core-root/terraform
I confirmed Viper's lowercasing end-to-end against the actual schema.MCPServerConfig shape (Env map[string]string):
env key=\"atmos_profile\" value=\"managers\"
env key=\"aws_region\" value=\"us-east-1\"
— so the authored ATMOS_PROFILE is gone by the time the filter runs.
scope of behavior change
- Already-uppercase callers (
ATMOS_PROFILE): unchanged. - Previously-dropped lowercase/mixed-case callers (
atmos_profile,Atmos_Profile): now honored — and those are exactly the users hitting the documented bug. - Non-
ATMOS_*keys: still dropped, regardless of case (aws_profile,FOO,foo). - Existing
TestFilterAtmosOverridescases still pass unchanged. - Existing
TestCreateAndAuthenticateManagerWithEnvOverrides_*tests still pass unchanged.
alternatives considered
I weighed three fix locations on the original issue:
- Uppercase inside
filterAtmosOverrides(this PR). Smallest possible surface, single source of truth for the auth path, doesn't touch the MCP layer. copyEnv(or equivalent) insideScopedAuthProvider.ForServer. Localizes to the MCP adapter; downside is a future non-MCP consumer ofCreateAndAuthenticateManagerWithEnvOverridesthat loads its env map from YAML would hit the same trap.- Uppercase at
ParseConfigtime. Widest reach — would also affect subprocess env propagation. A real (if narrow) behavior change for users who deliberately set unconventionally-cased env vars inenv:and expected those passed to the spawned MCP server verbatim.
Option 1 fixes the documented case without altering any other code path's behavior or risking the subprocess-env corner case in Option 3.
references
- Closes #2349
- Related context:
pkg/mcp/client/mcpconfig.go:128(copyEnv) — the parallel fix on the CLI-provider pass-through path that documents the Viper-lowercasing trap.
test plan
go test ./pkg/auth -run 'TestFilterAtmosOverrides|TestCreateAndAuthenticateManagerWithEnvOverrides' -v
go test ./pkg/auth ./pkg/mcp/client/...
Both pass. New regression subtests:
viper-lowercased atmos key is normalized to uppercasemixed-case atmos key is normalized to uppercaseviper-lowercased non-atmos key is droppedmixed casings across atmos and non-atmos keys
Summary by CodeRabbit
Bug Fixes
- Fixed an issue where environment configuration overrides specified in lowercase format (from YAML configuration files) were incorrectly dropped during processing. Environment override keys are now properly normalized to ensure consistent handling regardless of the input format used.