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

Commitc933c75

Browse files
authored
chore(scripts): add script to promote mainline to stable (#13054)
Fixes#12459Example dry-run:<img width="1229" alt="Screenshot 2024-04-23 at 21 16 55" src="https://github.com/coder/coder/assets/147409/7018d322-501b-41e2-bf47-af3fc39fb3d2">Example dry-run for non-latest version:<img width="1228" alt="Screenshot 2024-04-23 at 21 17 52" src="https://github.com/coder/coder/assets/147409/a05fcd44-560f-4e44-81b5-76c071c591b4">**Note:** This PR does not yet update docs to reflect the promoted version. This will be part of#12465.
1 parentb82a782 commitc933c75

File tree

5 files changed

+372
-0
lines changed

5 files changed

+372
-0
lines changed

‎go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ require (
218218
github.com/benbjohnson/clockv1.3.5
219219
github.com/coder/serpentv0.7.0
220220
github.com/gomarkdown/markdownv0.0.0-20231222211730-1d6d20845b47
221+
github.com/google/go-github/v61v61.0.0
221222
)
222223

223224
require (

‎go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
469469
github.com/google/go-cmpv0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
470470
github.com/google/go-github/v43v43.0.1-0.20220414155304-00e42332e405 h1:DdHws/YnnPrSywrjNYu2lEHqYHWp/LnEx56w59esd54=
471471
github.com/google/go-github/v43v43.0.1-0.20220414155304-00e42332e405/go.mod h1:4RgUDSnsxP19d65zJWqvqJ/poJxBCvmna50eXmIvoR8=
472+
github.com/google/go-github/v61v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go=
473+
github.com/google/go-github/v61v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY=
472474
github.com/google/go-querystringv1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
473475
github.com/google/go-querystringv1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
474476
github.com/google/gofuzzv1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=

‎scripts/release/main.go

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

‎scripts/release/main_test.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/google/go-cmp/cmp"
8+
)
9+
10+
funcTest_removeMainlineBlurb(t*testing.T) {
11+
t.Parallel()
12+
13+
tests:= []struct {
14+
namestring
15+
bodystring
16+
wantstring
17+
}{
18+
{
19+
name:"NoMainlineBlurb",
20+
body:`## Changelog
21+
22+
### Chores
23+
24+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
25+
26+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
27+
28+
## Container image
29+
30+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
31+
32+
## Install/upgrade
33+
34+
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.
35+
`,
36+
want:`## Changelog
37+
38+
### Chores
39+
40+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
41+
42+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
43+
44+
## Container image
45+
46+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
47+
48+
## Install/upgrade
49+
50+
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.
51+
`,
52+
},
53+
{
54+
name:"WithMainlineBlurb",
55+
body:`## Changelog
56+
57+
> [!NOTE]
58+
> 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).
59+
60+
### Chores
61+
62+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
63+
64+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
65+
66+
## Container image
67+
68+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
69+
70+
## Install/upgrade
71+
72+
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.
73+
`,
74+
want:`## Changelog
75+
76+
### Chores
77+
78+
- Add support for additional Azure Instance Identity RSA Certificates (#13028) (@kylecarbs)
79+
80+
Compare: [`+"`"+`v2.10.1...v2.10.2`+"`"+`](https://github.com/coder/coder/compare/v2.10.1...v2.10.2)
81+
82+
## Container image
83+
84+
- `+"`"+`docker pull ghcr.io/coder/coder:v2.10.2`+"`"+`
85+
86+
## Install/upgrade
87+
88+
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.
89+
`,
90+
},
91+
{
92+
name:"EntireQuotedBlurbIsRemoved",
93+
body:`## Changelog
94+
95+
> [!NOTE]
96+
> 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).
97+
> This is an extended note.
98+
> This is another extended note.
99+
100+
### Best release yet!
101+
102+
Enjoy.
103+
`,
104+
want:`## Changelog
105+
106+
### Best release yet!
107+
108+
Enjoy.
109+
`,
110+
},
111+
}
112+
113+
for_,tt:=rangetests {
114+
tt:=tt
115+
t.Run(tt.name,func(t*testing.T) {
116+
t.Parallel()
117+
ifdiff:=cmp.Diff(removeMainlineBlurb(tt.body),tt.want);diff!="" {
118+
t.Errorf("removeMainlineBlurb() mismatch (-want +got):\n%s",diff)
119+
}
120+
})
121+
}
122+
}
123+
124+
funcTest_addStableSince(t*testing.T) {
125+
t.Parallel()
126+
127+
date:=time.Date(2024,time.April,23,0,0,0,0,time.UTC)
128+
body:="## Changelog"
129+
130+
expected:="> ## Stable (since April 23, 2024)\n\n## Changelog"
131+
result:=addStableSince(date,body)
132+
133+
ifdiff:=cmp.Diff(expected,result);diff!="" {
134+
t.Errorf("addStableSince() mismatch (-want +got):\n%s",diff)
135+
}
136+
}

‎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