Skip to content

Commit 2e06404

Browse files
committed
feat: add reproducible debian packaging with goreleaser & CI workflow
1 parent a55991a commit 2e06404

File tree

10 files changed

+552
-113
lines changed

10 files changed

+552
-113
lines changed

.github/workflows/checks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ jobs:
6464
run: go install mvdan.cc/[email protected]
6565

6666
- name: Install staticcheck
67-
run: go install honnef.co/go/tools/cmd/staticcheck@2025.1.1
67+
run: go install honnef.co/go/tools/cmd/staticcheck@latest
6868

6969
- name: Install golangci-lint
70-
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.8
70+
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
7171

7272
# - name: Install NilAway
7373
# run: go install go.uber.org/nilaway/cmd/[email protected]

.github/workflows/release.yaml

Lines changed: 111 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@ on:
44
push:
55
tags:
66
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
snapshot:
10+
description: 'Create snapshot release'
11+
required: false
12+
default: false
13+
type: boolean
714

815
permissions:
916
contents: write
17+
packages: write
1018

1119
jobs:
12-
build_and_release:
20+
release:
1321
runs-on: ubuntu-latest
1422
steps:
1523
- name: Checkout
@@ -20,97 +28,115 @@ jobs:
2028
- name: Set up Go
2129
uses: actions/setup-go@v5
2230
with:
23-
go-version: ^v1.24
24-
25-
- name: Build
26-
run: make build
31+
go-version: '1.24'
32+
cache: true
33+
34+
- name: Set SOURCE_DATE_EPOCH for reproducible builds
35+
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)" >> $GITHUB_ENV
36+
37+
- name: Set up packaging dependencies
38+
run: |
39+
# Install nfpm for packaging
40+
echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
41+
sudo apt-get update
42+
sudo apt-get install -y nfpm
43+
44+
- name: Import GPG key (if available)
45+
id: import_gpg
46+
uses: crazy-max/ghaction-import-gpg@v6
47+
if: env.GPG_PRIVATE_KEY != ''
48+
with:
49+
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
50+
passphrase: ${{ secrets.GPG_PASSPHRASE }}
51+
env:
52+
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
2753

28-
# https://goreleaser.com/cmd/goreleaser_release/
29-
- name: Run GoReleaser
54+
- name: Run GoReleaser (Release)
3055
uses: goreleaser/goreleaser-action@v6
56+
if: startsWith(github.ref, 'refs/tags/') && !inputs.snapshot
3157
with:
3258
distribution: goreleaser
3359
version: "~> v2"
34-
args: release --config .goreleaser.yaml
60+
args: release --clean
3561
env:
3662
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
64+
GPG_KEY_PATH: ${{ steps.import_gpg.outputs.keyid && format('/tmp/gpg-{0}.key', steps.import_gpg.outputs.keyid) || '' }}
65+
NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
3766

