mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-02-01 13:07:49 +02:00
feat: Checksums as a template field (#4064)
this would allow to add the checksums to the body of the release contents, for example. refs https://github.com/orgs/goreleaser/discussions/4063 --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
d0ba64e70d
commit
09411ea60a
@ -2,8 +2,10 @@ package release
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
@ -15,7 +17,21 @@ const bodyTemplateText = `{{ with .Header }}{{ . }}{{ "\n" }}{{ end }}
|
||||
|
||||
func describeBody(ctx *context.Context) (bytes.Buffer, error) {
|
||||
var out bytes.Buffer
|
||||
t := tmpl.New(ctx)
|
||||
var checksum string
|
||||
if l := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List(); len(l) > 0 {
|
||||
if err := l[0].Refresh(); err != nil {
|
||||
return out, err
|
||||
}
|
||||
bts, err := os.ReadFile(l[0].Path)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
checksum = string(bts)
|
||||
}
|
||||
|
||||
t := tmpl.New(ctx).WithExtraFields(tmpl.Fields{
|
||||
"Checksums": checksum,
|
||||
})
|
||||
|
||||
header, err := t.Apply(ctx.Config.Release.Header)
|
||||
if err != nil {
|
||||
|
@ -1,8 +1,11 @@
|
||||
package release
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/golden"
|
||||
"github.com/goreleaser/goreleaser/internal/testctx"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
@ -36,12 +39,39 @@ func TestDescribeBodyWithHeaderAndFooter(t *testing.T) {
|
||||
config.Project{
|
||||
Release: config.Release{
|
||||
Header: "## Yada yada yada\nsomething\n",
|
||||
Footer: "\n---\n\nGet images at docker.io/foo/bar:{{.Tag}}\n\n---\n\nGet GoReleaser Pro at https://goreleaser.com/pro",
|
||||
Footer: `
|
||||
---
|
||||
|
||||
Get images at docker.io/foo/bar:{{.Tag}}
|
||||
|
||||
---
|
||||
|
||||
Get GoReleaser Pro at https://goreleaser.com/pro
|
||||
|
||||
---
|
||||
|
||||
## Checksums
|
||||
|
||||
` + "```\n{{ .Checksums }}\n```" + `
|
||||
`,
|
||||
},
|
||||
},
|
||||
testctx.WithCurrentTag("v1.0"),
|
||||
func(ctx *context.Context) { ctx.ReleaseNotes = changelog },
|
||||
)
|
||||
|
||||
checksumPath := filepath.Join(t.TempDir(), "checksums.txt")
|
||||
checksumContent := "f674623cf1edd0f753e620688cedee4e7c0e837ac1e53c0cbbce132ffe35fd52 foo.zip"
|
||||
ctx.Artifacts.Add(&artifact.Artifact{
|
||||
Name: "checksums.txt",
|
||||
Path: checksumPath,
|
||||
Type: artifact.Checksum,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraRefresh: func() error {
|
||||
return os.WriteFile(checksumPath, []byte(checksumContent), 0o644)
|
||||
},
|
||||
},
|
||||
})
|
||||
out, err := describeBody(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -11,3 +11,12 @@ Get images at docker.io/foo/bar:v1.0
|
||||
---
|
||||
|
||||
Get GoReleaser Pro at https://goreleaser.com/pro
|
||||
|
||||
---
|
||||
|
||||
## Checksums
|
||||
|
||||
```
|
||||
f674623cf1edd0f753e620688cedee4e7c0e837ac1e53c0cbbce132ffe35fd52 foo.zip
|
||||
```
|
||||
|
||||
|
@ -6,64 +6,69 @@ Those fields are often suffixed with `_template`, but sometimes they may not
|
||||
be. The documentation of each section should be explicit about which fields
|
||||
support templating.
|
||||
|
||||
<!-- to format the tables, use: https://tabletomarkdown.com/format-markdown-table/ -->
|
||||
|
||||
## Common Fields
|
||||
|
||||
On fields that support templating, these fields are always available:
|
||||
In fields that support templates, these fields are always available:
|
||||
|
||||
Key |Description
|
||||
----------------------|--------------------------------------------------------------------------------------------------------------------
|
||||
`.ProjectName` |the project name
|
||||
`.Version` |the version being released[^version-prefix]
|
||||
`.Branch` |the current git branch
|
||||
`.PrefixedTag` |the current git tag prefixed with the monorepo config tag prefix (if any)
|
||||
`.Tag` |the current git tag
|
||||
`.PrefixedPreviousTag`|the previous git tag prefixed with the monorepo config tag prefix (if any)
|
||||
`.PreviousTag` |the previous git tag, or empty if no previous tags
|
||||
`.ShortCommit` |the git commit short hash
|
||||
`.FullCommit` |the git commit full hash
|
||||
`.Commit` |the git commit hash (deprecated)
|
||||
`.CommitDate` |the UTC commit date in RFC 3339 format
|
||||
`.CommitTimestamp` |the UTC commit date in Unix format
|
||||
`.GitURL` |the git remote url
|
||||
`.IsGitDirty` |whether or not current git state is dirty. Since v1.19.
|
||||
`.Major` |the major part of the version[^tag-is-semver]
|
||||
`.Minor` |the minor part of the version[^tag-is-semver]
|
||||
`.Patch` |the patch part of the version[^tag-is-semver]
|
||||
`.Prerelease` |the prerelease part of the version, e.g. `beta`[^tag-is-semver]
|
||||
`.RawVersion` |composed of `{Major}.{Minor}.{Patch}` [^tag-is-semver]
|
||||
`.ReleaseNotes` |the generated release notes, available after the changelog step has been executed
|
||||
`.IsDraft` |`true` if `release.draft` is set in the configuration, `false` otherwise. Since v1.17.
|
||||
`.IsSnapshot` |`true` if `--snapshot` is set, `false` otherwise
|
||||
`.IsNightly` |`true` if `--nightly` is set, `false` otherwise
|
||||
`.Env` |a map with system's environment variables
|
||||
`.Date` |current UTC date in RFC 3339 format
|
||||
`.Now` |current UTC date as `time.Time` struct, allows all `time.Time` functions (e.g. `{{ .Now.Format "2006" }}`) . Since v1.17.
|
||||
`.Timestamp` |current UTC time in Unix format
|
||||
`.ModulePath` |the go module path, as reported by `go list -m`
|
||||
`incpatch "v1.2.4"` |increments the patch of the given version[^panic-if-not-semver]
|
||||
`incminor "v1.2.4"` |increments the minor of the given version[^panic-if-not-semver]
|
||||
`incmajor "v1.2.4"` |increments the major of the given version[^panic-if-not-semver]
|
||||
`.ReleaseURL` |the current release download url[^scm-release-url]
|
||||
`.Summary` |the git summary, e.g. `v1.0.0-10-g34f56g3`[^git-summary]
|
||||
`.PrefixedSummary` |the git summary prefixed with the monorepo config tag prefix (if any)
|
||||
`.TagSubject` |the annotated tag message subject, or the message subject of the commit it points out[^git-tag-subject]. Since v1.2.
|
||||
`.TagContents` |the annotated tag message, or the message of the commit it points out[^git-tag-body]. Since v1.2.
|
||||
`.TagBody` |the annotated tag message's body, or the message's body of the commit it points out[^git-tag-body]. Since v1.2.
|
||||
`.Runtime.Goos` |equivalent to `runtime.GOOS`. Since v1.5.
|
||||
`.Runtime.Goarch` |equivalent to `runtime.GOARCH`. Since v1.5.
|
||||
`.Artifacts` |the current artifact list. See table bellow for fields. Since v1.16-pro.
|
||||
| Key | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `.ProjectName` | the project name |
|
||||
| `.Version` | the version being released[^version-prefix] |
|
||||
| `.Branch` | the current git branch |
|
||||
| `.PrefixedTag` | the current git tag prefixed with the monorepo config tag prefix (if any) |
|
||||
| `.Tag` | the current git tag |
|
||||
| `.PrefixedPreviousTag` | the previous git tag prefixed with the monorepo config tag prefix (if any) |
|
||||
| `.PreviousTag` | the previous git tag, or empty if no previous tags |
|
||||
| `.ShortCommit` | the git commit short hash |
|
||||
| `.FullCommit` | the git commit full hash |
|
||||
| `.Commit` | the git commit hash (deprecated) |
|
||||
| `.CommitDate` | the UTC commit date in RFC 3339 format |
|
||||
| `.CommitTimestamp` | the UTC commit date in Unix format |
|
||||
| `.GitURL` | the git remote url |
|
||||
| `.IsGitDirty` | whether or not current git state is dirty. Since v1.19. |
|
||||
| `.Major` | the major part of the version[^tag-is-semver] |
|
||||
| `.Minor` | the minor part of the version[^tag-is-semver] |
|
||||
| `.Patch` | the patch part of the version[^tag-is-semver] |
|
||||
| `.Prerelease` | the prerelease part of the version, e.g. `beta`[^tag-is-semver] |
|
||||
| `.RawVersion` | composed of `{Major}.{Minor}.{Patch}` [^tag-is-semver] |
|
||||
| `.ReleaseNotes` | the generated release notes, available after the changelog step has been executed |
|
||||
| `.IsDraft` | `true` if `release.draft` is set in the configuration, `false` otherwise. Since v1.17. |
|
||||
| `.IsSnapshot` | `true` if `--snapshot` is set, `false` otherwise |
|
||||
| `.IsNightly` | `true` if `--nightly` is set, `false` otherwise |
|
||||
| `.Env` | a map with system's environment variables |
|
||||
| `.Date` | current UTC date in RFC 3339 format |
|
||||
| `.Now` | current UTC date as `time.Time` struct, allows all `time.Time` functions (e.g. `{{ .Now.Format "2006" }}`) . Since v1.17. |
|
||||
| `.Timestamp` | current UTC time in Unix format |
|
||||
| `.ModulePath` | the go module path, as reported by `go list -m` |
|
||||
| `incpatch "v1.2.4"` | increments the patch of the given version[^panic-if-not-semver] |
|
||||
| `incminor "v1.2.4"` | increments the minor of the given version[^panic-if-not-semver] |
|
||||
| `incmajor "v1.2.4"` | increments the major of the given version[^panic-if-not-semver] |
|
||||
| `.ReleaseURL` | the current release download url[^scm-release-url] |
|
||||
| `.Summary` | the git summary, e.g. `v1.0.0-10-g34f56g3`[^git-summary] |
|
||||
| `.PrefixedSummary` | the git summary prefixed with the monorepo config tag prefix (if any) |
|
||||
| `.TagSubject` | the annotated tag message subject, or the message subject of the commit it points out[^git-tag-subject]. Since v1.2. |
|
||||
| `.TagContents` | the annotated tag message, or the message of the commit it points out[^git-tag-body]. Since v1.2. |
|
||||
| `.TagBody` | the annotated tag message's body, or the message's body of the commit it points out[^git-tag-body]. Since v1.2. |
|
||||
| `.Runtime.Goos` | equivalent to `runtime.GOOS`. Since v1.5. |
|
||||
| `.Runtime.Goarch` | equivalent to `runtime.GOARCH`. Since v1.5. |
|
||||
| `.Artifacts` | the current artifact list. See table bellow for fields. Since v1.16-pro. |
|
||||
| `.Checksums` | the current checksum file contents. Only available in the release body. Since v1.19. |
|
||||
|
||||
[^version-prefix]:
|
||||
The `v` prefix is stripped, and it might be changed in
|
||||
`snapshot` and `nightly` builds.
|
||||
|
||||
[^version-prefix]: The `v` prefix is stripped, and it might be changed in
|
||||
`snapshot` and `nightly` builds.
|
||||
[^tag-is-semver]: Assuming `Tag` is a valid a SemVer, otherwise empty/zeroed.
|
||||
[^panic-if-not-semver]: Will panic if not a semantic version.
|
||||
[^scm-release-url]: Composed of the current SCM's download URL and current tag.
|
||||
For instance, on GitHub, it'll be
|
||||
`https://github.com/{owner}/{repo}/releases/tag/{tag}`.
|
||||
[^git-summary]: It is generated by `git describe --dirty --always --tags`, the
|
||||
format will be `{Tag}-$N-{CommitSHA}`
|
||||
[^scm-release-url]:
|
||||
Composed of the current SCM's download URL and current tag.
|
||||
For instance, on GitHub, it'll be
|
||||
`https://github.com/{owner}/{repo}/releases/tag/{tag}`.
|
||||
|
||||
[^git-summary]:
|
||||
It is generated by `git describe --dirty --always --tags`, the
|
||||
format will be `{Tag}-$N-{CommitSHA}`
|
||||
|
||||
[^git-tag-subject]: As reported by `git tag -l --format='%(contents:subject)'`
|
||||
[^git-tag-body]: As reported by `git tag -l --format='%(contents)'`
|
||||
|
||||
@ -83,8 +88,8 @@ You should be able to use all its fields on each item:
|
||||
- `.Type`
|
||||
- `.Extra`
|
||||
|
||||
|
||||
!!! success "GoReleaser Pro"
|
||||
|
||||
The `.Artifacts` template variable is [GoReleaser Pro feature](/pro/).
|
||||
|
||||
## Single-artifact extra fields
|
||||
@ -92,17 +97,17 @@ You should be able to use all its fields on each item:
|
||||
On fields that are related to a single artifact (e.g., the binary name), you
|
||||
may have some extra fields:
|
||||
|
||||
Key |Description
|
||||
---------------|--------------------------------------------
|
||||
`.Os` |`GOOS`[^archive-replacementes]
|
||||
`.Arch` |`GOARCH`[^archive-replacementes]
|
||||
`.Arm` |`GOARM`[^archive-replacementes]
|
||||
`.Mips` |`GOMIPS`[^archive-replacementes]
|
||||
`.Amd64` |`GOAMD64`[^archive-replacementes]
|
||||
`.Binary` |binary name
|
||||
`.ArtifactName`|archive name
|
||||
`.ArtifactPath`|absolute path to artifact
|
||||
`.ArtifactExt` |binary extension (e.g. `.exe`). Since v1.11.
|
||||
| Key | Description |
|
||||
| --------------- | -------------------------------------------- |
|
||||
| `.Os` | `GOOS`[^archive-replacementes] |
|
||||
| `.Arch` | `GOARCH`[^archive-replacementes] |
|
||||
| `.Arm` | `GOARM`[^archive-replacementes] |
|
||||
| `.Mips` | `GOMIPS`[^archive-replacementes] |
|
||||
| `.Amd64` | `GOAMD64`[^archive-replacementes] |
|
||||
| `.Binary` | binary name |
|
||||
| `.ArtifactName` | archive name |
|
||||
| `.ArtifactPath` | absolute path to artifact |
|
||||
| `.ArtifactExt` | binary extension (e.g. `.exe`). Since v1.11. |
|
||||
|
||||
[^archive-replacementes]: Might have been replaced by `archives.replacements`.
|
||||
|
||||
@ -110,40 +115,41 @@ Key |Description
|
||||
|
||||
On the nFPM name template field, you can use those extra fields as well:
|
||||
|
||||
Key |Description
|
||||
-----------------------|--------------------------------------------------------------
|
||||
`.Release` |release from the nfpm config
|
||||
`.Epoch` |epoch from the nfpm config
|
||||
`.PackageName` |package the name. Same as `ProjectName` if not overridden.
|
||||
`.ConventionalFileName` |conventional package file name as provided by nFPM.[^arm-names]
|
||||
`.ConventionalExtension`|conventional package extension as provided by nFPM. Since v1.16.
|
||||
| Key | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------- |
|
||||
| `.Release` | release from the nfpm config |
|
||||
| `.Epoch` | epoch from the nfpm config |
|
||||
| `.PackageName` | package the name. Same as `ProjectName` if not overridden. |
|
||||
| `.ConventionalFileName` | conventional package file name as provided by nFPM.[^arm-names] |
|
||||
| `.ConventionalExtension` | conventional package extension as provided by nFPM. Since v1.16. |
|
||||
|
||||
[^arm-names]: Please beware: some OSs might have the same names for different
|
||||
ARM versions, for example, for Debian both ARMv6 and ARMv7 are called `armhf`.
|
||||
Make sure that's not your case otherwise you might end up with colliding
|
||||
names. It also does not handle multiple GOAMD64 versions.
|
||||
[^arm-names]:
|
||||
Please beware: some OSs might have the same names for different
|
||||
ARM versions, for example, for Debian both ARMv6 and ARMv7 are called `armhf`.
|
||||
Make sure that's not your case otherwise you might end up with colliding
|
||||
names. It also does not handle multiple GOAMD64 versions.
|
||||
|
||||
## Functions
|
||||
|
||||
On all fields, you have these available functions:
|
||||
|
||||
Usage |Description
|
||||
------------------------------|------------------------------------------------------------------------------------------------------------------------------
|
||||
`replace "v1.2" "v" ""` |replaces all matches. See [ReplaceAll](https://golang.org/pkg/strings/#ReplaceAll).
|
||||
`split "1.2" "."` |split string at separator. See [Split](https://golang.org/pkg/strings/#Split). Since v1.11.
|
||||
`time "01/02/2006"` |current UTC time in the specified format (this is not deterministic, a new time for every call).
|
||||
`tolower "V1.2"` |makes input string lowercase. See [ToLower](https://golang.org/pkg/strings/#ToLower).
|
||||
`toupper "v1.2"` |makes input string uppercase. See [ToUpper](https://golang.org/pkg/strings/#ToUpper).
|
||||
`trim " v1.2 "` |removes all leading and trailing white space. See [TrimSpace](https://golang.org/pkg/strings/#TrimSpace).
|
||||
`trimprefix "v1.2" "v"` |removes provided leading prefix string, if present. See [TrimPrefix](https://golang.org/pkg/strings/#TrimPrefix).
|
||||
`trimsuffix "1.2v" "v"` |removes provided trailing suffix string, if present. See [TrimSuffix](https://pkg.go.dev/strings#TrimSuffix).
|
||||
`dir .Path` |returns all but the last element of path, typically the path's directory. See [Dir](https://golang.org/pkg/path/filepath/#Dir).
|
||||
`base .Path` |returns the last element of path. See [Base](https://golang.org/pkg/path/filepath/#Base). Since v1.16.
|
||||
`abs .ArtifactPath` |returns an absolute representation of path. See [Abs](https://golang.org/pkg/path/filepath/#Abs).
|
||||
`filter "text" "regex"` |keeps only the lines matching the given regex, analogous to `grep -E`. Since v1.6.
|
||||
`reverseFilter "text" "regex"`|keeps only the lines **not** matching the given regex, analogous to `grep -vE`. Since v1.6.
|
||||
`title "foo"` |"titlenize" the string using english as language. See [Title](https://pkg.go.dev/golang.org/x/text/cases#Title). Since v1.14.
|
||||
`mdv2escape "foo"` |escape characteres according to MarkdownV2, especially useful in the Telegram integration. Since v1.19.
|
||||
| Usage | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `replace "v1.2" "v" ""` | replaces all matches. See [ReplaceAll](https://golang.org/pkg/strings/#ReplaceAll). |
|
||||
| `split "1.2" "."` | split string at separator. See [Split](https://golang.org/pkg/strings/#Split). Since v1.11. |
|
||||
| `time "01/02/2006"` | current UTC time in the specified format (this is not deterministic, a new time for every call). |
|
||||
| `tolower "V1.2"` | makes input string lowercase. See [ToLower](https://golang.org/pkg/strings/#ToLower). |
|
||||
| `toupper "v1.2"` | makes input string uppercase. See [ToUpper](https://golang.org/pkg/strings/#ToUpper). |
|
||||
| `trim " v1.2 "` | removes all leading and trailing white space. See [TrimSpace](https://golang.org/pkg/strings/#TrimSpace). |
|
||||
| `trimprefix "v1.2" "v"` | removes provided leading prefix string, if present. See [TrimPrefix](https://golang.org/pkg/strings/#TrimPrefix). |
|
||||
| `trimsuffix "1.2v" "v"` | removes provided trailing suffix string, if present. See [TrimSuffix](https://pkg.go.dev/strings#TrimSuffix). |
|
||||
| `dir .Path` | returns all but the last element of path, typically the path's directory. See [Dir](https://golang.org/pkg/path/filepath/#Dir). |
|
||||
| `base .Path` | returns the last element of path. See [Base](https://golang.org/pkg/path/filepath/#Base). Since v1.16. |
|
||||
| `abs .ArtifactPath` | returns an absolute representation of path. See [Abs](https://golang.org/pkg/path/filepath/#Abs). |
|
||||
| `filter "text" "regex"` | keeps only the lines matching the given regex, analogous to `grep -E`. Since v1.6. |
|
||||
| `reverseFilter "text" "regex"` | keeps only the lines **not** matching the given regex, analogous to `grep -vE`. Since v1.6. |
|
||||
| `title "foo"` | "titlenize" the string using english as language. See [Title](https://pkg.go.dev/golang.org/x/text/cases#Title). Since v1.14. |
|
||||
| `mdv2escape "foo"` | escape characteres according to MarkdownV2, especially useful in the Telegram integration. Since v1.19. |
|
||||
|
||||
With all those fields, you may be able to compose the name of your artifacts
|
||||
pretty much the way you want:
|
||||
@ -155,7 +161,7 @@ example_template: '{{ tolower .ProjectName }}_{{ .Env.USER }}_{{ time "2006" }}'
|
||||
For example, if you want to add the go version to some artifact:
|
||||
|
||||
```yaml
|
||||
foo_template: 'foo_{{ .Env.GOVERSION }}'
|
||||
foo_template: "foo_{{ .Env.GOVERSION }}"
|
||||
```
|
||||
|
||||
And then you can run:
|
||||
@ -165,13 +171,15 @@ GOVERSION_NR=$(go version | awk '{print $3;}') goreleaser
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
Note that those are hypothetical examples and the fields `foo_template` and
|
||||
`example_template` are not valid GoReleaser configurations.
|
||||
|
||||
## Custom variables
|
||||
|
||||
!!! success "GoReleaser Pro"
|
||||
Custom template variables support is a [GoReleaser Pro feature](/pro/).
|
||||
|
||||
Custom template variables support is a [GoReleaser Pro feature](/pro/).
|
||||
|
||||
You can also declare custom variables. This feature is specially useful with
|
||||
[includes](/customization/includes/), so you can have more generic configuration
|
||||
@ -188,4 +196,3 @@ variables:
|
||||
```
|
||||
|
||||
And then you can use those fields as `{{ .Var.description }}`, for example.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user