belt 0.3.30 → 0.3.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79ffa332a2eb6408d42c4652d1643009edac470adb6eabbcb9e6818286276977
4
- data.tar.gz: 145edae1f0f725c16232a648d64ad3224ac93baca18273648b901e7d4ef6ad66
3
+ metadata.gz: d6661697f19873dc93fa45b49d27d6665e370d771b947a6ea5539fb33a0970c9
4
+ data.tar.gz: ad996f0d38638b90ae2ebb1c8c761487b9bc4939fe3dba009dbed4f8ea4a6b4d
5
5
  SHA512:
6
- metadata.gz: '09e7a47ed0e3d34e699cbd2e1c14785399015ea66cde8b21dfd194e86d09456df246da0363e0bc0e543ad06129938376c148e87edc6885b0b6c9d94645ffdcd3'
7
- data.tar.gz: 16ec119be87259081c896497229cf3202901c3657ac4aea2f3e47e05ff3976d7130e23a99dcdf1c85b80f8d386243878e0acccd4bc9cb721b0ca8d8e189e4122
6
+ metadata.gz: 5eda51e4ed021da4d55135db7d5945c8370bbd6ae2d378e760aab837cdd353fc70dd34f2ae18c35dca6bd5d57eb8222bc0646b017a2199bdd01c747c94d6c6ee
7
+ data.tar.gz: 0e3e599b0972fb45145735ff8d390ff23bca425521c1fdaba2c5758071017b1857aad884a57fcf124a39bdba2f66845ca85b8890f21d9b5e0f3bf2ab9ae6e1be
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.32
4
+
5
+ ### Enhancement
6
+
7
+ - **`belt destroy environment --full` for fully non-interactive teardown**: Added
8
+ a `--full` / `-y` flag that tears an environment down with zero prompts —
9
+ intended for CI pipelines and agents that spin up ephemeral per-PR
10
+ environments and destroy them on merge. Unlike `--force` (which skips
11
+ terraform and only removes local files), `--full` **always runs
12
+ `terraform destroy`** when terraform state is present, then deletes the local
13
+ `infrastructure/<env>/` files. It also auto-continues past the nested-children
14
+ warning. When no terraform state exists there is nothing to tear down, so the
15
+ destroy step is skipped and only the files are removed.
16
+
17
+ ```bash
18
+ belt destroy environment pr-1234 --full
19
+ ```
20
+
21
+ ## 0.3.31
22
+
23
+ ### Bug Fix
24
+
25
+ - **`belt destroy environment` now uses the environment's AWS profile**: The
26
+ terraform destroy path (and remote-state detection) previously inherited
27
+ whatever `AWS_PROFILE` was in the shell, which could point at the wrong
28
+ account and fail with "No valid credential sources found". It now loads
29
+ `infrastructure/<env>/belt.rb` and applies the configured `aws_profile` and
30
+ env vars before running terraform — matching `belt deploy` and
31
+ `belt terraform`.
32
+
3
33
  ## 0.3.16
4
34
 
5
35
  ### Enhancement
@@ -6,6 +6,7 @@ require_relative 'auth_command'
6
6
  require_relative 'frontend_registry'
7
7
  require_relative 'generator_registry'
8
8
  require_relative 'tables_command'
9
+ require_relative 'environment_config'
9
10
  require_relative '../inflector'
10
11
 
11
12
  module Belt
@@ -46,7 +47,7 @@ module Belt
46
47
  when 'environment'
47
48
  name = args.shift
48
49
  if name.nil? || name.empty?
49
- puts 'Usage: belt destroy environment <name> [--force] [--skip-terraform]'
50
+ puts 'Usage: belt destroy environment <name> [--full] [--force] [--skip-terraform]'
50
51
  exit 1
51
52
  end
52
53
  flags = parse_environment_flags(args)
@@ -78,13 +79,15 @@ module Belt
78
79
  end
79
80
 
80
81
  def self.parse_environment_flags(args)
81
- flags = { force: false, skip_terraform: false }
82
+ flags = { force: false, skip_terraform: false, full: false }
82
83
  args.each do |arg|
83
84
  case arg
84
85
  when '--force', '-f'
85
86
  flags[:force] = true
86
87
  when '--skip-terraform'
87
88
  flags[:skip_terraform] = true
89
+ when '--full', '-y'
90
+ flags[:full] = true
88
91
  end
89
92
  end
90
93
  flags
@@ -113,7 +116,11 @@ module Belt
113
116
  views Remove React pages for a resource
114
117
 
115
118
  Environment options:
116
- --force, -f Skip all prompts (CI mode)
119
+ --full, -y Non-interactive teardown: ALWAYS run terraform
120
+ destroy, then delete local files, no prompts
121
+ (use this for CI / agents tearing down ephemeral envs)
122
+ --force, -f Skip all prompts but SKIP terraform destroy —
123
+ only deletes local files (leaves cloud resources)
117
124
  --skip-terraform Delete local files without running terraform destroy
118
125
 
119
126
  Examples:
@@ -123,6 +130,7 @@ module Belt
123
130
  belt d environment staging
124
131
  belt d environment dev --skip-terraform
125
132
  belt d environment dev --force
133
+ belt d environment pr-1234 --full # full non-interactive teardown
126
134
  belt d frontend
127
135
  belt d frontend --frontend ops
128
136
  belt d views post
@@ -132,16 +140,18 @@ module Belt
132
140
 
133
141
  For environments: if terraform state is detected, you'll be prompted to run
134
142
  `terraform destroy` first to tear down cloud resources before removing files.
