discharger 0.3.2 → 0.3.4

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: 487fc4990548d3bae797d7538d41363f6c02064c1e0682ff3ef11bdeac4de7de
4
- data.tar.gz: 7125f6b47e9fea4e457d418fcda09ef12045ed72c5c96200b4d1887ae832a658
3
+ metadata.gz: 25a6ab71ff65d9ada8fe82ce0a706b08d335aaa533b10c1b57a652434149cd91
4
+ data.tar.gz: 524b68d60300a017c7d83bc7162f1962819b44f1be1255ec1fd8651b47740374
5
5
  SHA512:
6
- metadata.gz: 5e485c19d5c6285108dad2f14172b818046edcc4cec7fd9a3e5936c76e2a76df65fb4db0729b9862fc9f6e6ebb0750cb18f1fb23080920321438e19078626d5b
7
- data.tar.gz: 61431222b20ebd419407d1db9d2f969df34993cbdbce465c302d26bd80081aabacda5085f85e5e2aae758c23641f31124c2c9edbce1ff9ff733a9e5b014dbb73
6
+ metadata.gz: 7b67aaf1127f81ca25f3f4f78ce3fc5884920048baa022128b46dfa24e4ab01dee3b4574894d7e3305026cdfc7eb4659351b3cf649dc509e2d8c76982207bf01
7
+ data.tar.gz: 894a03d8fd806db6d0c831a1c47191332aa5cae0ab02fdf7709a040cab2e50f9e8a2ee02030d6e5015bfe2ab03d8a5e7ae806d6e79e9f0fe3f020a8f2cdc8a75
data/CHANGELOG.md CHANGED
@@ -5,19 +5,14 @@ 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.3.2] - 2026-07-15
8
+ ## [0.3.4] - 2026-07-22
9
9
 
10
- ### Changed
11
-
12
- - Treat generated pg_tools setup as opt-in for apps that use structure.sql or PostgreSQL CLI workflows.
13
-
14
- ### Fixed
10
+ ### Added
15
11
 
16
- - Retry `brew bundle` once before failing setup, so transient Homebrew lock contention (e.g. two `bin/setup` runs on the same host) doesn't hard-fail the whole run.
17
- - pg-tools wrappers no longer forward localhost -h/-p flags into docker exec, where the host-mapped port doesn't exist; remote hosts still pass through untouched (a3869d2)
12
+ - Runbook announcement on stage builds, previewing post-release steps before production (c77b552)
18
13
 
19
- ## [0.3.1] - 2026-05-13
14
+ ## [0.3.3] - 2026-07-22
20
15
 
21
16
  ### Added
22
17
 
23
- - database.prefer_docker setup.yml option for explicit Docker vs native PostgreSQL selection (2fca81e)
18
+ - Post-release runbook announcement in the Slack release thread, from Reissue's runbook_file (0cf9620)
data/README.md CHANGED
@@ -89,6 +89,56 @@ changelog.d/
89
89
 
90
90
  Each fragment file should contain the changelog entry for a specific change or feature.
91
91
 
