Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3013aeb

Browse files
committed
feat(scripts): add script to promote mainline to stable
1 parent215dd7b commit3013aeb

File tree

3 files changed

+325
-0
lines changed

3 files changed

+325
-0
lines changed

‎scripts/release/main.go

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"errors"
6+
"os"
7+
"slices"
8+
"strings"
9+
10+
"github.com/google/go-cmp/cmp"
11+
"github.com/google/go-github/v43/github"
12+
"golang.org/x/mod/semver"
13+
"golang.org/x/xerrors"
14+
15+
"cdr.dev/slog"
16+
"cdr.dev/slog/sloggers/sloghuman"
17+
"github.com/coder/coder/v2/cli/cliui"
18+
"github.com/coder/serpent"
19+
)
20+
21+
const (
22+
owner="coder"
23+
repo="coder"
24+
)
25+
26+
funcmain() {
27+
logger:=slog.Make(sloghuman.Sink(os.Stderr)).Leveled(slog.LevelDebug)
28+
29+
vardryRunbool
30+
31+
cmd:= serpent.Command{
32+
Use:"release <subcommand>",
33+
Short:"Prepare, create and publish releases.",
34+
Options: serpent.OptionSet{
35+
{
36+
Flag:"dry-run",
37+
FlagShorthand:"n",
38+
Description:"Do not make any changes, only print what would be done.",
39+
Value:serpent.BoolOf(&dryRun),
40+
},
41+
},
42+
Children: []*serpent.Command{
43+
{
44+
Use:"promote <version>",
45+
Short:"Promote version to stable.",
46+
Handler:func(inv*serpent.Invocation)error {
47+
ctx:=inv.Context()
48+
iflen(inv.Args)==0 {
49+
returnxerrors.New("version argument missing")
50+
}
51+
52+
err:=promoteVersionToStable(ctx,inv,logger,dryRun,inv.Args[0])
53+
iferr!=nil {
54+
returnerr
55+
}
56+
57+
returnnil
58+
},
59+
},
60+
},
61+
}
62+
63+
err:=cmd.Invoke().WithOS().Run()
64+
iferr!=nil {
65+
iferrors.Is(err,cliui.Canceled) {
66+
os.Exit(1)
67+
}
68+
logger.Error(context.Background(),"release command failed","err",err)
69+
os.Exit(1)
70+
}
71+
}
72+
73+
//nolint:revive // Allow dryRun control flag.
74+
funcpromoteVersionToStable(ctx context.Context,inv*serpent.Invocation,logger slog.Logger,dryRunbool,versionstring)error {
75+
client:=github.NewClient(nil)
76+
77+
logger=logger.With(slog.F("dry_run",dryRun),slog.F("version",version))
78+
79+
logger.Info(ctx,"checking current stable release")
80+
81+
// Check if the version is already the latest stable release.
82+
currentStable,_,err:=client.Repositories.GetLatestRelease(ctx,"coder","coder")
83+
iferr!=nil {
84+
returnerr
85+
}
86+
87+
logger=logger.With(slog.F("stable_version",currentStable.GetTagName()))
88+
logger.Info(ctx,"found current stable release")
89+
90+
ifcurrentStable.GetTagName()==version {
91+
returnxerrors.Errorf("version %q is already the latest stable release",version)
92+
}
93+
94+
// Ensure the version is a valid release.
95+
perPage:=20
96+
latestReleases,_,err:=client.Repositories.ListReleases(ctx,owner,repo,&github.ListOptions{
97+
Page:0,
98+
PerPage:perPage,
99+
})
100+
iferr!=nil {
101+
returnerr
102+
}
103+
104+
varreleaseVersions []string
105+
varnewStable*github.RepositoryRelease
106+
for_,r:=rangelatestReleases {
107+
releaseVersions=append(releaseVersions,r.GetTagName())
108+
ifr.GetTagName()==version {
109+
newStable=r
110+
}
111+
}
112+
semver.Sort(releaseVersions)
113+
slices.Reverse(releaseVersions)
114+
115+
switch {
116+
caselen(releaseVersions)==0:
117+
returnxerrors.Errorf("no releases found")
118+
casenewStable==nil:
119+
returnxerrors.Errorf("version %q is not found in the last %d releases",version,perPage)
120+
}
121+
122+
logger=logger.With(slog.F("mainline_version",releaseVersions[0]))
123+
124+
ifversion!=releaseVersions[0] {
125+
logger.Warn(ctx,"selected version is not the latest mainline release")
126+
}
127+
128+
ifreply,err:=cliui.Prompt(inv, cliui.PromptOptions{
129+
Text:"Are you sure you want to promote this version to stable?",
130+
Default:"no",
131+
IsConfirm:true,
132+
});err!=nil {
133+
ifreply==cliui.ConfirmNo {
134+
returnnil
135+
}
136+
returnerr
137+
}
138+
139+
logger.Info(ctx,"promoting version to stable")
140+
141+
// Update the release to latest.
142+
updatedNewStable:=cloneRelease(newStable)
143+
144+
updatedNewStable.Name=github.String(newStable.GetName()+" (Stable)")
145+
updatedNewStable.Body=github.String(removeMainlineBlurb(newStable.GetBody()))
146+
updatedNewStable.Prerelease=github.Bool(false)
147+
updatedNewStable.Draft=github.Bool(false)
148+
if!dryRun {
149+
_,_,err=client.Repositories.EditRelease(ctx,"mafredri",repo,newStable.GetID(),newStable)
150+
iferr!=nil {
151+
returnerr
152+
}
153+
logger.Info(ctx,"version promoted to stable")
154+
}else {
155+
logger.Info(ctx,"dry-run: release not updated","uncommitted_changes",cmp.Diff(newStable,updatedNewStable))
156+
}
157+
158+
logger.Info(ctx,"updating title of the previous stable release")
159+
160+
// Update the previous stable release to a regular release.
161+
updatedOldStable:=cloneRelease(currentStable)
162+
currentStable.Name=github.String(strings.TrimSuffix(currentStable.GetName()," (Stable)"))
163+
164+
if!dryRun {
165+
_,_,err=client.Repositories.EditRelease(ctx,"mafredri",repo,currentStable.GetID(),currentStable)
166+
iferr!=nil {
167+
returnerr
168+
}
169+
logger.Info(ctx,"title of the previous stable release updated")
170+
}else {
171+
logger.Info(ctx,"dry-run: release not updated","uncommitted_changes",cmp.Diff(currentStable,updatedOldStable))
172+
}
173+
174+
returnnil
175+
}
176+
177+
funccloneRelease(r*github.RepositoryRelease)*github.RepositoryRelease {
178+
rr:=*r
179+
return&rr
180+
}
181+
182+
// removeMainlineBlurb removes the mainline blurb from the release body.
183+
//
184+
// Example:
185+
//
186+
//> [!NOTE]
187+
//> This is a mainline Coder release. We advise enterprise customers without a staging environment to install our [latest stable release](https://github.com/coder/coder/releases/latest) while we refine this version. Learn more about our [Release Schedule](https://coder.com/docs/v2/latest/install/releases).
188+
funcremoveMainlineBlurb(bodystring)string {
189+
lines:=strings.Split(body,"\n")
190+
191+
varnewBody,clip []string
192+
varfoundbool
193+
for_,line:=rangelines {
194+
ifstrings.HasPrefix(strings.TrimSpace(line),"> [!NOTE]") {
195+
clip=append(clip,line)
196+
found=true
197+
continue
198+
}
199+
iffound {
200+
clip=append(clip,line)
201+
found=strings.HasPrefix(strings.TrimSpace(line),">")
202+
continue
203+
}
204+
if!found&&len(clip)>0 {
205+
if!strings.Contains(strings.ToLower(strings.Join(clip,"\n")),"this is a mainline coder release") {
206+
newBody=append(newBody,clip...)// This is some other note, restore it.
207+
}
208+
clip=nil
209+
}
210+
newBody=append(newBody,line)
211+
}
212+
213+
returnstrings.Join(newBody,"\n")
214+
}

