Skip to content

[codex] consolidate terraform bulk execution on scheduler - #2466

Merged
Andriy Knysh (aknysh) merged 29 commits into
mainfrom
codex/dag-terraform-graph-bulk-path
Jun 6, 2026
Merged

Andriy Knysh (aknysh) merged 29 commits into
mainfrom
codex/dag-terraform-graph-bulk-path

Conversation

@shirkevich

@shirkevich Mikhail Shirkov (shirkevich) commented May 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • route Terraform --all, --components, and --query through the scheduler-backed Terraform adapter
  • build Terraform dependency graphs from dependencies.components first, with settings.depends_on fallback
  • preserve query-path auth manager setup, store resolver bridging, YAML function processing, and per-component CI hook capture
  • includes fix(terraform): preserve explicit identity and auth context for local runs #2348 identity/auth fixes in this stack so local --identity terraform testing works
  • include the credential-store concurrency-safety prerequisite discovered by concurrency validation
  • keep effective scheduler concurrency fixed at 1 for this PR

Stacking

This PR is stacked on PR 2 and targets codex/dag-scheduler-core.

PR 4 is #2468 and is stacked on this branch to introduce plan-only --max-concurrency wiring.

Supersedes the earlier fork-headed draft #2462 now that the stack branches exist in cloudposse/atmos.

Draft note

This branch is back to the intended PR 3 review shape: Terraform --all, --components, and --query share the graph-backed scheduler path, but execution remains sequential.

The temporary ATMOS_EXPERIMENTAL_DAG_MAX_CONCURRENCY validation hook has been removed. User-visible plan concurrency now belongs to PR 4.

This branch retains the narrow credential-store concurrency-safety prerequisite discovered during validation:

  • credential-store initialization no longer mutates global Viper env bindings per component and preserves ATMOS_KEYRING_TYPE precedence

Validation

  • go test ./pkg/scheduler ./pkg/scheduler/adapters ./internal/exec -run TestExecuteTerraformQuery|TestExecuteTerraformQueryNoMatches|TestBuildTerraformDependencyGraph|TestExecuteTerraformAllUsesGraphBackedSequentialOrder|TestExecuteTerraformComponentsUsesGraphBackedSequentialOrder|TestExecuteTerraformQueryUsesGraphBackedSequentialOrder|TestExecuteTerraformKeepsIndependentComponentsSequential|TestBuildTerraformGraph
  • go test ./pkg/auth/credentials
  • go test -race ./pkg/auth/credentials -run TestNewCredentialStoreWithConfig_ConcurrentInitialization
  • go test ./pkg/auth ./internal/exec -run TestCreateAndAuthenticateManagerWithAtmosConfig|TestSetupTerraformAuth|TestProcessComponentConfig_PropagatesAuthManager|TestProcessComponentConfig_AuthManagerGuardBranches
  • built build/atmos and live-tested against a downstream stack with terraform plan --all and an explicit identity

Validation findings carried forward

  • The first concurrency-4 validation run exposed an auth race: per-component credential-store initialization called global viper.BindEnv, causing fatal error: concurrent map writes. This PR fixes that narrowly in pkg/auth/credentials.
  • Higher-concurrency validation also showed local Terraform working-directory contention when multiple logical aliases share one physical Terraform component directory. PR 4 keeps path-based locking while introducing plan concurrency.

Follow-up discussion

The longer-term way to unlock true parallelism for aliases sharing one physical Terraform folder would be per-node isolated workdirs plus isolated TF_DATA_DIR and generated files. That needs repo-owner discussion because it changes the operator debugging model: Atmos would need to decide whether and how to retain those per-node copies for inspection, how atmos terraform shell maps to them, and how cleanup/debug artifacts are managed.

Summary by CodeRabbit

  • New Features

    • Graph-backed Terraform scheduler with deterministic dependency order, reversed destroy order, per-resource serialization, concurrency control, per-component output capture/hooks, and signal-aware cancellation.
    • New Terraform run options: --failure-mode, --max-concurrency, log-order, hide (including no-changes), and execution-summary file.
    • Line-prefixing writer for prefixed log output.
  • Bug Fixes

    • Credential keyring type now respects ATMOS_KEYRING_TYPE and is safe for concurrent init.
    • Workdir sync/hash skips Terraform/OpenTofu runtime dirs.
    • More tolerant Git repo opening for worktrees.
  • Tests

    • Large expansion of tests covering scheduler behavior, CLI options, concurrency, logging, auth, and new utilities.

@atmos-pro

