@@ -32,6 +32,7 @@ import (
32
32
"os/exec"
33
33
"path/filepath"
34
34
"regexp"
35
+ "strconv"
35
36
"strings"
36
37
)
37
38
@@ -187,11 +188,11 @@ func runPackage(cmd *command, args []string) {
187
188
188
189
tagName := requireEnv ("TAG_NAME" )
189
190
190
- version , _ := releaseVersionInfo (tagName )
191
- checkPackageJSON (tagName )
191
+ version , isPrerelease := releaseVersionInfo (tagName )
192
+ checkPackageJSON (tagName , isPrerelease )
192
193
outDir := prepareOutputDir (cmd .lookupFlag ("out" ).String ())
193
194
vsix := filepath .Join (outDir , fmt .Sprintf ("go-%s.vsix" , version ))
194
- buildPackage (version , tagName , vsix )
195
+ buildPackage (version , tagName , isPrerelease , vsix )
195
196
}
196
197
197
198
// runPublish implements the "publish" subcommand.
@@ -206,11 +207,11 @@ func runPublish(cmd *command, args []string) {
206
207
requireEnv ("GITHUB_TOKEN" )
207
208
tagName := requireEnv ("TAG_NAME" )
208
209
209
- version , isRC := releaseVersionInfo (tagName )
210
- checkPackageJSON (tagName )
210
+ version , isPrerelease := releaseVersionInfo (tagName )
211
+ checkPackageJSON (tagName , isPrerelease )
211
212
inDir := prepareInputDir (cmd .lookupFlag ("in" ).String ())
212
213
vsix := filepath .Join (inDir , fmt .Sprintf ("go-%s.vsix" , version ))
213
- publish (tagName , vsix , isRC )
214
+ publish (tagName , vsix , isPrerelease )
214
215
}
215
216
216
217
func fatalf (format string , args ... any ) {
@@ -294,46 +295,67 @@ func checkWD() {
294
295
// releaseVersionInfo computes the version and label information for this release.
295
296
// It requires the TAG_NAME environment variable to be set and the tag matches the version info embedded in package.json.
296
297
func releaseVersionInfo (tagName string ) (version string , isPrerelease bool ) {
297
- // versionTag should be of the form vMajor.Minor.Patch[-rc.N].
298
- // e.g. v1.1.0-rc.1, v1.1.0
299
- // The MajorMinorPatch part should match the version in package.json.
300
- // The optional `-rc.N` part is captured as the `Label` group
301
- // and the validity is checked below.
302
- mmp , label := parseVersionTagName (tagName )
298
+ // Odd numbered minor version -> prerelease, after v0.42.
299
+ major , minor , patch , label := parseVersionTagName (tagName )
300
+ if (major != 0 || minor > 42 ) && minor % 2 == 1 {
301
+ isPrerelease = true
302
+ }
303
303
if label != "" {
304
304
if ! strings .HasPrefix (label , "-rc." ) {
305
305
fatalf ("TAG_NAME environment variable %q is not a valid release candidate version" , tagName )
306
306
}
307
307
isPrerelease = true
308
308
}
309
- return mmp + label , isPrerelease
309
+ return fmt . Sprintf ( "%d.%d.%d" , major , minor , patch ) + label , isPrerelease
310
310
}
311
311
312
- func parseVersionTagName (tagName string ) (majorMinorPatch , label string ) {
313
- versionTagRE := regexp .MustCompile (`^v(?P<MajorMinorPatch >\d+\. \d+\. \d+)(?P<Label>\S*)$` )
312
+ func parseVersionTagName (tagName string ) (major , minor , patch int , label string ) {
313
+ versionTagRE := regexp .MustCompile (`^v(?P<Major >\d+)\.(?P<Minor> \d+)\.(?P<Patch> \d+)(?P<Label>\S*)$` )
314
314
m := versionTagRE .FindStringSubmatch (tagName )
315
315
if m == nil {
316
316
fatalf ("TAG_NAME environment variable %q is not a valid version" , tagName )
317
317
}
318
- return m [versionTagRE .SubexpIndex ("MajorMinorPatch" )], m [versionTagRE .SubexpIndex ("Label" )]
318
+ atoi := func (key string ) int {
319
+ val , err := strconv .Atoi (m [versionTagRE .SubexpIndex (key )])
320
+ if err != nil {
321
+ fatalf ("%v in %v (%q) is not valid" , key , tagName , m [versionTagRE .SubexpIndex (key )])
322
+ }
323
+ return val
324
+ }
325
+ return atoi ("Major" ), atoi ("Minor" ), atoi ("Patch" ), m [versionTagRE .SubexpIndex ("Label" )]
319
326
}
320
327
321
- func checkPackageJSON (tagName string ) {
328
+ // checkPackageJSON checks if package.json has the expected version value.
329
+ // If prerelease, the major/minor version should match.
330
+ // Otherwise, major/minor/patch version should match.
331
+ func checkPackageJSON (tagName string , isPrerelease bool ) {
332
+ if ! strings .HasPrefix (tagName , "v" ) {
333
+ fatalf ("unexpected tagName in checkPackageJSON: %q" , tagName )
334
+ }
335
+
322
336
if flagN {
323
337
tracef ("jq -r .version package.json" )
324
338
return
325
339
}
326
- mmp , _ := parseVersionTagName (tagName )
327
340
cmd := exec .Command ("jq" , "-r" , ".version" , "package.json" )
328
341
cmd .Stderr = os .Stderr
329
342
var buf bytes.Buffer
330
343
cmd .Stdout = & buf
331
344
if err := commandRun (cmd ); err != nil {
332
345
fatalf ("failed to read package.json version" )
333
346
}
334
- versionInPackageJSON := buf .Bytes ()
335
- if got := string (bytes .TrimSpace (versionInPackageJSON )); got != mmp {
336
- fatalf ("package.json version %q does not match TAG_NAME %q" , got , tagName )
347
+
348
+ versionInPackageJSON := string (bytes .TrimSpace (buf .Bytes ()))
349
+ if ! isPrerelease {
350
+ if got , want := versionInPackageJSON , tagName [1 :]; got != want {
351
+ fatalf ("package.json version %q does not match wanted string %q" , got , want )
352
+ }
353
+ return
354
+ }
355
+ // Check only major.minor for prerelease.
356
+ major , minor , _ , _ := parseVersionTagName (tagName )
357
+ if want := fmt .Sprintf ("%d.%d." , major , minor ); strings .HasPrefix (versionInPackageJSON , want ) {
358
+ fatalf ("package.json version %q does not match wanted string %q" , versionInPackageJSON , want )
337
359
}
338
360
}
339
361
@@ -361,19 +383,26 @@ func copy(dst, src string) error {
361
383
}
362
384
363
385
// buildPackage builds the extension of the given version, using npx vsce package.
364
- func buildPackage (version , tagName , output string ) {
386
+ func buildPackage (version , tagName string , isPrerelease bool , output string ) {
365
387
if err := copy ("README.md" , filepath .Join (".." , "README.md" )); err != nil {
366
388
fatalf ("failed to copy README.md: %v" , err )
367
389
}
368
390
// build the package.
369
- cmd := exec . Command ( "npx" , "vsce" , "package" ,
391
+ args := [] string { "vsce" , "package" ,
370
392
"-o" , output ,
371
- "--baseContentUrl" , "https://github.com/golang/vscode-go/raw/" + tagName ,
372
- "--baseImagesUrl" , "https://github.com/golang/vscode-go/raw/" + tagName ,
393
+ "--baseContentUrl" , "https://github.com/golang/vscode-go/raw/" + tagName ,
394
+ "--baseImagesUrl" , "https://github.com/golang/vscode-go/raw/" + tagName ,
373
395
"--no-update-package-json" ,
374
396
"--no-git-tag-version" ,
375
- version )
397
+ }
398
+ if isPrerelease {
399
+ args = append (args , "--pre-release" )
376
400
401
+ }
402
+ args = append (args , version )
403
+
404
+ // build the package.
405
+ cmd := exec .Command ("npx" , args ... )
377
406
cmd .Stderr = os .Stderr
378
407
if err := commandRun (cmd ); err != nil {
379
408
fatalf ("failed to build package: %v" , err )
@@ -390,12 +419,13 @@ func publish(tagName, packageFile string, isPrerelease bool) {
390
419
fatalf ("package file %q does not exist. Did you run 'go run build/release.go package'?" , packageFile )
391
420
}
392
421
}
422
+ isRC := strings .Contains (tagName , "-rc." )
393
423
394
424
// publish release to GitHub. This will create a draft release - manually publish it after reviewing the draft.
395
425
// TODO(hyangah): populate the changelog (the first section of CHANGELOG.md) and pass it using --notes-file instead of --generate-notes.
396
426
ghArgs := []string {"release" , "create" , "--generate-notes" , "--target" , commitSHA (), "--title" , "Release " + tagName , "--draft" }
397
427
fmt .Printf ("%s\n " , strings .Join (ghArgs , " " ))
398
- if isPrerelease {
428
+ if isRC || isPrerelease {
399
429
ghArgs = append (ghArgs , "--prerelease" )
400
430
}
401
431
ghArgs = append (ghArgs , "-R" , "github.com/golang/vscode-go" )
@@ -406,11 +436,14 @@ func publish(tagName, packageFile string, isPrerelease bool) {
406
436
fatalf ("failed to publish release: %v" , err )
407
437
}
408
438
409
- if isPrerelease {
410
- return // TODO: release with the -pre-release flag if isPrerelease is set.
439
+ if isRC { // Do not publish RC versions to the marketplace.
440
+ return
411
441
}
412
442
413
443
npxVsceArgs := []string {"vsce" , "publish" , "-i" , packageFile }
444
+ if isPrerelease {
445
+ npxVsceArgs = append (npxVsceArgs , "--pre-release" )
446
+ }
414
447
cmd2 := exec .Command ("npx" , npxVsceArgs ... )
415
448
cmd2 .Stderr = os .Stderr
416
449
if err := commandRun (cmd2 ); err != nil {
0 commit comments