1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-05 13:15:26 +02:00

feat: allow to delete existing artifacts in the release (#4711)

closes #4692
This commit is contained in:
Carlos Alexandro Becker 2024-03-19 23:25:42 -03:00 committed by GitHub
parent 1007d766a5
commit 6e0f426339
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 81 additions and 9 deletions

View File

@ -68,7 +68,7 @@ func newGitHub(ctx *context.Context, token string) (*githubClient, error) {
}
func (c *githubClient) checkRateLimit(ctx *context.Context) {
limits, _, err := c.client.RateLimits(ctx)
limits, _, err := c.client.RateLimit.Get(ctx)
if err != nil {
log.Warn("could not check rate limits, hoping for the best...")
return
@ -463,6 +463,50 @@ func (c *githubClient) ReleaseURLTemplate(ctx *context.Context) (string, error)
), nil
}
func (c *githubClient) deleteReleaseArtifact(ctx *context.Context, releaseID int64, name string, page int) error {
c.checkRateLimit(ctx)
log.WithField("name", name).Info("delete pre-existing asset from the release")
assets, resp, err := c.client.Repositories.ListReleaseAssets(
ctx,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
releaseID,
&github.ListOptions{
PerPage: 100,
Page: page,
},
)
if err != nil {
githubErrLogger(resp, err).
WithField("release-id", releaseID).
Warn("could not list release assets")
return err
}
for _, asset := range assets {
if asset.GetName() != name {
continue
}
resp, err := c.client.Repositories.DeleteReleaseAsset(
ctx,
ctx.Config.Release.GitHub.Owner,
ctx.Config.Release.GitHub.Name,
asset.GetID(),
)
if err != nil {
githubErrLogger(resp, err).
WithField("release-id", releaseID).
WithField("id", asset.GetID()).
WithField("name", name).
Warn("could not delete asset")
}
return err
}
if next := resp.NextPage; next > 0 {
return c.deleteReleaseArtifact(ctx, releaseID, name, next)
}
return nil
}
func (c *githubClient) Upload(
ctx *context.Context,
releaseID string,
@ -485,21 +529,26 @@ func (c *githubClient) Upload(
file,
)
if err != nil {
requestID := ""
if resp != nil {
requestID = resp.Header.Get("X-GitHub-Request-Id")
}
log.WithField("name", artifact.Name).
githubErrLogger(resp, err).
WithField("name", artifact.Name).
WithField("release-id", releaseID).
WithField("request-id", requestID).
Warn("upload failed")
}
if err == nil {
return nil
}
// this status means the asset already exists
if resp != nil && resp.StatusCode == http.StatusUnprocessableEntity {
if !ctx.Config.Release.ReplaceExistingArtifacts {
return err
}
// if the user allowed to delete assets, we delete it, and return a
// retriable error.
if err := c.deleteReleaseArtifact(ctx, githubReleaseID, artifact.Name, 1); err != nil {
return err
}
return RetriableError{err}
}
return RetriableError{err}
}
@ -606,3 +655,11 @@ func (c *githubClient) deleteExistingDraftRelease(ctx *context.Context, name str
opt.Page = resp.NextPage
}
}
func githubErrLogger(resp *github.Response, err error) *log.Entry {
requestID := ""
if resp != nil {
requestID = resp.Header.Get("X-GitHub-Request-Id")
}
return log.WithField("request-id", requestID).WithError(err)
}

View File

@ -752,6 +752,7 @@ type Release struct {
Footer string `yaml:"footer,omitempty" json:"footer,omitempty"`
ReleaseNotesMode ReleaseNotesMode `yaml:"mode,omitempty" json:"mode,omitempty" jsonschema:"enum=keep-existing,enum=append,enum=prepend,enum=replace,default=keep-existing"`
ReplaceExistingArtifacts bool `yaml:"replace_existing_artifacts,omitempty" json:"replace_existing_artifacts,omitempty"`
}
// Milestone config used for VCS milestone.

View File

@ -32,12 +32,26 @@ release:
# Whether to remove existing draft releases with the same name before creating
# a new one.
#
# Only effective if `draft` is set to true.
# Available only for GitHub.
#
# Since: v1.11
replace_existing_draft: true
# Whether to remove an artifact that already exists.
#
# Available only for GitHub.
# This might be a bit expensive (rate-limiting speaking), so it is only done
# when the upload of an artifact fails with a 422 (which means it already
# exists in the release).
# We then grab the list of artifacts from the release, and delete the file
# that matches the one we're trying to upload.
# GoReleaser will then retry its upload.
#
# Since: v1.25
replace_existing_artifacts: true
# Useful if you want to delay the creation of the tag in the remote.
# You can create the tag locally, but not push it, and run GoReleaser.
# It'll then set the `target_commitish` portion of the GitHub release to the