atmos-pro Bot commented May 21, 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/l Large size PR label May 21, 2026
@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@mergify

mergify Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

⚠️ The sha of the head commit of this PR conflicts with #2462. Mergify cannot evaluate rules on this PR. Once #2462 is merged or closed, Mergify will resume processing this PR. ⚠️

@codecov

codecov Bot commented May 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.15736% with 270 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.89%. Comparing base (3c0b3e5) to head (e41a389).

Files with missing lines Patch % Lines
pkg/scheduler/adapters/terraform.go 77.15% 113 Missing and 65 partials ⚠️
pkg/git/git.go 67.36% 17 Missing and 14 partials ⚠️
cmd/terraform/utils.go 41.17% 19 Missing and 1 partial ⚠️
internal/exec/terraform_affected.go 76.92% 7 Missing and 5 partials ⚠️
cmd/terraform/destroy.go 65.21% 4 Missing and 4 partials ⚠️
cmd/terraform/workspace.go 16.66% 4 Missing and 1 partial ⚠️
cmd/terraform/apply.go 75.00% 1 Missing and 1 partial ⚠️
cmd/terraform/deploy.go 50.00% 1 Missing and 1 partial ⚠️
cmd/terraform/init.go 33.33% 1 Missing and 1 partial ⚠️
cmd/terraform/options.go 93.75% 1 Missing and 1 partial ⚠️
... and 4 more