92
+ ### Post-release Runbook
93
+
94
+ Some releases need manual follow-up: run a rake task, backfill data, re-index documents.
95
+ Reissue collects those steps from `Runbook:` commit trailers, and Discharger announces
96
+ them to your team in the release thread.
97
+
98
+ ```ruby
99
+ Discharger::Task.create do |task|
100
+ # ... other configuration ...
101
+ task.runbook_file = "RUNBOOK.md" # Default: nil (disabled)
102
+ end
103
+ ```
104
+
105
+ Add steps as you work, in the same commit as the change that requires them:
106
+
107
+ ```bash
108
+ git commit -m "Add data migration
109
+
110
+ Fixed: Duplicate user records
111
+ Runbook: Run \`rake data:cleanup\` after deploy"
112
+ ```
113
+
114
+ `rake release:prepare` finalizes the runbook alongside the changelog, so the release tag
115
+ records exactly which steps that version needs. Discharger posts the checklist to Slack as
116
+ a reply in the deploy thread — both on the stage build (`rake release:build` /
117
+ `rake release:stage`, threaded under "Building…") and after the production release
118
+ (threaded under the release announcement, right after the changelog):
119
+
120
+ ```
121
+ *Post-release runbook for 1.2.3* — 2 steps
122
+
123
+ • Run `rake data:cleanup` (abc1234)
124
+ • Re-index search documents (def5678)
125
+ ```
126
+
127
+ Staging shows the steps as a preview so the team sees what production will need before it
128
+ happens; the production thread repeats them when the release actually lands.
129
+
130
+ When a release needs no follow-up, the thread says so explicitly rather than staying
131
+ silent, so nobody has to wonder whether the check was skipped:
132
+
133
+ ```
134
+ *Post-release runbook for 1.2.3*
135
+ No runbook tasks for this release.
136
+ ```
137
+
138
+ Leave `runbook_file` unset and Discharger posts nothing extra. See the
139
+ [Reissue runbook documentation](https://github.com/SOFware/reissue#post-release-runbook)
140
+ for how items are collected and merged.
141
+
92
142
  ## Available Tasks
93
143
 
94
144
  The gem creates several Rake tasks for managing your deployment workflow:
@@ -24,6 +24,7 @@ module Discharger
24
24
  reissue.fragment = task.fragment
25
25
  reissue.clear_fragments = task.clear_fragments
26
26
  reissue.tag_pattern = task.tag_pattern
27
+ reissue.runbook_file = task.runbook_file
27
28
  end
28
29
  task.define
29
30
  task
@@ -179,6 +180,40 @@ module Discharger
179
180
  stdout.strip
180
181
  end
181
182
 
183
+ # The post-release steps collected from "Runbook:" commit trailers.
184
+ # Empty when no runbook is configured or the file has yet to be written.
185
+ def runbook_items
186
+ return [] unless runbook_file
187
+
188
+ Reissue::Runbook.new(Rails.root.join(runbook_file).to_s).items
189
+ end
190
+
191
+ # Build the Slack message listing the post-release steps for a version.
192
+ # Returns nil when the project does not use a runbook, which is distinct
193
+ # from a configured runbook that happens to have no steps this release.
194
+ def runbook_announcement(version, items = runbook_items)
195
+ return nil unless runbook_file
196
+
197
+ header = "*Post-release runbook for #{version}*"
198
+ return "#{header}\nNo runbook tasks for this release." if items.empty?
199
+
200
+ "#{header} — #{items.size} step#{"s" unless items.size == 1}\n\n" +
201
+ items.map { |item| "• #{item}" }.join("\n")
202
+ end
203
+
204
+ # Post the runbook as a reply in a Slack thread, when a runbook is
205
+ # configured. Reuses the same message on the stage build and the
206
+ # production release. Returns the message posted, or nil when there is
207
+ # no thread to reply to or no runbook to announce.
208
+ def post_runbook_to_thread(version, thread_ts)
209
+ return unless thread_ts.present?
210
+ return unless (message = runbook_announcement(version))
211
+
212
+ tasker["#{name}:slack"].reenable
213
+ tasker["#{name}:slack"].invoke(message, release_message_channel, ":clipboard:", thread_ts)
214
+ message
215
+ end
216
+
182
217
  def existing_pr_number(base, head)
183
218
  stdout, _, status = Open3.capture3(
184
219
  "gh", "pr", "list",
@@ -286,10 +321,14 @@ module Discharger
286
321
  ["git push origin v#{current_version}"]
287
322
  ) do
288
323
  tasker["#{name}:slack"].invoke("Released #{app_name} #{current_version} (#{commit_identifier.call}) to production.", release_message_channel, ":chipmunk:")
289
- if last_message_ts.present?
324
+ # Capture the root before replying; each post overwrites last_message_ts.
325
+ thread_ts = last_message_ts
326
+ if thread_ts.present?
290
327
  text = File.read(Rails.root.join(changelog_file))
291
328
  tasker["#{name}:slack"].reenable
292
- tasker["#{name}:slack"].invoke(text, release_message_channel, ":log:", last_message_ts)
329
+ tasker["#{name}:slack"].invoke(text, release_message_channel, ":log:", thread_ts)
330
+
331
+ post_runbook_to_thread(current_version, thread_ts)
293
332
  end
294
333
  # Signal success — no branch switch needed since we stay on working_branch throughout
295
334
  true
@@ -356,6 +395,7 @@ module Discharger
356
395
  ) do
357
396
  current_version = Object.const_get(version_constant)
358
397
  tasker["#{name}:slack"].invoke("Building #{app_name} #{current_version} (#{commit_identifier.call}) on #{staging_branch}.", release_message_channel)
398
+ post_runbook_to_thread(current_version, last_message_ts)
359
399
  syscall ["git checkout #{build_branch}"]
360
400
  end
361
401
  end
@@ -1,3 +1,3 @@
1
1
  module Discharger
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discharger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Gay
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '0.5'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '0.5'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: slack-ruby-client
85
85
  requirement: !ruby/object:Gem::Requirement