discharger 0.2.23 → 0.2.24
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 +4 -4
- data/CHANGELOG.md +2 -2
- data/lib/discharger/setup_runner/commands/docker_command.rb +22 -5
- data/lib/discharger/task.rb +103 -9
- data/lib/discharger/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9f3ccebbf82065fe09a136e6f5d44a5e78bfa95643b52fee75f40d0763941615
|
|
4
|
+
data.tar.gz: c46241c30ee25101a1e0873e891d03c9beb89a9a65c587324a59a7645334a585
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e6ed61916d2d2502eece7911d48d108026e74c5e11b1c689dec61ae451c0e5aeb99decf4215d521d2193f96634c9b880fb0e8cffa22a989db288f434de219c2
|
|
7
|
+
data.tar.gz: 21eee7c2dce99efa8cdf15fbb9d04ac1484209773b3941ead3e950a322a16c1d52f9ea37e95236b9d37ba805eb6e25d80f09f6bda59967114d9c89a9ffa92854
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,6 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
7
|
|
|
8
|
-
## [0.2.
|
|
8
|
+
## [0.2.24] - 2026-01-22
|
|
9
9
|
|
|
10
|
-
## [0.2.
|
|
10
|
+
## [0.2.23] - 2026-01-16
|
|
@@ -70,11 +70,28 @@ module Discharger
|
|
|
70
70
|
create_container(name: name, port: port, image: image, env: env, volume: volume, internal_port: internal_port)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
wait_for_container_running(name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def wait_for_container_running(name, timeout: 30)
|
|
77
|
+
require "open3"
|
|
78
|
+
start_time = Time.now
|
|
79
|
+
loop do
|
|
80
|
+
return true if system_quiet("docker ps | grep #{name} > /dev/null 2>&1")
|
|
81
|
+
|
|
82
|
+
status, = Open3.capture3("docker", "inspect", "-f", "{{.State.Status}}", name)
|
|
83
|
+
status = status.strip
|
|
84
|
+
if status == "exited"
|
|
85
|
+
exit_code, = Open3.capture3("docker", "inspect", "-f", "{{.State.ExitCode}}", name)
|
|
86
|
+
logs, = Open3.capture3("docker", "logs", "--tail", "20", name)
|
|
87
|
+
raise "#{name} container exited with code #{exit_code.strip}:\n#{logs}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if Time.now - start_time > timeout
|
|
91
|
+
raise "#{name} container failed to start within #{timeout} seconds (current status: #{status})"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
sleep 1
|
|
78
95
|
end
|
|
79
96
|
end
|
|
80
97
|
|
data/lib/discharger/task.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "rake/tasklib"
|
|
2
2
|
require "reissue/rake"
|
|
3
3
|
require "rainbow/refinement"
|
|
4
|
+
require "open3"
|
|
4
5
|
using Rainbow
|
|
5
6
|
|
|
6
7
|
module Discharger
|
|
@@ -34,6 +35,7 @@ module Discharger
|
|
|
34
35
|
attr_accessor :working_branch
|
|
35
36
|
attr_accessor :staging_branch
|
|
36
37
|
attr_accessor :production_branch
|
|
38
|
+
attr_accessor :auto_deploy_staging
|
|
37
39
|
|
|
38
40
|
attr_accessor :release_message_channel
|
|
39
41
|
attr_accessor :version_constant
|
|
@@ -63,6 +65,7 @@ module Discharger
|
|
|
63
65
|
@production_branch = "main"
|
|
64
66
|
@description = "Release the current version to #{staging_branch}"
|
|
65
67
|
@clear_fragments = true
|
|
68
|
+
@auto_deploy_staging = false
|
|
66
69
|
end
|
|
67
70
|
private attr_reader :tasker
|
|
68
71
|
|
|
@@ -109,15 +112,72 @@ module Discharger
|
|
|
109
112
|
success
|
|
110
113
|
end
|
|
111
114
|
|
|
112
|
-
# Echo a message to the console
|
|
113
|
-
#
|
|
114
|
-
# @param message [String] the message to echo
|
|
115
|
-
# return [TrueClass]
|
|
116
115
|
def sysecho(message, output: $stdout)
|
|
117
116
|
output.puts message
|
|
118
117
|
true
|
|
119
118
|
end
|
|
120
119
|
|
|
120
|
+
# Abort if staging branch has different VERSION than working branch
|
|
121
|
+
def validate_version_match!(staging, working, output: $stdout)
|
|
122
|
+
staging_v = git_show_version(staging)
|
|
123
|
+
working_v = git_show_version(working)
|
|
124
|
+
|
|
125
|
+
return sysecho("✓ Versions match (#{working_v})".bg(:green).black, output:) if staging_v == working_v
|
|
126
|
+
|
|
127
|
+
abort <<~ERROR.bg(:red).white
|
|
128
|
+
VERSION mismatch: #{staging}=#{staging_v || "not found"}, #{working}=#{working_v || "not found"}
|
|
129
|
+
|
|
130
|
+
Run: rake #{name}:stage
|
|
131
|
+
Then retry: rake #{name}
|
|
132
|
+
ERROR
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Abort if HEAD is not the commit that last touched the version file
|
|
136
|
+
def validate_release_commit!(branch, output: $stdout)
|
|
137
|
+
head_sha = git_local_sha(branch)
|
|
138
|
+
release_sha = git_version_file_commit(branch)
|
|
139
|
+
|
|
140
|
+
if head_sha.nil? || release_sha.nil?
|
|
141
|
+
abort <<~ERROR.bg(:red).white
|
|
142
|
+
Could not determine release commit.
|
|
143
|
+
|
|
144
|
+
HEAD: #{head_sha || "not found"}
|
|
145
|
+
Release commit: #{release_sha || "not found"}
|
|
146
|
+
|
|
147
|
+
Ensure #{branch} exists and #{version_file} has been modified.
|
|
148
|
+
ERROR
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
return sysecho("✓ HEAD is the release commit (#{head_sha[0, 8]})".bg(:green).black, output:) if head_sha == release_sha
|
|
152
|
+
|
|
153
|
+
abort <<~ERROR.bg(:red).white
|
|
154
|
+
HEAD is not the release commit!
|
|
155
|
+
|
|
156
|
+
HEAD: #{head_sha[0, 8]}
|
|
157
|
+
Release commit: #{release_sha[0, 8]} (last commit to touch #{version_file})
|
|
158
|
+
|
|
159
|
+
Something was merged after the release PR. Verify the branch contents and retry.
|
|
160
|
+
ERROR
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def git_show_version(branch)
|
|
164
|
+
content, _, status = Open3.capture3("git", "show", "origin/#{branch}:#{version_file}")
|
|
165
|
+
return nil unless status.success?
|
|
166
|
+
content[/VERSION\s*=\s*["']([^"']+)["']/, 1]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def git_local_sha(branch)
|
|
170
|
+
stdout, _, status = Open3.capture3("git", "rev-parse", branch)
|
|
171
|
+
return nil unless status.success?
|
|
172
|
+
stdout.strip
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def git_version_file_commit(branch)
|
|
176
|
+
stdout, _, status = Open3.capture3("git", "log", branch, "-1", "--format=%H", "--", version_file)
|
|
177
|
+
return nil unless status.success?
|
|
178
|
+
stdout.strip
|
|
179
|
+
end
|
|
180
|
+
|
|
121
181
|
def define
|
|
122
182
|
require "slack-ruby-client"
|
|
123
183
|
Slack.configure do |config|
|
|
@@ -137,22 +197,40 @@ module Discharger
|
|
|
137
197
|
DESC
|
|
138
198
|
task "#{name}": [:environment] do
|
|
139
199
|
current_version = Object.const_get(version_constant)
|
|
200
|
+
|
|
201
|
+
# When auto_deploy_staging is enabled, release directly from working_branch
|
|
202
|
+
# instead of staging_branch (for CI/CD pipelines that auto-deploy staging)
|
|
203
|
+
release_source = auto_deploy_staging ? working_branch : staging_branch
|
|
204
|
+
|
|
140
205
|
sysecho <<~MSG
|
|
141
206
|
Releasing version #{current_version} to production.
|
|
142
207
|
|
|
143
208
|
This will tag the current version and push it to the production branch.
|
|
209
|
+
Release source: #{release_source}
|
|
144
210
|
MSG
|
|
145
211
|
sysecho "Are you ready to continue? (Press Enter to continue, Type 'x' and Enter to exit)".bg(:yellow).black
|
|
146
212
|
input = $stdin.gets
|
|
147
213
|
exit if input.chomp.match?(/^x/i)
|
|
148
214
|
|
|
149
|
-
|
|
215
|
+
# Fetch first, then validate what we fetched
|
|
216
|
+
syscall(
|
|
150
217
|
["git checkout #{working_branch}"],
|
|
151
218
|
["git branch -D #{staging_branch} 2>/dev/null || true"],
|
|
152
219
|
["git branch -D #{production_branch} 2>/dev/null || true"],
|
|
153
|
-
["git fetch origin #{
|
|
220
|
+
["git fetch origin #{release_source}:#{release_source} #{production_branch}:#{production_branch}"]
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if auto_deploy_staging
|
|
224
|
+
# Ensure HEAD is the release commit (the commit that touched the version file)
|
|
225
|
+
validate_release_commit!(release_source)
|
|
226
|
+
else
|
|
227
|
+
# Standard mode: validate staging branch has same VERSION as working branch
|
|
228
|
+
validate_version_match!(staging_branch, working_branch)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
continue = syscall(
|
|
154
232
|
["git checkout #{production_branch}"],
|
|
155
|
-
["git reset --hard #{
|
|
233
|
+
["git reset --hard #{release_source}"],
|
|
156
234
|
["git tag -a v#{current_version} -m 'Release #{current_version}'"],
|
|
157
235
|
["git push origin #{production_branch}:#{production_branch} v#{current_version}:v#{current_version}"],
|
|
158
236
|
["git push origin v#{current_version}"]
|
|
@@ -209,6 +287,10 @@ module Discharger
|
|
|
209
287
|
|
|
210
288
|
desc description
|
|
211
289
|
task build: :environment do
|
|
290
|
+
if auto_deploy_staging
|
|
291
|
+
sysecho "Note: auto_deploy_staging is enabled. Staging deploys automatically from #{working_branch}.".bg(:yellow).black
|
|
292
|
+
end
|
|
293
|
+
|
|
212
294
|
# Allow overriding the working branch via environment variable
|
|
213
295
|
build_branch = ENV["DISCHARGER_BUILD_BRANCH"] || working_branch
|
|
214
296
|
|
|
@@ -287,6 +369,9 @@ module Discharger
|
|
|
287
369
|
|
|
288
370
|
pr_url = "#{pull_request_url}/compare/#{finish_branch}?#{params.to_query}"
|
|
289
371
|
|
|
372
|
+
next_step = auto_deploy_staging ? "rake #{name}" : "rake #{name}:stage"
|
|
373
|
+
next_step_desc = auto_deploy_staging ? "release to production" : "stage the release branch"
|
|
374
|
+
|
|
290
375
|
continue = syscall ["git push origin #{finish_branch} --force"] do
|
|
291
376
|
sysecho <<~MSG
|
|
292
377
|
Branch #{finish_branch} created.
|
|
@@ -295,8 +380,8 @@ module Discharger
|
|
|
295
380
|
#{pr_url}
|
|
296
381
|
|
|
297
382
|
Once the PR is merged, pull down #{working_branch} and run
|
|
298
|
-
'
|
|
299
|
-
to
|
|
383
|
+
'#{next_step}'
|
|
384
|
+
to #{next_step_desc}.
|
|
300
385
|
MSG
|
|
301
386
|
end
|
|
302
387
|
if continue
|
|
@@ -316,6 +401,15 @@ module Discharger
|
|
|
316
401
|
bin/rails #{name}:build
|
|
317
402
|
DESC
|
|
318
403
|
task stage: [:environment] do
|
|
404
|
+
if auto_deploy_staging
|
|
405
|
+
sysecho <<~MSG.bg(:yellow).black
|
|
406
|
+
Note: auto_deploy_staging is enabled.
|
|
407
|
+
Staging is handled automatically when code is pushed to #{working_branch}.
|
|
408
|
+
To release to production, run: 'rake #{name}'
|
|
409
|
+
MSG
|
|
410
|
+
next
|
|
411
|
+
end
|
|
412
|
+
|
|
319
413
|
tasker["build"].invoke
|
|
320
414
|
current_version = Object.const_get(version_constant)
|
|
321
415
|
|
data/lib/discharger/version.rb
CHANGED