discharger 0.2.27 → 0.2.29
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/base_command.rb +8 -8
- data/lib/discharger/setup_runner/commands/docker_command.rb +5 -6
- data/lib/discharger/setup_runner/commands/pg_tools_command.rb +64 -5
- data/lib/discharger/task.rb +49 -13
- 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: 04fa2c7e508709b01420db373058a6ab1cc81314c8cf6aab7a2c1a627e404c86
|
|
4
|
+
data.tar.gz: '09a4b2197db9c3c1509c685192abb53911156c8b7980d96671da59c7049be79f'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a56b02162d085a4db4ed5460066360c95819f2cc7735dc183f7e522ad31228cbf2a1e1f44c160766b4ceb2f660226f6cfce0b4f7563981a05999016e0e446ae2
|
|
7
|
+
data.tar.gz: ad6369eb6c7f782e92523c9c4e987a2471480e0140d0c918b4ee32b023f83692dddcc98a14a9eac4f2d4f0490e0c5badecedbb64e8e575e59483ab2309289b70
|
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.29] - 2026-03-10
|
|
9
9
|
|
|
10
|
-
## [0.2.
|
|
10
|
+
## [0.2.28] - 2026-02-17
|
|
@@ -163,19 +163,19 @@ module Discharger
|
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
def ask_to_install(description)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if gets
|
|
166
|
+
return yield unless $stdin.tty?
|
|
167
|
+
|
|
168
|
+
puts "You do not currently use #{description}.\n ===> If you want to, type Y\nOtherwise hit any key to ignore."
|
|
169
|
+
if gets&.chomp == "Y"
|
|
170
170
|
yield
|
|
171
171
|
end
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
def proceed_with(task)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if gets
|
|
175
|
+
return yield unless $stdin.tty?
|
|
176
|
+
|
|
177
|
+
puts "Proceed with #{task}?\n ===> Type Y to proceed\nOtherwise hit any key to ignore."
|
|
178
|
+
if gets&.chomp == "Y"
|
|
179
179
|
yield
|
|
180
180
|
end
|
|
181
181
|
end
|
|
@@ -152,12 +152,11 @@ module Discharger
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def native_postgresql_available?
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
end
|
|
155
|
+
configured_port = (config.database&.port || 5432).to_i
|
|
156
|
+
|
|
157
|
+
if postgresql_running_on_port?(configured_port)
|
|
158
|
+
@native_pg_port = configured_port
|
|
159
|
+
return true
|
|
161
160
|
end
|
|
162
161
|
false
|
|
163
162
|
end
|
|
@@ -104,8 +104,16 @@ module Discharger
|
|
|
104
104
|
exit 0
|
|
105
105
|
fi
|
|
106
106
|
|
|
107
|
-
# Fallback to system pg_dump
|
|
108
|
-
|
|
107
|
+
# Fallback to system pg_dump (skip this wrapper in PATH to avoid infinite loop)
|
|
108
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
109
|
+
CLEAN_PATH="${PATH//$SCRIPT_DIR:/}"
|
|
110
|
+
CLEAN_PATH="${CLEAN_PATH%:$SCRIPT_DIR}"
|
|
111
|
+
FALLBACK=$(PATH="$CLEAN_PATH" command -v pg_dump 2>/dev/null)
|
|
112
|
+
if [[ -n "$FALLBACK" ]]; then
|
|
113
|
+
exec "$FALLBACK" "$@"
|
|
114
|
+
fi
|
|
115
|
+
echo "Error: pg_dump not found. Start Docker or install PostgreSQL client tools." >&2
|
|
116
|
+
exit 1
|
|
109
117
|
BASH
|
|
110
118
|
end
|
|
111
119
|
|
|
@@ -119,11 +127,62 @@ module Discharger
|
|
|
119
127
|
# Docker first: use container's #{tool} if running
|
|
120
128
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER}$"; then
|
|
121
129
|
echo "Using #{tool} from Docker container: $CONTAINER" >&2
|
|
122
|
-
|
|
130
|
+
|
|
131
|
+
# Parse arguments to handle --file option specially
|
|
132
|
+
# When running in Docker, host paths don't exist in the container
|
|
133
|
+
# so we pipe file content via stdin instead
|
|
134
|
+
INPUT_FILE=""
|
|
135
|
+
HAS_USER=""
|
|
136
|
+
ARGS=()
|
|
137
|
+
while [[ $# -gt 0 ]]; do
|
|
138
|
+
case $1 in
|
|
139
|
+
--file)
|
|
140
|
+
INPUT_FILE="$2"
|
|
141
|
+
shift 2
|
|
142
|
+
;;
|
|
143
|
+
--file=*)
|
|
144
|
+
INPUT_FILE="${1#*=}"
|
|
145
|
+
shift
|
|
146
|
+
;;
|
|
147
|
+
-f)
|
|
148
|
+
INPUT_FILE="$2"
|
|
149
|
+
shift 2
|
|
150
|
+
;;
|
|
151
|
+
-U|--username|--username=*)
|
|
152
|
+
HAS_USER="1"
|
|
153
|
+
ARGS+=("$1")
|
|
154
|
+
shift
|
|
155
|
+
;;
|
|
156
|
+
*)
|
|
157
|
+
ARGS+=("$1")
|
|
158
|
+
shift
|
|
159
|
+
;;
|
|
160
|
+
esac
|
|
161
|
+
done
|
|
162
|
+
|
|
163
|
+
# Default to postgres user if not specified (container runs as root)
|
|
164
|
+
if [[ -z "$HAS_USER" ]]; then
|
|
165
|
+
ARGS=("-U" "postgres" "${ARGS[@]}")
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
if [[ -n "$INPUT_FILE" ]]; then
|
|
169
|
+
docker exec -i "$CONTAINER" #{tool} "${ARGS[@]}" < "$INPUT_FILE"
|
|
170
|
+
else
|
|
171
|
+
exec docker exec -i "$CONTAINER" #{tool} "${ARGS[@]}"
|
|
172
|
+
fi
|
|
173
|
+
exit 0
|
|
123
174
|
fi
|
|
124
175
|
|
|
125
|
-
# Fallback to system #{tool}
|
|
126
|
-
|
|
176
|
+
# Fallback to system #{tool} (skip this wrapper in PATH to avoid infinite loop)
|
|
177
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
178
|
+
CLEAN_PATH="${PATH//$SCRIPT_DIR:/}"
|
|
179
|
+
CLEAN_PATH="${CLEAN_PATH%:$SCRIPT_DIR}"
|
|
180
|
+
FALLBACK=$(PATH="$CLEAN_PATH" command -v #{tool} 2>/dev/null)
|
|
181
|
+
if [[ -n "$FALLBACK" ]]; then
|
|
182
|
+
exec "$FALLBACK" "$@"
|
|
183
|
+
fi
|
|
184
|
+
echo "Error: #{tool} not found. Start Docker or install PostgreSQL client tools." >&2
|
|
185
|
+
exit 1
|
|
127
186
|
BASH
|
|
128
187
|
end
|
|
129
188
|
|
data/lib/discharger/task.rb
CHANGED
|
@@ -179,6 +179,20 @@ module Discharger
|
|
|
179
179
|
stdout.strip
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
+
def existing_pr_number(base, head)
|
|
183
|
+
stdout, _, status = Open3.capture3(
|
|
184
|
+
"gh", "pr", "list",
|
|
185
|
+
"--base", base,
|
|
186
|
+
"--head", head,
|
|
187
|
+
"--state", "open",
|
|
188
|
+
"--json", "number",
|
|
189
|
+
"--jq", ".[0].number // empty"
|
|
190
|
+
)
|
|
191
|
+
return nil unless status.success?
|
|
192
|
+
pr = stdout.strip
|
|
193
|
+
pr.empty? ? nil : pr
|
|
194
|
+
end
|
|
195
|
+
|
|
182
196
|
def define
|
|
183
197
|
require "slack-ruby-client"
|
|
184
198
|
Slack.configure do |config|
|
|
@@ -189,14 +203,17 @@ module Discharger
|
|
|
189
203
|
---------- STEP 3 ----------
|
|
190
204
|
Release the current version to production
|
|
191
205
|
|
|
192
|
-
This task
|
|
193
|
-
|
|
194
|
-
remote repository.
|
|
206
|
+
This task merges the release branch into production via a GitHub pull
|
|
207
|
+
request and tags the current version.
|
|
195
208
|
|
|
196
209
|
After the release is complete, a new branch will be created to bump the
|
|
197
210
|
version for the next release.
|
|
198
211
|
DESC
|
|
199
212
|
task "#{name}": [:environment] do
|
|
213
|
+
unless system("gh --version > /dev/null 2>&1")
|
|
214
|
+
abort "Error: GitHub CLI (gh) is required for the release process but was not found. Install it: https://cli.github.com"
|
|
215
|
+
end
|
|
216
|
+
|
|
200
217
|
current_version = Object.const_get(version_constant)
|
|
201
218
|
|
|
202
219
|
# When auto_deploy_staging is enabled, release directly from working_branch
|
|
@@ -213,27 +230,45 @@ module Discharger
|
|
|
213
230
|
input = $stdin.gets
|
|
214
231
|
exit if input.chomp.match?(/^x/i)
|
|
215
232
|
|
|
216
|
-
# Fetch first, then validate what we fetched
|
|
217
233
|
syscall(
|
|
218
234
|
["git checkout #{working_branch}"],
|
|
219
235
|
["git branch -D #{staging_branch} 2>/dev/null || true"],
|
|
220
|
-
["git branch -D #{production_branch} 2>/dev/null || true"]
|
|
221
|
-
["git fetch origin #{release_source}:#{release_source} #{production_branch}:#{production_branch}"]
|
|
236
|
+
["git branch -D #{production_branch} 2>/dev/null || true"]
|
|
222
237
|
)
|
|
223
238
|
|
|
224
239
|
if auto_deploy_staging
|
|
225
|
-
|
|
240
|
+
syscall(
|
|
241
|
+
["git fetch origin #{production_branch}:#{production_branch} #{working_branch}"],
|
|
242
|
+
["git reset --hard origin/#{working_branch}"]
|
|
243
|
+
)
|
|
226
244
|
validate_release_commit!(release_source)
|
|
227
245
|
else
|
|
228
|
-
|
|
246
|
+
syscall(
|
|
247
|
+
["git fetch origin #{release_source}:#{release_source} #{production_branch}:#{production_branch}"]
|
|
248
|
+
)
|
|
229
249
|
validate_version_match!(staging_branch, working_branch)
|
|
230
250
|
end
|
|
231
251
|
|
|
252
|
+
pr_ref = release_source
|
|
253
|
+
if auto_deploy_staging
|
|
254
|
+
pr_number = existing_pr_number(production_branch, release_source)
|
|
255
|
+
if pr_number
|
|
256
|
+
sysecho "Reusing existing PR ##{pr_number} from #{release_source} to #{production_branch}."
|
|
257
|
+
pr_ref = pr_number
|
|
258
|
+
else
|
|
259
|
+
syscall(
|
|
260
|
+
["gh pr create --base #{production_branch} --head #{release_source} --title 'Release #{current_version}' --body 'Deploy #{current_version} to production.'"]
|
|
261
|
+
)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
syscall(
|
|
266
|
+
["gh pr merge #{pr_ref} --merge"]
|
|
267
|
+
)
|
|
268
|
+
|
|
232
269
|
continue = syscall(
|
|
233
|
-
["git
|
|
234
|
-
["git
|
|
235
|
-
["git tag -a v#{current_version} -m 'Release #{current_version}'"],
|
|
236
|
-
["git push origin #{production_branch}:#{production_branch} v#{current_version}:v#{current_version}"],
|
|
270
|
+
["git fetch origin #{production_branch}:#{production_branch}"],
|
|
271
|
+
["git tag -a v#{current_version} -m 'Release #{current_version}' #{production_branch}"],
|
|
237
272
|
["git push origin v#{current_version}"]
|
|
238
273
|
) do
|
|
239
274
|
tasker["#{name}:slack"].invoke("Released #{app_name} #{current_version} (#{commit_identifier.call}) to production.", release_message_channel, ":chipmunk:")
|
|
@@ -242,7 +277,8 @@ module Discharger
|
|
|
242
277
|
tasker["#{name}:slack"].reenable
|
|
243
278
|
tasker["#{name}:slack"].invoke(text, release_message_channel, ":log:", last_message_ts)
|
|
244
279
|
end
|
|
245
|
-
|
|
280
|
+
# Signal success — no branch switch needed since we stay on working_branch throughout
|
|
281
|
+
true
|
|
246
282
|
end
|
|
247
283
|
|
|
248
284
|
abort "Release failed." unless continue
|
data/lib/discharger/version.rb
CHANGED