diff --git a/internal/client/github.go b/internal/client/github.go index 02bd41bf87e..5bd3e64b008 100644 --- a/internal/client/github.go +++ b/internal/client/github.go @@ -207,6 +207,12 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (string, return "", err } + if ctx.Config.Release.Draft && ctx.Config.Release.ReplaceExistingDraft { + if err := c.deleteExistedDraftRelease(ctx, title); err != nil { + return "", err + } + } + // Truncate the release notes if it's too long (github doesn't allow more than 125000 characters) body = truncateReleaseBody(body) @@ -357,3 +363,34 @@ func overrideGitHubClientAPI(ctx *context.Context, client *github.Client) error return nil } + +func (c *githubClient) deleteExistedDraftRelease(ctx *context.Context, name string) error { + opt := github.ListOptions{PerPage: 50} + for { + releases, resp, err := c.client.Repositories.ListReleases( + ctx, + ctx.Config.Release.GitHub.Owner, + ctx.Config.Release.GitHub.Name, + &opt, + ) + if err != nil { + return fmt.Errorf("could not delete existing drafts: %w", err) + } + for _, r := range releases { + if r.GetDraft() && r.GetName() == name { + if _, err := c.client.Repositories.DeleteRelease( + ctx, + ctx.Config.Release.GitHub.Owner, + ctx.Config.Release.GitHub.Name, + r.GetID(), + ); err != nil { + return fmt.Errorf("could not delete previous draft release: %w", err) + } + } + } + if resp.NextPage == 0 { + return nil + } + opt.Page = resp.NextPage + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 826958b12fe..69aa20ba911 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -500,6 +500,7 @@ type Release struct { GitLab Repo `yaml:"gitlab,omitempty" json:"gitlab,omitempty"` Gitea Repo `yaml:"gitea,omitempty" json:"gitea,omitempty"` Draft bool `yaml:"draft,omitempty" json:"draft,omitempty"` + ReplaceExistingDraft bool `yaml:"replace_existing_draft,omitempty" json:"replace_existing_draft,omitempty"` Disable bool `yaml:"disable,omitempty" json:"disable,omitempty"` SkipUpload bool `yaml:"skip_upload,omitempty" json:"skip_upload,omitempty"` Prerelease string `yaml:"prerelease,omitempty" json:"prerelease,omitempty"` diff --git a/www/docs/customization/release.md b/www/docs/customization/release.md index 0019d8c9bbe..b0a17f847c4 100644 --- a/www/docs/customization/release.md +++ b/www/docs/customization/release.md @@ -24,9 +24,16 @@ release: - bar # If set to true, will not auto-publish the release. + # Available only for GitHub and Gitea. # Default is false. draft: true + # 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. + # Default is false. + replace_existing_draft: true + # If set, will create a release discussion in the category specified. # # Warning: do not use categories in the 'Announcement' format. @@ -97,7 +104,7 @@ release: ``` !!! tip - [Learn how to setup an API token, GitHub Enterprise and etc](/scm/github/). + [Learn how to set up an API token, GitHub Enterprise, etc](/scm/github/). ## GitLab @@ -153,7 +160,7 @@ release: ``` !!! tip - [Learn how to setup an API token, self-hosted GitLab and etc](/scm/gitlab/). + [Learn how to set up an API token, self-hosted GitLab, etc](/scm/gitlab/). !!! tip If you use GitLab subgroups, you need to specify it in the `owner` field, e.g. `mygroup/mysubgroup`. @@ -220,7 +227,7 @@ ALLOWED_TYPES = application/gzip|application/x-gzip|application/x-gtar|applicati ``` !!! tip - [Learn how to setup an API token](/scm/gitea/). + [Learn how to set up an API token](/scm/gitea/). !!! tip Learn more about the [name template engine](/customization/templates/).