-
Notifications
You must be signed in to change notification settings - Fork 0
207 lines (193 loc) · 7.89 KB
/
release-github.yml
File metadata and controls
207 lines (193 loc) · 7.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# Workflow assumes:
# - Repository variables and secrets:
# - vars.CHUMPCHIEF_RELEASE_BOT_APP_ID
# - secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY
# - Note: would prefer to put these in an environment requiring approval, but this then requires
# each individual job to be approved which is too annoying. See:
# https://github.com/orgs/community/discussions/14417#discussioncomment-2904984
# - Automatic head branch deletion (Github repository setting)
name: Create Github Release
run-name: Release from ${{ github.ref_name }}${{ inputs.dryRun && ' (dry run)' || '' }}
permissions:
contents: write
pull-requests: write
on:
# Only runs on demand
workflow_dispatch:
inputs:
dryRun:
description: "Dry run (only create bump branch and draft PR)"
required: true
type: boolean
default: true
jobs:
lock_branch:
name: Lock the branch
runs-on: ubuntu-latest
if: ${{ !inputs.dryRun }}
outputs:
lockRulesetId: ${{ steps.lock_branch.outputs.result }}
steps:
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
- name: Lock branch
id: lock_branch
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
result-encoding: string
# Pass rule id through as an output so it can be deleted at the end
script: |
const branchName = context.ref.replace("refs/heads/", "");
console.log(`Locking branch ${ branchName }...`);
const { data: lockRuleset } = await github.rest.repos.createRepoRuleset({ repo: context.repo.repo, owner: context.repo.owner, name: `Lock ${ branchName } for bump`, enforcement: "active", bypass_actors: [ { actor_id: 5, actor_type: "RepositoryRole", bypass_mode: "pull_request" } ], conditions: { ref_name: { include: [ context.ref ], exclude: [] } }, rules: [ { type: "update" } ] });
console.log(`Locked the branch. Ruleset ID: ${ lockRuleset.id }`);
return lockRuleset.id;
create_bump_branch:
name: Create bump branch
runs-on: ubuntu-latest
if: ${{ success() || inputs.dryRun }}
needs: [lock_branch]
outputs:
bumpBranchInfo: ${{ steps.create_bump_branch.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Node setup
uses: actions/setup-node@v4
with:
node-version: 22
- name: pnpm setup
uses: pnpm/action-setup@v3
with:
version: 10
- name: Install dependencies
run: |
pnpm i
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
- name: Create bump branch
id: create_bump_branch
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
script: |
const script = require(".github/workflows/scripts/createBumpBranch.cjs");
return script({ github, context, core, exec }, ${{ inputs.dryRun }});
create_bump_pr:
name: Create bump PR
runs-on: ubuntu-latest
if: ${{ success() || inputs.dryRun }}
needs: [create_bump_branch]
outputs:
bumpPrInfo: ${{ steps.create_bump_pr.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
# TODO: Use fewer external scripts to avoid requiring checkout?
- name: Create bump PR
id: create_bump_pr
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
script: |
const script = require(".github/workflows/scripts/createBumpPR.cjs");
return script({ github, context, core, exec }, ${{ needs.create_bump_branch.outputs.bumpBranchInfo }}, ${{ inputs.dryRun }});
wait_for_pr_merge:
name: Wait for PR merge
runs-on: ubuntu-latest
needs: [create_bump_pr]
outputs:
mergeInfo: ${{ steps.wait_for_pr_merge.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v4
# TODO: Also wait for CI of the merged PR to finish successfully?
- name: Wait for PR merge
id: wait_for_pr_merge
uses: actions/github-script@v7
with:
script: |
const script = require(".github/workflows/scripts/waitForPRMerge.cjs");
return script({ github, context, core, exec }, ${{ needs.create_bump_pr.outputs.bumpPrInfo }});
# TODO: Ensure this runs even if earlier steps fail?
unlock_branch:
name: Unlock the branch
runs-on: ubuntu-latest
needs: [lock_branch, wait_for_pr_merge]
steps:
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
- name: Unlock branch
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
script: |
console.log("Unlocking the branch...");
console.log("Deleting ruleset ${{ needs.lock_branch.outputs.lockRulesetId }}...");
await github.rest.repos.deleteRepoRuleset({ repo: context.repo.repo, owner: context.repo.owner, ruleset_id: ${{ needs.lock_branch.outputs.lockRulesetId }} });
create_tag:
name: Create a tag
runs-on: ubuntu-latest
needs: [create_bump_branch, wait_for_pr_merge]
outputs:
tagInfo: ${{ steps.create_tag.outputs.result }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.wait_for_pr_merge.outputs.mergeInfo.mergeCommitSha }}
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
- name: Create tag
id: create_tag
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
script: |
const script = require(".github/workflows/scripts/createTag.cjs");
return script({ github, context, core, exec }, ${{ needs.create_bump_branch.outputs.bumpBranchInfo }}, ${{ needs.wait_for_pr_merge.outputs.mergeInfo }});
create_release:
name: Create a Github Release
runs-on: ubuntu-latest
needs: [create_bump_branch, create_tag]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.create_tag.outputs.tagInfo.tagName }}
- name: Generate app token
id: generate_app_token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.CHUMPCHIEF_RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.CHUMPCHIEF_RELEASE_BOT_APP_PRIVATE_KEY }}
- name: Create release
uses: actions/github-script@v7
with:
github-token: ${{ steps.generate_app_token.outputs.token }}
script: |
const script = require(".github/workflows/scripts/createRelease.cjs");
return script({ github, context, core, exec }, ${{ needs.create_bump_branch.outputs.bumpBranchInfo }}, ${{ needs.create_tag.outputs.tagInfo }});