Skip to content

Fix native CI dogfood regressions - #2681

Merged
Andriy Knysh (aknysh) merged 5 commits into
mainfrom
osterman/explore-release-bugs
Jul 3, 2026
Merged

Andriy Knysh (aknysh) merged 5 commits into
mainfrom
osterman/explore-release-bugs

Conversation

@osterman

@osterman Erik Osterman (Cloud Posse) (osterman) commented Jul 2, 2026 •

Copy link
Copy Markdown
Member

what

  • Fix native CI bootstrap so atmos git clone can run before repo-local profile/config files exist, and make the cache action fail fast when Atmos cache metadata is missing.
  • Add regressions and fixes for local backend path state reads, remote source-provisioned lock persistence, Docker python3, Aqua latest lookup fallback, and emulator job-container networking.
  • Attach emulator containers to the current GitHub job container network with aliases so Terraform can reach emulator endpoints without a nested docker run --network host wrapper.

why

  • Dogfooding Atmos native CI exposed release gaps across checkout bootstrap, cache setup, Terraform fixture state reads, source-provisioned workdirs, inherited toolchain installs, and emulator endpoint resolution.
  • These changes let GitHub Actions run the Atmos image as the job container while still using the host Docker socket for emulator-backed Terraform tests.

references

@atmos-pro

atmos-pro Bot commented Jul 2, 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 Jul 2, 2026
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@mergify

mergify Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

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 Jul 2, 2026
@osterman Erik Osterman (Cloud Posse) (osterman) added the patch A minor, backward compatible change label Jul 2, 2026
@osterman
Erik Osterman (Cloud Posse) (osterman) marked this pull request as ready for review July 2, 2026 19:37
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Resource Changes Found for bucket in test

Atmos CI create

Plan: 5 to add, 0 to change, 0 to destroy.
To reproduce this locally, run:

atmos terraform plan bucket -s test

Create

+ aws_s3_bucket.checkov_target
+ aws_s3_bucket.kics_target
+ aws_s3_bucket.this
+ aws_s3_bucket.trivy_target
+ aws_s3_bucket_public_access_block.trivy_target
Terraform Plan Summary
  # aws_s3_bucket.checkov_target will be created
  + resource "aws_s3_bucket" "checkov_target" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "atmos-native-ci-e2e-checkov-test"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + cors_rule (known after apply)

      + grant (known after apply)

      + lifecycle_rule (known after apply)

      + logging (known after apply)

      + object_lock_configuration (known after apply)

      + replication_configuration (known after apply)

      + server_side_encryption_configuration (known after apply)

      + versioning (known after apply)

      + website (known after apply)
    }

  # aws_s3_bucket.kics_target will be created
  + resource "aws_s3_bucket" "kics_target" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "atmos-native-ci-e2e-kics-test"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + cors_rule (known after apply)

      + grant (known after apply)

      + lifecycle_rule (known after apply)

      + logging (known after apply)

      + object_lock_configuration (known after apply)

      + replication_configuration (known after apply)

      + server_side_encryption_configuration (known after apply)

      + versioning (known after apply)

      + website (known after apply)
    }

  # aws_s3_bucket.this will be created
  + resource "aws_s3_bucket" "this" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "atmos-native-ci-e2e-test"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "AtmosFixture" = "native-ci-e2e"
          + "Stage"        = "test"
        }
      + tags_all                    = {
          + "AtmosFixture" = "native-ci-e2e"
          + "Stage"        = "test"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + cors_rule (known after apply)

      + grant (known after apply)

      + lifecycle_rule (known after apply)

      + logging (known after apply)

      + object_lock_configuration (known after apply)

      + replication_configuration (known after apply)

      + server_side_encryption_configuration (known after apply)

      + versioning (known after apply)

      + website (known after apply)
    }

  # aws_s3_bucket.trivy_target will be created
  + resource "aws_s3_bucket" "trivy_target" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "atmos-native-ci-e2e-trivy-test"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + cors_rule (known after apply)

      + grant (known after apply)

      + lifecycle_rule (known after apply)

      + logging (known after apply)

      + object_lock_configuration (known after apply)

      + replication_configuration (known after apply)

      + server_side_encryption_configuration (known after apply)

      + versioning (known after apply)

      + website (known after apply)
    }

  # aws_s3_bucket_public_access_block.trivy_target will be created
  + resource "aws_s3_bucket_public_access_block" "trivy_target" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }

