Skip to content

Commit db87cd5

Browse files
committed
Replace release docs with release script
Instead of manually following a text-based release process, automate the release process with a script. In reality, the script just prints the existing documentation then prompts the user to continue to the next step. In the future, we can extend the script to fully automate some steps. Inspired by Dan Slimmon's do-nothing scripting idea: https://blog.danslimmon.com/2019/07/15/do-nothing-scripting-the-key-to-gradual-automation/
1 parent 2037481 commit db87cd5

File tree

2 files changed

+253
-65
lines changed

2 files changed

+253
-65
lines changed

dist/release.go

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// Copyright (C) 2020 Matthew "strager" Glazar
2+
// See end of file for extended copyright information.
3+
4+
package main
5+
6+
import "bufio"
7+
import "flag"
8+
import "fmt"
9+
import "log"
10+
import "os"
11+
12+
type Step struct {
13+
Title string
14+
Run func()
15+
}
16+
17+
var Steps []Step = []Step{
18+
Step{
19+
Title: "Update release notes file",
20+
Run: func() {
21+
fmt.Printf("Update the release notes file: docs/CHANGELOG.md\n")
22+
WaitForDone()
23+
},
24+
},
25+
26+
Step{
27+
Title: "Update version number and release date",
28+
Run: func() {
29+
fmt.Printf("Change these files containing version numbers:\n")
30+
fmt.Printf("* Formula/quick-lint-js.rb\n")
31+
fmt.Printf("* dist/arch/PKGBUILD-dev\n")
32+
fmt.Printf("* dist/arch/PKGBUILD-git\n")
33+
fmt.Printf("* dist/arch/PKGBUILD-release\n")
34+
fmt.Printf("* dist/debian/README.md\n")
35+
fmt.Printf("* dist/debian/debian/changelog\n")
36+
fmt.Printf("* dist/npm/BUILDING.md\n")
37+
fmt.Printf("* dist/npm/package.json\n")
38+
fmt.Printf("* dist/sign-release.go\n")
39+
fmt.Printf("* plugin/vim/quick-lint-js.vim/doc/quick-lint-js.txt\n")
40+
fmt.Printf("* plugin/vscode-lsp/README.md\n")
41+
fmt.Printf("* plugin/vscode-lsp/package.json\n")
42+
fmt.Printf("* plugin/vscode/BUILDING.md\n")
43+
fmt.Printf("* plugin/vscode/package.json\n")
44+
fmt.Printf("* version\n")
45+
WaitForDone()
46+
},
47+
},
48+
49+
Step{
50+
Title: "Re-generate man pages",
51+
Run: func() {
52+
fmt.Printf("Re-generate man pages to include the updated version number by running:\n")
53+
fmt.Printf("$ ./docs/man/generate-man-pages\n")
54+
WaitForDone()
55+
},
56+
},
57+
58+
Step{
59+
Title: "Create commit",
60+
Run: func() {
61+
fmt.Printf("Create a commit.\n")
62+
WaitForDone()
63+
},
64+
},
65+
66+
Step{
67+
Title: "Push to GitHub",
68+
Run: func() {
69+
fmt.Printf("Push your commit to GitHub on a non-main branch on https://github.com/quick-lint/quick-lint-js (not a fork).\n")
70+
WaitForDone()
71+
},
72+
},
73+
74+
Step{
75+
Title: "Wait for builds",
76+
Run: func() {
77+
fmt.Printf("Wait for all GitHub Actions workflows to finish and to succeed.\n")
78+
WaitForDone()
79+
},
80+
},
81+
82+
Step{
83+
Title: "Download builds",
84+
Run: func() {
85+
fmt.Printf("Download the build artifacts from the artifact server:\n")
86+
fmt.Printf("$ rsync -av [email protected]:/var/www/c.quick-lint-js.com/builds/$YOUR_COMMIT_HASH/ builds/\n")
87+
WaitForDone()
88+
},
89+
},
90+
91+
Step{
92+
Title: "Sign the build artifacts",
93+
Run: func() {
94+
fmt.Printf("Sign the build artifacts:\n")
95+
fmt.Printf("$ go run dist/sign-release.go -AppleCodesignIdentity=quick-lint-js -GPGIdentity=0327DE8F9CEF499851D19F6ED20BA9DCCF0E9D20 -PrivateKeyPKCS12=dist/certificates/quick-lint-js-PRIVATE.p12 builds/ signed-builds/\n")
96+
fmt.Printf("**Warning**: This signing command only works on macOS hosts.\n")
97+
WaitForDone()
98+
},
99+
},
100+
101+
Step{
102+
Title: "Upload the signed build artifacts",
103+
Run: func() {
104+
fmt.Printf("Upload the signed build artifacts to the artifact server:\n")
105+
fmt.Printf("$ rsync -av signed-builds/ [email protected]:/var/www/c.quick-lint-js.com/releases/$YOUR_VERSION_NUMBER/`\n")
106+
WaitForDone()
107+
},
108+
},
109+
110+
Step{
111+
Title: "Update `latest` symlink",
112+
Run: func() {
113+
fmt.Printf("Update the `latest` symlink on the artifact server:\n")
114+
fmt.Printf("$ ssh [email protected] \"ln --force --no-dereference --symbolic $YOUR_VERSION_NUMBER /var/www/c.quick-lint-js.com/releases/latest\"\n")
115+
WaitForDone()
116+
},
117+
},
118+
119+
Step{
120+
Title: "Publish the Visual Studio Code extension to the Marketplace",
121+
Run: func() {
122+
fmt.Printf("With the `vscode/quick-lint-js-*.vsix` artifact:\n")
123+
fmt.Printf("$ npx vsce publish --packagePath signed-builds/vscode/quick-lint-js-*.vsix\n")
124+
WaitForDone()
125+
},
126+
},
127+
128+
Step{
129+
Title: "Publish the Visual Studio Code extension to the Open VSX Registry",
130+
Run: func() {
131+
fmt.Printf("With the `vscode/quick-lint-js-*.vsix` artifact:\n")
132+
fmt.Printf("$ npx ovsx publish signed-builds/vscode/quick-lint-js-*.vsix --pat YOUR_ACCESS_TOKEN\n")
133+
WaitForDone()
134+
},
135+
},
136+
137+
Step{
138+
Title: "Publish to npm",
139+
Run: func() {
140+
fmt.Printf("With the `npm/quick-lint-js-*.tgz` artifact:\n")
141+
fmt.Printf("$ npm publish signed-builds/npm/quick-lint-js-*.tgz\n")
142+
WaitForDone()
143+
},
144+
},
145+
146+
Step{
147+
Title: "Publish Debian packages",
148+
Run: func() {
149+
fmt.Printf("Run the `dist/debian/sync-releases-to-apt` script.\n")
150+
WaitForDone()
151+
},
152+
},
153+
154+
Step{
155+
Title: "Publish the website",
156+
Run: func() {
157+
fmt.Printf("Publish the website: Run `./website/deploy.sh COMMIT_HASH_HERE`.\n")
158+
WaitForDone()
159+
},
160+
},
161+
162+
Step{
163+
Title: "Create Git tag",
164+
Run: func() {
165+
fmt.Printf("Create a Git tag named after the version number (e.g. `0.1.0`). Push it to GitHub.\n")
166+
WaitForDone()
167+
},
168+
},
169+
170+
Step{
171+
Title: "Push to master",
172+
Run: func() {
173+
fmt.Printf("Push the commit to the `master` branch on GitHub.\n")
174+
WaitForDone()
175+
},
176+
},
177+
178+
Step{
179+
Title: "Update Arch Linux user repositories (AUR)",
180+
Run: func() {
181+
fmt.Printf("1. Clone ssh://[email protected]/quick-lint-js with Git.\n")
182+
fmt.Printf("2. Update README to point to the tag's commit.\n")
183+
fmt.Printf("3. Run `dist/arch/update-aur.sh --docker --test /path/to/quick-lint-js-aur-clone`.\n")
184+
fmt.Printf("4. Commit all files with message \"Update quick-lint-js to version VERSION_NUMBER\".\n")
185+
fmt.Printf("5. Push to the `master` branch on AUR.\n")
186+
WaitForDone()
187+
},
188+
},
189+
}
190+
191+
var ConsoleInput *bufio.Reader
192+
var CurrentStepIndex int
193+
194+
func main() {
195+
ConsoleInput = bufio.NewReader(os.Stdin)
196+
197+
startAtStepNumber := 0
198+
flag.IntVar(&startAtStepNumber, "StartAtStep", 1, "")
199+
flag.Parse()
200+
if flag.NArg() != 0 {
201+
fmt.Fprintf(os.Stderr, "error: unexpected arguments\n")
202+
os.Exit(2)
203+
}
204+
CurrentStepIndex = startAtStepNumber - 1
205+
206+
for CurrentStepIndex < len(Steps) {
207+
step := &Steps[CurrentStepIndex]
208+
fmt.Printf("#%d: %s\n", CurrentStepIndex+1, step.Title)
209+
step.Run()
210+
fmt.Printf("\n")
211+
CurrentStepIndex += 1
212+
}
213+
}
214+
215+
func WaitForDone() {
216+
fmt.Printf("Type 'done' when you're done: ")
217+
retry:
218+
text, err := ConsoleInput.ReadString('\n')
219+
if err != nil {
220+
log.Fatal(err)
221+
}
222+
if text == "done\n" {
223+
return
224+
}
225+
if text == "stop\n" {
226+
fmt.Printf("\nStopped at step #%d\n", CurrentStepIndex+1)
227+
fmt.Printf("To resume, run:\n")
228+
fmt.Printf("$ go run dist/release.go -StartAtStep=%d\n", CurrentStepIndex+1)
229+
os.Exit(0)
230+
}
231+
fmt.Printf("What's that? Type 'done' or 'stop': ")
232+
goto retry
233+
}
234+
235+
// quick-lint-js finds bugs in JavaScript programs.
236+
// Copyright (C) 2020 Matthew "strager" Glazar
237+
//
238+
// This file is part of quick-lint-js.
239+
//
240+
// quick-lint-js is free software: you can redistribute it and/or modify
241+
// it under the terms of the GNU General Public License as published by
242+
// the Free Software Foundation, either version 3 of the License, or
243+
// (at your option) any later version.
244+
//
245+
// quick-lint-js is distributed in the hope that it will be useful,
246+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
247+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
248+
// GNU General Public License for more details.
249+
//
250+
// You should have received a copy of the GNU General Public License
251+
// along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>.