❌ Your patch check has failed because the patch coverage (77.15%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2466      +/-   ##
==========================================
+ Coverage   78.88%   78.89%   +0.01%     
==========================================
  Files        1198     1200       +2     
  Lines      114797   115889    +1092     
==========================================
+ Hits        90560    91435     +875     
- Misses      19270    19397     +127     
- Partials     4967     5057      +90     
Flag Coverage Δ
unittests 78.89% <77.15%> (+0.01%) ⬆️

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/terraform_all.go 78.06% <100.00%> (-6.81%) ⬇️
internal/exec/terraform_query.go 100.00% <100.00%> (+20.37%) ⬆️
pkg/auth/credentials/store.go 79.06% <100.00%> (+0.49%) ⬆️
pkg/schema/schema.go 87.70% <ø> (ø)
pkg/terraform/output/environment.go 95.55% <100.00%> (+0.31%) ⬆️
cmd/terraform/apply.go 77.04% <75.00%> (-1.14%) ⬇️
cmd/terraform/deploy.go 80.00% <50.00%> (-2.76%) ⬇️
cmd/terraform/init.go 60.00% <33.33%> (-6.67%) ⬇️
cmd/terraform/options.go 96.00% <93.75%> (-4.00%) ⬇️
... and 10 more

... and 10 files with indirect coverage changes

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

@mergify

mergify Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

💥 This pull request now has conflicts. Could you fix it Mikhail Shirkov (@shirkevich)? 🙏

@mergify mergify Bot added the conflict This PR has conflicts label May 25, 2026
@shirkevich
Mikhail Shirkov (shirkevich) force-pushed the codex/dag-terraform-graph-bulk-path branch from 1f0197e to 3d1c53c Compare May 25, 2026 07:53
@github-actions github-actions Bot added size/m Medium size PR and removed size/l Large size PR labels May 25, 2026
@mergify mergify Bot removed the conflict This PR has conflicts label May 25, 2026
@shirkevich
Mikhail Shirkov (shirkevich) marked this pull request as ready for review May 26, 2026 18:07
@shirkevich
Mikhail Shirkov (shirkevich) requested a review from a team as a code owner May 26, 2026 18:07
@osterman

Copy link
Copy Markdown
Member

CodeRabbit (@coderabbitai) can you spot any regressions?

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get list of files changed in PR `#2466`
gh pr view 2466 --repo cloudposse/atmos --json files --jq '.files[].path' 2>/dev/null | head -80

Length of output: 399


🏁 Script executed:

#!/bin/bash
# Get the PR diff
gh pr diff 2466 --repo cloudposse/atmos 2>/dev/null | head -2000

Length of output: 32391


🏁 Script executed:

#!/bin/bash
# Check for any remaining references to removed functions from terraform_all.go
rg -n "buildTerraformDependencyGraph|applyFiltersToGraph|executeInDependencyOrder|processTerraformComponent|walkTerraformComponents" --type go

Length of output: 7726


🏁 Script executed:

#!/bin/bash
# Check what remains in terraform_all.go after the diff
cat internal/exec/terraform_all.go

Length of output: 10527


🏁 Script executed:

#!/bin/bash
# Check what remains in terraform_query.go after the diff
cat internal/exec/terraform_query.go

Length of output: 4079


🏁 Script executed:

#!/bin/bash
# Check the full terraform_all.go on the PR branch for dead code / orphaned functions
gh api repos/cloudposse/atmos/contents/internal/exec/terraform_all.go?ref=codex/dag-scheduler-consolidate-bulk-terraform 2>/dev/null | jq -r '.content' | base64 -d 2>/dev/null || echo "Try different branch ref"

Length of output: 356


🏁 Script executed:

#!/bin/bash
# Get PR branch name
gh pr view 2466 --repo cloudposse/atmos --json headRefName --jq '.headRefName'

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Check for destroy-order reversal in the scheduler
rg -n "destroy|reverse|SubCommand" --type go pkg/scheduler/

Length of output: 858


🏁 Script executed:

#!/bin/bash
# Check isComponentEnabled implementation
rg -n "func isComponentEnabled" --type go -A 20

Length of output: 2994


🏁 Script executed:

#!/bin/bash
# Check if executeInDependencyOrder or executeTerraformForNode are called anywhere else
rg -n "executeInDependencyOrder|executeTerraformForNode" --type go

Length of output: 1353


🏁 Script executed:

#!/bin/bash
# Check if applyFiltersToGraph is called from production code (not tests)
rg -n "applyFiltersToGraph" --type go -g '!*_test.go'

Length of output: 449


🏁 Script executed:

#!/bin/bash
# Check the terraform_affected_graph.go call to buildTerraformDependencyGraph for context
rg -n "buildTerraformDependencyGraph" --type go -C 5 internal/exec/terraform_affected_graph.go

Length of output: 514


🏁 Script executed:

#!/bin/bash
# Check the new adapter's shouldSkipComponent vs old shouldSkipComponentForGraph - specifically for metadata.enabled
rg -n "enabled" --type go internal/exec/terraform_all.go -C 3

Length of output: 433



@osterman Here are the regressions I spotted:


🔴 Regression 1 — terraform destroy --all executes in wrong order

File: internal/exec/terraform_all.go → now delegates to scheduleradapters.ExecuteTerraform

The old executeInDependencyOrder (still in terraform_all.go but no longer called) explicitly reverses topological order for the destroy subcommand so that dependents are destroyed before their dependencies:

// terraform_all.go (dead path)
if info.SubCommand == "destroy" {
    for i, j := 0, len(executionOrder)-1; i < j; i, j = i+1, j-1 {
        executionOrder[i], executionOrder[j] = executionOrder[j], executionOrder[i]
    }
}

The new scheduleradapters.ExecuteTerraform has no equivalent reversal. The TerraformDispatcher and the scheduler both operate in standard topological sort order regardless of subcommand. Running atmos terraform destroy --all will now destroy dependencies before dependents, which is the inverse of safe destroy ordering.


🟡 Regression 2 — Dead production code left behind in terraform_all.go

executeInDependencyOrder (line 77) is no longer called by ExecuteTerraformAll and has no other callers outside tests. Same for applyFiltersToGraph (line 196) — it's only referenced in terraform_all_test.go, not from any production path. These are orphaned functions that should either be removed or (for executeInDependencyOrder) their destroy-reversal logic should be ported to the adapter.


🟡 Regression 3 — Duplicate walkTerraformComponents with divergence risk

internal/exec/terraform_utils.go and pkg/scheduler/adapters/terraform.go both define walkTerraformComponents independently. Fixes to one won't propagate to the other. terraform_affected_graph.go uses the exec version; bulk execution uses the adapter version.


ℹ️ Minor — Double query evaluation

FilterTerraformGraph already removes non-matching nodes; TerraformDispatcher.shouldSkipByQuery re-evaluates the same query expression during dispatch. Not a behavioral regression, just redundant work.

@shirkevich
Mikhail Shirkov (shirkevich) force-pushed the codex/dag-terraform-graph-bulk-path branch from 3d1c53c to 713f3ff Compare May 27, 2026 18:13
@shirkevich

Copy link
Copy Markdown
Collaborator Author

CodeRabbit (@coderabbitai) review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented May 27, 2026 •

Copy link
Copy Markdown
Contributor

Wondering what really moved? Review this PR in Change Stack to inspect semantic changes, definitions, and references.

Review Change Stack

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: ef40b136-29ca-4b3f-8412-e7c9a9d0651d

📥 Commits

Reviewing files that changed from the base of the PR and between d57ce42 and e41a389.

📒 Files selected for processing (2)
  • internal/exec/terraform_all.go
  • pkg/auth/credentials/store_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/exec/terraform_all.go
  • pkg/auth/credentials/store_test.go

📝 Walkthrough

Walkthrough

Routes multi-component Terraform execution through a scheduler adapter with context-aware entrypoints, adds CLI options for concurrency/failure/logging, implements graph build/filter/reverse and dispatch, centralizes per-node execution/output capture and hooks, and adds extensive tests, fixtures, and small utilities.

Changes

Terraform Scheduler Adapter & Integration

Layer / File(s) Summary
CLI options and parsing
cmd/terraform/options.go, cmd/terraform/*, pkg/schema/schema.go, cmd/terraform/options_test.go
Add/validate Terraform run options (max-concurrency, failure-mode, plan log/hide, summary file); ParseTerraformRunOptions now returns (opts, error) and options are mapped into ConfigAndStacksInfo.
Context-aware CLI routing & signal handling
cmd/terraform/utils.go, cmd/terraform/workspace.go, cmd/terraform/*
Introduce signal-cancelable contexts and route multi-component execution to context-aware entrypoints (Execute*WithContext).
internal exec entrypoints
internal/exec/terraform_all.go, internal/exec/terraform_query.go, internal/exec/terraform_affected.go
Add context-aware ExecuteTerraform*WithContext, resolve stacks by info.Stack, and delegate multi-component execution to scheduleradapters.ExecuteTerraform with per-component executor wiring.
Scheduler adapter API & orchestration
pkg/scheduler/adapters/terraform.go
New adapter types (TerraformExecution, TerraformOptions, TerraformExecutor, selection), graph build/filter/reverse logic, concurrency/failure-mode enforcement, scheduler invocation, and deterministic JSON summary output.
Dispatcher, locking, and output
pkg/scheduler/adapters/terraform.go
TerraformDispatcher.Dispatch handles query-based skips, per-resource serialization (keyed mutex), grouped vs stream logging, per-node log files, masking/truncation of failure output, and result mapping.
Adapter test suite
pkg/scheduler/adapters/terraform_test.go
Comprehensive tests for ordering (including destroy reverse order), selection semantics, concurrency/serialization, log/capture modes, auto-approve rules, and summary writing.
Per-component capture & hooks
internal/exec/terraform_query.go, internal/exec/terraform_utils_test.go
New executor (executeTerraformQueryComponent) captures stdout/stderr when requested and invokes info.PerComponentHook with combined output and error.
Credential store keyring resolution & tests
pkg/auth/credentials/store.go, pkg/auth/credentials/store_test.go
Introduce resolveKeyringType that prefers ATMOS_KEYRING_TYPE env var, add concurrent initialization test for NewCredentialStoreWithConfig.
Git worktree-tolerant repo open & tests
pkg/git/git.go, pkg/git/git_test.go
Add tolerant storer and helpers to open repos when go-git errors on worktreeConfig extensions; add native-git tests covering extension scenarios and new sentinel error.
LinePrefixWriter utility & tests
pkg/io/line_prefix_writer.go, pkg/io/line_prefix_writer_test.go
New writer that prefixes complete lines with buffering/flush and supports shared mutex serialization; tests for buffering, concurrency, error handling, and carriage-return segments.
Workdir sync/hash exclusions & tests
pkg/provisioner/workdir/fs.go, pkg/provisioner/workdir/fs_test.go
Centralize skip list for runtime dirs (.atmos, .terraform, terraform.tfstate.d) in SyncDir and HashDir and add tests verifying skipped copies and hash stability.
Fixtures & CLI snapshots
tests/fixtures/scenarios/terraform-floci-dag/*, tests/snapshots/*
Add terraform-floci-dag fixtures and update CLI help snapshots for new flags.
CLI test runner refactor
tests/cli_test.go, various tests/* files
Centralize Atmos test runner initialization with ensureAtmosRunner (sync.Once) and update multiple CLI tests to use it.
go.mod & errors
go.mod, errors/errors.go
Promote mapstructure to direct require and add ErrUnexpectedGitRevParseOutput sentinel.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Describe as ExecuteDescribeStacks
  participant Adapter as scheduleradapters.ExecuteTerraform
  participant Scheduler
  participant Dispatcher as TerraformDispatcher
  participant Executor as TerraformExecutor

  CLI->>Describe: describe stacks (info.Stack)
  CLI->>Adapter: ExecuteTerraform(ctx, TerraformOptions)
  Adapter->>Scheduler: schedule filtered nodes
  Scheduler->>Dispatcher: run node
  Dispatcher->>Executor: invoke per-node executor with node-specific Info
  Executor->>Dispatcher: return result / error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

minor

Suggested reviewers

  • osterman
✨ 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 codex/dag-terraform-graph-bulk-path

# Conflicts:
#	pkg/terraform/output/environment.go

@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: 2

🧹 Nitpick comments (2)
pkg/git/git.go (1)

317-324: ⚡ Quick win

Consider adding a comment explaining string-based error detection.

String-based error inspection is fragile to upstream message changes. A brief comment explaining that go-git doesn't expose typed errors for this extension failure would help future maintainers understand why this approach is necessary.

Example:

// isUnsupportedWorktreeConfigError reports go-git failures caused by worktreeConfig.
// Uses string matching because go-git does not export typed errors for extension failures.
func isUnsupportedWorktreeConfigError(err error) bool {
🤖 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/git/git.go` around lines 317 - 324, Add a brief explanatory comment above
isUnsupportedWorktreeConfigError explaining why the function relies on string
matching (e.g., go-git does not export typed errors for worktreeConfig/extension
failures so we must inspect the error text), then keep the existing
implementation; reference the function name isUnsupportedWorktreeConfigError and
mention the specific strings "repositoryformatversion" and "worktreeconfig" to
clarify why those substrings are used.
cmd/terraform/apply.go (1)

124-125: ⚡ Quick win

Inconsistency: apply missing max-concurrency flag.

The destroy and plan commands both register a --max-concurrency flag (destroy.go:41, plan.go:128), but apply does not. This creates an inconsistent UX where users can control concurrency for plan/destroy but not apply when using --all, --affected, or --components.

🔧 Suggested addition
 		flags.WithBoolFlag("all", "", false, "Apply all components in all stacks"),
 		flags.WithStringFlag("failure-mode", "", terraformFailureModeFailFast, "Terraform apply failure handling mode. Supported values: fail-fast, keep-going"),
+		flags.WithIntFlag("max-concurrency", "", 1, "Maximum number of Terraform apply components to execute concurrently"),
 		flags.WithBoolFlag("ci", "", false, "Enable CI mode for automated pipelines (writes job summary, outputs)"),
 		flags.WithEnvVars("from-plan", "ATMOS_TERRAFORM_APPLY_FROM_PLAN"),
 		flags.WithEnvVars("planfile", "ATMOS_TERRAFORM_APPLY_PLANFILE"),
 		flags.WithEnvVars("failure-mode", "ATMOS_TERRAFORM_APPLY_FAILURE_MODE"),
+		flags.WithEnvVars("max-concurrency", "ATMOS_TERRAFORM_APPLY_MAX_CONCURRENCY"),
 		flags.WithEnvVars("ci", "ATMOS_CI", "CI"),
🤖 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 `@cmd/terraform/apply.go` around lines 124 - 125, The apply command is missing
the same max-concurrency option that plan and destroy already expose, creating
an inconsistent CLI surface for multi-component operations. Update the flag
registration in the apply command setup to add the `--max-concurrency` option
alongside the existing flags in the apply command’s flag list, using the same
naming and behavior as the corresponding flag handling in the plan and destroy
commands so `--all`, `--affected`, and `--components` can be controlled
consistently.
🤖 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 `@cmd/terraform/options.go`:
- Around line 78-80: The parsed values for FailureMode and PlanLogOrder must be
validated immediately after building the options struct (the block that sets
MaxConcurrency, FailureMode, PlanLogOrder in cmd/terraform/options.go) to fail
fast with a clear message; check FailureMode against the allowed set
{"fail-fast","keep-going"} and PlanLogOrder against {"stream","grouped"} and
return a formatted error listing valid options if either is invalid. Change the
options builder function to return (options, error) instead of only options and
propagate that error through all call sites mentioned (apply.go, destroy.go,
plan.go) so callers handle the validation error. Ensure error messages reference
the offending flag name and allowed values.

In `@pkg/git/git.go`:
- Around line 387-402: In gitRepositoryPaths, wrap the error returned by
exec.Command(...).Output() with the static sentinel from errors/errors.go
instead of returning the raw err; replace the current "return "", "", "", err"
with a wrapped error (e.g. fmt.Errorf("%w: %v", errors.<appropriateSentinel>,
err)) so the failure to execute "git rev-parse" is categorized, and keep the
existing use of errUtils.ErrUnexpectedGitRevParseOutput for the unexpected
output branch.

---

Nitpick comments:
In `@cmd/terraform/apply.go`:
- Around line 124-125: The apply command is missing the same max-concurrency
option that plan and destroy already expose, creating an inconsistent CLI
surface for multi-component operations. Update the flag registration in the
apply command setup to add the `--max-concurrency` option alongside the existing
flags in the apply command’s flag list, using the same naming and behavior as
the corresponding flag handling in the plan and destroy commands so `--all`,
`--affected`, and `--components` can be controlled consistently.

In `@pkg/git/git.go`:
- Around line 317-324: Add a brief explanatory comment above
isUnsupportedWorktreeConfigError explaining why the function relies on string
matching (e.g., go-git does not export typed errors for worktreeConfig/extension
failures so we must inspect the error text), then keep the existing
implementation; reference the function name isUnsupportedWorktreeConfigError and
mention the specific strings "repositoryformatversion" and "worktreeconfig" to
clarify why those substrings are used.
🪄 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: 6d2209e8-cff4-4ece-90dc-a3ed128fd179

📥 Commits

Reviewing files that changed from the base of the PR and between 1ad352d and 31e4a44.

📒 Files selected for processing (47)
  • cmd/terraform/apply.go
  • cmd/terraform/destroy.go
  • cmd/terraform/options.go
  • cmd/terraform/options_test.go
  • cmd/terraform/plan.go
  • cmd/terraform/utils.go
  • errors/errors.go
  • go.mod
  • internal/exec/terraform_affected.go
  • internal/exec/terraform_all.go
  • internal/exec/terraform_query.go
  • internal/exec/terraform_utils_test.go
  • pkg/auth/credentials/store.go
  • pkg/auth/credentials/store_test.go
  • pkg/git/git.go
  • pkg/git/git_test.go
  • pkg/io/line_prefix_writer.go
  • pkg/io/line_prefix_writer_test.go
  • pkg/provisioner/workdir/fs.go
  • pkg/provisioner/workdir/fs_test.go
  • pkg/scheduler/adapters/terraform.go
  • pkg/scheduler/adapters/terraform_test.go
  • pkg/schema/schema.go
  • pkg/terraform/output/environment.go
  • tests/cli_auth_console_test.go
  • tests/cli_auth_login_provider_test.go
  • tests/cli_describe_identity_test.go
  • tests/cli_double_hyphen_test.go
  • tests/cli_identity_flag_test.go
  • tests/cli_interactive_test.go
  • tests/cli_plugin_cache_test.go
  • tests/cli_profile_test.go
  • tests/cli_skip_init_test.go
  • tests/cli_terraform_test.go
  • tests/cli_test.go
  • tests/cli_workdir_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/atmos.yaml
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/alias-shared/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/bucket-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/final-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/queue-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/seed/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/topic-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/stacks/deploy/local.yaml
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stdout.golden
  • tests/snapshots/TestCLICommands_config_alias_tp_--help_shows_terraform_plan_help.stdout.golden
💤 Files with no reviewable changes (31)
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stdout.golden
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/bucket-marker/main.tf
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden
  • tests/cli_describe_identity_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/atmos.yaml
  • pkg/io/line_prefix_writer.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/topic-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/seed/main.tf
  • tests/cli_double_hyphen_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/final-marker/main.tf
  • pkg/terraform/output/environment.go
  • tests/cli_terraform_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/queue-marker/main.tf
  • tests/cli_skip_init_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/stacks/deploy/local.yaml
  • tests/cli_test.go
  • tests/cli_identity_flag_test.go
  • tests/cli_auth_login_provider_test.go
  • tests/cli_interactive_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/alias-shared/main.tf
  • pkg/provisioner/workdir/fs.go
  • pkg/io/line_prefix_writer_test.go
  • tests/cli_plugin_cache_test.go
  • tests/snapshots/TestCLICommands_config_alias_tp_--help_shows_terraform_plan_help.stdout.golden
  • tests/cli_auth_console_test.go
  • tests/cli_profile_test.go
  • pkg/provisioner/workdir/fs_test.go
  • tests/cli_workdir_test.go
  • pkg/schema/schema.go
  • pkg/scheduler/adapters/terraform_test.go
  • pkg/scheduler/adapters/terraform.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/auth/credentials/store.go

Comment thread cmd/terraform/options.go
Comment thread pkg/git/git.go
@aknysh

Copy link
Copy Markdown
Member

Mikhail Shirkov (@shirkevich) please address the coderabbitai comments (and nitpick comments), thanks

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

Caution

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

⚠️ Outside diff range comments (1)
pkg/auth/credentials/store_test.go (1)

183-193: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Subtests missing env var cleanup - test is environment-dependent.

The "auth config overrides default" and "default remains system" subtests don't clear ATMOS_KEYRING_TYPE. If this var is set externally (CI, dev machine), these tests become flaky or pass for the wrong reason.

Proposed fix
 	t.Run("auth config overrides default", func(t *testing.T) {
+		t.Setenv("ATMOS_KEYRING_TYPE", "") // Clear any inherited value.
 		authConfig := &schema.AuthConfig{
 			Keyring: schema.KeyringConfig{Type: "file"},
 		}

 		assert.Equal(t, "file", resolveKeyringType(authConfig))
 	})

 	t.Run("default remains system", func(t *testing.T) {
+		t.Setenv("ATMOS_KEYRING_TYPE", "") // Clear any inherited value.
 		assert.Equal(t, "system", resolveKeyringType(nil))
 	})

Based on learnings: "tests should prefer t.Setenv for environment variable setup/teardown instead of os.Setenv/Unsetenv to ensure test-scoped isolation."

🤖 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/auth/credentials/store_test.go` around lines 183 - 193, The two subtests
around resolveKeyringType are environment-dependent because they don't isolate
ATMOS_KEYRING_TYPE; update both subtests to use t.Setenv("ATMOS_KEYRING_TYPE",
"") (or set to a specific value) at the start so the env var is test-scoped and
automatically restored, ensuring "auth config overrides default" and "default
remains system" reliably exercise resolveKeyringType(authConfig) and
resolveKeyringType(nil) respectively.
🧹 Nitpick comments (2)
internal/exec/terraform_all.go (2)

7-7: 💤 Low value

Import alias inconsistency.

This file imports github.com/charmbracelet/log directly while the coding guidelines specify using pkg/logger with the log alias. Other files in this PR (e.g., terraform_affected.go) use log "github.com/cloudposse/atmos/pkg/logger".

Suggested fix
-	log "github.com/charmbracelet/log"
+	log "github.com/cloudposse/atmos/pkg/logger"
🤖 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/terraform_all.go` at line 7, The import in terraform_all.go
currently pulls github.com/charmbracelet/log; change it to use the project
logger alias by replacing that import with log
"github.com/cloudposse/atmos/pkg/logger" so it matches other files (e.g.,
terraform_affected.go) and coding guidelines; ensure any references to log in
the file continue to compile with the new import alias.

89-119: ⚡ Quick win

Dead production code flagged in PR comments.

Per the PR discussion, executeInDependencyOrder and applyFiltersToGraph are no longer called by production paths and are only referenced from tests. The scheduler adapter now handles this logic. Consider removing or marking as deprecated to avoid maintenance burden.

Also applies to: 208-240

🤖 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/terraform_all.go` around lines 89 - 119, The functions
executeInDependencyOrder and applyFiltersToGraph are dead production code and
should be removed or explicitly deprecated; either delete both functions (and
clean up any now-unused imports) and update tests to exercise the scheduler
adapter logic instead, or if tests still need them keep them but add a clear
deprecation comment (// Deprecated: use scheduler adapter XYZ) and mark them
unexported or gate them behind a test-only build tag, then run and fix any
failing tests that referenced executeInDependencyOrder or applyFiltersToGraph so
all usages point to the scheduler adapter methods.
🤖 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.

Outside diff comments:
In `@pkg/auth/credentials/store_test.go`:
- Around line 183-193: The two subtests around resolveKeyringType are
environment-dependent because they don't isolate ATMOS_KEYRING_TYPE; update both
subtests to use t.Setenv("ATMOS_KEYRING_TYPE", "") (or set to a specific value)
at the start so the env var is test-scoped and automatically restored, ensuring
"auth config overrides default" and "default remains system" reliably exercise
resolveKeyringType(authConfig) and resolveKeyringType(nil) respectively.

---

Nitpick comments:
In `@internal/exec/terraform_all.go`:
- Line 7: The import in terraform_all.go currently pulls
github.com/charmbracelet/log; change it to use the project logger alias by
replacing that import with log "github.com/cloudposse/atmos/pkg/logger" so it
matches other files (e.g., terraform_affected.go) and coding guidelines; ensure
any references to log in the file continue to compile with the new import alias.
- Around line 89-119: The functions executeInDependencyOrder and
applyFiltersToGraph are dead production code and should be removed or explicitly
deprecated; either delete both functions (and clean up any now-unused imports)
and update tests to exercise the scheduler adapter logic instead, or if tests
still need them keep them but add a clear deprecation comment (// Deprecated:
use scheduler adapter XYZ) and mark them unexported or gate them behind a
test-only build tag, then run and fix any failing tests that referenced
executeInDependencyOrder or applyFiltersToGraph so all usages point to the
scheduler adapter methods.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 126ca3cd-7b45-4fed-88eb-5795a375b1d9

📥 Commits

Reviewing files that changed from the base of the PR and between 1ad352d and d57ce42.

📒 Files selected for processing (51)
  • cmd/terraform/apply.go
  • cmd/terraform/deploy.go
  • cmd/terraform/destroy.go
  • cmd/terraform/init.go
  • cmd/terraform/options.go
  • cmd/terraform/options_test.go
  • cmd/terraform/plan.go
  • cmd/terraform/plan_diff.go
  • cmd/terraform/subcommands_test.go
  • cmd/terraform/utils.go
  • cmd/terraform/workspace.go
  • errors/errors.go
  • go.mod
  • internal/exec/terraform_affected.go
  • internal/exec/terraform_all.go
  • internal/exec/terraform_query.go
  • internal/exec/terraform_utils_test.go
  • pkg/auth/credentials/store.go
  • pkg/auth/credentials/store_test.go
  • pkg/git/git.go
  • pkg/git/git_test.go
  • pkg/io/line_prefix_writer.go
  • pkg/io/line_prefix_writer_test.go
  • pkg/provisioner/workdir/fs.go
  • pkg/provisioner/workdir/fs_test.go
  • pkg/scheduler/adapters/terraform.go
  • pkg/scheduler/adapters/terraform_test.go
  • pkg/schema/schema.go
  • pkg/terraform/output/environment.go
  • tests/cli_auth_console_test.go
  • tests/cli_auth_login_provider_test.go
  • tests/cli_describe_identity_test.go
  • tests/cli_double_hyphen_test.go
  • tests/cli_identity_flag_test.go
  • tests/cli_interactive_test.go
  • tests/cli_plugin_cache_test.go
  • tests/cli_profile_test.go
  • tests/cli_skip_init_test.go
  • tests/cli_terraform_test.go
  • tests/cli_test.go
  • tests/cli_workdir_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/atmos.yaml
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/alias-shared/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/bucket-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/final-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/queue-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/seed/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/topic-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/stacks/deploy/local.yaml
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stdout.golden
💤 Files with no reviewable changes (30)
  • tests/fixtures/scenarios/terraform-floci-dag/atmos.yaml
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/topic-marker/main.tf
  • tests/fixtures/scenarios/terraform-floci-dag/stacks/deploy/local.yaml
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_--help.stdout.golden
  • tests/cli_auth_login_provider_test.go
  • tests/snapshots/TestCLICommands_atmos_terraform_apply_help.stdout.golden
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/bucket-marker/main.tf
  • pkg/provisioner/workdir/fs.go
  • pkg/terraform/output/environment.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/queue-marker/main.tf
  • tests/cli_identity_flag_test.go
  • tests/cli_interactive_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/seed/main.tf
  • tests/cli_terraform_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/final-marker/main.tf
  • tests/cli_test.go
  • pkg/provisioner/workdir/fs_test.go
  • tests/fixtures/scenarios/terraform-floci-dag/components/terraform/alias-shared/main.tf
  • tests/cli_auth_console_test.go
  • tests/cli_profile_test.go
  • tests/cli_double_hyphen_test.go
  • pkg/io/line_prefix_writer.go
  • tests/cli_skip_init_test.go
  • pkg/io/line_prefix_writer_test.go
  • tests/cli_workdir_test.go
  • pkg/schema/schema.go
  • tests/cli_plugin_cache_test.go
  • pkg/scheduler/adapters/terraform.go
  • pkg/scheduler/adapters/terraform_test.go
  • tests/cli_describe_identity_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • go.mod
  • pkg/auth/credentials/store.go

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 5, 2026
@aknysh
Andriy Knysh (aknysh) merged commit 0946fbc into main Jun 6, 2026
60 checks passed
@aknysh
Andriy Knysh (aknysh) deleted the codex/dag-terraform-graph-bulk-path branch June 6, 2026 00:04
@atmos-pro

atmos-pro Bot commented Jun 6, 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 commented Jun 6, 2026

Copy link
Copy Markdown

These changes were released in v1.221.0-rc.5.

This branch was successfully deployed

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

Labels

no-release Do not create a new release (wait for additional code changes) size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants