Skip to content

Commit c202f62

Browse files
authored
feat: release setup with goreleaser (#16)
1 parent a2a8f48 commit c202f62

File tree

9 files changed

+289
-0
lines changed

9 files changed

+289
-0
lines changed

.github/workflows/release.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
goreleaser:
13+
name: GoReleaser
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
17+
with:
18+
fetch-depth: 0
19+
20+
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
21+
with:
22+
go-version-file: go.mod
23+
24+
- name: Run GoReleaser
25+
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
26+
with:
27+
distribution: goreleaser
28+
version: '~> v2'
29+
args: release --clean
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.goreleaser.yml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
version: 2
2+
3+
project_name: sumup
4+
5+
release:
6+
prerelease: auto
7+
8+
before:
9+
hooks:
10+
- go mod download
11+
12+
builds:
13+
- id: macos
14+
main: ./cmd/sumup/main.go
15+
binary: sumup
16+
env:
17+
- CGO_ENABLED=0
18+
goos:
19+
- darwin
20+
goarch:
21+
- amd64
22+
- arm64
23+
ldflags:
24+
- -s -w -X github.com/sumup/sumup-cli/internal/buildinfo.Version={{ .Version }} -X github.com/sumup/sumup-cli/internal/buildinfo.Commit={{ .Commit }} -X github.com/sumup/sumup-cli/internal/buildinfo.Date={{ .Date }}
25+
26+
- id: linux
27+
main: ./cmd/sumup/main.go
28+
binary: sumup
29+
env:
30+
- CGO_ENABLED=0
31+
goos:
32+
- linux
33+
goarch:
34+
- amd64
35+
- arm64
36+
ldflags:
37+
- -s -w -X github.com/sumup/sumup-cli/internal/buildinfo.Version={{ .Version }} -X github.com/sumup/sumup-cli/internal/buildinfo.Commit={{ .Commit }} -X github.com/sumup/sumup-cli/internal/buildinfo.Date={{ .Date }}
38+
39+
- id: windows
40+
main: ./cmd/sumup/main.go
41+
binary: sumup
42+
env:
43+
- CGO_ENABLED=0
44+
goos:
45+
- windows
46+
goarch:
47+
- amd64
48+
- arm64
49+
ldflags:
50+
- -s -w -X github.com/sumup/sumup-cli/internal/buildinfo.Version={{ .Version }} -X github.com/sumup/sumup-cli/internal/buildinfo.Commit={{ .Commit }} -X github.com/sumup/sumup-cli/internal/buildinfo.Date={{ .Date }}
51+
52+
# Enable when signing credentials are configured in CI.
53+
# hooks:
54+
# post:
55+
# - cmd: >-
56+
# {{ if eq .Os "darwin" }}./scripts/sign-macos.sh '{{ .Path }}'{{ else }}echo{{ end }}
57+
# output: true
58+
# - cmd: >-
59+
# {{ if eq .Os "windows" }}pwsh ./scripts/sign-windows.ps1 '{{ .Path }}'{{ else }}echo{{ end }}
60+
# output: true
61+
62+
archives:
63+
- id: linux-archive
64+
ids: [linux]
65+
formats: [tar.gz]
66+
name_template: >-
67+
{{ .ProjectName }}_{{ .Version }}_linux_
68+
{{- if eq .Arch "amd64" }}x86_64{{ else }}{{ .Arch }}{{ end }}
69+
files:
70+
- LICENSE
71+
- README.md
72+
- id: macos-archive
73+
ids: [macos]
74+
formats: [tar.gz]
75+
name_template: >-
76+
{{ .ProjectName }}_{{ .Version }}_macOS_
77+
{{- if eq .Arch "amd64" }}x86_64{{ else }}{{ .Arch }}{{ end }}
78+
files:
79+
- LICENSE
80+
- README.md
81+
- id: windows-archive
82+
ids: [windows]
83+
formats: [zip]
84+
name_template: >-
85+
{{ .ProjectName }}_{{ .Version }}_windows_
86+
{{- if eq .Arch "amd64" }}x86_64{{ else }}{{ .Arch }}{{ end }}
87+
files:
88+
- LICENSE
89+
- README.md
90+
91+
checksum:
92+
name_template: checksums.txt
93+
94+
changelog:
95+
sort: asc
96+
filters:
97+
exclude:
98+
- '^docs:'
99+
- '^test:'
100+
- '^chore:'

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ vulncheck-sarif: ## Check for Vulnerabilities
3131
.PHONY: install-tools
3232
install-tools: # Install development dependencies
3333
go install golang.org/x/vuln/cmd/govulncheck@latest
34+
35+
VERSION ?= dev
36+
COMMIT ?= $(shell git rev-parse --short HEAD)
37+
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
38+
LDFLAGS := -s -w \
39+
-X github.com/sumup/sumup-cli/internal/buildinfo.Version=$(VERSION) \
40+
-X github.com/sumup/sumup-cli/internal/buildinfo.Commit=$(COMMIT) \
41+
-X github.com/sumup/sumup-cli/internal/buildinfo.Date=$(DATE)
42+
43+
.PHONY: build
44+
build: ## Build CLI binary with build metadata
45+
go build -ldflags "$(LDFLAGS)" -o ./bin/sumup ./cmd/sumup

cmd/sumup/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/urfave/cli/v3"
99

1010
"github.com/sumup/sumup-cli/internal/app"
11+
"github.com/sumup/sumup-cli/internal/buildinfo"
1112
"github.com/sumup/sumup-cli/internal/commands"
1213
"github.com/sumup/sumup-cli/internal/display/message"
1314
)
@@ -16,6 +17,7 @@ func main() {
1617
cliApp := &cli.Command{
1718
Name: "sumup",
1819
Usage: "Command line tool for the SumUp API",
20+
Version: buildinfo.Short(),
1921
EnableShellCompletion: true,
2022
Flags: []cli.Flag{
2123
&cli.StringFlag{

internal/buildinfo/buildinfo.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package buildinfo
2+
3+
import (
4+
"fmt"
5+
"runtime/debug"
6+
"strings"
7+
)
8+
9+
var (
10+
// Version is the semantic version of the CLI.
11+
Version = "dev"
12+
// Commit is the VCS revision used for the build.
13+
Commit = "unknown"
14+
// Date is the build timestamp in UTC (RFC3339 format).
15+
Date = "unknown"
16+
)
17+
18+
func info() (version, commit, date string, dirty bool) {
19+
version = Version
20+
commit = Commit
21+
date = Date
22+
23+
bi, ok := debug.ReadBuildInfo()
24+
if !ok {
25+
return version, commit, date, false
26+
}
27+
28+
if (version == "dev" || version == "(devel)") && bi.Main.Version != "" && bi.Main.Version != "(devel)" {
29+
version = bi.Main.Version
30+
}
31+
32+
for _, setting := range bi.Settings {
33+
switch setting.Key {
34+
case "vcs.revision":
35+
if commit == "unknown" && setting.Value != "" {
36+
commit = setting.Value
37+
}
38+
case "vcs.time":
39+
if date == "unknown" && setting.Value != "" {
40+
date = setting.Value
41+
}
42+
case "vcs.modified":
43+
dirty = setting.Value == "true"
44+
}
45+
}
46+
47+
return version, commit, date, dirty
48+
}
49+
50+
// Short returns a concise version string suitable for --version output.
51+
func Short() string {
52+
version, commit, _, dirty := info()
53+
54+
var parts []string
55+
parts = append(parts, version)
56+
if commit != "" && commit != "unknown" {
57+
shortCommit := commit
58+
if len(shortCommit) > 7 {
59+
shortCommit = shortCommit[:7]
60+
}
61+
parts = append(parts, shortCommit)
62+
}
63+
if dirty {
64+
parts = append(parts, "dirty")
65+
}
66+
67+
return strings.Join(parts, " ")
68+
}
69+
70+
// Long returns full build details.
71+
func Long() string {
72+
version, commit, date, _ := info()
73+
return fmt.Sprintf(
74+
"Version: %s\nCommit: %s\nDate: %s",
75+
version,
76+
commit,
77+
date,
78+
)
79+
}

internal/commands/commands.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/sumup/sumup-cli/internal/commands/receipts"
1515
"github.com/sumup/sumup-cli/internal/commands/roles"
1616
"github.com/sumup/sumup-cli/internal/commands/transactions"
17+
"github.com/sumup/sumup-cli/internal/commands/version"
1718
)
1819

1920
// All returns the list of resource commands exposed by the CLI.
@@ -30,5 +31,6 @@ func All() []*cli.Command {
3031
receipts.NewCommand(),
3132
roles.NewCommand(),
3233
transactions.NewCommand(),
34+
version.NewCommand(),
3335
}
3436
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package version
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/urfave/cli/v3"
8+
9+
"github.com/sumup/sumup-cli/internal/buildinfo"
10+
)
11+
12+
// NewCommand returns the version command.
13+
func NewCommand() *cli.Command {
14+
return &cli.Command{
15+
Name: "version",
16+
Usage: "Print CLI build information",
17+
Action: func(_ context.Context, _ *cli.Command) error {
18+
fmt.Println(buildinfo.Long())
19+
return nil
20+
},
21+
}
22+
}

scripts/sign-macos.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
binary_path="${1:-}"
5+
if [[ -z "$binary_path" ]]; then
6+
echo "usage: $0 <binary-path>" >&2
7+
exit 1
8+
fi
9+
10+
# Placeholder script for future macOS signing and notarization.
11+
# Expected env vars once enabled:
12+
# - APPLE_CERT_BASE64
13+
# - APPLE_CERT_PASSWORD
14+
# - APPLE_TEAM_ID
15+
# - APPLE_ID
16+
# - APPLE_APP_SPECIFIC_PASSWORD
17+
#
18+
# Example (to enable later):
19+
# security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
20+
# echo "$APPLE_CERT_BASE64" | base64 --decode > cert.p12
21+
# security import cert.p12 -k build.keychain -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign
22+
# codesign --force --timestamp --options runtime --sign "Developer ID Application: ..." "$binary_path"
23+
24+
echo "macOS signing is currently disabled. Skipping: $binary_path"

scripts/sign-windows.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[string]$BinaryPath
4+
)
5+
6+
$ErrorActionPreference = "Stop"
7+
8+
# Placeholder script for future Windows Authenticode signing.
9+
# Expected env vars once enabled:
10+
# - WINDOWS_CERT_BASE64
11+
# - WINDOWS_CERT_PASSWORD
12+
#
13+
# Example (to enable later):
14+
# [IO.File]::WriteAllBytes("cert.pfx", [Convert]::FromBase64String($env:WINDOWS_CERT_BASE64))
15+
# signtool sign /f cert.pfx /p $env:WINDOWS_CERT_PASSWORD /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 $BinaryPath
16+
17+
Write-Output "Windows signing is currently disabled. Skipping: $BinaryPath"

0 commit comments

Comments
 (0)