docs/RELEASE.md

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,5 @@
11
# Releasing quick-lint-js
22

3-
Follow the following steps to release a new version of quick-lint-js:
3+
To release a new version of quick-lint-js, run the `dist/release.go` tool:
44

5-
1. Update the release notes file: docs/CHANGELOG.md
6-
7-
2. Update version number and release date. Change these files containing version
8-
numbers:
9-
* Formula/quick-lint-js.rb
10-
* dist/arch/PKGBUILD-dev
11-
* dist/arch/PKGBUILD-git
12-
* dist/arch/PKGBUILD-release
13-
* dist/debian/README.md
14-
* dist/debian/debian/changelog
15-
* dist/npm/BUILDING.md
16-
* dist/npm/package.json
17-
* dist/sign-release.go
18-
* plugin/vim/quick-lint-js.vim/doc/quick-lint-js.txt
19-
* plugin/vscode-lsp/README.md
20-
* plugin/vscode-lsp/package.json
21-
* plugin/vscode/BUILDING.md
22-
* plugin/vscode/package.json
23-
* version
24-
25-
3. Re-generate man pages to include the updated version number by running
26-
`./docs/man/generate-man-pages`.
27-
28-
4. Create a commit. Push it to GitHub on a non-main branch on
29-
https://github.com/quick-lint/quick-lint-js (not a fork).
30-
31-
5. Wait for all GitHub Actions workflows to finish and to succeed.
32-
33-
6. Download the build artifacts from the artifact server:
34-
`rsync -av [email protected]:/var/www/c.quick-lint-js.com/builds/$YOUR_COMMIT_HASH/ builds/`
35-
36-
7. Sign the build artifacts:
37-
`go run dist/sign-release.go -AppleCodesignIdentity=quick-lint-js -GPGIdentity=0327DE8F9CEF499851D19F6ED20BA9DCCF0E9D20 -PrivateKeyPKCS12=dist/certificates/quick-lint-js-PRIVATE.p12 builds/ signed-builds/`
38-
* **Warning**: This signing command only works on macOS hosts.
39-
40-
8. Upload the signed build artifacts to the artifact server:
41-
`rsync -av signed-builds/ [email protected]:/var/www/c.quick-lint-js.com/releases/$YOUR_VERSION_NUMBER/`
42-
43-
9. Update the `latest` symlink on the artifact server:
44-
`ssh [email protected] "ln --force --no-dereference --symbolic $YOUR_VERSION_NUMBER /var/www/c.quick-lint-js.com/releases/latest"`
45-
46-
10. Publish the packages:
47-
* With the `vscode/quick-lint-js-*.vsix` artifact:
48-
`npx vsce publish --packagePath signed-builds/vscode/quick-lint-js-*.vsix`
49-
* With the `vscode/quick-lint-js-*.vsix` artifact:
50-
`npx ovsx publish signed-builds/vscode/quick-lint-js-*.vsix --pat YOUR_ACCESS_TOKEN`
51-
* With the `npm/quick-lint-js-*.tgz` artifact:
52-
`npm publish signed-builds/npm/quick-lint-js-*.tgz`
53-
* Run the `dist/debian/sync-releases-to-apt` script.
54-
55-
11. Publish the website: Run `./website/deploy.sh COMMIT_HASH_HERE`.
56-
57-
12. Create a Git tag named after the version number (e.g. `0.1.0`). Push it to
58-
GitHub.
59-
60-
13. Push the commit to the `master` branch on GitHub.
61-
62-
14. Update Arch Linux user repositories (AUR):
63-
1. Clone ssh://[email protected]/quick-lint-js with Git.
64-
2. Update README to point to the tag's commit.
65-
3. Run `dist/arch/update-aur.sh --docker --test /path/to/quick-lint-js-aur-clone`.
66-
4. Commit all files with message "Update quick-lint-js to version
67-
VERSION_NUMBER".
68-
5. Push to the `master` branch on AUR.
5+
$ go run dist/release.go

0 commit comments

Comments
 (0)