‎scripts/release/main_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/google/go-cmp/cmp"
7+
)
8+
9+
funcTest_removeMainlineBlurb(t*testing.T) {
10+
t.Parallel()
11+
12+
tests:= []struct {
13+
namestring
14+
bodystring
15+
wantstring
16+
}{
17+
{
18+
name:"NoMainlineBlurb",
19+
body:`## Changelog
20+
21+
### Chores
22+
23+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
24+
25+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
26+
27+
## Container image
28+
29+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
30+
31+
## Install/upgrade
32+
33+
Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
34+
`,
35+
want:`## Changelog
36+
37+
### Chores
38+
39+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
40+
41+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
42+
43+
## Container image
44+
45+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
46+
47+
## Install/upgrade
48+
49+
Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
50+
`,
51+
},
52+
{
53+
name:"WithMainlineBlurb",
54+
body:`## Changelog
55+
56+
> [!NOTE]
57+
> This is a mainline Coder release. We advise enterprise customers without a staging environment to install our [latest stable release](https://github.com/coder/coder/releases/latest) while we refine this version. Learn more about our [Release Schedule](https://coder.com/docs/v2/latest/install/releases).
58+
59+
### Chores
60+
61+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
62+
63+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
64+
65+
## Container image
66+
67+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
68+
69+
## Install/upgrade
70+
71+
Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
72+
`,
73+
want:`## Changelog
74+
75+
### Chores
76+
77+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
78+
79+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
80+
81+
## Container image
82+
83+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
84+
85+
## Install/upgrade
86+
87+
Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
88+
`,
89+
},
90+
}
91+
92+
for_,tt:=rangetests {
93+
tt:=tt
94+
t.Run(tt.name,func(t*testing.T) {
95+
t.Parallel()
96+
ifdiff:=cmp.Diff(removeMainlineBlurb(tt.body),tt.want);diff!="" {
97+
t.Errorf("removeMainlineBlurb() mismatch (-want +got):\n%s",diff)
98+
}
99+
})
100+
}
101+
}

‎scripts/release_promote_stable.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
# shellcheck source=scripts/lib.sh
5+
source"$(dirname"${BASH_SOURCE[0]}")/lib.sh"
6+
7+
# This script is a convenience wrapper around the release promote command.
8+
#
9+
# Sed hack to make help text look like this script.
10+
exec go run"${SCRIPT_DIR}/release" promote"$@"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp