@orderful/droid 0.43.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 +12 -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 +16 -9
- package/dist/tools/release/skills/release/references/templates.md +68 -4
- package/dist/tools/release/skills/release/references/workflows.md +161 -12
- 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 +16 -9
- package/src/tools/release/skills/release/references/templates.md +68 -4
- package/src/tools/release/skills/release/references/workflows.md +161 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
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
|
+
|
|
9
|
+
## 0.44.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#259](https://github.com/Orderful/droid/pull/259) [`f64bab2`](https://github.com/Orderful/droid/commit/f64bab250e25bb57ad9c1c2ac50246455a18eb42) Thanks [@frytyler](https://github.com/frytyler)! - Add /release merge command to merge release PRs when all checks pass and notify Slack. Fix release notes generation to compare branches instead of listing all historically merged PRs.
|
|
14
|
+
|
|
3
15
|
## 0.43.0
|
|
4
16
|
|
|
5
17
|
### 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, checking release status, or completing a release. User prompts like 'start a release', 'release
|
|
4
|
-
argument-hint: "[start [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,9 +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 |
|
|
51
|
-
| `/release
|
|
52
|
-
| `/release
|
|
52
|
+
| `/release start [repo] [--no-lock]` | Create release PR + auto-lock branch + notify Slack |
|
|
53
|
+
| `/release merge [repo]` | Merge release PR (only if checks pass) + notify Slack |
|
|
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 |
|
|
53
58
|
|
|
54
59
|
See `references/workflows.md` for detailed step-by-step procedures and exact `gh` commands.
|
|
55
60
|
|
|
@@ -68,6 +73,8 @@ See `references/templates.md` for Slack message and PR body templates.
|
|
|
68
73
|
|-------|--------|
|
|
69
74
|
| No release repos configured | Suggest `droid repos add` with release branch |
|
|
70
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 |
|
|
71
77
|
| Slack not configured | Print message to terminal, suggest `droid integrations setup slack` |
|
|
78
|
+
| Branch already locked | Warn user, offer to unlock first |
|
|
72
79
|
| Release PR already exists | Show existing PR, ask if user wants to proceed |
|
|
73
80
|
| CI checks failing | Show status, do not auto-merge |
|
|
@@ -6,24 +6,60 @@ 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:`
|
|
26
29
|
|
|
30
|
+
### Release Merged
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
:merged-pr: *Release merged — {repo_name}*
|
|
34
|
+
|
|
35
|
+
*PR:* <{pr_url}|#{pr_number}>
|
|
36
|
+
*Branch:* `{release_branch}` → `{production_branch}`
|
|
37
|
+
|
|
38
|
+
Monitoring deployment :eyes:
|
|
39
|
+
|
|
40
|
+
Posted with :droid:
|
|
41
|
+
```
|
|
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
|
+
|
|
27
63
|
### Release Complete
|
|
28
64
|
|
|
29
65
|
```
|
|
@@ -35,6 +71,11 @@ Risk emojis:
|
|
|
35
71
|
Posted with :droid:
|
|
36
72
|
```
|
|
37
73
|
|
|
74
|
+
If auto-unlocked, append:
|
|
75
|
+
```
|
|
76
|
+
:unlock: Auto-unlocked `{release_branch}`
|
|
77
|
+
```
|
|
78
|
+
|
|
38
79
|
---
|
|
39
80
|
|
|
40
81
|
## Release PR Body
|
|
@@ -68,12 +109,35 @@ Where `{pr_list}` is a bulleted list of merged PRs:
|
|
|
68
109
|
|
|
69
110
|
When Slack is not configured, print a plain-text version to terminal:
|
|
70
111
|
|
|
71
|
-
### Release
|
|
112
|
+
### Release Open for Review (terminal)
|
|
72
113
|
```
|
|
73
|
-
Release
|
|
114
|
+
Release open for review — {repo_name}
|
|
74
115
|
Risk: {risk_level}
|
|
75
116
|
PR: {pr_url}
|
|
76
117
|
Branch: {release_branch} -> {production_branch}
|
|
118
|
+
Lock: {release_branch} locked (no merges until release completes)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If `--no-lock` was used, omit the Lock line.
|
|
122
|
+
|
|
123
|
+
### Release Merged (terminal)
|
|
124
|
+
```
|
|
125
|
+
Release merged — {repo_name}
|
|
126
|
+
PR: {pr_url}
|
|
127
|
+
Branch: {release_branch} -> {production_branch}
|
|
128
|
+
Monitoring deployment...
|
|
129
|
+
```
|
|
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
|
|
77
141
|
```
|
|
78
142
|
|
|
79
143
|
### Release Complete (terminal)
|
|
@@ -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
|
|
|
@@ -39,11 +41,14 @@ Create a release PR and notify Slack.
|
|
|
39
41
|
```
|
|
40
42
|
If one exists, show it and ask: "A release PR already exists. Open it instead?"
|
|
41
43
|
|
|
42
|
-
3. **Generate release notes** —
|
|
44
|
+
3. **Generate release notes** — compare branches to find PRs included in this release:
|
|
43
45
|
```bash
|
|
44
|
-
|
|
46
|
+
# Get commits in release_branch that aren't in production_branch
|
|
47
|
+
gh api repos/{owner}/{repo}/compare/{production_branch}...{release_branch} --jq '.commits[].commit.message'
|
|
45
48
|
```
|
|
46
|
-
|
|
49
|
+
Extract PR numbers from commit messages (e.g. `(#1234)`) and format as a bulleted list for the PR body.
|
|
50
|
+
|
|
51
|
+
**Do NOT use** `gh pr list --base {release_branch} --state merged` — that returns ALL historically merged PRs, not just the ones since the last release.
|
|
47
52
|
|
|
48
53
|
4. **Ask risk level** — use AskUserQuestion:
|
|
49
54
|
- Low Risk (routine release, no breaking changes)
|
|
@@ -61,7 +66,22 @@ Create a release PR and notify Slack.
|
|
|
61
66
|
```
|
|
62
67
|
See `templates.md` for the PR body template.
|
|
63
68
|
|
|
64
|
-
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:**
|
|
65
85
|
```bash
|
|
66
86
|
node -e 'process.stdout.write(JSON.stringify({
|
|
67
87
|
channel: "{slack_channel}",
|
|
@@ -69,9 +89,118 @@ Create a release PR and notify Slack.
|
|
|
69
89
|
unfurl_links: false
|
|
70
90
|
}))' | droid integrations slack post
|
|
71
91
|
```
|
|
72
|
-
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).
|
|
93
|
+
|
|
94
|
+
8. **Confirm to user** — show PR URL, lock status, and Slack post confirmation.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## `/release merge [repo]`
|
|
99
|
+
|
|
100
|
+
Merge the release PR if all checks are green, then notify Slack.
|
|
101
|
+
|
|
102
|
+
### Steps
|
|
103
|
+
|
|
104
|
+
1. **Detect repo** — match cwd or ask user
|
|
105
|
+
|
|
106
|
+
2. **Find the open release PR:**
|
|
107
|
+
```bash
|
|
108
|
+
gh pr list --search "[RELEASE]" --state open --base {production_branch} --head {release_branch} --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
109
|
+
```
|
|
110
|
+
If no open release PR found, error: "No open release PR found. Run `/release start` first."
|
|
73
111
|
|
|
74
|
-
|
|
112
|
+
3. **Check all status checks:**
|
|
113
|
+
Parse `statusCheckRollup` from the PR data. Every check must have `conclusion: "SUCCESS"` or `state: "SUCCESS"`.
|
|
114
|
+
|
|
115
|
+
If any checks are pending: "CI checks are still running on PR #{number}. Wait for them to finish."
|
|
116
|
+
If any checks are failing: "CI checks are failing on PR #{number}. Fix them before merging." Show the failing checks.
|
|
117
|
+
|
|
118
|
+
4. **Confirm with user** — use AskUserQuestion:
|
|
119
|
+
"All checks are green on PR #{number}. Merge `{release_branch}` → `{production_branch}`?"
|
|
120
|
+
|
|
121
|
+
5. **Merge the PR:**
|
|
122
|
+
```bash
|
|
123
|
+
gh pr merge {pr_number} --merge --repo {owner}/{repo}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
6. **Post to Slack** — release merged notification (see `templates.md`).
|
|
127
|
+
|
|
128
|
+
7. **Confirm to user** — show merge confirmation and Slack post confirmation.
|
|
129
|
+
|
|
130
|
+
---
|
|
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}`."
|
|
75
204
|
|
|
76
205
|
---
|
|
77
206
|
|
|
@@ -90,11 +219,17 @@ Check release status across all configured release repos.
|
|
|
90
219
|
gh pr list --search "[RELEASE]" --state open --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
91
220
|
```
|
|
92
221
|
|
|
222
|
+
**Lock state:**
|
|
223
|
+
```bash
|
|
224
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
225
|
+
```
|
|
226
|
+
|
|
93
227
|
3. **Format and display** as a summary:
|
|
94
228
|
|
|
95
229
|
```
|
|
96
230
|
{repo_name}
|
|
97
231
|
Release PR: #{number} — {CI status} (green/pending/failing)
|
|
232
|
+
Branch lock: {release_branch} — locked/unlocked
|
|
98
233
|
```
|
|
99
234
|
|
|
100
235
|
If no open release PR: "No active release"
|
|
@@ -104,7 +239,7 @@ Check release status across all configured release repos.
|
|
|
104
239
|
|
|
105
240
|
## `/release complete [repo]`
|
|
106
241
|
|
|
107
|
-
Close out a release — notify Slack.
|
|
242
|
+
Close out a release — notify Slack and auto-unlock.
|
|
108
243
|
|
|
109
244
|
### Steps
|
|
110
245
|
|
|
@@ -124,6 +259,20 @@ Close out a release — notify Slack.
|
|
|
124
259
|
|
|
125
260
|
3. **Post to Slack** — release complete notification (see `templates.md`).
|
|
126
261
|
|
|
127
|
-
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:**
|
|
128
276
|
- "Release complete for `{repo_name}`"
|
|
277
|
+
- "Auto-unlocked `{release_branch}`" (if was locked)
|
|
129
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, checking release status, or completing a release. User prompts like 'start a release', 'release
|
|
4
|
-
argument-hint: "[start [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,9 +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 |
|
|
51
|
-
| `/release
|
|
52
|
-
| `/release
|
|
52
|
+
| `/release start [repo] [--no-lock]` | Create release PR + auto-lock branch + notify Slack |
|
|
53
|
+
| `/release merge [repo]` | Merge release PR (only if checks pass) + notify Slack |
|
|
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 |
|
|
53
58
|
|
|
54
59
|
See `references/workflows.md` for detailed step-by-step procedures and exact `gh` commands.
|
|
55
60
|
|
|
@@ -68,6 +73,8 @@ See `references/templates.md` for Slack message and PR body templates.
|
|
|
68
73
|
|-------|--------|
|
|
69
74
|
| No release repos configured | Suggest `droid repos add` with release branch |
|
|
70
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 |
|
|
71
77
|
| Slack not configured | Print message to terminal, suggest `droid integrations setup slack` |
|
|
78
|
+
| Branch already locked | Warn user, offer to unlock first |
|
|
72
79
|
| Release PR already exists | Show existing PR, ask if user wants to proceed |
|
|
73
80
|
| CI checks failing | Show status, do not auto-merge |
|
|
@@ -6,24 +6,60 @@ 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:`
|
|
26
29
|
|
|
30
|
+
### Release Merged
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
:merged-pr: *Release merged — {repo_name}*
|
|
34
|
+
|
|
35
|
+
*PR:* <{pr_url}|#{pr_number}>
|
|
36
|
+
*Branch:* `{release_branch}` → `{production_branch}`
|
|
37
|
+
|
|
38
|
+
Monitoring deployment :eyes:
|
|
39
|
+
|
|
40
|
+
Posted with :droid:
|
|
41
|
+
```
|
|
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
|
+
|
|
27
63
|
### Release Complete
|
|
28
64
|
|
|
29
65
|
```
|
|
@@ -35,6 +71,11 @@ Risk emojis:
|
|
|
35
71
|
Posted with :droid:
|
|
36
72
|
```
|
|
37
73
|
|
|
74
|
+
If auto-unlocked, append:
|
|
75
|
+
```
|
|
76
|
+
:unlock: Auto-unlocked `{release_branch}`
|
|
77
|
+
```
|
|
78
|
+
|
|
38
79
|
---
|
|
39
80
|
|
|
40
81
|
## Release PR Body
|
|
@@ -68,12 +109,35 @@ Where `{pr_list}` is a bulleted list of merged PRs:
|
|
|
68
109
|
|
|
69
110
|
When Slack is not configured, print a plain-text version to terminal:
|
|
70
111
|
|
|
71
|
-
### Release
|
|
112
|
+
### Release Open for Review (terminal)
|
|
72
113
|
```
|
|
73
|
-
Release
|
|
114
|
+
Release open for review — {repo_name}
|
|
74
115
|
Risk: {risk_level}
|
|
75
116
|
PR: {pr_url}
|
|
76
117
|
Branch: {release_branch} -> {production_branch}
|
|
118
|
+
Lock: {release_branch} locked (no merges until release completes)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If `--no-lock` was used, omit the Lock line.
|
|
122
|
+
|
|
123
|
+
### Release Merged (terminal)
|
|
124
|
+
```
|
|
125
|
+
Release merged — {repo_name}
|
|
126
|
+
PR: {pr_url}
|
|
127
|
+
Branch: {release_branch} -> {production_branch}
|
|
128
|
+
Monitoring deployment...
|
|
129
|
+
```
|
|
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
|
|
77
141
|
```
|
|
78
142
|
|
|
79
143
|
### Release Complete (terminal)
|
|
@@ -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
|
|
|
@@ -39,11 +41,14 @@ Create a release PR and notify Slack.
|
|
|
39
41
|
```
|
|
40
42
|
If one exists, show it and ask: "A release PR already exists. Open it instead?"
|
|
41
43
|
|
|
42
|
-
3. **Generate release notes** —
|
|
44
|
+
3. **Generate release notes** — compare branches to find PRs included in this release:
|
|
43
45
|
```bash
|
|
44
|
-
|
|
46
|
+
# Get commits in release_branch that aren't in production_branch
|
|
47
|
+
gh api repos/{owner}/{repo}/compare/{production_branch}...{release_branch} --jq '.commits[].commit.message'
|
|
45
48
|
```
|
|
46
|
-
|
|
49
|
+
Extract PR numbers from commit messages (e.g. `(#1234)`) and format as a bulleted list for the PR body.
|
|
50
|
+
|
|
51
|
+
**Do NOT use** `gh pr list --base {release_branch} --state merged` — that returns ALL historically merged PRs, not just the ones since the last release.
|
|
47
52
|
|
|
48
53
|
4. **Ask risk level** — use AskUserQuestion:
|
|
49
54
|
- Low Risk (routine release, no breaking changes)
|
|
@@ -61,7 +66,22 @@ Create a release PR and notify Slack.
|
|
|
61
66
|
```
|
|
62
67
|
See `templates.md` for the PR body template.
|
|
63
68
|
|
|
64
|
-
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:**
|
|
65
85
|
```bash
|
|
66
86
|
node -e 'process.stdout.write(JSON.stringify({
|
|
67
87
|
channel: "{slack_channel}",
|
|
@@ -69,9 +89,118 @@ Create a release PR and notify Slack.
|
|
|
69
89
|
unfurl_links: false
|
|
70
90
|
}))' | droid integrations slack post
|
|
71
91
|
```
|
|
72
|
-
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).
|
|
93
|
+
|
|
94
|
+
8. **Confirm to user** — show PR URL, lock status, and Slack post confirmation.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## `/release merge [repo]`
|
|
99
|
+
|
|
100
|
+
Merge the release PR if all checks are green, then notify Slack.
|
|
101
|
+
|
|
102
|
+
### Steps
|
|
103
|
+
|
|
104
|
+
1. **Detect repo** — match cwd or ask user
|
|
105
|
+
|
|
106
|
+
2. **Find the open release PR:**
|
|
107
|
+
```bash
|
|
108
|
+
gh pr list --search "[RELEASE]" --state open --base {production_branch} --head {release_branch} --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
109
|
+
```
|
|
110
|
+
If no open release PR found, error: "No open release PR found. Run `/release start` first."
|
|
73
111
|
|
|
74
|
-
|
|
112
|
+
3. **Check all status checks:**
|
|
113
|
+
Parse `statusCheckRollup` from the PR data. Every check must have `conclusion: "SUCCESS"` or `state: "SUCCESS"`.
|
|
114
|
+
|
|
115
|
+
If any checks are pending: "CI checks are still running on PR #{number}. Wait for them to finish."
|
|
116
|
+
If any checks are failing: "CI checks are failing on PR #{number}. Fix them before merging." Show the failing checks.
|
|
117
|
+
|
|
118
|
+
4. **Confirm with user** — use AskUserQuestion:
|
|
119
|
+
"All checks are green on PR #{number}. Merge `{release_branch}` → `{production_branch}`?"
|
|
120
|
+
|
|
121
|
+
5. **Merge the PR:**
|
|
122
|
+
```bash
|
|
123
|
+
gh pr merge {pr_number} --merge --repo {owner}/{repo}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
6. **Post to Slack** — release merged notification (see `templates.md`).
|
|
127
|
+
|
|
128
|
+
7. **Confirm to user** — show merge confirmation and Slack post confirmation.
|
|
129
|
+
|
|
130
|
+
---
|
|
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}`."
|
|
75
204
|
|
|
76
205
|
---
|
|
77
206
|
|
|
@@ -90,11 +219,17 @@ Check release status across all configured release repos.
|
|
|
90
219
|
gh pr list --search "[RELEASE]" --state open --json number,title,url,statusCheckRollup --repo {owner}/{repo}
|
|
91
220
|
```
|
|
92
221
|
|
|
222
|
+
**Lock state:**
|
|
223
|
+
```bash
|
|
224
|
+
gh api repos/{owner}/{repo}/branches/{release_branch}/protection --jq '.lock_branch.enabled // false'
|
|
225
|
+
```
|
|
226
|
+
|
|
93
227
|
3. **Format and display** as a summary:
|
|
94
228
|
|
|
95
229
|
```
|
|
96
230
|
{repo_name}
|
|
97
231
|
Release PR: #{number} — {CI status} (green/pending/failing)
|
|
232
|
+
Branch lock: {release_branch} — locked/unlocked
|
|
98
233
|
```
|
|
99
234
|
|
|
100
235
|
If no open release PR: "No active release"
|
|
@@ -104,7 +239,7 @@ Check release status across all configured release repos.
|
|
|
104
239
|
|
|
105
240
|
## `/release complete [repo]`
|
|
106
241
|
|
|
107
|
-
Close out a release — notify Slack.
|
|
242
|
+
Close out a release — notify Slack and auto-unlock.
|
|
108
243
|
|
|
109
244
|
### Steps
|
|
110
245
|
|
|
@@ -124,6 +259,20 @@ Close out a release — notify Slack.
|
|
|
124
259
|
|
|
125
260
|
3. **Post to Slack** — release complete notification (see `templates.md`).
|
|
126
261
|
|
|
127
|
-
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:**
|
|
128
276
|
- "Release complete for `{repo_name}`"
|
|
277
|
+
- "Auto-unlocked `{release_branch}`" (if was locked)
|
|
129
278
|
- Show Slack message confirmation
|