Skip to content

Commit 9d35b70

Browse files
committed
build: finalise release process
1 parent d0a5317 commit 9d35b70

File tree

7 files changed

+562
-21
lines changed

7 files changed

+562
-21
lines changed

.github/workflows/release-manual.yml

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
name: Release (Manual)
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Release version (e.g., v1.0.0)'
8+
required: true
9+
type: string
10+
draft:
11+
description: 'Create as draft release'
12+
required: false
13+
type: boolean
14+
default: true
15+
16+
permissions: read-all
17+
18+
jobs:
19+
validate:
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
outputs:
24+
version: ${{ steps.validate.outputs.version }}
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
28+
with:
29+
fetch-depth: 0
30+
31+
- name: Validate version format
32+
id: validate
33+
run: |
34+
VERSION="${{ github.event.inputs.version }}"
35+
36+
# Check version format
37+
if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9\.\-]+)?(\+[a-zA-Z0-9\.\-]+)?$ ]]; then
38+
echo "❌ Invalid version format: $VERSION"
39+
echo "Version must follow semantic versioning: vMAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]"
40+
exit 1
41+
fi
42+
43+
# Check if tag already exists
44+
if git rev-parse "$VERSION" >/dev/null 2>&1; then
45+
echo "❌ Tag $VERSION already exists"
46+
exit 1
47+
fi
48+
49+
echo "✅ Version $VERSION is valid"
50+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
51+
52+
test:
53+
needs: validate
54+
runs-on: ubuntu-latest
55+
permissions:
56+
contents: read
57+
steps:
58+
- name: Checkout
59+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
60+
61+
- name: Set up Go
62+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
63+
with:
64+
go-version: '1.24.3'
65+
cache: true
66+
67+
- name: Run tests
68+
run: make test
69+
70+
- name: Run audit
71+
run: make audit
72+
73+
release:
74+
needs: [validate, test]
75+
runs-on: ubuntu-latest
76+
permissions:
77+
contents: write # To create releases and tags
78+
packages: write # To push container images (if needed)
79+
id-token: write # For cosign signing
80+
outputs:
81+
hashes: ${{ steps.hash.outputs.hashes }}
82+
steps:
83+
- name: Checkout
84+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
85+
with:
86+
fetch-depth: 0
87+
token: ${{ secrets.GITHUB_TOKEN }}
88+
89+
- name: Set up Go
90+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
91+
with:
92+
go-version: '1.24.3'
93+
cache: true
94+
95+
- name: Install cosign
96+
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
97+
98+
- name: Install syft
99+
uses: anchore/sbom-action/download-syft@fc46e51fd3cb168ffb36c6d1915723c47db58abb # v0.17.7
100+
101+
- name: Create and push tag
102+
run: |
103+
VERSION="${{ needs.validate.outputs.version }}"
104+
git config user.name "github-actions[bot]"
105+
git config user.email "github-actions[bot]@users.noreply.github.com"
106+
107+
# Create annotated tag
108+
git tag -a "$VERSION" -m "Release $VERSION"
109+
git push origin "$VERSION"
110+
111+
- name: Run GoReleaser
112+
id: goreleaser
113+
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
114+
with:
115+
version: v2.9.0
116+
args: release --clean ${{ github.event.inputs.draft == 'true' && '--draft' || '' }}
117+
env:
118+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119+
120+
- name: Generate subject for provenance
121+
id: hash
122+
env:
123+
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
124+
run: |
125+
set -euo pipefail
126+
127+
# Parse artifacts JSON to extract checksums
128+
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
129+
130+
# Generate base64-encoded checksums for SLSA provenance
131+
echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"
132+
133+
provenance:
134+
needs: [release]
135+
permissions:
136+
actions: read # To read the workflow path
137+
id-token: write # To sign the provenance
138+
contents: write # To add assets to a release
139+
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
140+
with:
141+
base64-subjects: "${{ needs.release.outputs.hashes }}"
142+
upload-assets: true

.github/workflows/release.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Release (Automated)
2+
3+
# This workflow is triggered by tags created by the release-manual workflow
4+
# Direct tag pushes should be prevented by branch/tag protection rules
5+
on:
6+
push:
7+
tags:
8+
- 'v*'
9+
10+
permissions: read-all
11+
12+
jobs:
13+
goreleaser:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write # To create releases
17+
packages: write # To push container images (if needed)
18+
id-token: write # For cosign signing
19+
outputs:
20+
hashes: ${{ steps.hash.outputs.hashes }}
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
24+
with:
25+
fetch-depth: 0
26+
27+
- name: Set up Go
28+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
29+
with:
30+
go-version: '1.24.3'
31+
cache: true
32+
33+
- name: Install cosign
34+
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
35+
36+
- name: Run GoReleaser
37+
id: goreleaser
38+
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
39+
with:
40+
version: v2
41+
args: release --clean
42+
env:
43+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
45+
- name: Generate subject for provenance
46+
id: hash
47+
env:
48+
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
49+
run: |
50+
set -euo pipefail
51+
52+
# Parse artifacts JSON to extract checksums
53+
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
54+
55+
# Generate base64-encoded checksums for SLSA provenance
56+
echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"
57+
58+
provenance:
59+
needs: [goreleaser]
60+
permissions:
61+
actions: read # To read the workflow path
62+
id-token: write # To sign the provenance
63+
contents: write # To add assets to a release
64+
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
65+
with:
66+
base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
67+
upload-assets: true

