Skip to content

Commit 6cf6a20

Browse files
authored
all: add goreleaser and setup release workflow (#1)
* analysis: add missing license header * all: add goreleaser and setup release workflow
1 parent eeddb98 commit 6cf6a20

File tree

7 files changed

+482
-0
lines changed

7 files changed

+482
-0
lines changed

.github/release.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
changelog:
2+
exclude:
3+
labels:
4+
- "type: dependencies"
5+
categories:
6+
- title: "⚠️ Breaking changes"
7+
labels:
8+
- "status: breaking"
9+
- title: "✨ Additions"
10+
labels:
11+
- "type: feature"
12+
- title: "🐛 Fixes"
13+
labels:
14+
- "type: bug"
15+
- "type: broken metric"
16+
- title: "🔧 Improvements"
17+
labels:
18+
- "type: enhancement"
19+
- "type: refactor"
20+
- title: "📖 Documentation"
21+
labels:
22+
- "type: documentation"
23+
- title: "🧪 Test coverage"
24+
labels:
25+
- "type: test"
26+
- title: "⚙️ Other"
27+
labels:
28+
- "*"

.github/workflows/release.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright (c) 2025 Joshua Sing <joshua@joshuasing.dev>
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
# GitHub Actions workflow to create releases using GoReleaser.
22+
name: "Release"
23+
24+
on:
25+
push:
26+
tags: [ "v*.*.*" ]
27+
28+
env:
29+
GO_VERSION: "1.24.x"
30+
31+
jobs:
32+
release:
33+
name: "Release"
34+
runs-on: "ubuntu-latest"
35+
environment:
36+
name: "release"
37+
permissions:
38+
contents: write
39+
id-token: write
40+
packages: write
41+
attestations: write
42+
env:
43+
DOCKER_CLI_EXPERIMENTAL: enabled
44+
steps:
45+
- name: "Checkout repository"
46+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
47+
with:
48+
fetch-depth: 0
49+
50+
- name: "Setup Go ${{ env.GO_VERSION }}"
51+
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0
52+
with:
53+
go-version: "${{ env.GO_VERSION }}"
54+
cache: true
55+
check-latest: true
56+
57+
- name: "Install cosign"
58+
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
59+
60+
- name: "Install Syft"
61+
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
62+
63+
- name: "Setup QEMU"
64+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
65+
66+
- name: "Setup Docker Buildx"
67+
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
68+
69+
- name: "Login to DockerHub"
70+
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
71+
with:
72+
username: "${{ secrets.DOCKERHUB_USERNAME }}"
73+
password: "${{ secrets.DOCKERHUB_TOKEN }}"
74+
75+
- name: "Login to GitHub Container Registry"
76+
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
77+
with:
78+
registry: "ghcr.io"
79+
username: "${{ github.repository_owner }}"
80+
password: "${{ secrets.GITHUB_TOKEN }}"
81+
82+
- name: "Release"
83+
uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1
84+
with:
85+
args: "release --clean"
86+
env:
87+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
88+
89+
- name: "Attest release artifacts"
90+
uses: actions/attest-build-provenance@c074443f1aee8d4aeeae555aebba3282517141b2 # v2.2.3
91+
with:
92+
subject-path: |
93+
dist/**/starlink_exporter
94+
dist/*.tar.gz
95+
dist/*.zip
96+
dist/*.txt
97+
dist/*.pem
98+
dist/*.sig

.goreleaser.Dockerfile

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (c) 2025 Joshua Sing <joshua@joshuasing.dev>
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
# Build stage
22+
FROM alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c AS builder
23+
24+
# Add ca-certificates, timezone data
25+
RUN apk --no-cache add --update ca-certificates tzdata
26+
27+
# Create non-root user
28+
RUN addgroup --gid 65532 golicenser && \
29+
adduser --disabled-password --gecos "" \
30+
--no-create-home --shell="/sbin/nologin" \
31+
-G golicenser --uid 65532 golicenser
32+
33+
# Run stage
34+
FROM scratch
35+
36+
# Build metadata
37+
ARG VERSION
38+
ARG VCS_REF
39+
ARG BUILD_DATE
40+
41+
LABEL maintainer="Joshua Sing <joshua@joshuasing.dev>"
42+
LABEL org.opencontainers.image.created=$BUILD_DATE \
43+
org.opencontainers.image.authors="Joshua Sing <joshua@joshuasing.dev>" \
44+
org.opencontainers.image.url="https://github.com/joshuasing/golicenser" \
45+
org.opencontainers.image.source="https://github.com/joshuasing/golicenser" \
46+
org.opencontainers.image.version=$VERSION \
47+
org.opencontainers.image.revision=$VCS_REF \
48+
org.opencontainers.image.licenses="MIT" \
49+
org.opencontainers.image.vendor="Joshua Sing <joshua@joshuasing.dev>" \
50+
org.opencontainers.image.title="golicenser" \
51+
org.opencontainers.image.description="A fast, easy-to-use, license header linter for Go"
52+
53+
# Copy files
54+
COPY --from=builder /etc/group /etc/group
55+
COPY --from=builder /etc/passwd /etc/passwd
56+
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
57+
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
58+
COPY golicenser /usr/local/bin/golicenser
59+
60+
USER golicenser:golicenser
61+
ENTRYPOINT ["/usr/local/bin/golicenser"]

.goreleaser.yml

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
2+
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
3+
version: 2
4+
5+
project_name: "golicenser"
6+
report_sizes: true
7+
8+
env:
9+
- AUTHOR=Joshua Sing <joshua@joshuasing.dev>
10+
- GITHUB_USER=joshuasing
11+
- DOCKER_HUB_USER=joshuasing
12+
- DESCRIPTION=A fast, easy-to-use, license header linter for Go
13+
- LICENSE=MIT
14+
15+
before:
16+
hooks:
17+
- "go mod tidy"
18+
- "go mod download"
19+
- "go mod verify"
20+
21+
builds:
22+
- binary: "{{ .ProjectName }}"
23+
main: "./cmd/{{ .ProjectName }}/"
24+
env: [ "CGO_ENABLED=0", "GOGC=off" ]
25+
ldflags: >-
26+
-s -w
27+
flags: [ "-trimpath" ]
28+
goos:
29+
- "linux"
30+
- "windows"
31+
- "darwin"
32+
goarch:
33+
- "amd64"
34+
- "arm"
35+
- "arm64"
36+
goarm: [ "7" ]
37+
ignore:
38+
- goos: "windows"
39+
goarch: "arm"
40+
41+
archives:
42+
- formats: "tar.gz"
43+
wrap_in_directory: true
44+
name_template: >-
45+
{{ .ProjectName }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}
46+
format_overrides:
47+
- goos: "windows"
48+
formats: "zip"
49+
files:
50+
- "README*"
51+
- "LICENSE*"
52+
53+
# Create sources archive.
54+
source:
55+
enabled: true
56+
name_template: "{{ .ProjectName }}_v{{ .Version }}_sources"
57+
format: "tar.gz"
58+
59+
# Create checksums file.
60+
checksum:
61+
name_template: "{{ .ProjectName }}_v{{ .Version }}_checksums.txt"
62+
algorithm: "sha256"
63+
64+
# Create SBOMs for all archives and the source archive.
65+
sboms:
66+
- id: "archive"
67+
artifacts: "archive"
68+
- id: "source"
69+
artifacts: "source"
70+
71+
# Sign the checksum file, which includes the checksums for all files (including SBOMs).
72+
signs:
73+
- cmd: "cosign"
74+
certificate: "${artifact}.pem"
75+
args:
76+
- "sign-blob"
77+
- "--output-certificate=${certificate}"
78+
- "--output-signature=${signature}"
79+
- "${artifact}"
80+
- "--yes"
81+
artifacts: "checksum"
82+
output: true
83+
84+
# Create Docker images.
85+
dockers:
86+
# linux/amd64
87+
- id: "{{ .ProjectName }}-amd64"
88+
goos: "linux"
89+
goarch: "amd64"
90+
dockerfile: ".goreleaser.Dockerfile"
91+
use: buildx
92+
image_templates:
93+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
94+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
95+
build_flag_templates:
96+
- "--platform=linux/amd64"
97+
- "--build-arg=VERSION={{ .Version }}"
98+
- "--build-arg=VCS_REF={{ .FullCommit }}"
99+
- "--build-arg=BUILD_DATE={{ .Date }}"
100+
101+
# linux/arm64/v8
102+
- id: "{{ .ProjectName }}-arm64"
103+
goos: "linux"
104+
goarch: "arm64"
105+
dockerfile: ".goreleaser.Dockerfile"
106+
use: buildx
107+
image_templates:
108+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
109+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
110+
build_flag_templates:
111+
- "--platform=linux/arm64/v8"
112+
- "--build-arg=VERSION={{ .Version }}"
113+
- "--build-arg=VCS_REF={{ .FullCommit }}"
114+
- "--build-arg=BUILD_DATE={{ .Date }}"
115+
116+
# linux/arm/v7
117+
- id: "{{ .ProjectName }}-armv7"
118+
goos: "linux"
119+
goarch: "arm"
120+
goarm: "7"
121+
dockerfile: ".goreleaser.Dockerfile"
122+
use: buildx
123+
image_templates:
124+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
125+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
126+
build_flag_templates:
127+
- "--platform=linux/arm/v7"
128+
- "--build-arg=VERSION={{ .Version }}"
129+
- "--build-arg=VCS_REF={{ .FullCommit }}"
130+
- "--build-arg=BUILD_DATE={{ .Date }}"
131+
132+
# Create Docker manifests for each image, containing the images for each
133+
# supported system architecture.
134+
docker_manifests:
135+
# Docker Hub
136+
- name_template: "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:latest"
137+
image_templates:
138+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
139+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
140+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
141+
- name_template: "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}"
142+
image_templates:
143+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
144+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
145+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
146+
- name_template: "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Major }}.{{ .Minor }}"
147+
image_templates:
148+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
149+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
150+
- "{{ .Env.DOCKER_HUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
151+
152+
# GitHub Container Registry
153+
- name_template: "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:latest"
154+
image_templates:
155+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
156+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
157+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
158+
- name_template: "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}"
159+
image_templates:
160+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
161+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
162+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
163+
- name_template: "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Major }}.{{ .Minor }}"
164+
image_templates:
165+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-amd64"
166+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-arm64"
167+
- "ghcr.io/{{ .Env.GITHUB_USER }}/{{ .ProjectName }}:{{ .Version }}-armv7"
168+
169+
# Sign Docker images and manifests.
170+
docker_signs:
171+
- artifacts: "all"
172+
cmd: "cosign"
173+
args:
174+
- "sign"
175+
- "${artifact}"
176+
- "--yes"
177+
178+
# Snapshot version settings.
179+
snapshot:
180+
version_template: "{{ incpatch .Version }}-{{ .ShortCommit }}"
181+
182+
# Generate changelog for releases.
183+
changelog:
184+
use: "github-native"
185+
186+
# Create GitHub release.
187+
release:
188+
name_template: "golicenser v{{ .Version }}"
189+
github:
190+
owner: "joshuasing"
191+
name: "golicenser"
192+
prerelease: auto
193+
mode: "append"
194+
195+
# Close milestones for the released tag.
196+
milestones:
197+
- repo:
198+
owner: "joshuasing"
199+
name: "golicenser"
200+
close: true
201+
name_template: "{{ .Tag }}"

0 commit comments

Comments
 (0)