143
+ Pass --full to run the whole teardown non-interactively (destroy + delete).
135
144
  HELP
136
145
  end
137
146
 
138
147
  # -- keyword options for destroy flags
139
- def initialize(generator, name, fields, force: false, skip_terraform: false, frontend_name: nil)
148
+ def initialize(generator, name, fields, force: false, skip_terraform: false, full: false, frontend_name: nil)
140
149
  @generator = generator
141
150
  @name = name&.downcase&.gsub(/[^a-z0-9_]/, '_')
142
151
  @fields = fields
143
152
  @force = force
144
153
  @skip_terraform = skip_terraform
154
+ @full = full
145
155
  @frontend_name = frontend_name
146
156
  @app_name = detect_namespace
147
157
  @singular_name = @name ? Belt::Inflector.singularize(@name) : nil
@@ -204,7 +214,7 @@ module Belt
204
214
  puts ' Consider destroying nested environments first:'
205
215
  nested_children.each { |child| puts " belt destroy environment #{child}" }
206
216
  puts ''
207
- unless @force
217
+ unless @force || @full
208
218
  print ' Continue anyway? [y/N] '
209
219
  response = $stdin.gets&.strip&.downcase
210
220
  unless response&.start_with?('y')
@@ -214,12 +224,24 @@ module Belt
214
224
  end
215
225
  end
216
226
 
227
+ # Apply the environment's AWS profile + env vars from infrastructure/<env>/belt.rb
228
+ # BEFORE any terraform/aws calls, so both remote-state detection and the
229
+ # subsequent destroy authenticate against the correct account. Without this,
230
+ # terraform inherits whatever AWS_PROFILE is in the shell, which may point at
231
+ # the wrong account (mirrors `belt deploy` / `belt terraform`).
232
+ apply_env_config! unless @skip_terraform
233
+
217
234
  # Check if terraform state exists (infra may still be live)
218
235
  if !@skip_terraform && terraform_state_exists?(dir)
219
236
  puts "⚠ Environment '#{@name}' appears to have active infrastructure."
220
237
  puts " Terraform state was found — resources may still be running.\n\n"
221
238
 
222
- if @force
239
+ if @full
240
+ # Fully non-interactive teardown (CI / agents): always run terraform
241
+ # destroy, then delete files. This is the flag to reach for when an
242
+ # automated workflow spins an environment up and tears it down.
243
+ run_terraform_destroy(dir)
244
+ elsif @force
223
245
  puts ' --force passed, skipping terraform destroy.'
224
246
  else
225
247
  puts ' Options:'
@@ -243,7 +265,7 @@ module Belt
243
265
  end
244
266
 
245
267
  # Final confirmation before deleting files
246
- unless @force
268
+ unless @force || @full
247
269
  print "\nPermanently delete #{dir}/? [y/N] "
248
270
  response = $stdin.gets&.strip&.downcase
249
271
  unless response&.start_with?('y')
@@ -380,6 +402,15 @@ module Belt
380
402
  puts ' ✓ Infrastructure destroyed.'
381
403
  end
382
404
 
405
+ # Load infrastructure/<env>/belt.rb and apply its aws_profile + env vars to
406
+ # the current process so terraform (and any aws CLI calls during destroy)
407
+ # authenticate against the right account. Mirrors DeployCommand / TerraformCommand.
408
+ def apply_env_config!
409
+ env_config = EnvironmentConfig.load(@name)
410
+ env_config.apply!
411
+ puts " 🔑 Using AWS profile: #{env_config.aws_profile}" if env_config.aws_profile?
412
+ end
413
+
383
414
  def empty_s3_buckets_in_state
384
415
  output = `terraform state list 2>/dev/null`
385
416
  return unless Process.last_status.success?
@@ -106,6 +106,34 @@ belt destroy frontend --frontend ops
106
106
  belt destroy views post
107
107
  ```
108
108
 
109
+ ### Non-interactive environment teardown
110
+
111
+ `belt destroy environment` is interactive by default: it prompts before running
112
+ `terraform destroy` and again before deleting local files. For CI pipelines and
113
+ agents that spin up ephemeral per-PR environments and tear them down on merge,
114
+ use `--full`:
115
+
116
+ ```bash
117
+ belt destroy environment pr-1234 --full
118
+ ```
119
+
120
+ `--full` (alias `-y`) runs the whole teardown with zero prompts: it **always runs
121
+ `terraform destroy`** (when terraform state is present), then deletes the local
122
+ `infrastructure/<env>/` files.
123
+
124
+ Flag comparison:
125
+
126
+ | Flag | terraform destroy | Deletes local files | Prompts |
127
+ |------|-------------------|---------------------|---------|
128
+ | _(none)_ | Prompted | Prompted | Yes |
129
+ | `--full` / `-y` | Always (if state exists) | Yes | No |
130
+ | `--force` / `-f` | **Skipped** (leaves cloud resources) | Yes | No |
131
+ | `--skip-terraform` | Never | Yes | Final delete only |
132
+
133
+ > `--force` is for the "just clean up my local files" case — it intentionally
134
+ > leaves cloud infrastructure running. Reach for `--full` when you want the
135
+ > environment fully gone.
136
+
109
137
  ## Plugin Generators
110
138
 
111
139
  Gems that follow the Belt plugin contract are auto-discovered:
data/lib/belt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Belt
4
- VERSION = '0.3.30'
4
+ VERSION = '0.3.32'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: belt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.30
4
+ version: 0.3.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stowzilla