Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sdk action publishing improvements #133

Merged
merged 11 commits into from
May 31, 2024
9 changes: 8 additions & 1 deletion internal/actions/publishEvent.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (
)

func PublishEvent() error {
if _, err := initAction(); err != nil {
g, err := initAction()
if err != nil {
return err
}

Expand All @@ -39,6 +40,12 @@ func PublishEvent() error {

version := processLockFile(*loadedCfg.LockFile, event)

if strings.Contains(strings.ToLower(os.Getenv("GH_ACTION_RESULT")), "success") {
if err = g.SetReleaseToPublished(version); err != nil {
fmt.Println("Failed to set release to published %w", err)
}
}

var processingErr error
switch os.Getenv("INPUT_REGISTRY_NAME") {
case "pypi":
Expand Down
12 changes: 6 additions & 6 deletions internal/actions/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ func Release() error {
return err
}

if environment.CreateGitRelease() {
if err := g.CreateRelease(*latestRelease); err != nil {
return err
}
}

outputs := map[string]string{}

for lang, info := range latestRelease.Languages {
Expand All @@ -68,6 +62,12 @@ func Release() error {
return err
}

if environment.CreateGitRelease() {
if err := g.CreateRelease(*latestRelease, outputs); err != nil {
return err
}
}

if err = setOutputs(outputs); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/actions/runWorkflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func finalize(inputs finalizeInputs) error {
}

if !inputs.SourcesOnly && environment.CreateGitRelease() {
if err := inputs.Git.CreateRelease(*releaseInfo); err != nil {
if err := inputs.Git.CreateRelease(*releaseInfo, inputs.Outputs); err != nil {
return err
}
}
Expand Down
45 changes: 42 additions & 3 deletions internal/git/releases.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/google/go-github/v54/github"
"github.com/speakeasy-api/sdk-generation-action/internal/environment"
Expand All @@ -16,7 +17,32 @@ import (
//go:embed goreleaser.yml
var tfGoReleaserConfig string

func (g *Git) CreateRelease(releaseInfo releases.ReleasesInfo) error {
func (g *Git) SetReleaseToPublished(version string) error {
if g.repo == nil {
return fmt.Errorf("repo not cloned")
}
tag := "v" + version

release, _, err := g.client.Repositories.GetReleaseByTag(context.Background(), os.Getenv("GITHUB_REPOSITORY_OWNER"), getRepo(), tag)
if err != nil {
return fmt.Errorf("failed to get release for tag %s: %w", tag, err)
}

if release != nil && release.ID != nil {
if release.Body != nil && !strings.Contains(*release.Body, "Publishing Completed") {
body := *release.Body + "\n\nPublishing Completed"
release.Body = &body
}

if _, _, err = g.client.Repositories.EditRelease(context.Background(), os.Getenv("GITHUB_REPOSITORY_OWNER"), getRepo(), *release.ID, release); err != nil {
return fmt.Errorf("failed to add to release body for tag %s: %w", tag, err)
}
}

return nil
}

func (g *Git) CreateRelease(releaseInfo releases.ReleasesInfo, outputs map[string]string) error {
if g.repo == nil {
return fmt.Errorf("repo not cloned")
}
Expand Down Expand Up @@ -61,14 +87,27 @@ func (g *Git) CreateRelease(releaseInfo releases.ReleasesInfo) error {
return fmt.Errorf("failed to run goreleaser: %w", err)
}
} else {
tagName := github.String(tag)
_, _, err = g.client.Repositories.CreateRelease(context.Background(), os.Getenv("GITHUB_REPOSITORY_OWNER"), getRepo(), &github.RepositoryRelease{
TagName: github.String(tag),
TagName: tagName,
TargetCommitish: github.String(commitHash),
Name: github.String(fmt.Sprintf("%s - %s - %s", lang, tag, environment.GetInvokeTime().Format("2006-01-02 15:04:05"))),
Body: github.String(fmt.Sprintf(`# Generated by Speakeasy CLI%s`, releaseInfo)),
})
if err != nil {
return fmt.Errorf("failed to create release: %w", err)
if release, _, err := g.client.Repositories.GetReleaseByTag(context.Background(), os.Getenv("GITHUB_REPOSITORY_OWNER"), getRepo(), *tagName); err == nil && release != nil {
if release.Body != nil && strings.Contains(*release.Body, "Publishing Completed") {
fmt.Println(fmt.Sprintf("a github release with tag %s already existing ... skipping publishing", *tagName))
fmt.Println(fmt.Sprintf("to publish this version again delete the github tag and release"))
if _, ok := outputs[fmt.Sprintf("publish_%s", lang)]; ok {
outputs[fmt.Sprintf("publish_%s", lang)] = "false"
}
}
// TODO: Consider deleting and recreating the release if we are moving forward with publishing
return nil
}

return fmt.Errorf("failed to create release for tag %s: %w", *tagName, err)
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/releases/releases.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,16 @@ func UpdateReleasesFile(releaseInfo ReleasesInfo, dir string) error {

var (
releaseInfoRegex = regexp.MustCompile(`(?s)## (.*?)\n### Changes\nBased on:\n- OpenAPI Doc (.*?) (.*?)\n- Speakeasy CLI (.*?) (\((.*?)\))?.*?`)
generatedLanguagesRegex = regexp.MustCompile(`- \[([a-z]+) v(\d+\.\d+\.\d+)\] (.*)`)
npmReleaseRegex = regexp.MustCompile(`- \[NPM v(\d+\.\d+\.\d+)\] (https:\/\/www\.npmjs\.com\/package\/(.*?)\/v\/\d+\.\d+\.\d+) - (.*)`)
pypiReleaseRegex = regexp.MustCompile(`- \[PyPI v(\d+\.\d+\.\d+)\] (https:\/\/pypi\.org\/project\/(.*?)\/\d+\.\d+\.\d+) - (.*)`)
goReleaseRegex = regexp.MustCompile(`- \[Go v(\d+\.\d+\.\d+)\] (https:\/\/(github.com\/.*?)\/releases\/tag\/.*?\/?v\d+\.\d+\.\d+) - (.*)`)
composerReleaseRegex = regexp.MustCompile(`- \[Composer v(\d+\.\d+\.\d+)\] (https:\/\/packagist\.org\/packages\/(.*?)#v\d+\.\d+\.\d+) - (.*)`)
mavenReleaseRegex = regexp.MustCompile(`- \[Maven Central v(\d+\.\d+\.\d+)\] (https:\/\/central\.sonatype\.com\/artifact\/(.*?)\/(.*?)\/.*?) - (.*)`)
terraformReleaseRegex = regexp.MustCompile(`- \[Terraform v(\d+\.\d+\.\d+)\] (https:\/\/registry\.terraform\.io\/providers\/(.*?)\/(.*?)\/.*?) - (.*)`)
rubyGemReleaseRegex = regexp.MustCompile(`- \[Ruby Gems v(\d+\.\d+\.\d+)\] (https:\/\/rubygems\.org\/gems\/(.*?)\/versions\/.*?) - (.*)`)
nugetReleaseRegex = regexp.MustCompile(`- \[NuGet v(\d+\.\d+\.\d+)\] (https:\/\/www\.nuget\.org\/packages\/(.*?)\/\d+\.\d+\.\d+) - (.*)`)
swiftReleaseRegex = regexp.MustCompile(`- \[Swift Package Manager v(\d+\.\d+\.\d+)\] (https:\/\/(github.com\/.*?)\/releases\/tag\/.*?\/?v\d+\.\d+\.\d+) - (.*)`)
generatedLanguagesRegex = regexp.MustCompile(`- \[([a-z]+) v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (.*)`)
npmReleaseRegex = regexp.MustCompile(`- \[NPM v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/www\.npmjs\.com\/package\/(.*?)\/v\/\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
pypiReleaseRegex = regexp.MustCompile(`- \[PyPI v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/pypi\.org\/project\/(.*?)\/\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
goReleaseRegex = regexp.MustCompile(`- \[Go v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/(github.com\/.*?)\/releases\/tag\/.*?\/?v\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
composerReleaseRegex = regexp.MustCompile(`- \[Composer v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/packagist\.org\/packages\/(.*?)#v\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
mavenReleaseRegex = regexp.MustCompile(`- \[Maven Central v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/central\.sonatype\.com\/artifact\/(.*?)\/(.*?)\/.*?) - (.*)`)
terraformReleaseRegex = regexp.MustCompile(`- \[Terraform v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/registry\.terraform\.io\/providers\/(.*?)\/(.*?)\/.*?) - (.*)`)
rubyGemReleaseRegex = regexp.MustCompile(`- \[Ruby Gems v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/rubygems\.org\/gems\/(.*?)\/versions\/.*?) - (.*)`)
nugetReleaseRegex = regexp.MustCompile(`- \[NuGet v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/www\.nuget\.org\/packages\/(.*?)\/\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
swiftReleaseRegex = regexp.MustCompile(`- \[Swift Package Manager v(\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?)] (https:\/\/(github.com\/.*?)\/releases\/tag\/.*?\/?v\d+\.\d+\.\d+(?:-\w+(?:\.\w+)*)?) - (.*)`)
)

func GetLastReleaseInfo(dir string) (*ReleasesInfo, error) {
Expand Down
45 changes: 45 additions & 0 deletions pkg/releases/releases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,48 @@ Based on:
LanguagesGenerated: map[string]releases.GenerationInfo{},
}, *info)
}

func TestReleases_ParseCodatPreRelease_Success(t *testing.T) {
releasesStr := `

## Version 1.1.0
### Changes
Based on:
- OpenAPI Doc v1 https://api.codat.io/swagger/v1/swagger.json
- Speakeasy CLI 0.21.0 https://github.com/speakeasy-api/speakeasy
### Releases
- [NPM v1.1.0-alpha] https://www.npmjs.com/package/@codatio/codat-ts/v/1.1.0-alpha - typescript-client-sdk
- [PyPI v1.1.0-beta.1] https://pypi.org/project/codatapi/1.1.0-beta.1 - python-client-sdk
- [Go v1.1.0-alpha.12] https://github.com/speakeasy-sdks/codat-sdks/releases/tag/v1.1.0-alpha.12 - go-client-sdk`

info, err := releases.ParseReleases(releasesStr)

assert.NoError(t, err)
assert.Equal(t, releases.ReleasesInfo{
ReleaseTitle: "Version 1.1.0",
DocVersion: "v1",
DocLocation: "https://api.codat.io/swagger/v1/swagger.json",
SpeakeasyVersion: "0.21.0",
Languages: map[string]releases.LanguageReleaseInfo{
"typescript": {
PackageName: "@codatio/codat-ts",
Path: "typescript-client-sdk",
Version: "1.1.0-alpha",
URL: "https://www.npmjs.com/package/@codatio/codat-ts/v/1.1.0-alpha",
},
"python": {
PackageName: "codatapi",
Path: "python-client-sdk",
Version: "1.1.0-beta.1",
URL: "https://pypi.org/project/codatapi/1.1.0-beta.1",
},
"go": {
PackageName: "github.com/speakeasy-sdks/codat-sdks/go-client-sdk",
Path: "go-client-sdk",
Version: "1.1.0-alpha.12",
URL: "https://github.com/speakeasy-sdks/codat-sdks/releases/tag/v1.1.0-alpha.12",
},
},
LanguagesGenerated: map[string]releases.GenerationInfo{},
}, *info)
}
Loading