@orderful/droid 0.44.0 → 0.44.1
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.
- package/CHANGELOG.md +6 -0
- package/dist/tools/release/.claude-plugin/plugin.json +1 -1
- package/dist/tools/release/TOOL.yaml +2 -2
- package/dist/tools/release/commands/release.md +16 -8
- package/dist/tools/release/skills/release/SKILL.md +15 -9
- package/dist/tools/release/skills/release/references/templates.md +47 -4
- package/dist/tools/release/skills/release/references/workflows.md +121 -9
- package/package.json +1 -1
- package/src/tools/release/.claude-plugin/plugin.json +1 -1
- package/src/tools/release/TOOL.yaml +2 -2
- package/src/tools/release/commands/release.md +16 -8
- package/src/tools/release/skills/release/SKILL.md +15 -9
- package/src/tools/release/skills/release/references/templates.md +47 -4
- package/src/tools/release/skills/release/references/workflows.md +121 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @orderful/droid
|
|
2
2
|
|
|
3
|
+
## 0.44.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#258](https://github.com/Orderful/droid/pull/258) [`2e19bbd`](https://github.com/Orderful/droid/commit/2e19bbda7146847836ccda028e1c6bf802a5215e) Thanks [@frytyler](https://github.com/frytyler)! - Add lock/unlock commands to release tool. Requires branch-lock.yml GitHub Action deployed to target repos.
|
|
8
|
+
|
|
3
9
|
## 0.44.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: release
|
|
2
2
|
description: "Release ceremony automation — create release PRs, check status, notify Slack."
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.2.0
|
|
4
4
|
status: alpha
|
|
5
5
|
|
|
6
6
|
includes:
|
|
@@ -18,4 +18,4 @@ config_schema:
|
|
|
18
18
|
slack_channel:
|
|
19
19
|
type: string
|
|
20
20
|
description: "Slack channel for release notifications"
|
|
21
|
-
default: "#
|
|
21
|
+
default: "#release_management"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release
|
|
3
|
-
description: "Release ceremony automation"
|
|
4
|
-
argument-hint: "[start [repo] | status | complete [repo]]"
|
|
3
|
+
description: "Release ceremony automation and branch locking"
|
|
4
|
+
argument-hint: "[start [repo] [--no-lock] | merge [repo] | lock [repo] | unlock [repo] | status | complete [repo]]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# /release
|
|
@@ -12,17 +12,25 @@ argument-hint: "[start [repo] | status | complete [repo]]"
|
|
|
12
12
|
|
|
13
13
|
## Examples
|
|
14
14
|
|
|
15
|
-
- `/release start` → Create release PR
|
|
15
|
+
- `/release start` → Create release PR + auto-lock branch
|
|
16
16
|
- `/release start orderful-workspace` → Create release PR for a specific repo
|
|
17
|
-
- `/release
|
|
18
|
-
- `/release
|
|
17
|
+
- `/release start --no-lock` → Create release PR without locking
|
|
18
|
+
- `/release merge` → Merge release PR (checks must be green)
|
|
19
|
+
- `/release lock` → Manually lock the release branch
|
|
20
|
+
- `/release unlock` → Unlock the release branch
|
|
21
|
+
- `/release status` → Check CI and lock state across release repos
|
|
22
|
+
- `/release complete` → Post "release complete" to Slack, auto-unlock if locked
|
|
19
23
|
|
|
20
24
|
## Quick Reference
|
|
21
25
|
|
|
22
26
|
```
|
|
23
|
-
/release start [repo]
|
|
24
|
-
/release
|
|
25
|
-
/release
|
|
27
|
+
/release start [repo] # Create release PR + auto-lock + notify Slack
|
|
28
|
+
/release start --no-lock # Create release PR without locking
|
|
29
|
+
/release merge [repo] # Merge release PR (checks must pass)
|
|
30
|
+
/release lock [repo] # Manually lock release branch
|
|
31
|
+
/release unlock [repo] # Unlock release branch
|
|
32
|
+
/release status # CI + lock state across repos
|
|
33
|
+
/release complete [repo] # Notify Slack + auto-unlock
|
|
26
34
|
```
|
|
27
35
|
|
|
28
36
|
See the **release skill** for complete documentation.
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release
|
|
3
|
-
description: "Release ceremony automation for dev-to-master releases. Use when starting a release, merging a release, checking release status, or completing a release. User prompts like 'start a release', 'merge the release', 'release status', '
|
|
4
|
-
argument-hint: "[start [repo] | merge [repo] | status | complete [repo]]"
|
|
3
|
+
description: "Release ceremony automation for dev-to-master releases. Use when starting a release, merging a release, locking a branch, checking release status, or completing a release. User prompts like 'start a release', 'merge the release', 'lock dev', 'release status', 'unlock the branch'."
|
|
4
|
+
argument-hint: "[start [repo] | merge [repo] | lock [repo] | unlock [repo] | status | complete [repo]]"
|
|
5
5
|
allowed-tools: [Read, Write, Glob, Grep, Bash, Edit]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Release Skill
|
|
9
9
|
|
|
10
|
-
Automate dev → master release ceremonies: create release PRs, notify Slack, and track status.
|
|
10
|
+
Automate dev → master release ceremonies: create release PRs, lock branches during CI, notify Slack, and track status.
|
|
11
11
|
|
|
12
12
|
## When to Use
|
|
13
13
|
|
|
14
14
|
- User wants to start a release (create PR from dev → master)
|
|
15
|
-
- User
|
|
15
|
+
- User wants to lock or unlock a branch during a release
|
|
16
|
+
- User asks about release status (open PRs, lock state, CI checks)
|
|
16
17
|
- User says "release complete" or wants to close out a release
|
|
17
|
-
- Natural language like "start a release", "what's the release status?"
|
|
18
|
+
- Natural language like "start a release", "lock dev", "what's the release status?"
|
|
18
19
|
|
|
19
20
|
## When NOT to Use
|
|
20
21
|
|
|
@@ -26,6 +27,7 @@ Automate dev → master release ceremonies: create release PRs, notify Slack, an
|
|
|
26
27
|
|
|
27
28
|
1. **`gh` CLI** — authenticated with access to target repos
|
|
28
29
|
2. **Slack integration** — `droid integrations slack post` configured (optional, falls back to terminal)
|
|
30
|
+
3. **`branch-lock.yml`** — GitHub Action deployed to target repo (required for auto-lock on start + lock/unlock commands)
|
|
29
31
|
|
|
30
32
|
## Configuration
|
|
31
33
|
|
|
@@ -37,7 +39,7 @@ droid config --get repos
|
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
- **Repos:** Filter `repos` array for entries with `release_branch` set — these are release repos
|
|
40
|
-
- **Slack channel:** From `tools.release.slack_channel` (default: `#
|
|
42
|
+
- **Slack channel:** From `tools.release.slack_channel` (default: `#release_management`)
|
|
41
43
|
- **Repo detection:** Match cwd against repo paths, or ask user if ambiguous
|
|
42
44
|
|
|
43
45
|
If no repos have `release_branch` set, tell user:
|
|
@@ -47,10 +49,12 @@ If no repos have `release_branch` set, tell user:
|
|
|
47
49
|
|
|
48
50
|
| Command | Action |
|
|
49
51
|
|---------|--------|
|
|
50
|
-
| `/release start [repo]` | Create release PR + notify Slack |
|
|
52
|
+
| `/release start [repo] [--no-lock]` | Create release PR + auto-lock branch + notify Slack |
|
|
51
53
|
| `/release merge [repo]` | Merge release PR (only if checks pass) + notify Slack |
|
|
52
|
-
| `/release
|
|
53
|
-
| `/release
|
|
54
|
+
| `/release lock [repo]` | Lock release branch (confirms first) |
|
|
55
|
+
| `/release unlock [repo]` | Unlock release branch |
|
|
56
|
+
| `/release status` | Check open release PRs + CI state + lock state |
|
|
57
|
+
| `/release complete [repo]` | Post completion to Slack + auto-unlock |
|
|
54
58
|
|
|
55
59
|
See `references/workflows.md` for detailed step-by-step procedures and exact `gh` commands.
|
|
56
60
|
|
|
@@ -69,6 +73,8 @@ See `references/templates.md` for Slack message and PR body templates.
|
|
|
69
73
|
|-------|--------|
|
|
70
74
|
| No release repos configured | Suggest `droid repos add` with release branch |
|
|
71
75
|
| `gh` CLI not authenticated | Suggest `gh auth login` |
|
|
76
|
+
| `branch-lock.yml` not found in repo | Tell user to add the `branch-lock.yml` workflow to the repo |
|
|
72
77
|
| Slack not configured | Print message to terminal, suggest `droid integrations setup slack` |
|
|
78
|
+
| Branch already locked | Warn user, offer to unlock first |
|
|
73
79
|
| Release PR already exists | Show existing PR, ask if user wants to proceed |
|
|
74
80
|
| CI checks failing | Show status, do not auto-merge |
|
|
@@ -6,20 +6,23 @@ Slack mrkdwn and PR body templates for release notifications.
|
|
|
6
6
|
|
|
7
7
|
All Slack messages are posted via `droid integrations slack post`. Format as Slack mrkdwn (not GitHub markdown).
|
|
8
8
|
|
|
9
|
-
### Release
|
|
9
|
+
### Release Open for Review
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
:rocket: *Release
|
|
12
|
+
:rocket: *Release open for review — {repo_name}*
|
|
13
13
|
|
|
14
14
|
*Risk:* {risk_emoji} {risk_level}
|
|
15
15
|
*PR:* <{pr_url}|#{pr_number}>
|
|
16
16
|
*Branch:* `{release_branch}` → `{production_branch}`
|
|
17
|
+
:lock: `{release_branch}` is locked — no merges until release completes
|
|
17
18
|
|
|
18
19
|
{pr_summary}
|
|
19
20
|
|
|
20
21
|
Posted with :droid:
|
|
21
22
|
```
|
|
22
23
|
|
|
24
|
+
If `--no-lock` was used, omit the lock line.
|
|
25
|
+
|
|
23
26
|
Risk emojis:
|
|
24
27
|
- Low Risk: `:large_green_circle:`
|
|
25
28
|
- High Risk: `:warning:`
|
|
@@ -37,6 +40,26 @@ Monitoring deployment :eyes:
|
|
|
37
40
|
Posted with :droid:
|
|
38
41
|
```
|
|
39
42
|
|
|
43
|
+
### Branch Locked
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
:lock: *Branch locked — {repo_name}*
|
|
47
|
+
|
|
48
|
+
`{branch}` is now read-only. No merges until unlocked.
|
|
49
|
+
|
|
50
|
+
Posted with :droid:
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Branch Unlocked
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
:unlock: *Branch unlocked — {repo_name}*
|
|
57
|
+
|
|
58
|
+
`{branch}` is open for merges.
|
|
59
|
+
|
|
60
|
+
Posted with :droid:
|
|
61
|
+
```
|
|
62
|
+
|
|
40
63
|
### Release Complete
|
|
41
64
|
|
|
42
65
|
```
|
|
@@ -48,6 +71,11 @@ Posted with :droid:
|
|
|
48
71
|
Posted with :droid:
|
|
49
72
|
```
|
|
50
73
|
|
|
74
|
+
If auto-unlocked, append:
|
|
75
|
+
```
|
|
76
|
+
:unlock: Auto-unlocked `{release_branch}`
|
|
77
|
+
```
|
|
78
|
+
|
|
51
79
|
---
|
|
52
80
|
|
|
53
81
|
## Release PR Body
|
|
@@ -81,14 +109,17 @@ Where `{pr_list}` is a bulleted list of merged PRs:
|
|
|
81
109
|
|
|
82
110
|
When Slack is not configured, print a plain-text version to terminal:
|
|
83
111
|
|
|
84
|
-
### Release
|
|
112
|
+
### Release Open for Review (terminal)
|
|
85
113
|
```
|
|
86
|
-
Release
|
|
114
|
+
Release open for review — {repo_name}
|
|
87
115
|
Risk: {risk_level}
|
|
88
116
|
PR: {pr_url}
|
|
89
117
|
Branch: {release_branch} -> {production_branch}
|
|
118
|
+
Lock: {release_branch} locked (no merges until release completes)
|
|
90
119
|
```
|
|
91
120
|
|
|
121
|
+
If `--no-lock` was used, omit the Lock line.
|
|
122
|
+
|
|
92
123
|
### Release Merged (terminal)
|
|
93
124
|
```
|
|
94
125
|
Release merged — {repo_name}
|
|
@@ -97,6 +128,18 @@ Release merged — {repo_name}
|
|
|
97
128
|
Monitoring deployment...
|
|
98
129
|
```
|
|
99
130
|
|
|
131
|
+
### Branch Locked (terminal)
|
|
132
|
+
```
|
|
133
|
+
Branch locked — {repo_name}
|
|
134
|
+
{branch} is now read-only
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Branch Unlocked (terminal)
|
|
138
|
+
```
|
|
139
|
+
Branch unlocked — {repo_name}
|
|
140
|
+
{branch} is open for merges
|
|
141
|
+
```
|
|
142
|
+
|
|
100
143
|
### Release Complete (terminal)
|
|
101
144
|
```
|
|
102
145
|
Release complete — {repo_name}
|
|
@@ -7,8 +7,8 @@ Detailed step-by-step procedures for each `/release` subcommand. All commands us
|
|
|
7
7
|
```bash
|
|
8
8
|
# 1. Read config
|
|
9
9
|
SLACK_CHANNEL=$(droid config --get tools.release.slack_channel)
|
|
10
|
-
# Default to #
|
|
11
|
-
SLACK_CHANNEL="${SLACK_CHANNEL:-#
|
|
10
|
+
# Default to #release_management if not set
|
|
11
|
+
SLACK_CHANNEL="${SLACK_CHANNEL:-#release_management}"
|
|
12
12
|
|
|
13
13
|
# 2. Get repos and filter for release repos (those with release_branch set)
|
|
14
14
|
droid config --get repos
|
|
@@ -25,9 +25,11 @@ git -C {repo_path} remote get-url origin
|
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
## `/release start [repo]`
|
|
28
|
+
## `/release start [repo] [--no-lock]`
|
|
29
29
|
|
|
30
|
-
Create a release PR and notify Slack.
|
|
30
|
+
Create a release PR, auto-lock the release branch, and notify Slack.
|
|
31
|
+
|
|
32
|
+
**Auto-lock is on by default.** The branch is locked immediately after the PR is created to prevent blind merges during CI. Pass `--no-lock` (or natural language like "start without locking") to skip.
|
|
31
33
|
|
|
32
34
|
### Steps
|
|
33
35
|
|
|
@@ -64,7 +66,22 @@ Create a release PR and notify Slack.
|
|
|
64
66
|
```
|
|
65
67
|
See `templates.md` for the PR body template.
|
|
66
68
|
|
|
67
|
-
6. **
|
|
69
|
+
6. **Auto-lock branch** (unless `--no-lock`):
|
|
70
|
+
```bash
|
|
71
|
+
gh workflow run branch-lock.yml \
|
|
72
|
+
-f action=lock \
|
|
73
|
+
-f branch={release_branch} \
|
|
74
|
+
--repo {owner}/{repo}
|
|
75
|
+
```
|
|
76
|
+
Verify lock applied:
|
|
77
|
+
```bash
|
|
78
|
+
sleep 5
|
|
79
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
80
|
+
```
|
|
81
|
+
If `branch-lock.yml` is not found in the repo, warn but don't fail:
|
|
82
|
+
"Could not auto-lock — `branch-lock.yml` not found in `{repo_name}`. Use `/release lock` manually after adding the workflow."
|
|
83
|
+
|
|
84
|
+
7. **Post to Slack:**
|
|
68
85
|
```bash
|
|
69
86
|
node -e 'process.stdout.write(JSON.stringify({
|
|
70
87
|
channel: "{slack_channel}",
|
|
@@ -72,9 +89,9 @@ Create a release PR and notify Slack.
|
|
|
72
89
|
unfurl_links: false
|
|
73
90
|
}))' | droid integrations slack post
|
|
74
91
|
```
|
|
75
|
-
See `templates.md` for the Slack message template (release
|
|
92
|
+
See `templates.md` for the Slack message template (release open for review — includes lock status).
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
8. **Confirm to user** — show PR URL, lock status, and Slack post confirmation.
|
|
78
95
|
|
|
79
96
|
---
|
|
80
97
|
|
|
@@ -112,6 +129,81 @@ Merge the release PR if all checks are green, then notify Slack.
|
|
|
112
129
|
|
|
113
130
|
---
|
|
114
131
|
|
|
132
|
+
## `/release lock [repo]`
|
|
133
|
+
|
|
134
|
+
Manually lock the release branch. Use when you need to lock outside of `/release start` (which auto-locks).
|
|
135
|
+
|
|
136
|
+
### Steps
|
|
137
|
+
|
|
138
|
+
1. **Detect repo** — match cwd or ask user
|
|
139
|
+
|
|
140
|
+
2. **Check current lock state:**
|
|
141
|
+
```bash
|
|
142
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
143
|
+
```
|
|
144
|
+
If already locked, warn: "Branch `{release_branch}` is already locked. Unlock first?"
|
|
145
|
+
|
|
146
|
+
3. **Confirm with user** — use AskUserQuestion:
|
|
147
|
+
"Lock `{release_branch}` on `{repo_name}`? No one will be able to merge until unlocked."
|
|
148
|
+
|
|
149
|
+
4. **Trigger the lock Action:**
|
|
150
|
+
```bash
|
|
151
|
+
gh workflow run branch-lock.yml \
|
|
152
|
+
-f action=lock \
|
|
153
|
+
-f branch={release_branch} \
|
|
154
|
+
--repo {owner}/{repo}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
5. **Verify lock applied** (wait a few seconds, then check):
|
|
158
|
+
```bash
|
|
159
|
+
sleep 5
|
|
160
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
161
|
+
```
|
|
162
|
+
If still not locked, check the workflow run status:
|
|
163
|
+
```bash
|
|
164
|
+
gh run list --workflow=branch-lock.yml --limit 1 --json status,conclusion --repo {owner}/{repo}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
6. **Post to Slack** — lock notification (see `templates.md`).
|
|
168
|
+
|
|
169
|
+
7. **Confirm to user** — "Locked `{release_branch}` on `{repo_name}`."
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## `/release unlock [repo]`
|
|
174
|
+
|
|
175
|
+
Unlock the release branch.
|
|
176
|
+
|
|
177
|
+
### Steps
|
|
178
|
+
|
|
179
|
+
1. **Detect repo** — match cwd or ask user
|
|
180
|
+
|
|
181
|
+
2. **Check current lock state:**
|
|
182
|
+
```bash
|
|
183
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
184
|
+
```
|
|
185
|
+
If not locked, inform: "Branch `{release_branch}` is not currently locked."
|
|
186
|
+
|
|
187
|
+
3. **Trigger the unlock Action:**
|
|
188
|
+
```bash
|
|
189
|
+
gh workflow run branch-lock.yml \
|
|
190
|
+
-f action=unlock \
|
|
191
|
+
-f branch={release_branch} \
|
|
192
|
+
--repo {owner}/{repo}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
4. **Verify unlock applied:**
|
|
196
|
+
```bash
|
|
197
|
+
sleep 5
|
|
198
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
5. **Post to Slack** — unlock notification (see `templates.md`).
|
|
202
|
+
|
|
203
|
+
6. **Confirm to user** — "Unlocked `{release_branch}` on `{repo_name}`."
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
115
207
|
## `/release status`
|
|
116
208
|
|
|
117
209
|
Check release status across all configured release repos.
|
|
@@ -127,11 +219,17 @@ Check release status across all configured release repos.
|
|
|
127
219
|
gh pr list --search "[RELEASE]" --state open --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
128
220
|
```
|
|
129
221
|
|
|
222
|
+
**Lock state:**
|
|
223
|
+
```bash
|
|
224
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
225
|
+
```
|
|
226
|
+
|
|
130
227
|
3. **Format and display** as a summary:
|
|
131
228
|
|
|
132
229
|
```
|
|
133
230
|
{repo_name}
|
|
134
231
|
Release PR: #{number} — {CI status} (green/pending/failing)
|
|
232
|
+
Branch lock: {release_branch} — locked/unlocked
|
|
135
233
|
```
|
|
136
234
|
|
|
137
235
|
If no open release PR: "No active release"
|
|
@@ -141,7 +239,7 @@ Check release status across all configured release repos.
|
|
|
141
239
|
|
|
142
240
|
## `/release complete [repo]`
|
|
143
241
|
|
|
144
|
-
Close out a release — notify Slack.
|
|
242
|
+
Close out a release — notify Slack and auto-unlock.
|
|
145
243
|
|
|
146
244
|
### Steps
|
|
147
245
|
|
|
@@ -161,6 +259,20 @@ Close out a release — notify Slack.
|
|
|
161
259
|
|
|
162
260
|
3. **Post to Slack** — release complete notification (see `templates.md`).
|
|
163
261
|
|
|
164
|
-
4. **
|
|
262
|
+
4. **Auto-unlock if locked:**
|
|
263
|
+
```bash
|
|
264
|
+
LOCKED=$(gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false')
|
|
265
|
+
```
|
|
266
|
+
If locked, trigger unlock:
|
|
267
|
+
```bash
|
|
268
|
+
gh workflow run branch-lock.yml \
|
|
269
|
+
-f action=unlock \
|
|
270
|
+
-f branch={release_branch} \
|
|
271
|
+
--repo {owner}/{repo}
|
|
272
|
+
```
|
|
273
|
+
Post unlock notification to Slack as well.
|
|
274
|
+
|
|
275
|
+
5. **Confirm to user:**
|
|
165
276
|
- "Release complete for `{repo_name}`"
|
|
277
|
+
- "Auto-unlocked `{release_branch}`" (if was locked)
|
|
166
278
|
- Show Slack message confirmation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: release
|
|
2
2
|
description: "Release ceremony automation — create release PRs, check status, notify Slack."
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.2.0
|
|
4
4
|
status: alpha
|
|
5
5
|
|
|
6
6
|
includes:
|
|
@@ -18,4 +18,4 @@ config_schema:
|
|
|
18
18
|
slack_channel:
|
|
19
19
|
type: string
|
|
20
20
|
description: "Slack channel for release notifications"
|
|
21
|
-
default: "#
|
|
21
|
+
default: "#release_management"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release
|
|
3
|
-
description: "Release ceremony automation"
|
|
4
|
-
argument-hint: "[start [repo] | status | complete [repo]]"
|
|
3
|
+
description: "Release ceremony automation and branch locking"
|
|
4
|
+
argument-hint: "[start [repo] [--no-lock] | merge [repo] | lock [repo] | unlock [repo] | status | complete [repo]]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# /release
|
|
@@ -12,17 +12,25 @@ argument-hint: "[start [repo] | status | complete [repo]]"
|
|
|
12
12
|
|
|
13
13
|
## Examples
|
|
14
14
|
|
|
15
|
-
- `/release start` → Create release PR
|
|
15
|
+
- `/release start` → Create release PR + auto-lock branch
|
|
16
16
|
- `/release start orderful-workspace` → Create release PR for a specific repo
|
|
17
|
-
- `/release
|
|
18
|
-
- `/release
|
|
17
|
+
- `/release start --no-lock` → Create release PR without locking
|
|
18
|
+
- `/release merge` → Merge release PR (checks must be green)
|
|
19
|
+
- `/release lock` → Manually lock the release branch
|
|
20
|
+
- `/release unlock` → Unlock the release branch
|
|
21
|
+
- `/release status` → Check CI and lock state across release repos
|
|
22
|
+
- `/release complete` → Post "release complete" to Slack, auto-unlock if locked
|
|
19
23
|
|
|
20
24
|
## Quick Reference
|
|
21
25
|
|
|
22
26
|
```
|
|
23
|
-
/release start [repo]
|
|
24
|
-
/release
|
|
25
|
-
/release
|
|
27
|
+
/release start [repo] # Create release PR + auto-lock + notify Slack
|
|
28
|
+
/release start --no-lock # Create release PR without locking
|
|
29
|
+
/release merge [repo] # Merge release PR (checks must pass)
|
|
30
|
+
/release lock [repo] # Manually lock release branch
|
|
31
|
+
/release unlock [repo] # Unlock release branch
|
|
32
|
+
/release status # CI + lock state across repos
|
|
33
|
+
/release complete [repo] # Notify Slack + auto-unlock
|
|
26
34
|
```
|
|
27
35
|
|
|
28
36
|
See the **release skill** for complete documentation.
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release
|
|
3
|
-
description: "Release ceremony automation for dev-to-master releases. Use when starting a release, merging a release, checking release status, or completing a release. User prompts like 'start a release', 'merge the release', 'release status', '
|
|
4
|
-
argument-hint: "[start [repo] | merge [repo] | status | complete [repo]]"
|
|
3
|
+
description: "Release ceremony automation for dev-to-master releases. Use when starting a release, merging a release, locking a branch, checking release status, or completing a release. User prompts like 'start a release', 'merge the release', 'lock dev', 'release status', 'unlock the branch'."
|
|
4
|
+
argument-hint: "[start [repo] | merge [repo] | lock [repo] | unlock [repo] | status | complete [repo]]"
|
|
5
5
|
allowed-tools: [Read, Write, Glob, Grep, Bash, Edit]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Release Skill
|
|
9
9
|
|
|
10
|
-
Automate dev → master release ceremonies: create release PRs, notify Slack, and track status.
|
|
10
|
+
Automate dev → master release ceremonies: create release PRs, lock branches during CI, notify Slack, and track status.
|
|
11
11
|
|
|
12
12
|
## When to Use
|
|
13
13
|
|
|
14
14
|
- User wants to start a release (create PR from dev → master)
|
|
15
|
-
- User
|
|
15
|
+
- User wants to lock or unlock a branch during a release
|
|
16
|
+
- User asks about release status (open PRs, lock state, CI checks)
|
|
16
17
|
- User says "release complete" or wants to close out a release
|
|
17
|
-
- Natural language like "start a release", "what's the release status?"
|
|
18
|
+
- Natural language like "start a release", "lock dev", "what's the release status?"
|
|
18
19
|
|
|
19
20
|
## When NOT to Use
|
|
20
21
|
|
|
@@ -26,6 +27,7 @@ Automate dev → master release ceremonies: create release PRs, notify Slack, an
|
|
|
26
27
|
|
|
27
28
|
1. **`gh` CLI** — authenticated with access to target repos
|
|
28
29
|
2. **Slack integration** — `droid integrations slack post` configured (optional, falls back to terminal)
|
|
30
|
+
3. **`branch-lock.yml`** — GitHub Action deployed to target repo (required for auto-lock on start + lock/unlock commands)
|
|
29
31
|
|
|
30
32
|
## Configuration
|
|
31
33
|
|
|
@@ -37,7 +39,7 @@ droid config --get repos
|
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
- **Repos:** Filter `repos` array for entries with `release_branch` set — these are release repos
|
|
40
|
-
- **Slack channel:** From `tools.release.slack_channel` (default: `#
|
|
42
|
+
- **Slack channel:** From `tools.release.slack_channel` (default: `#release_management`)
|
|
41
43
|
- **Repo detection:** Match cwd against repo paths, or ask user if ambiguous
|
|
42
44
|
|
|
43
45
|
If no repos have `release_branch` set, tell user:
|
|
@@ -47,10 +49,12 @@ If no repos have `release_branch` set, tell user:
|
|
|
47
49
|
|
|
48
50
|
| Command | Action |
|
|
49
51
|
|---------|--------|
|
|
50
|
-
| `/release start [repo]` | Create release PR + notify Slack |
|
|
52
|
+
| `/release start [repo] [--no-lock]` | Create release PR + auto-lock branch + notify Slack |
|
|
51
53
|
| `/release merge [repo]` | Merge release PR (only if checks pass) + notify Slack |
|
|
52
|
-
| `/release
|
|
53
|
-
| `/release
|
|
54
|
+
| `/release lock [repo]` | Lock release branch (confirms first) |
|
|
55
|
+
| `/release unlock [repo]` | Unlock release branch |
|
|
56
|
+
| `/release status` | Check open release PRs + CI state + lock state |
|
|
57
|
+
| `/release complete [repo]` | Post completion to Slack + auto-unlock |
|
|
54
58
|
|
|
55
59
|
See `references/workflows.md` for detailed step-by-step procedures and exact `gh` commands.
|
|
56
60
|
|
|
@@ -69,6 +73,8 @@ See `references/templates.md` for Slack message and PR body templates.
|
|
|
69
73
|
|-------|--------|
|
|
70
74
|
| No release repos configured | Suggest `droid repos add` with release branch |
|
|
71
75
|
| `gh` CLI not authenticated | Suggest `gh auth login` |
|
|
76
|
+
| `branch-lock.yml` not found in repo | Tell user to add the `branch-lock.yml` workflow to the repo |
|
|
72
77
|
| Slack not configured | Print message to terminal, suggest `droid integrations setup slack` |
|
|
78
|
+
| Branch already locked | Warn user, offer to unlock first |
|
|
73
79
|
| Release PR already exists | Show existing PR, ask if user wants to proceed |
|
|
74
80
|
| CI checks failing | Show status, do not auto-merge |
|
|
@@ -6,20 +6,23 @@ Slack mrkdwn and PR body templates for release notifications.
|
|
|
6
6
|
|
|
7
7
|
All Slack messages are posted via `droid integrations slack post`. Format as Slack mrkdwn (not GitHub markdown).
|
|
8
8
|
|
|
9
|
-
### Release
|
|
9
|
+
### Release Open for Review
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
:rocket: *Release
|
|
12
|
+
:rocket: *Release open for review — {repo_name}*
|
|
13
13
|
|
|
14
14
|
*Risk:* {risk_emoji} {risk_level}
|
|
15
15
|
*PR:* <{pr_url}|#{pr_number}>
|
|
16
16
|
*Branch:* `{release_branch}` → `{production_branch}`
|
|
17
|
+
:lock: `{release_branch}` is locked — no merges until release completes
|
|
17
18
|
|
|
18
19
|
{pr_summary}
|
|
19
20
|
|
|
20
21
|
Posted with :droid:
|
|
21
22
|
```
|
|
22
23
|
|
|
24
|
+
If `--no-lock` was used, omit the lock line.
|
|
25
|
+
|
|
23
26
|
Risk emojis:
|
|
24
27
|
- Low Risk: `:large_green_circle:`
|
|
25
28
|
- High Risk: `:warning:`
|
|
@@ -37,6 +40,26 @@ Monitoring deployment :eyes:
|
|
|
37
40
|
Posted with :droid:
|
|
38
41
|
```
|
|
39
42
|
|
|
43
|
+
### Branch Locked
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
:lock: *Branch locked — {repo_name}*
|
|
47
|
+
|
|
48
|
+
`{branch}` is now read-only. No merges until unlocked.
|
|
49
|
+
|
|
50
|
+
Posted with :droid:
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Branch Unlocked
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
:unlock: *Branch unlocked — {repo_name}*
|
|
57
|
+
|
|
58
|
+
`{branch}` is open for merges.
|
|
59
|
+
|
|
60
|
+
Posted with :droid:
|
|
61
|
+
```
|
|
62
|
+
|
|
40
63
|
### Release Complete
|
|
41
64
|
|
|
42
65
|
```
|
|
@@ -48,6 +71,11 @@ Posted with :droid:
|
|
|
48
71
|
Posted with :droid:
|
|
49
72
|
```
|
|
50
73
|
|
|
74
|
+
If auto-unlocked, append:
|
|
75
|
+
```
|
|
76
|
+
:unlock: Auto-unlocked `{release_branch}`
|
|
77
|
+
```
|
|
78
|
+
|
|
51
79
|
---
|
|
52
80
|
|
|
53
81
|
## Release PR Body
|
|
@@ -81,14 +109,17 @@ Where `{pr_list}` is a bulleted list of merged PRs:
|
|
|
81
109
|
|
|
82
110
|
When Slack is not configured, print a plain-text version to terminal:
|
|
83
111
|
|
|
84
|
-
### Release
|
|
112
|
+
### Release Open for Review (terminal)
|
|
85
113
|
```
|
|
86
|
-
Release
|
|
114
|
+
Release open for review — {repo_name}
|
|
87
115
|
Risk: {risk_level}
|
|
88
116
|
PR: {pr_url}
|
|
89
117
|
Branch: {release_branch} -> {production_branch}
|
|
118
|
+
Lock: {release_branch} locked (no merges until release completes)
|
|
90
119
|
```
|
|
91
120
|
|
|
121
|
+
If `--no-lock` was used, omit the Lock line.
|
|
122
|
+
|
|
92
123
|
### Release Merged (terminal)
|
|
93
124
|
```
|
|
94
125
|
Release merged — {repo_name}
|
|
@@ -97,6 +128,18 @@ Release merged — {repo_name}
|
|
|
97
128
|
Monitoring deployment...
|
|
98
129
|
```
|
|
99
130
|
|
|
131
|
+
### Branch Locked (terminal)
|
|
132
|
+
```
|
|
133
|
+
Branch locked — {repo_name}
|
|
134
|
+
{branch} is now read-only
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Branch Unlocked (terminal)
|
|
138
|
+
```
|
|
139
|
+
Branch unlocked — {repo_name}
|
|
140
|
+
{branch} is open for merges
|
|
141
|
+
```
|
|
142
|
+
|
|
100
143
|
### Release Complete (terminal)
|
|
101
144
|
```
|
|
102
145
|
Release complete — {repo_name}
|
|
@@ -7,8 +7,8 @@ Detailed step-by-step procedures for each `/release` subcommand. All commands us
|
|
|
7
7
|
```bash
|
|
8
8
|
# 1. Read config
|
|
9
9
|
SLACK_CHANNEL=$(droid config --get tools.release.slack_channel)
|
|
10
|
-
# Default to #
|
|
11
|
-
SLACK_CHANNEL="${SLACK_CHANNEL:-#
|
|
10
|
+
# Default to #release_management if not set
|
|
11
|
+
SLACK_CHANNEL="${SLACK_CHANNEL:-#release_management}"
|
|
12
12
|
|
|
13
13
|
# 2. Get repos and filter for release repos (those with release_branch set)
|
|
14
14
|
droid config --get repos
|
|
@@ -25,9 +25,11 @@ git -C {repo_path} remote get-url origin
|
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
|
-
## `/release start [repo]`
|
|
28
|
+
## `/release start [repo] [--no-lock]`
|
|
29
29
|
|
|
30
|
-
Create a release PR and notify Slack.
|
|
30
|
+
Create a release PR, auto-lock the release branch, and notify Slack.
|
|
31
|
+
|
|
32
|
+
**Auto-lock is on by default.** The branch is locked immediately after the PR is created to prevent blind merges during CI. Pass `--no-lock` (or natural language like "start without locking") to skip.
|
|
31
33
|
|
|
32
34
|
### Steps
|
|
33
35
|
|
|
@@ -64,7 +66,22 @@ Create a release PR and notify Slack.
|
|
|
64
66
|
```
|
|
65
67
|
See `templates.md` for the PR body template.
|
|
66
68
|
|
|
67
|
-
6. **
|
|
69
|
+
6. **Auto-lock branch** (unless `--no-lock`):
|
|
70
|
+
```bash
|
|
71
|
+
gh workflow run branch-lock.yml \
|
|
72
|
+
-f action=lock \
|
|
73
|
+
-f branch={release_branch} \
|
|
74
|
+
--repo {owner}/{repo}
|
|
75
|
+
```
|
|
76
|
+
Verify lock applied:
|
|
77
|
+
```bash
|
|
78
|
+
sleep 5
|
|
79
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
80
|
+
```
|
|
81
|
+
If `branch-lock.yml` is not found in the repo, warn but don't fail:
|
|
82
|
+
"Could not auto-lock — `branch-lock.yml` not found in `{repo_name}`. Use `/release lock` manually after adding the workflow."
|
|
83
|
+
|
|
84
|
+
7. **Post to Slack:**
|
|
68
85
|
```bash
|
|
69
86
|
node -e 'process.stdout.write(JSON.stringify({
|
|
70
87
|
channel: "{slack_channel}",
|
|
@@ -72,9 +89,9 @@ Create a release PR and notify Slack.
|
|
|
72
89
|
unfurl_links: false
|
|
73
90
|
}))' | droid integrations slack post
|
|
74
91
|
```
|
|
75
|
-
See `templates.md` for the Slack message template (release
|
|
92
|
+
See `templates.md` for the Slack message template (release open for review — includes lock status).
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
8. **Confirm to user** — show PR URL, lock status, and Slack post confirmation.
|
|
78
95
|
|
|
79
96
|
---
|
|
80
97
|
|
|
@@ -112,6 +129,81 @@ Merge the release PR if all checks are green, then notify Slack.
|
|
|
112
129
|
|
|
113
130
|
---
|
|
114
131
|
|
|
132
|
+
## `/release lock [repo]`
|
|
133
|
+
|
|
134
|
+
Manually lock the release branch. Use when you need to lock outside of `/release start` (which auto-locks).
|
|
135
|
+
|
|
136
|
+
### Steps
|
|
137
|
+
|
|
138
|
+
1. **Detect repo** — match cwd or ask user
|
|
139
|
+
|
|
140
|
+
2. **Check current lock state:**
|
|
141
|
+
```bash
|
|
142
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
143
|
+
```
|
|
144
|
+
If already locked, warn: "Branch `{release_branch}` is already locked. Unlock first?"
|
|
145
|
+
|
|
146
|
+
3. **Confirm with user** — use AskUserQuestion:
|
|
147
|
+
"Lock `{release_branch}` on `{repo_name}`? No one will be able to merge until unlocked."
|
|
148
|
+
|
|
149
|
+
4. **Trigger the lock Action:**
|
|
150
|
+
```bash
|
|
151
|
+
gh workflow run branch-lock.yml \
|
|
152
|
+
-f action=lock \
|
|
153
|
+
-f branch={release_branch} \
|
|
154
|
+
--repo {owner}/{repo}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
5. **Verify lock applied** (wait a few seconds, then check):
|
|
158
|
+
```bash
|
|
159
|
+
sleep 5
|
|
160
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
161
|
+
```
|
|
162
|
+
If still not locked, check the workflow run status:
|
|
163
|
+
```bash
|
|
164
|
+
gh run list --workflow=branch-lock.yml --limit 1 --json status,conclusion --repo {owner}/{repo}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
6. **Post to Slack** — lock notification (see `templates.md`).
|
|
168
|
+
|
|
169
|
+
7. **Confirm to user** — "Locked `{release_branch}` on `{repo_name}`."
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## `/release unlock [repo]`
|
|
174
|
+
|
|
175
|
+
Unlock the release branch.
|
|
176
|
+
|
|
177
|
+
### Steps
|
|
178
|
+
|
|
179
|
+
1. **Detect repo** — match cwd or ask user
|
|
180
|
+
|
|
181
|
+
2. **Check current lock state:**
|
|
182
|
+
```bash
|
|
183
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
184
|
+
```
|
|
185
|
+
If not locked, inform: "Branch `{release_branch}` is not currently locked."
|
|
186
|
+
|
|
187
|
+
3. **Trigger the unlock Action:**
|
|
188
|
+
```bash
|
|
189
|
+
gh workflow run branch-lock.yml \
|
|
190
|
+
-f action=unlock \
|
|
191
|
+
-f branch={release_branch} \
|
|
192
|
+
--repo {owner}/{repo}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
4. **Verify unlock applied:**
|
|
196
|
+
```bash
|
|
197
|
+
sleep 5
|
|
198
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled'
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
5. **Post to Slack** — unlock notification (see `templates.md`).
|
|
202
|
+
|
|
203
|
+
6. **Confirm to user** — "Unlocked `{release_branch}` on `{repo_name}`."
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
115
207
|
## `/release status`
|
|
116
208
|
|
|
117
209
|
Check release status across all configured release repos.
|
|
@@ -127,11 +219,17 @@ Check release status across all configured release repos.
|
|
|
127
219
|
gh pr list --search "[RELEASE]" --state open --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
128
220
|
```
|
|
129
221
|
|
|
222
|
+
**Lock state:**
|
|
223
|
+
```bash
|
|
224
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
225
|
+
```
|
|
226
|
+
|
|
130
227
|
3. **Format and display** as a summary:
|
|
131
228
|
|
|
132
229
|
```
|
|
133
230
|
{repo_name}
|
|
134
231
|
Release PR: #{number} — {CI status} (green/pending/failing)
|
|
232
|
+
Branch lock: {release_branch} — locked/unlocked
|
|
135
233
|
```
|
|
136
234
|
|
|
137
235
|
If no open release PR: "No active release"
|
|
@@ -141,7 +239,7 @@ Check release status across all configured release repos.
|
|
|
141
239
|
|
|
142
240
|
## `/release complete [repo]`
|
|
143
241
|
|
|
144
|
-
Close out a release — notify Slack.
|
|
242
|
+
Close out a release — notify Slack and auto-unlock.
|
|
145
243
|
|
|
146
244
|
### Steps
|
|
147
245
|
|
|
@@ -161,6 +259,20 @@ Close out a release — notify Slack.
|
|
|
161
259
|
|
|
162
260
|
3. **Post to Slack** — release complete notification (see `templates.md`).
|
|
163
261
|
|
|
164
|
-
4. **
|
|
262
|
+
4. **Auto-unlock if locked:**
|
|
263
|
+
```bash
|
|
264
|
+
LOCKED=$(gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false')
|
|
265
|
+
```
|
|
266
|
+
If locked, trigger unlock:
|
|
267
|
+
```bash
|
|
268
|
+
gh workflow run branch-lock.yml \
|
|
269
|
+
-f action=unlock \
|
|
270
|
+
-f branch={release_branch} \
|
|
271
|
+
--repo {owner}/{repo}
|
|
272
|
+
```
|
|
273
|
+
Post unlock notification to Slack as well.
|
|
274
|
+
|
|
275
|
+
5. **Confirm to user:**
|
|
165
276
|
- "Release complete for `{repo_name}`"
|
|
277
|
+
- "Auto-unlocked `{release_branch}`" (if was locked)
|
|
166
278
|
- Show Slack message confirmation
|