Plan: 5 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + bucket_name = "atmos-native-ci-e2e-test"


Workspace "test" doesn't exist.

You can create this workspace with the "new" subcommand 
or include the "-or-create" flag with the "select" subcommand.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026 •

Copy link
Copy Markdown
Contributor

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: 4e3258eb-1833-4c5f-8454-e1e2ff1735eb

📥 Commits

Reviewing files that changed from the base of the PR and between 0789557 and e98b7ea.

📒 Files selected for processing (1)
  • .github/workflows/test.yml

📝 Walkthrough

Walkthrough

This PR updates CI and workflow settings, adds CI bootstrap handling for no-arg git clone, extends Terraform backend path resolution, adds container network attachment and inspection support, updates emulator endpoint/network behavior, skips remote workdir lock persistence, and adds Aqua registry retry handling.

Changes

Dockerfile and Cache Action Validation

Layer / File(s) Summary
Dependency and cache validation
Dockerfile, actions/cache/action.yml, cmd/docker_and_action_regression_test.go, .github/workflows/test.yml
Adds python3 to the image install list, adds cache metadata validation before cache use, updates workflow settings, and adds regression tests for the Dockerfile and cache action changes.

CI Git Clone Bootstrap Detection

Layer / File(s) Summary
Bootstrap detection and config init handling
cmd/root.go, cmd/root_test.go
Adds argument-parsing helpers for bootstrap detection, wires them into config init error handling, and adds unit tests for the detection and error path.

Terraform Local Backend Path Override

Layer / File(s) Summary
Configured backend path resolution
internal/terraform_backend/terraform_backend_local.go, internal/terraform_backend/terraform_backend_local_test.go
Adds configured local backend path lookup, uses it in local backend state resolution, and tests component-relative and workdir-relative path handling.

Container Network Attachment and Emulator Network Reuse

Layer / File(s) Summary
Network data model changes
pkg/container/runtime.go, pkg/container/lifecycle.go
Adds network attachment types and fields to the runtime and lifecycle container config structures.
Docker and Podman network parsing
pkg/container/common.go, pkg/container/common_test.go, pkg/container/docker.go, pkg/container/docker_unit_test.go, pkg/container/podman.go, pkg/container/podman_test.go
Adds network flags to container create args and populates container info networks from Docker and Podman inspect output, with tests.
Emulator endpoint host resolution
pkg/emulator/endpoint_host.go, pkg/emulator/endpoint_host_test.go
Adds host resolution, current-container-network selection, and Linux default gateway parsing, with tests for host and network selection paths.
Emulator alias attachment and endpoint selection
pkg/emulator/manager.go, pkg/emulator/manager_more_test.go, pkg/emulator/manager_test.go, pkg/emulator/network_test.go
Adds sanitized emulator network aliases, attaches shared networks through container network fields, and changes endpoint selection to use container-network or reachable-host paths, with manager tests.

Lock Persistence Skips Remote Workdir Sources

Layer / File(s) Summary
Remote workdir source skip
pkg/provisioner/lock/lock_hook.go, pkg/provisioner/lock/lock_hook_test.go
Skips per-instance lock persistence when workdir SourceType is remote or the local source path doesn't exist.

Aqua Registry Unauthenticated Retry

Layer / File(s) Summary
403 retry with default client
pkg/toolchain/registry/aqua/aqua.go, pkg/toolchain/registry/aqua/aqua_test.go
Stores githubToken on AquaRegistry and retries GitHub API requests with a fresh default client when a 403 is received with no token.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • cloudposse/atmos#2645: Overlaps with pkg/container/lifecycle.go and the container network attachment shape used by emulator changes.

Suggested labels: patch

Suggested reviewers: aknysh

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the CI-focused regression fixes described in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch osterman/explore-release-bugs

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.

@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)
Dockerfile (1)

21-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Nit: double space before --no-install-recommends.

Line 22 has apt-get -y install --no-install-recommends with two spaces. Cosmetic only.

🧹 Proposed fix
-    apt-get -y install  --no-install-recommends curl git ca-certificates python3; \
+    apt-get -y install --no-install-recommends curl git ca-certificates python3; \
🤖 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 `@Dockerfile` around lines 21 - 22, There is an extra space before the
--no-install-recommends flag in the Dockerfile install command. Clean up the
apt-get install line to use a single space there, keeping the command formatting
consistent and matching the surrounding setup steps in the Dockerfile.
pkg/provisioner/lock/lock_hook_test.go (1)

