Skip to content

Commit f920318

Browse files
authored
Merge branch 'main' into DEV-2964
2 parents ed1af3d + 4a129d0 commit f920318

File tree

14 files changed

+302
-55
lines changed

14 files changed

+302
-55
lines changed

.github/workflows/autofix.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
# The workflow name **must** be "autofix.ci" for Autofix CI to function correctly.
3+
# Any deviation from this name will cause Autofix CI to fail, as it relies on this
4+
# specific identifier for execution. This is a strict requirement of Autofix CI.
5+
name: autofix.ci
6+
on: pull_request
7+
permissions: {}
8+
jobs:
9+
autofix:
10+
runs-on: ubuntu-24.04
11+
permissions: {}
12+
timeout-minutes: 15
13+
steps:
14+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
15+
with:
16+
persist-credentials: false
17+
- uses: aquaproj/aqua-installer@e2d0136abcf70b7a2f6f505720640750557c4b33 # v3.1.1
18+
with:
19+
aqua_version: v2.43.0
20+
21+
- name: Update aqua-checksums.json
22+
run: aqua upc -prune
23+
24+
# go mod tidy
25+
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
26+
with:
27+
go-version-file: go.mod
28+
- run: go mod tidy
29+
30+
# gofumpt
31+
- name: Get changed Go files
32+
id: changed-files
33+
uses: tj-actions/changed-files@d6e91a2266cdb9d62096cebf1e8546899c6aa18f # v45.0.6
34+
with:
35+
use_rest_api: "true"
36+
files: |
37+
**/*.go
38+
- if: steps.changed-files.outputs.all_changed_files_count != '0'
39+
env:
40+
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
41+
run: |
42+
# shellcheck disable=SC2086
43+
gofumpt -l -w $ALL_CHANGED_FILES
44+
45+
46+
- uses: autofix-ci/action@2891949f3779a1cafafae1523058501de3d4e944 # v1.3.1

.github/workflows/test.yml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,25 +72,6 @@ jobs:
7272
path: |
7373
./build/
7474
75-
tidy:
76-
name: Tidy Go Modules
77-
runs-on: ubuntu-latest
78-
steps:
79-
- name: Check out code into the Go module directory
80-
uses: actions/checkout@v4
81-
82-
- name: Set up Go
83-
uses: actions/setup-go@v5
84-
with:
85-
go-version-file: "go.mod"
86-
id: go
87-
88-
- uses: j0hnsmith/go-mod-check@v1
89-
with:
90-
working-directory: ${{ github.workspace }}
91-
# optional, only if you're happy to have `replace ` lines in your go.mod file
92-
skip-replace-check: true
93-
9475
# run acceptance tests
9576
test:
9677
name: Acceptance Tests

Makefile

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@ SHELL := /bin/bash
88
#GOARCH=amd64
99
VERSION=test
1010

11-
# List of targets the `readme` target should call before generating the readme
12-
export README_DEPS ?= docs/targets.md
11+
export CGO_ENABLED=0
1312

14-
-include $(shell curl -sSL -o .build-harness "https://cloudposse.tools/build-harness"; echo .build-harness)
15-
16-
## Lint terraform code
17-
lint:
18-
$(SELF) terraform/install terraform/get-modules terraform/get-plugins terraform/lint terraform/validate
13+
readme:
14+
@echo "README.md generation temporarily disabled."
15+
@exit 0
1916

2017
get:
2118
go get

aqua/aqua-checksums.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"checksums": [
3+
{
4+
"id": "github_release/github.com/mvdan/gofumpt/v0.7.0/gofumpt_v0.7.0_darwin_amd64",
5+
"checksum": "B7D05E092DA45C5EC96344AB635B1D6547C3E27C840BA39BC76989934EFD7CE3",
6+
"algorithm": "sha256"
7+
},
8+
{
9+
"id": "github_release/github.com/mvdan/gofumpt/v0.7.0/gofumpt_v0.7.0_darwin_arm64",
10+
"checksum": "08F23114760A090B090706D92B8C52B9875B9EB352D76C77AA354D6AA20B045A",
11+
"algorithm": "sha256"
12+
},
13+
{
14+
"id": "github_release/github.com/mvdan/gofumpt/v0.7.0/gofumpt_v0.7.0_linux_amd64",
15+
"checksum": "6FF459C1DCAE3B0B00844C1A5A4A5B0F547237D8A4F3624AAEA8D424AEEF24C6",
16+
"algorithm": "sha256"
17+
},
18+
{
19+
"id": "github_release/github.com/mvdan/gofumpt/v0.7.0/gofumpt_v0.7.0_linux_arm64",
20+
"checksum": "00C18C88EF50437629626BA20D677F4648684CB280952814CDD887677D42CBD3",
21+
"algorithm": "sha256"
22+
},
23+
{
24+
"id": "github_release/github.com/mvdan/gofumpt/v0.7.0/gofumpt_v0.7.0_windows_amd64.exe",
25+
"checksum": "65F5B9EA7723AA936FA6880E184624747E9E6481802B62D4CB5B774EF2350CEC",
26+
"algorithm": "sha256"
27+
},
28+
{
29+
"id": "registries/github_content/github.com/aquaproj/aqua-registry/v4.302.1/registry.yaml",
30+
"checksum": "908B44E94A3583AA2D6F0B17F53E49D01ACD57E4ECDFEDB29EB082D335D9445478426E591AB57D37BAA02A2EF9581A71A3AA66C825CC787323D65A1D89B53072",
31+
"algorithm": "sha512"
32+
}
33+
]
34+
}

aqua/aqua.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# yaml-language-server: $schema=https://raw.githubusercontent.com/aquaproj/aqua/main/json-schema/aqua-yaml.json
3+
# aqua - Declarative CLI Version Manager
4+
# https://aquaproj.github.io/
5+
checksum:
6+
enabled: true
7+
require_checksum: true
8+
registries:
9+
- type: standard
10+
ref: v4.302.1 # renovate: depName=aquaproj/aqua-registry
11+
packages:
12+
- import: imports/*.yaml

aqua/imports/gofumpt.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages:
2+
- name: mvdan/[email protected]

internal/exec/terraform.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ const (
2020
outFlag = "-out"
2121
varFileFlag = "-var-file"
2222
skipTerraformLockFileFlag = "--skip-lock-file"
23-
everythingFlag = "--everything"
2423
forceFlag = "--force"
2524
)
2625

@@ -37,13 +36,10 @@ func shouldProcessStacks(info *schema.ConfigAndStacksInfo) (bool, bool) {
3736
shouldProcessStacks := true
3837
shouldCheckStack := true
3938

40-
if info.SubCommand == "clean" &&
41-
(u.SliceContainsString(info.AdditionalArgsAndFlags, everythingFlag) ||
42-
u.SliceContainsString(info.AdditionalArgsAndFlags, forceFlag)) {
39+
if info.SubCommand == "clean" {
4340
if info.ComponentFromArg == "" {
4441
shouldProcessStacks = false
4542
}
46-
4743
shouldCheckStack = info.Stack != ""
4844

4945
}
@@ -128,7 +124,7 @@ func ExecuteTerraform(info schema.ConfigAndStacksInfo) error {
128124
}
129125
}
130126

131-
if !info.ComponentIsEnabled {
127+
if !info.ComponentIsEnabled && info.SubCommand != "clean" {
132128
u.LogInfo(atmosConfig, fmt.Sprintf("component '%s' is not enabled and skipped", info.ComponentFromArg))
133129
return nil
134130
}

internal/exec/terraform_clean.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ func handleTFDataDir(componentPath string, relativePath string, atmosConfig sche
347347
}
348348

349349
}
350-
func initializeFilesToClear(info schema.ConfigAndStacksInfo, atmosConfig schema.AtmosConfiguration, everything bool) []string {
351-
if everything && info.Stack == "" {
350+
func initializeFilesToClear(info schema.ConfigAndStacksInfo, atmosConfig schema.AtmosConfiguration) []string {
351+
if info.ComponentFromArg == "" {
352352
return []string{".terraform", ".terraform.lock.hcl", "*.tfvar.json", "terraform.tfstate.d"}
353353
}
354354
varFile := constructTerraformComponentVarfileName(info)
@@ -407,8 +407,7 @@ func handleCleanSubCommand(info schema.ConfigAndStacksInfo, componentPath string
407407
}
408408

409409
force := u.SliceContainsString(info.AdditionalArgsAndFlags, forceFlag)
410-
everything := u.SliceContainsString(info.AdditionalArgsAndFlags, everythingFlag)
411-
filesToClear := initializeFilesToClear(info, atmosConfig, everything)
410+
filesToClear := initializeFilesToClear(info, atmosConfig)
412411
folders, err := CollectDirectoryObjects(cleanPath, filesToClear)
413412
if err != nil {
414413
u.LogTrace(atmosConfig, fmt.Errorf("error collecting folders and files: %v", err).Error())
@@ -456,7 +455,7 @@ func handleCleanSubCommand(info schema.ConfigAndStacksInfo, componentPath string
456455
u.PrintMessage(fmt.Sprintf("Do you want to delete the folder '%s'? ", tfDataDir))
457456
}
458457
var message string
459-
if everything && info.ComponentFromArg == "" {
458+
if info.ComponentFromArg == "" {
460459
message = fmt.Sprintf("This will delete %v local terraform state files affecting all components", total)
461460
} else if info.Component != "" && info.Stack != "" {
462461
message = fmt.Sprintf("This will delete %v local terraform state files for component '%s' in stack '%s'", total, info.Component, info.Stack)

internal/exec/utils.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,12 @@ func processArgsAndFlags(
688688
var additionalArgsAndFlags []string
689689
var globalOptions []string
690690
var indexesToRemove []int
691+
if len(inputArgsAndFlags) == 1 && inputArgsAndFlags[0] == "clean" {
692+
info.SubCommand = inputArgsAndFlags[0]
693+
}
691694

692-
// For commands like `atmos terraform clean` and `atmos terraform plan`, show the command help
693-
if len(inputArgsAndFlags) == 1 && inputArgsAndFlags[0] != "version" {
695+
// For commands like `atmos terraform plan`, show the command help
696+
if len(inputArgsAndFlags) == 1 && inputArgsAndFlags[0] != "version" && info.SubCommand == "" {
694697
info.SubCommand = inputArgsAndFlags[0]
695698
info.NeedHelp = true
696699
return info, nil

tests/cli_terraform_test.go

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package tests
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"fmt"
7+
"os"
8+
"os/exec"
9+
"path/filepath"
10+
"testing"
11+
)
12+
13+
func TestCLITerraformClean(t *testing.T) {
14+
// Capture the starting working directory
15+
startingDir, err := os.Getwd()
16+
if err != nil {
17+
t.Fatalf("Failed to get the current working directory: %v", err)
18+
}
19+
20+
// Initialize PathManager and update PATH
21+
pathManager := NewPathManager()
22+
pathManager.Prepend("../build", "..")
23+
err = pathManager.Apply()
24+
if err != nil {
25+
t.Fatalf("Failed to apply updated PATH: %v", err)
26+
}
27+
fmt.Printf("Updated PATH: %s\n", pathManager.GetPath())
28+
defer func() {
29+
// Change back to the original working directory after the test
30+
if err := os.Chdir(startingDir); err != nil {
31+
t.Fatalf("Failed to change back to the starting directory: %v", err)
32+
}
33+
}()
34+
35+
// Define the work directory and change to it
36+
workDir := "../examples/quick-start-simple"
37+
if err := os.Chdir(workDir); err != nil {
38+
t.Fatalf("Failed to change directory to %q: %v", workDir, err)
39+
}
40+
41+
// Find the binary path for "atmos"
42+
binaryPath, err := exec.LookPath("atmos")
43+
if err != nil {
44+
t.Fatalf("Binary not found: %s. Current PATH: %s", "atmos", pathManager.GetPath())
45+
}
46+
47+
// Force clean everything
48+
runTerraformCleanCommand(t, binaryPath, "--force")
49+
// Clean everything
50+
runTerraformCleanCommand(t, binaryPath)
51+
// Clean specific component
52+
runTerraformCleanCommand(t, binaryPath, "station")
53+
// Clean component with stack
54+
runTerraformCleanCommand(t, binaryPath, "station", "-s", "dev")
55+
56+
// Run terraform apply for prod environment
57+
runTerraformApply(t, binaryPath, "prod")
58+
verifyStateFilesExist(t, []string{"./components/terraform/weather/terraform.tfstate.d/prod-station"})
59+
runCLITerraformCleanComponent(t, binaryPath, "prod")
60+
verifyStateFilesDeleted(t, []string{"./components/terraform/weather/terraform.tfstate.d/prod-station"})
61+
62+
// Run terraform apply for dev environment
63+
runTerraformApply(t, binaryPath, "dev")
64+
65+
// Verify if state files exist before cleaning
66+
stateFiles := []string{
67+
"./components/terraform/weather/.terraform",
68+
"./components/terraform/weather/terraform.tfstate.d",
69+
"./components/terraform/weather/.terraform.lock.hcl",
70+
}
71+
verifyStateFilesExist(t, stateFiles)
72+
73+
// Run terraform clean
74+
runTerraformClean(t, binaryPath)
75+
76+
// Verify if state files have been deleted after clean
77+
verifyStateFilesDeleted(t, stateFiles)
78+
79+
}
80+
81+
// runTerraformApply runs the terraform apply command for a given environment.
82+
func runTerraformApply(t *testing.T, binaryPath, environment string) {
83+
cmd := exec.Command(binaryPath, "terraform", "apply", "station", "-s", environment)
84+
envVars := os.Environ()
85+
envVars = append(envVars, "ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE=true")
86+
cmd.Env = envVars
87+
88+
var stdout, stderr bytes.Buffer
89+
cmd.Stdout = &stdout
90+
cmd.Stderr = &stderr
91+
err := cmd.Run()
92+
t.Log(stdout.String())
93+
if err != nil {
94+
t.Fatalf("Failed to run terraform apply station -s %s: %v", environment, stderr.String())
95+
}
96+
}
97+
98+
// verifyStateFilesExist checks if the state files exist before cleaning.
99+
func verifyStateFilesExist(t *testing.T, stateFiles []string) {
100+
for _, file := range stateFiles {
101+
fileAbs, err := filepath.Abs(file)
102+
if err != nil {
103+
t.Fatalf("Failed to resolve absolute path for %q: %v", file, err)
104+
}
105+
if _, err := os.Stat(fileAbs); errors.Is(err, os.ErrNotExist) {
106+
t.Errorf("Expected file to exist before cleaning: %q", fileAbs)
107+
}
108+
}
109+
}
110+
111+
// runTerraformClean runs the terraform clean command.
112+
func runTerraformClean(t *testing.T, binaryPath string) {
113+
cmd := exec.Command(binaryPath, "terraform", "clean", "--force")
114+
var stdout, stderr bytes.Buffer
115+
cmd.Stdout = &stdout
116+
cmd.Stderr = &stderr
117+
err := cmd.Run()
118+
t.Logf("Clean command output:\n%s", stdout.String())
119+
if err != nil {
120+
t.Fatalf("Failed to run terraform clean: %v", stderr.String())
121+
}
122+
}
123+
124+
// verifyStateFilesDeleted checks if the state files have been deleted after cleaning.
125+
func verifyStateFilesDeleted(t *testing.T, stateFiles []string) {
126+
for _, file := range stateFiles {
127+
fileAbs, err := filepath.Abs(file)
128+
if err != nil {
129+
t.Fatalf("Failed to resolve absolute path for %q: %v", file, err)
130+
}
131+
_, err = os.Stat(fileAbs)
132+
if err == nil {
133+
t.Errorf("Expected Terraform state file to be deleted: %q", fileAbs)
134+
} else if !errors.Is(err, os.ErrNotExist) {
135+
t.Errorf("Unexpected error checking file %q: %v", fileAbs, err)
136+
}
137+
}
138+
}
139+
140+
func runCLITerraformCleanComponent(t *testing.T, binaryPath, environment string) {
141+
cmd := exec.Command(binaryPath, "terraform", "clean", "station", "-s", environment, "--force")
142+
var stdout, stderr bytes.Buffer
143+
cmd.Stdout = &stdout
144+
cmd.Stderr = &stderr
145+
err := cmd.Run()
146+
t.Logf("Clean command output:\n%s", stdout.String())
147+
if err != nil {
148+
t.Fatalf("Failed to run terraform clean: %v", stderr.String())
149+
}
150+
}
151+
func runCLITerraformClean(t *testing.T, binaryPath string) {
152+
cmd := exec.Command(binaryPath, "terraform", "clean")
153+
var stdout, stderr bytes.Buffer
154+
cmd.Stdout = &stdout
155+
cmd.Stderr = &stderr
156+
err := cmd.Run()
157+
t.Logf("Clean command output:\n%s", stdout.String())
158+
if err != nil {
159+
t.Fatalf("Failed to run terraform clean: %v", stderr.String())
160+
}
161+
162+
}
163+
164+
func runTerraformCleanCommand(t *testing.T, binaryPath string, args ...string) {
165+
cmdArgs := append([]string{"terraform", "clean"}, args...)
166+
cmd := exec.Command(binaryPath, cmdArgs...)
167+
var stdout, stderr bytes.Buffer
168+
cmd.Stdout = &stdout
169+
cmd.Stderr = &stderr
170+
err := cmd.Run()
171+
t.Logf("Clean command output:\n%s", stdout.String())
172+
if err != nil {
173+
t.Fatalf("Failed to run terraform clean: %v", stderr.String())
174+
}
175+
}

0 commit comments

Comments
 (0)