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:
parent
1007d766a5
commit
6e0f426339
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user