CI: Allow overwriting of existing GitHub release assets (#65127)

* CI: Allow overwriting of existing GitHub release assets

This closes #63698

* Use c for *cli.Context in publishgithub.go
pull/65127/merge
Horst Gutmann 2 years ago committed by GitHub
parent b11186f946
commit 4ab3bd6f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 62
      pkg/build/cmd/publishgithub.go
  2. 12
      pkg/build/cmd/publishgithub_test.go
  3. 2
      pkg/build/config/genmetadata.go

@ -19,6 +19,8 @@ type githubRepositoryService interface {
GetReleaseByTag(ctx context.Context, owner string, repo string, tag string) (*github.RepositoryRelease, *github.Response, error) GetReleaseByTag(ctx context.Context, owner string, repo string, tag string) (*github.RepositoryRelease, *github.Response, error)
CreateRelease(ctx context.Context, owner string, repo string, release *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error) CreateRelease(ctx context.Context, owner string, repo string, release *github.RepositoryRelease) (*github.RepositoryRelease, *github.Response, error)
UploadReleaseAsset(ctx context.Context, owner string, repo string, id int64, opt *github.UploadOptions, file *os.File) (*github.ReleaseAsset, *github.Response, error) UploadReleaseAsset(ctx context.Context, owner string, repo string, id int64, opt *github.UploadOptions, file *os.File) (*github.ReleaseAsset, *github.Response, error)
DeleteReleaseAsset(ctx context.Context, owner string, repo string, id int64) (*github.Response, error)
ListReleaseAssets(ctx context.Context, owner string, repo string, id int64, opt *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error)
} }
type githubRepo struct { type githubRepo struct {
@ -41,9 +43,10 @@ var (
errReleaseNotFound = errors.New(`release not found, use "--create" to create the release`) errReleaseNotFound = errors.New(`release not found, use "--create" to create the release`)
) )
func PublishGithub(ctx *cli.Context) error { func PublishGithub(c *cli.Context) error {
ctx := c.Context
token := os.Getenv("GH_TOKEN") token := os.Getenv("GH_TOKEN")
f, err := getPublishGithubFlags(ctx) f, err := getPublishGithubFlags(c)
if err != nil { if err != nil {
return err return err
} }
@ -57,18 +60,18 @@ func PublishGithub(ctx *cli.Context) error {
} }
if f.dryRun { if f.dryRun {
return runPublishGithubDryRun(f, token, ctx) return runPublishGithubDryRun(f, token, c)
} }
client := newGithubClient(ctx.Context, token) client := newGithubClient(ctx, token)
release, res, err := client.GetReleaseByTag(ctx.Context, f.repo.owner, f.repo.name, f.tag) release, res, err := client.GetReleaseByTag(ctx, f.repo.owner, f.repo.name, f.tag)
if err != nil && res.StatusCode != 404 { if err != nil && res.StatusCode != 404 {
return err return err
} }
if release == nil { if release == nil {
if f.create { if f.create {
release, _, err = client.CreateRelease(ctx.Context, f.repo.owner, f.repo.name, &github.RepositoryRelease{TagName: &f.tag}) release, _, err = client.CreateRelease(ctx, f.repo.owner, f.repo.name, &github.RepositoryRelease{TagName: &f.tag})
if err != nil { if err != nil {
return err return err
} }
@ -83,7 +86,32 @@ func PublishGithub(ctx *cli.Context) error {
return err return err
} }
asset, _, err := client.UploadReleaseAsset(ctx.Context, f.repo.owner, f.repo.name, *release.ID, &github.UploadOptions{Name: artifactName}, file) assetsPage := 1
foundAsset := false
for {
assets, resp, err := client.ListReleaseAssets(ctx, f.repo.owner, f.repo.name, *release.ID, &github.ListOptions{
Page: assetsPage,
})
if err != nil {
return err
}
for _, asset := range assets {
if asset.GetName() == artifactName {
fmt.Printf("Found existing artifact with the name '%s'. Deleting that now.\n", artifactName)
if _, err := client.DeleteReleaseAsset(ctx, f.repo.owner, f.repo.name, asset.GetID()); err != nil {
return fmt.Errorf("failed to delete already existing asset: %w", err)
}
foundAsset = true
break
}
}
if resp.NextPage <= assetsPage || foundAsset {
break
}
assetsPage = resp.NextPage
}
asset, _, err := client.UploadReleaseAsset(ctx, f.repo.owner, f.repo.name, *release.ID, &github.UploadOptions{Name: artifactName}, file)
if err != nil { if err != nil {
return err return err
} }
@ -101,21 +129,21 @@ func githubRepositoryClient(ctx context.Context, token string) githubRepositoryS
return client.Repositories return client.Repositories
} }
func getPublishGithubFlags(ctx *cli.Context) (*publishGithubFlags, error) { func getPublishGithubFlags(c *cli.Context) (*publishGithubFlags, error) {
metadata, err := config.GenerateMetadata(ctx) metadata, err := config.GenerateMetadata(c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tag := ctx.Value("tag").(string) tag := c.Value("tag").(string)
if tag == "" && metadata.GrafanaVersion != "" { if tag == "" && metadata.GrafanaVersion != "" {
tag = fmt.Sprintf("v%s", metadata.GrafanaVersion) tag = fmt.Sprintf("v%s", metadata.GrafanaVersion)
} }
fullRepo := ctx.Value("repo").(string) fullRepo := c.Value("repo").(string)
dryRun := ctx.Value("dry-run").(bool) dryRun := c.Value("dry-run").(bool)
owner := strings.Split(fullRepo, "/")[0] owner := strings.Split(fullRepo, "/")[0]
name := strings.Split(fullRepo, "/")[1] name := strings.Split(fullRepo, "/")[1]
create := ctx.Value("create").(bool) create := c.Value("create").(bool)
artifactPath := ctx.Value("path").(string) artifactPath := c.Value("path").(string)
if artifactPath == "" { if artifactPath == "" {
artifactPath = fmt.Sprintf("grafana-enterprise2-%s-amd64.img", metadata.GrafanaVersion) artifactPath = fmt.Sprintf("grafana-enterprise2-%s-amd64.img", metadata.GrafanaVersion)
fmt.Printf("path argument is not provided, resolving to default %s...\n", artifactPath) fmt.Printf("path argument is not provided, resolving to default %s...\n", artifactPath)
@ -132,10 +160,10 @@ func getPublishGithubFlags(ctx *cli.Context) (*publishGithubFlags, error) {
}, nil }, nil
} }
func runPublishGithubDryRun(f *publishGithubFlags, token string, ctx *cli.Context) error { func runPublishGithubDryRun(f *publishGithubFlags, token string, c *cli.Context) error {
client := newGithubClient(ctx.Context, token) client := newGithubClient(c.Context, token)
fmt.Println("Dry-Run: Retrieving release on repository by tag") fmt.Println("Dry-Run: Retrieving release on repository by tag")
release, res, err := client.GetReleaseByTag(ctx.Context, f.repo.owner, f.repo.name, f.tag) release, res, err := client.GetReleaseByTag(c.Context, f.repo.owner, f.repo.name, f.tag)
if err != nil && res.StatusCode != 404 { if err != nil && res.StatusCode != 404 {
fmt.Println("Dry-Run: Github communication error:\n", err) fmt.Println("Dry-Run: Github communication error:\n", err)
return nil return nil

@ -224,3 +224,15 @@ func (m *mockGithubRepositoryServiceImpl) UploadReleaseAsset(ctx context.Context
assetUrl := "testurl.com.br" assetUrl := "testurl.com.br"
return &github.ReleaseAsset{Name: &assetName, BrowserDownloadURL: &assetUrl}, &github.Response{}, m.uploadErr return &github.ReleaseAsset{Name: &assetName, BrowserDownloadURL: &assetUrl}, &github.Response{}, m.uploadErr
} }
func (m *mockGithubRepositoryServiceImpl) DeleteReleaseAsset(ctx context.Context, owner string, repo string, id int64) (*github.Response, error) {
return nil, nil
}
func (m *mockGithubRepositoryServiceImpl) ListReleaseAssets(ctx context.Context, owner string, repo string, id int64, opts *github.ListOptions) ([]*github.ReleaseAsset, *github.Response, error) {
resp := github.Response{}
resp.LastPage = 1
resp.FirstPage = 1
resp.NextPage = 0
return []*github.ReleaseAsset{}, &resp, nil
}

@ -84,7 +84,7 @@ func GenerateMetadata(c *cli.Context) (Metadata, error) {
CurrentCommit: currentCommit, CurrentCommit: currentCommit,
} }
fmt.Printf("building Grafana version: %s, release mode: %+v", metadata.GrafanaVersion, metadata.ReleaseMode) fmt.Printf("building Grafana version: %s, release mode: %+v\n", metadata.GrafanaVersion, metadata.ReleaseMode)
return metadata, nil return metadata, nil
} }

Loading…
Cancel
Save