@@ -32,6 +32,7 @@ import (
3232 "os/exec"
3333 "path/filepath"
3434 "regexp"
35+ "strconv"
3536 "strings"
3637)
3738
@@ -187,11 +188,11 @@ func runPackage(cmd *command, args []string) {
187188
188189 tagName := requireEnv ("TAG_NAME" )
189190
190- version , _ := releaseVersionInfo (tagName )
191- checkPackageJSON (tagName )
191+ version , isPrerelease := releaseVersionInfo (tagName )
192+ checkPackageJSON (tagName , isPrerelease )
192193 outDir := prepareOutputDir (cmd .lookupFlag ("out" ).String ())
193194 vsix := filepath .Join (outDir , fmt .Sprintf ("go-%s.vsix" , version ))
194- buildPackage (version , tagName , vsix )
195+ buildPackage (version , tagName , isPrerelease , vsix )
195196}
196197
197198// runPublish implements the "publish" subcommand.
@@ -206,11 +207,11 @@ func runPublish(cmd *command, args []string) {
206207 requireEnv ("GITHUB_TOKEN" )
207208 tagName := requireEnv ("TAG_NAME" )
208209
209- version , isRC := releaseVersionInfo (tagName )
210- checkPackageJSON (tagName )
210+ version , isPrerelease := releaseVersionInfo (tagName )
211+ checkPackageJSON (tagName , isPrerelease )
211212 inDir := prepareInputDir (cmd .lookupFlag ("in" ).String ())
212213 vsix := filepath .Join (inDir , fmt .Sprintf ("go-%s.vsix" , version ))
213- publish (tagName , vsix , isRC )
214+ publish (tagName , vsix , isPrerelease )
214215}
215216
216217func fatalf (format string , args ... any ) {
@@ -294,46 +295,67 @@ func checkWD() {
294295// releaseVersionInfo computes the version and label information for this release.
295296// It requires the TAG_NAME environment variable to be set and the tag matches the version info embedded in package.json.
296297func 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+ }
303303 if label != "" {
304304 if ! strings .HasPrefix (label , "-rc." ) {
305305 fatalf ("TAG_NAME environment variable %q is not a valid release candidate version" , tagName )
306306 }
307307 isPrerelease = true
308308 }
309- return mmp + label , isPrerelease
309+ return fmt . Sprintf ( "%d.%d.%d" , major , minor , patch ) + label , isPrerelease
310310}
311311
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*)$` )
314314 m := versionTagRE .FindStringSubmatch (tagName )
315315 if m == nil {
316316 fatalf ("TAG_NAME environment variable %q is not a valid version" , tagName )
317317 }
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" )]
319326}
320327
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+
322336 if flagN {
323337 tracef ("jq -r .version package.json" )
324338 return
325339 }
326- mmp , _ := parseVersionTagName (tagName )
327340 cmd := exec .Command ("jq" , "-r" , ".version" , "package.json" )
328341 cmd .Stderr = os .Stderr
329342 var buf bytes.Buffer
330343 cmd .Stdout = & buf
331344 if err := commandRun (cmd ); err != nil {
332345 fatalf ("failed to read package.json version" )
333346 }
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 )
337359 }
338360}
339361
@@ -361,19 +383,26 @@ func copy(dst, src string) error {
361383}
362384
363385// 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 ) {
365387 if err := copy ("README.md" , filepath .Join (".." , "README.md" )); err != nil {
366388 fatalf ("failed to copy README.md: %v" , err )
367389 }
368390 // build the package.
369- cmd := exec . Command ( "npx" , "vsce" , "package" ,
391+ args := [] string { "vsce" , "package" ,
370392 "-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 ,
373395 "--no-update-package-json" ,
374396 "--no-git-tag-version" ,
375- version )
397+ }
398+ if isPrerelease {
399+ args = append (args , "--pre-release" )
376400
401+ }
402+ args = append (args , version )
403+
404+ // build the package.
405+ cmd := exec .Command ("npx" , args ... )
377406 cmd .Stderr = os .Stderr
378407 if err := commandRun (cmd ); err != nil {
379408 fatalf ("failed to build package: %v" , err )
@@ -390,12 +419,13 @@ func publish(tagName, packageFile string, isPrerelease bool) {
390419 fatalf ("package file %q does not exist. Did you run 'go run build/release.go package'?" , packageFile )
391420 }
392421 }
422+ isRC := strings .Contains (tagName , "-rc." )
393423
394424 // publish release to GitHub. This will create a draft release - manually publish it after reviewing the draft.
395425 // TODO(hyangah): populate the changelog (the first section of CHANGELOG.md) and pass it using --notes-file instead of --generate-notes.
396426 ghArgs := []string {"release" , "create" , "--generate-notes" , "--target" , commitSHA (), "--title" , "Release " + tagName , "--draft" }
397427 fmt .Printf ("%s\n " , strings .Join (ghArgs , " " ))
398- if isPrerelease {
428+ if isRC || isPrerelease {
399429 ghArgs = append (ghArgs , "--prerelease" )
400430 }
401431 ghArgs = append (ghArgs , "-R" , "github.com/golang/vscode-go" )
@@ -406,11 +436,14 @@ func publish(tagName, packageFile string, isPrerelease bool) {
406436 fatalf ("failed to publish release: %v" , err )
407437 }
408438
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
411441 }
412442
413443 npxVsceArgs := []string {"vsce" , "publish" , "-i" , packageFile }
444+ if isPrerelease {
445+ npxVsceArgs = append (npxVsceArgs , "--pre-release" )
446+ }
414447 cmd2 := exec .Command ("npx" , npxVsceArgs ... )
415448 cmd2 .Stderr = os .Stderr
416449 if err := commandRun (cmd2 ); err != nil {
0 commit comments