85-109: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the complementary positive-path test.

This test only covers the "skip" branch for remote sources. There's no test confirming persistence still succeeds through the WorkdirPathKey path for a local source (i.e., SourceTypeLocal with an existing directory reaching line 154's return md.Source).

As per coding guidelines, "whenever a test verifies that a recovery/fallback triggers under condition X, add a corresponding test that verifies the recovery does NOT trigger when condition X is absent."

🤖 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/provisioner/lock/lock_hook_test.go` around lines 85 - 109, Add the
complementary positive-path test for autoLockProviders/lock_hook_test.go to
cover the local-source case that should use WorkdirPathKey persistence. Mirror
TestAutoLockProviders_SkipsRemoteWorkdirSource but set
WorkdirMetadata.SourceType to SourceTypeLocal and use an existing local
directory so the WorkdirPathKey path reaches the md.Source branch in the workdir
resolver. Then assert that autoLockProviders records the expected lock-file
write under the local source path, proving the skip logic only applies to remote
sources.

Source: Coding guidelines

pkg/provisioner/lock/lock_hook.go (1)

139-160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Skip logic looks correct.

Remote sources short-circuit before the os.Stat check, and the stat/IsDir guard correctly limits persistence to existing local directories. No functional issues here.

One gap: the os.Stat/!info.IsDir() failure branch (lines 150-153) isn't exercised by the new test — only the SourceTypeRemote skip path is covered. Consider adding a case where md.Source points to a missing path (or a file, not a dir) to lock in this branch's behavior.

As per coding guidelines, "Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages."

🤖 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/provisioner/lock/lock_hook.go` around lines 139 - 160, The new tests
cover the remote-source skip path, but the missing-path/non-directory branch in
persistDir is untested. Add a unit test around persistDir that sets
workdir.ReadMetadata to return a local md.Source pointing to a missing path or
file, then assert the function returns an empty string and logs the skip path;
use the persistDir helper and the md.SourceType/ os.Stat guard scenario so this
branch stays covered.

Source: Coding guidelines

cmd/root_test.go (1)

172-183: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a negative-path test for the recovery branch.

TestHandleConfigInitError_AllowsCIGitCloneBootstrap only proves the recovery fires. It's worth adding a mirror case confirming handleConfigInitError does NOT swallow the error (and leaves CI.Enabled false) when the CI condition is absent — e.g., GITHUB_ACTIONS unset or args are a normal git clone repo. This guards against the bootstrap bypass silently activating outside CI.

As per coding guidelines: "Include negative-path tests for recovery logic: whenever a test verifies that a recovery/fallback triggers under condition X, add a corresponding test that verifies the recovery does NOT trigger when condition X is absent."

🧪 Suggested negative-path test
func TestHandleConfigInitError_SkipsBootstrapOutsideCI(t *testing.T) {
	origArgs := os.Args
	t.Cleanup(func() { os.Args = origArgs })
	os.Args = []string{"atmos", "--profile", "github", "git", "clone"}
	t.Setenv("GITHUB_ACTIONS", "")

	cfg := &schema.AtmosConfiguration{}
	err := handleConfigInitError(assert.AnError, cfg)

	assert.Error(t, err)
	assert.False(t, cfg.CI.Enabled, "bootstrap bypass must not activate outside 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/root_test.go` around lines 172 - 183, Add a negative-path test alongside
TestHandleConfigInitError_AllowsCIGitCloneBootstrap to verify
handleConfigInitError does not recover when the CI bootstrap condition is
absent. Create a case with a normal git clone-style argv and GITHUB_ACTIONS
unset/empty, then assert the returned error is preserved and cfg.CI.Enabled
remains false. Use the existing handleConfigInitError and
schema.AtmosConfiguration symbols so the test mirrors the recovery path without
triggering it.

Source: Coding guidelines

pkg/toolchain/registry/aqua/aqua_test.go (1)

503-525: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Solid retry test — consider asserting the retry is truly unauthenticated.

The test confirms the retry fires (calls == 2), but the server ignores auth, so it wouldn't catch a regression where the retried request still carries Authorization. Since dropping the token is the actual purpose of this fix, capturing the header per call makes the test guard what matters.

♻️ Assert no Authorization header on the second request
 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		calls++
 		if calls == 1 {
 			w.WriteHeader(http.StatusForbidden)
 			return
 		}
+		assert.Empty(t, r.Header.Get("Authorization"), "retry must be unauthenticated")
 		w.Header().Set("Content-Type", "application/json")
 		json.NewEncoder(w).Encode(releases)
 	}))