.github/workflows/workflow.yml renamed to .github/workflows/test.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
name: CI Workflow
1+
name: Test
22

33
on:
44
pull_request:
55
branches:
6-
- develop
76
- master
87

98
permissions: read-all
@@ -18,7 +17,7 @@ jobs:
1817
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
1918

2019
- name: Set up Go
21-
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
20+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
2221
with:
2322
go-version: ${{ matrix.go-version }}
2423
cache: true

.goreleaser.yml

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ builds:
1515
- -X main.BuildTime={{ .Date }}
1616

1717
archives:
18-
- formats: [tar.gz]
18+
- formats: ["tar.gz"]
1919
name_template: >-
2020
{{ .ProjectName }}_
2121
{{- title .Os }}_
@@ -25,24 +25,94 @@ archives:
2525
{{- if .Arm }}v{{ .Arm }}{{ end }}
2626
format_overrides:
2727
- goos: windows
28-
formats: [zip]
28+
formats: ["zip"]
2929

3030
checksum:
3131
name_template: "{{ .ProjectName }}_checksums.txt"
3232
algorithm: sha256
3333

34+
signs:
35+
- cmd: cosign
36+
env:
37+
- COSIGN_EXPERIMENTAL=1
38+
certificate: '${artifact}.pem'
39+
args:
40+
- sign-blob
41+
- '--output-certificate=${certificate}'
42+
- '--output-signature=${signature}'
43+
- '${artifact}'
44+
- "--yes" # needed on cosign 2.0.0+
45+
artifacts: checksum
46+
output: true
47+
3448
sboms:
3549
- artifacts: archive
3650
id: sboms
3751

3852
changelog:
3953
sort: asc
54+
use: github
55+
groups:
56+
- title: "✨ Features"
57+
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
58+
order: 0
59+
- title: "🐛 Bug Fixes"
60+
regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'
61+
order: 1
62+
- title: "📚 Documentation"
63+
regexp: '^.*?docs(\([[:word:]]+\))??!?:.+$'
64+
order: 2
65+
- title: "🧪 Testing"
66+
regexp: '^.*?test(\([[:word:]]+\))??!?:.+$'
67+
order: 3
68+
- title: "🔧 Other Changes"
69+
order: 999
4070
filters:
4171
exclude:
42-
- "^docs:"
43-
- "^test:"
72+
- "^chore:"
73+
- "^ci:"
74+
- "^build\\(deps\\):"
4475

4576
release:
4677
github:
4778
owner: jakec-dev
4879
name: aws-local-sync
80+
81+
draft: true
82+
replace_existing_draft: true
83+
84+
prerelease: auto
85+
86+
name_template: "{{ .ProjectName }} {{ .Tag }}"
87+
88+
header: |
89+
## AWS Local Sync {{ .Tag }}
90+
91+
High-performance CLI tool that syncs data from AWS services (RDS, DynamoDB, S3, Elasticsearch, etc.) to your local development environment.
92+
93+
### Highlights
94+
95+
footer: |
96+
97+
---
98+
99+
### Installation
100+
101+
#### Binary installation
102+
```bash
103+
# Download and extract (example for Linux x86_64)
104+
curl -sSL https://github.com/jakec-dev/aws-local-sync/releases/download/{{ .Tag }}/aws-local-sync_Linux_x86_64.tar.gz | tar xz
105+
106+
# Verify checksum signature
107+
cosign verify-blob \
108+
--certificate aws-local-sync_checksums.txt.pem \
109+
--signature aws-local-sync_checksums.txt.sig \
110+
aws-local-sync_checksums.txt
111+
```
112+
113+
#### Go installation
114+
```bash
115+
go install github.com/jakec-dev/aws-local-sync/cmd/aws-local-sync@{{ .Tag }}
116+
```
117+
118+
**Full Changelog**: https://github.com/jakec-dev/aws-local-sync/compare/{{ .PreviousTag }}...{{ .Tag }}

0 commit comments

Comments
 (0)