38-
# docker-image:
39-
# name: Publish Docker Image
40-
# runs-on: ubuntu-latest
41-
42-
# steps:
43-
# - name: Checkout sources
44-
# uses: actions/checkout@v2
45-
46-
# - name: Get tag version
47-
# run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
48-
49-
# - name: Print version
50-
# run: |
51-
# echo $RELEASE_VERSION
52-
# echo ${{ env.RELEASE_VERSION }}
53-
54-
# - name: Set up QEMU
55-
# uses: docker/setup-qemu-action@v3
56-
57-
# - name: Set up Docker Buildx
58-
# uses: docker/setup-buildx-action@v3
59-
60-
# - name: Extract metadata (tags, labels) for Docker
61-
# id: meta
62-
# uses: docker/metadata-action@v5
63-
# with:
64-
# images: flashbots/go-template
65-
# tags: |
66-
# type=sha
67-
# type=pep440,pattern={{version}}
68-
# type=pep440,pattern={{major}}.{{minor}}
69-
# type=raw,value=latest,enable=${{ !contains(env.RELEASE_VERSION, '-') }}
70-
71-
# - name: Login to DockerHub
72-
# uses: docker/login-action@v3
73-
# with:
74-
# username: ${{ secrets.DOCKERHUB_USERNAME }}
75-
# password: ${{ secrets.DOCKERHUB_TOKEN }}
76-
77-
# - name: Go Build Cache for Docker
78-
# uses: actions/cache@v3
79-
# with:
80-
# path: go-build-cache
81-
# key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.sum') }}
82-
83-
# - name: inject go-build-cache into docker
84-
# uses: reproducible-containers/[email protected]
85-
# with:
86-
# cache-source: go-build-cache
87-
88-
# - name: Build and push
89-
# uses: docker/build-push-action@v5
90-
# with:
91-
# context: .
92-
# build-args: |
93-
# VERSION=${{ env.RELEASE_VERSION }}
94-
# push: true
95-
# tags: ${{ steps.meta.outputs.tags }}
96-
# labels: ${{ steps.meta.outputs.labels }}
97-
# platforms: linux/amd64,linux/arm64
98-
# cache-from: type=gha
99-
# cache-to: type=gha,mode=max
67+
- name: Run GoReleaser (Snapshot)
68+
uses: goreleaser/goreleaser-action@v6
69+
if: inputs.snapshot || (!startsWith(github.ref, 'refs/tags/'))
70+
with:
71+
distribution: goreleaser
72+
version: "~> v2"
73+
args: release --snapshot --clean
74+
env:
75+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}
77+
GPG_KEY_PATH: ${{ steps.import_gpg.outputs.keyid && format('/tmp/gpg-{0}.key', steps.import_gpg.outputs.keyid) || '' }}
78+
NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
10079

101-
# github-release:
102-
# runs-on: ubuntu-latest
103-
# steps:
104-
# - name: Checkout sources
105-
# uses: actions/checkout@v2
80+
- name: Upload artifacts
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: packages
84+
path: |
85+
dist/*.deb
86+
dist/*.rpm
87+
dist/*.tar.gz
88+
dist/checksums.txt
89+
retention-days: 30
90+
91+
- name: Test package installation
92+
run: |
93+
# Test Debian package installation
94+
DEB_FILE=$(find dist -name "*httpserver*.deb" | head -1)
95+
if [ -n "$DEB_FILE" ]; then
96+
echo "Testing package installation: $DEB_FILE"
97+
sudo dpkg -i "$DEB_FILE" || true
98+
sudo apt-get -f install -y
99+
100+
# Test if binary is installed and working
101+
/usr/bin/go-template-httpserver --help
102+
103+
# Test systemd service
104+
sudo systemctl daemon-reload
105+
sudo systemctl is-enabled go-template-httpserver
106+
107+
echo "✅ Package installation test passed"
108+
else
109+
echo "❌ No .deb file found for testing"
110+
exit 1
111+
fi
112+
113+
reproducibility-test:
114+
runs-on: ubuntu-latest
115+
needs: release
116+
if: always()
117+
steps:
118+
- name: Checkout
119+
uses: actions/checkout@v4
120+
with:
121+
fetch-depth: 0
106122

107-
# - name: Create release
108-
# id: create_release
109-
# uses: actions/create-release@v1
110-
# env:
111-
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
112-
# with:
113-
# tag_name: ${{ github.ref }}
114-
# release_name: ${{ github.ref }}
115-
# draft: false
116-
# prerelease: false
123+
- name: Set up Go
124+
uses: actions/setup-go@v5
125+
with:
126+
go-version: '1.24'
127+
cache: true
128+
129+
- name: Set SOURCE_DATE_EPOCH for reproducible builds
130+
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)" >> $GITHUB_ENV
131+
132+
- name: Test reproducible builds
133+
run: |
134+
# Install GoReleaser
135+
go install github.com/goreleaser/goreleaser/v2@latest
136+
137+
# Run reproducibility test
138+
make package-test-reproducible
139+
140+
echo "✅ Reproducibility test passed"
141+
env:
142+
SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }}

0 commit comments

Comments
 (0)