🤖 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/toolchain/registry/aqua/aqua_test.go` around lines 503 - 525, The retry
test in TestAquaRegistry_GetLatestVersion_RetriesUnauthenticatedAfterForbidden
only checks that a second request happens, but it does not verify that the retry
drops authentication. Update the httptest.Server handler to inspect and record
the Authorization header for each call, and assert that the first request is
authenticated while the second request made by GetLatestVersion is
unauthenticated after the 403 response. Use the existing ar.githubToken setup
and the call-count logic to keep the test focused on the retry behavior.
internal/terraform_backend/terraform_backend_local_test.go (1)

219-295: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Solid coverage — consider one more subtest to lock the contract.

Both subtests exercise only the happy path (relative path, file present). A quick add that pays off: a case where the configured path is set but the file is absent, asserting nil, nil is returned. If you also decide on the named-workspace behavior from the source-side comment, a subtest pinning that down here would keep the contract explicit.

🤖 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/terraform_backend/terraform_backend_local_test.go` around lines 219
- 295, Add a subtest in TestReadTerraformBackendLocal_ConfiguredBackendPath that
sets a configured backend path but does not create the state file, and assert
ReadTerraformBackendLocal returns nil content with a nil error. Use the existing
ReadTerraformBackendLocal and ProcessTerraformStateFile helpers as the anchors
for locating the test, and if you are also fixing workspace handling, add a
separate subtest to pin the named-workspace behavior so the contract stays
explicit.
pkg/emulator/endpoint_host.go (1)

78-90: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider excluding the default bridge network too.

firstReachableNetwork skips "", "host", "none" but not "bridge", Docker's default network. If a container ends up attached to both bridge and an intentional custom job network, bridge is a valid pick here even though it typically doesn't support the kind of alias-based container-to-container resolution this feature relies on. Combined with the nondeterministic ordering from getNetworksFromInspect/parsePodmanNetworks (see comments on those files), this could route emulator lookups to the wrong network.

