Class: KamalGitlabReviewApp::CLI::Stop

Inherits:
Object
  • Object
show all
Defined in:
lib/kamal_gitlab_review_app/cli/stop.rb

Overview

Tears down the review app for the current MR. Best-effort: every step is isolated so one failure (e.g. Kamal app already gone, DNS record already deleted) never prevents the remaining teardown steps from running. Never raises to the caller.

Returns true when at least one top-level step succeeded, false when every step failed (so CI can still surface a fully broken stop while keeping allow_failure: true).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(runner: method(:system)) ⇒ Stop

Returns a new instance of Stop.



18
19
20
# File 'lib/kamal_gitlab_review_app/cli/stop.rb', line 18

def initialize(runner: method(:system))
  @runner = runner
end

Class Method Details

.call(**kwargs) ⇒ Object



14
15
16
# File 'lib/kamal_gitlab_review_app/cli/stop.rb', line 14

def self.call(**kwargs)
  new(**kwargs).call
end

Instance Method Details

#callObject



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/kamal_gitlab_review_app/cli/stop.rb', line 22

def call
  project_root = ENV.fetch('KAMAL_GITLAB_REVIEW_APP_PROJECT_ROOT', Dir.pwd)
  iid = ENV.fetch('CI_MERGE_REQUEST_IID')

  # Kamal teardown needs the project root (config/.kamal/); DNS delete and remote
  # Docker cleanup do not touch the local filesystem at all. Keep them as separate
  # top-level best-effort steps so a bad/unenterable project_root (or any kamal
  # failure) never skips DNS deletion or remote cleanup.
  results = []
  results << best_effort('kamal teardown') { kamal_teardown(project_root:, iid:) }
  results << best_effort('dns delete') { delete_dns(iid:) }
  results << best_effort('remote docker cleanup') {
    KamalGitlabReviewApp::Remote::DockerCleanup.call(iid:, runner: @runner)
  }
  results.any?
rescue StandardError => e
  warn "kamal-gitlab-review-app stop: #{e.message}"
  false
end