-
Notifications
You must be signed in to change notification settings - Fork 1
198 lines (168 loc) · 6.33 KB
/
Copy pathrelease.yml
File metadata and controls
198 lines (168 loc) · 6.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: Build Release Binaries
# Mirrors the pattern used by the WolfStack repo: every push to main
# that touches the crate or the workflow itself rebuilds static musl
# binaries for x86_64 and aarch64, signs them via cosign keyless OIDC,
# and creates / updates the GitHub release tagged after the version in
# Cargo.toml.
#
# setup.sh then downloads the matching binary instead of cargo-building
# on the operator's box, which removes the rustup-toolchain / build-
# deps surface as a failure mode.
on:
push:
branches: [main]
paths:
- 'Cargo.toml'
- 'src/**'
- '.github/workflows/release.yml'
workflow_dispatch:
jobs:
# Hard gate: clippy with warnings-as-errors + the test suite must pass
# before any release binary is built. Keeps the tree clippy-clean (the
# wolfstack repo enforces the same bar). Fix at root — no bare #[allow].
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Clippy (warnings = errors)
run: cargo clippy --all-targets -- -D warnings
- name: Tests
run: cargo test --all-targets
build:
needs: lint
strategy:
matrix:
include:
- target: x86_64-unknown-linux-musl
arch: x86_64
runner: ubuntu-latest
- target: aarch64-unknown-linux-musl
arch: aarch64
runner: ubuntu-latest
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v5
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Build static binary
run: cross build --release --target ${{ matrix.target }}
- name: Get version
id: version
run: echo "version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
- name: Package binary
run: |
mkdir -p dist
cp target/${{ matrix.target }}/release/wolfproxy dist/wolfproxy-${{ matrix.arch }}
chmod +x dist/wolfproxy-${{ matrix.arch }}
- name: Upload artifact
uses: actions/upload-artifact@v6
with:
name: wolfproxy-${{ matrix.arch }}
path: dist/wolfproxy-${{ matrix.arch }}
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write # gh release create
id-token: write # cosign keyless OIDC + attest provenance
attestations: write # actions/attest-build-provenance
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Get version
id: version
run: echo "version=$(grep '^version' Cargo.toml | head -1 | sed 's/.*\"\(.*\)\".*/\1/')" >> "$GITHUB_OUTPUT"
- name: Download all artifacts
uses: actions/download-artifact@v7
with:
path: dist
merge-multiple: true
- name: Compute SHA-256 checksums
run: |
cd dist
sha256sum wolfproxy-x86_64 wolfproxy-aarch64 > SHA256SUMS
- name: Generate build-provenance attestation
uses: actions/attest-build-provenance@v3
with:
subject-path: |
dist/wolfproxy-x86_64
dist/wolfproxy-aarch64
- name: Install cosign
uses: sigstore/cosign-installer@v3
with:
cosign-release: 'v2.4.1'
- name: Sign binaries with cosign (keyless)
# Keyless OIDC — signing identity is this workflow, anchored
# to the GitHub Actions OIDC token. Verifiers walk the cert
# chain back to Sigstore's Fulcio CA + Rekor transparency log.
run: |
cd dist
for f in wolfproxy-x86_64 wolfproxy-aarch64; do
cosign sign-blob --yes \
--bundle "${f}.cosign.bundle" \
"$f"
done
- name: Generate release notes from release-commit body
id: notes
run: |
BODY=$(git log -50 --grep='^v[0-9]' -1 --pretty=format:'%b' || echo "")
SUBJECT=$(git log -50 --grep='^v[0-9]' -1 --pretty=format:'%s' || echo "Release")
{
echo "## $SUBJECT"
echo
if [ -n "$BODY" ]; then
echo "$BODY"
echo
fi
cat <<'EOF'
---
## Verifying this release
Each binary is signed via [cosign](https://docs.sigstore.dev/) keyless OIDC and ships with a [SLSA build provenance](https://slsa.dev/spec/v1.0/provenance) attestation.
**Verify the cosign signature:**
```
cosign verify-blob \
--bundle wolfproxy-x86_64.cosign.bundle \
--certificate-identity-regexp 'https://github.com/wolfsoftwaresystemsltd/wolfproxy/\.github/workflows/release\.yml@.*' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
wolfproxy-x86_64
```
**Verify the build provenance:**
```
gh attestation verify wolfproxy-x86_64 --repo wolfsoftwaresystemsltd/wolfproxy
```
**Verify the SHA-256 checksum:**
```
sha256sum -c SHA256SUMS
```
## Artifacts
- `wolfproxy-x86_64` / `wolfproxy-aarch64` — static musl binaries (Linux x86_64 and ARM64).
- `wolfproxy-<arch>.cosign.bundle` — cosign signature bundle (cert + signature + Rekor entry).
- `SHA256SUMS` — checksums for both binaries.
EOF
} > release-notes.md
- name: Create or update release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="v${{ steps.version.outputs.version }}"
gh release delete "$VERSION" --yes 2>/dev/null || true
git push --delete origin "$VERSION" 2>/dev/null || true
git tag -d "$VERSION" 2>/dev/null || true
gh release create "$VERSION" \
--target main \
--title "WolfProxy $VERSION" \
--notes-file release-notes.md \
dist/wolfproxy-x86_64 \
dist/wolfproxy-x86_64.cosign.bundle \
dist/wolfproxy-aarch64 \
dist/wolfproxy-aarch64.cosign.bundle \
dist/SHA256SUMS