🤖 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/emulator/endpoint_host.go` around lines 78 - 90, firstReachableNetwork
currently treats bridge as a usable network, which can cause emulator lookups to
pick Docker’s default network instead of the intended job network. Update the
firstReachableNetwork function to also skip "bridge" alongside "", "host", and
"none", so it only returns a network that is suitable for alias-based container
resolution.
🤖 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 `@pkg/container/docker.go`:
- Around line 261-278: getNetworksFromInspect returns network names by ranging
over a map, so the order is nondeterministic and can make firstReachableNetwork
in endpoint_host.go pick different networks between runs. Update
getNetworksFromInspect to collect the names from NetworkSettings.Networks, then
sort the resulting slice before returning it so Info.Networks is stable and
deterministic.

In `@pkg/container/podman.go`:
- Around line 277-284: The map[string]interface{} branch in parsePodmanNetworks
builds the network list by ranging over a map, so its order is nondeterministic
and can change which network firstReachableNetwork selects. Update
parsePodmanNetworks to produce a stable, sorted slice before returning it,
matching the deterministic behavior needed by firstReachableNetwork and the
existing docker.go handling.

In `@pkg/emulator/endpoint_host_test.go`:
- Around line 3-10: The import block in endpoint_host_test.go needs to be split
into the standard three groups with blank lines between them: stdlib imports
first, then third-party imports, then Atmos packages. Reorder the imports in the
test file so github.com/stretchr/testify/assert stays in the third-party group
and github.com/cloudposse/atmos/pkg/container moves to the Atmos group, with
context, os, and testing kept together in the stdlib group.

In `@pkg/emulator/endpoint_host.go`:
- Around line 3-13: The import block in endpoint_host.go is grouped incorrectly:
Atmos packages like container and perf are mixed with the 3rd-party viper
import. Reorder the imports in the package’s import section so they are split
into three blank-line-separated groups: stdlib imports first, then 3rd-party
imports such as viper, and finally Atmos imports like container and perf,
keeping each group alphabetized.

In `@pkg/emulator/manager.go`:
- Around line 257-260: The current-container-network path can collide because
emulatorNetworkAlias(name) only uses the component name, so different stacks can
register the same network alias on the shared network. Update the alias
generation to include the stack identifier for this path, or change the
current-container-network flow in manager.go to use per-stack networks so
aliases remain unique; use emulatorNetworkAlias and the network setup logic
together when applying the fix.

In `@pkg/provisioner/lock/lock_hook_test.go`:
- Around line 107-108: The current `lock_hook_test.go` assertion uses a
repo-relative `filepath.Join(...)`, so a regression in `persistDir`/`copyLock`
could create real `github.com/...` directories in the checkout instead of
staying inside the temp area. Update the test to anchor path resolution to
`t.TempDir()` or `t.Chdir(dir)`, or assert directly on `persistDir(cc,
workdirPath)` returning empty for remote sources, so the check remains
side-effect free while still validating `os.Stat`/`os.IsNotExist` behavior.

---

Nitpick comments:
In `@cmd/root_test.go`:
- Around line 172-183: Add a negative-path test alongside
TestHandleConfigInitError_AllowsCIGitCloneBootstrap to verify
handleConfigInitError does not recover when the CI bootstrap condition is
absent. Create a case with a normal git clone-style argv and GITHUB_ACTIONS
unset/empty, then assert the returned error is preserved and cfg.CI.Enabled
remains false. Use the existing handleConfigInitError and
schema.AtmosConfiguration symbols so the test mirrors the recovery path without
triggering it.

In `@Dockerfile`:
- Around line 21-22: There is an extra space before the --no-install-recommends
flag in the Dockerfile install command. Clean up the apt-get install line to use
a single space there, keeping the command formatting consistent and matching the
surrounding setup steps in the Dockerfile.

In `@internal/terraform_backend/terraform_backend_local_test.go`:
- Around line 219-295: Add a subtest in
TestReadTerraformBackendLocal_ConfiguredBackendPath that sets a configured
backend path but does not create the state file, and assert
ReadTerraformBackendLocal returns nil content with a nil error. Use the existing
ReadTerraformBackendLocal and ProcessTerraformStateFile helpers as the anchors
for locating the test, and if you are also fixing workspace handling, add a
separate subtest to pin the named-workspace behavior so the contract stays
explicit.

In `@pkg/emulator/endpoint_host.go`:
- Around line 78-90: firstReachableNetwork currently treats bridge as a usable
network, which can cause emulator lookups to pick Docker’s default network
instead of the intended job network. Update the firstReachableNetwork function
to also skip "bridge" alongside "", "host", and "none", so it only returns a
network that is suitable for alias-based container resolution.

In `@pkg/provisioner/lock/lock_hook_test.go`:
- Around line 85-109: Add the complementary positive-path test for
autoLockProviders/lock_hook_test.go to cover the local-source case that should
use WorkdirPathKey persistence. Mirror
TestAutoLockProviders_SkipsRemoteWorkdirSource but set
WorkdirMetadata.SourceType to SourceTypeLocal and use an existing local
directory so the WorkdirPathKey path reaches the md.Source branch in the workdir
resolver. Then assert that autoLockProviders records the expected lock-file
write under the local source path, proving the skip logic only applies to remote
sources.

In `@pkg/provisioner/lock/lock_hook.go`:
- Around line 139-160: The new tests cover the remote-source skip path, but the
missing-path/non-directory branch in persistDir is untested. Add a unit test
around persistDir that sets workdir.ReadMetadata to return a local md.Source
pointing to a missing path or file, then assert the function returns an empty
string and logs the skip path; use the persistDir helper and the md.SourceType/
os.Stat guard scenario so this branch stays covered.

In `@pkg/toolchain/registry/aqua/aqua_test.go`:
- Around line 503-525: The retry test in
TestAquaRegistry_GetLatestVersion_RetriesUnauthenticatedAfterForbidden only
checks that a second request happens, but it does not verify that the retry
drops authentication. Update the httptest.Server handler to inspect and record
the Authorization header for each call, and assert that the first request is
authenticated while the second request made by GetLatestVersion is
unauthenticated after the 403 response. Use the existing ar.githubToken setup
and the call-count logic to keep the test focused on the retry behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bcbdf4fb-5306-4317-94b1-62dd029d03c8

📥 Commits

Reviewing files that changed from the base of the PR and between 1bc4cd3 and b7179f0.

📒 Files selected for processing (24)
  • Dockerfile
  • actions/cache/action.yml
  • cmd/docker_and_action_regression_test.go
  • cmd/root.go
  • cmd/root_test.go
  • internal/terraform_backend/terraform_backend_local.go
  • internal/terraform_backend/terraform_backend_local_test.go
  • pkg/container/common.go
  • pkg/container/common_test.go
  • pkg/container/docker.go
  • pkg/container/docker_unit_test.go
  • pkg/container/lifecycle.go
  • pkg/container/podman.go
  • pkg/container/podman_test.go
  • pkg/container/runtime.go
  • pkg/emulator/endpoint_host.go
  • pkg/emulator/endpoint_host_test.go
  • pkg/emulator/manager.go
  • pkg/emulator/manager_more_test.go
  • pkg/emulator/manager_test.go
  • pkg/provisioner/lock/lock_hook.go
  • pkg/provisioner/lock/lock_hook_test.go
  • pkg/toolchain/registry/aqua/aqua.go
  • pkg/toolchain/registry/aqua/aqua_test.go

Comment thread pkg/container/docker.go
Comment thread pkg/container/podman.go
Comment thread pkg/emulator/endpoint_host_test.go
Comment thread pkg/emulator/endpoint_host.go
Comment thread pkg/emulator/manager.go Outdated
Comment thread pkg/provisioner/lock/lock_hook_test.go
@codecov

codecov Bot commented Jul 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.64463% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.60%. Comparing base (1bc4cd3) to head (e98b7ea).

Files with missing lines Patch % Lines
pkg/emulator/endpoint_host.go 77.33% 9 Missing and 8 partials ⚠️
cmd/root.go 85.45% 7 Missing and 1 partial ⚠️
pkg/emulator/manager.go 78.37% 7 Missing and 1 partial ⚠️
pkg/provisioner/lock/lock_hook.go 50.00% 3 Missing ⚠️
pkg/container/common.go 80.00% 1 Missing and 1 partial ⚠️
pkg/container/docker.go 85.71% 1 Missing and 1 partial ⚠️
pkg/container/podman.go 90.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2681      +/-   ##
==========================================
+ Coverage   80.58%   80.60%   +0.02%     
==========================================
  Files        1524     1525       +1     
  Lines      144122   144360     +238     
==========================================
+ Hits       116142   116365     +223     
  Misses      21466    21466              
- Partials     6514     6529      +15     
Flag Coverage Δ
unittests 80.60% <82.64%> (+0.02%) ⬆️

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

Files with missing lines Coverage Δ
...ernal/terraform_backend/terraform_backend_local.go 79.72% <100.00%> (+4.31%) ⬆️
pkg/container/lifecycle.go 83.45% <100.00%> (+0.12%) ⬆️
pkg/container/runtime.go 100.00% <ø> (ø)
pkg/toolchain/registry/aqua/aqua.go 85.38% <100.00%> (+0.30%) ⬆️
pkg/container/common.go 94.60% <80.00%> (-0.55%) ⬇️
pkg/container/docker.go 80.41% <85.71%> (+0.27%) ⬆️
pkg/container/podman.go 80.50% <90.00%> (+0.73%) ⬆️
pkg/provisioner/lock/lock_hook.go 78.48% <50.00%> (+0.39%) ⬆️
cmd/root.go 71.91% <85.45%> (+0.87%) ⬆️
pkg/emulator/manager.go 70.25% <78.37%> (+1.07%) ⬆️
... and 1 more

... and 6 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[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
@github-actions

github-actions Bot commented Jul 2, 2026 •

Copy link
Copy Markdown

Note

SHA Pin Verification Passed ✅

All 101 SHA-pinned action(s) verified against upstream tags.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
@aknysh
Andriy Knysh (aknysh) merged commit c0c515a into main Jul 3, 2026
77 checks passed
@atmos-pro

atmos-pro Bot commented Jul 3, 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.

@aknysh
Andriy Knysh (aknysh) deleted the osterman/explore-release-bugs branch July 3, 2026 07:21
@mergify mergify Bot removed the needs-cloudposse Needs Cloud Posse assistance label Jul 3, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

These changes were released in v1.223.0-rc.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/m Medium size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants