mirror of
https://github.com/goreleaser/goreleaser.git
synced 2026-06-19 23:24:39 +02:00
feat(pipe/release): Mark GitHub releases as non-draft only after all artifacts are uploaded. (#4626)
Previously end-users would see missing artifacts if trying to use latest version while artifacts are being uploaded. This currently applies only to GitHub releases. GitLab does not support drafts, and I don't dare to make the change for Gitea since I don't use it (and can't test easily). --------- Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
co-authored by
Carlos Alexandro Becker
parent
42d2db2021
commit
ef90821ee7
@@ -52,7 +52,9 @@ func (r Repo) String() string {
|
|||||||
// Client interface.
|
// Client interface.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
CloseMilestone(ctx *context.Context, repo Repo, title string) (err error)
|
CloseMilestone(ctx *context.Context, repo Repo, title string) (err error)
|
||||||
|
// Creates a release. It's marked as draft if possible (should call PublishRelease to finish publishing).
|
||||||
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
|
CreateRelease(ctx *context.Context, body string) (releaseID string, err error)
|
||||||
|
PublishRelease(ctx *context.Context, releaseID string) (err error)
|
||||||
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
|
Upload(ctx *context.Context, releaseID string, artifact *artifact.Artifact, file *os.File) (err error)
|
||||||
Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error)
|
Changelog(ctx *context.Context, repo Repo, prev, current string) (string, error)
|
||||||
ReleaseURLTemplater
|
ReleaseURLTemplater
|
||||||
|
|||||||
@@ -276,6 +276,11 @@ func (c *giteaClient) CreateRelease(ctx *context.Context, body string) (string,
|
|||||||
return strconv.FormatInt(release.ID, 10), nil
|
return strconv.FormatInt(release.ID, 10), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *giteaClient) PublishRelease(_ *context.Context, _ string /* releaseID */) (err error) {
|
||||||
|
// TODO: Create release as draft while uploading artifacts and only publish it here.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *giteaClient) ReleaseURLTemplate(ctx *context.Context) (string, error) {
|
func (c *giteaClient) ReleaseURLTemplate(ctx *context.Context) (string, error) {
|
||||||
downloadURL, err := tmpl.New(ctx).Apply(ctx.Config.GiteaURLs.Download)
|
downloadURL, err := tmpl.New(ctx).Apply(ctx.Config.GiteaURLs.Download)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -357,7 +357,9 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (string,
|
|||||||
Name: github.String(title),
|
Name: github.String(title),
|
||||||
TagName: github.String(ctx.Git.CurrentTag),
|
TagName: github.String(ctx.Git.CurrentTag),
|
||||||
Body: github.String(body),
|
Body: github.String(body),
|
||||||
Draft: github.Bool(ctx.Config.Release.Draft),
|
// Always start with a draft release while uploading artifacts.
|
||||||
|
// PublishRelease will undraft it.
|
||||||
|
Draft: github.Bool(true),
|
||||||
Prerelease: github.Bool(ctx.PreRelease),
|
Prerelease: github.Bool(ctx.PreRelease),
|
||||||
MakeLatest: github.String("true"),
|
MakeLatest: github.String("true"),
|
||||||
}
|
}
|
||||||
@@ -388,6 +390,19 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (string,
|
|||||||
return strconv.FormatInt(release.GetID(), 10), nil
|
return strconv.FormatInt(release.GetID(), 10), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *githubClient) PublishRelease(ctx *context.Context, releaseID string) (err error) {
|
||||||
|
releaseIDInt, err := strconv.ParseInt(releaseID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("non-numeric release ID %q: %w", releaseID, err)
|
||||||
|
}
|
||||||
|
if _, err := c.updateRelease(ctx, releaseIDInt, &github.RepositoryRelease{
|
||||||
|
Draft: github.Bool(ctx.Config.Release.Draft),
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("could not update existing release: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *githubClient) createOrUpdateRelease(ctx *context.Context, data *github.RepositoryRelease, body string) (*github.RepositoryRelease, error) {
|
func (c *githubClient) createOrUpdateRelease(ctx *context.Context, data *github.RepositoryRelease, body string) (*github.RepositoryRelease, error) {
|
||||||
c.checkRateLimit(ctx)
|
c.checkRateLimit(ctx)
|
||||||
release, _, err := c.client.Repositories.GetReleaseByTag(
|
release, _, err := c.client.Repositories.GetReleaseByTag(
|
||||||
|
|||||||
@@ -348,6 +348,11 @@ func (c *gitlabClient) CreateRelease(ctx *context.Context, body string) (release
|
|||||||
return tagName, err // gitlab references a tag in a repo by its name
|
return tagName, err // gitlab references a tag in a repo by its name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *gitlabClient) PublishRelease(_ *context.Context, _ string /* releaseID */) (err error) {
|
||||||
|
// GitLab doesn't support draft releases. So a created release is already published.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *gitlabClient) ReleaseURLTemplate(ctx *context.Context) (string, error) {
|
func (c *gitlabClient) ReleaseURLTemplate(ctx *context.Context) (string, error) {
|
||||||
var urlTemplate string
|
var urlTemplate string
|
||||||
gitlabName, err := tmpl.New(ctx).Apply(ctx.Config.Release.GitLab.Name)
|
gitlabName, err := tmpl.New(ctx).Apply(ctx.Config.Release.GitLab.Name)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type Mock struct {
|
|||||||
FailToUpload bool
|
FailToUpload bool
|
||||||
CreatedRelease bool
|
CreatedRelease bool
|
||||||
UploadedFile bool
|
UploadedFile bool
|
||||||
|
ReleasePublished bool
|
||||||
UploadedFileNames []string
|
UploadedFileNames []string
|
||||||
UploadedFilePaths map[string]string
|
UploadedFilePaths map[string]string
|
||||||
FailFirstUpload bool
|
FailFirstUpload bool
|
||||||
@@ -81,6 +82,11 @@ func (c *Mock) CreateRelease(_ *context.Context, _ string) (string, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Mock) PublishRelease(_ *context.Context, _ string /* releaseID */) (err error) {
|
||||||
|
c.ReleasePublished = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Mock) ReleaseURLTemplate(_ *context.Context) (string, error) {
|
func (c *Mock) ReleaseURLTemplate(_ *context.Context) (string, error) {
|
||||||
return "https://dummyhost/download/{{ .Tag }}/{{ .ArtifactName }}", nil
|
return "https://dummyhost/download/{{ .Tag }}/{{ .ArtifactName }}", nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,7 +171,11 @@ func doPublish(ctx *context.Context, client client.Client) error {
|
|||||||
return upload(ctx, client, releaseID, artifact)
|
return upload(ctx, client, releaseID, artifact)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return g.Wait()
|
if err := g.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.PublishRelease(ctx, releaseID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func upload(ctx *context.Context, cli client.Client, releaseID string, artifact *artifact.Artifact) error {
|
func upload(ctx *context.Context, cli client.Client, releaseID string, artifact *artifact.Artifact) error {
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ func TestRunPipeWithoutIDsThenDoesNotFilter(t *testing.T) {
|
|||||||
require.NoError(t, doPublish(ctx, client))
|
require.NoError(t, doPublish(ctx, client))
|
||||||
require.True(t, client.CreatedRelease)
|
require.True(t, client.CreatedRelease)
|
||||||
require.True(t, client.UploadedFile)
|
require.True(t, client.UploadedFile)
|
||||||
|
require.True(t, client.ReleasePublished)
|
||||||
require.Contains(t, client.UploadedFileNames, "source.tar.gz")
|
require.Contains(t, client.UploadedFileNames, "source.tar.gz")
|
||||||
require.Contains(t, client.UploadedFileNames, "bin.deb")
|
require.Contains(t, client.UploadedFileNames, "bin.deb")
|
||||||
require.Contains(t, client.UploadedFileNames, "bin.tar.gz")
|
require.Contains(t, client.UploadedFileNames, "bin.tar.gz")
|
||||||
@@ -192,6 +193,7 @@ func TestRunPipeWithIDsThenFilters(t *testing.T) {
|
|||||||
require.NoError(t, doPublish(ctx, client))
|
require.NoError(t, doPublish(ctx, client))
|
||||||
require.True(t, client.CreatedRelease)
|
require.True(t, client.CreatedRelease)
|
||||||
require.True(t, client.UploadedFile)
|
require.True(t, client.UploadedFile)
|
||||||
|
require.True(t, client.ReleasePublished)
|
||||||
require.Contains(t, client.UploadedFileNames, "bin.deb")
|
require.Contains(t, client.UploadedFileNames, "bin.deb")
|
||||||
require.Contains(t, client.UploadedFileNames, "bin.tar.gz")
|
require.Contains(t, client.UploadedFileNames, "bin.tar.gz")
|
||||||
require.Contains(t, client.UploadedFileNames, "f1")
|
require.Contains(t, client.UploadedFileNames, "f1")
|
||||||
@@ -215,6 +217,7 @@ func TestRunPipeReleaseCreationFailed(t *testing.T) {
|
|||||||
require.Error(t, doPublish(ctx, client))
|
require.Error(t, doPublish(ctx, client))
|
||||||
require.False(t, client.CreatedRelease)
|
require.False(t, client.CreatedRelease)
|
||||||
require.False(t, client.UploadedFile)
|
require.False(t, client.UploadedFile)
|
||||||
|
require.False(t, client.ReleasePublished)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunPipeWithFileThatDontExist(t *testing.T) {
|
func TestRunPipeWithFileThatDontExist(t *testing.T) {
|
||||||
@@ -262,6 +265,7 @@ func TestRunPipeUploadFailure(t *testing.T) {
|
|||||||
require.EqualError(t, doPublish(ctx, client), "failed to upload bin.tar.gz after 1 tries: upload failed")
|
require.EqualError(t, doPublish(ctx, client), "failed to upload bin.tar.gz after 1 tries: upload failed")
|
||||||
require.True(t, client.CreatedRelease)
|
require.True(t, client.CreatedRelease)
|
||||||
require.False(t, client.UploadedFile)
|
require.False(t, client.UploadedFile)
|
||||||
|
require.False(t, client.ReleasePublished)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunPipeExtraFileNotFound(t *testing.T) {
|
func TestRunPipeExtraFileNotFound(t *testing.T) {
|
||||||
@@ -330,6 +334,7 @@ func TestRunPipeUploadRetry(t *testing.T) {
|
|||||||
require.NoError(t, doPublish(ctx, client))
|
require.NoError(t, doPublish(ctx, client))
|
||||||
require.True(t, client.CreatedRelease)
|
require.True(t, client.CreatedRelease)
|
||||||
require.True(t, client.UploadedFile)
|
require.True(t, client.UploadedFile)
|
||||||
|
require.True(t, client.ReleasePublished)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefault(t *testing.T) {
|
func TestDefault(t *testing.T) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ release:
|
|||||||
- bar
|
- bar
|
||||||
|
|
||||||
# If set to true, will not auto-publish the release.
|
# If set to true, will not auto-publish the release.
|
||||||
|
# Note: all GitHub releases start as drafts while artifacts are uploaded.
|
||||||
# Available only for GitHub and Gitea.
|
# Available only for GitHub and Gitea.
|
||||||
draft: true
|
draft: true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user