Skip to content

Commit d29c6ad

Browse files
ammarioclaude
andcommitted
feat: enhance release workflow with binary builds and test support
- Rename publish.yml to release.yml to better reflect its purpose - Add binary building for multiple platforms: - Linux x86_64 and ARM64 - macOS x86_64 and Apple Silicon - Create GitHub releases with: - Automated changelog from commits between tags - Pre-built binary tarballs for all platforms - Support test releases with -test suffix: - Creates draft/prerelease for tags ending in -test - Skips crates.io publishing for test releases - Adds warning banner in release notes - Still publishes to crates.io for production releases 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 6de3841 commit d29c6ad

2 files changed

Lines changed: 226 additions & 61 deletions

File tree

.github/workflows/publish.yml

Lines changed: 0 additions & 61 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
env:
9+
CARGO_TERM_COLOR: always
10+
11+
jobs:
12+
# Run all tests first using the reusable workflow
13+
tests:
14+
uses: ./.github/workflows/tests.yml
15+
16+
# Build binaries for different platforms
17+
build-binaries:
18+
name: Build ${{ matrix.target }}
19+
needs: tests
20+
runs-on: ${{ matrix.os }}
21+
strategy:
22+
matrix:
23+
include:
24+
- target: x86_64-unknown-linux-gnu
25+
os: ubuntu-latest-8-cores
26+
name: linux-x86_64
27+
- target: aarch64-unknown-linux-gnu
28+
os: ubuntu-latest-8-cores
29+
name: linux-aarch64
30+
- target: x86_64-apple-darwin
31+
os: macos-13
32+
name: macos-x86_64
33+
- target: aarch64-apple-darwin
34+
os: macos-14
35+
name: macos-aarch64
36+
37+
steps:
38+
- uses: actions/checkout@v4
39+
40+
- name: Install Rust
41+
uses: dtolnay/rust-toolchain@stable
42+
with:
43+
toolchain: stable
44+
targets: ${{ matrix.target }}
45+
46+
- name: Setup Rust cache
47+
uses: Swatinem/rust-cache@v2
48+
with:
49+
shared-key: ${{ matrix.target }}
50+
51+
- name: Install cross-compilation tools for ARM64 Linux
52+
if: matrix.target == 'aarch64-unknown-linux-gnu'
53+
run: |
54+
sudo apt-get update
55+
sudo apt-get install -y gcc-aarch64-linux-gnu
56+
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
57+
echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
58+
echo "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++" >> $GITHUB_ENV
59+
60+
- name: Build binary
61+
run: cargo build --release --target ${{ matrix.target }}
62+
63+
- name: Create tarball
64+
run: |
65+
# Get version from tag
66+
VERSION=${GITHUB_REF_NAME#v}
67+
68+
# Create directory structure
69+
mkdir -p httpjail-${VERSION}-${{ matrix.name }}
70+
71+
# Copy binary
72+
cp target/${{ matrix.target }}/release/httpjail httpjail-${VERSION}-${{ matrix.name }}/
73+
74+
# Copy README and LICENSE if they exist
75+
[ -f README.md ] && cp README.md httpjail-${VERSION}-${{ matrix.name }}/
76+
[ -f LICENSE ] && cp LICENSE httpjail-${VERSION}-${{ matrix.name }}/
77+
78+
# Create tarball
79+
tar czf httpjail-${VERSION}-${{ matrix.name }}.tar.gz httpjail-${VERSION}-${{ matrix.name }}
80+
81+
# Output path for upload
82+
echo "ASSET_PATH=httpjail-${VERSION}-${{ matrix.name }}.tar.gz" >> $GITHUB_ENV
83+
echo "ASSET_NAME=httpjail-${VERSION}-${{ matrix.name }}.tar.gz" >> $GITHUB_ENV
84+
85+
- name: Upload artifact
86+
uses: actions/upload-artifact@v4
87+
with:
88+
name: binary-${{ matrix.name }}
89+
path: ${{ env.ASSET_PATH }}
90+
retention-days: 1
91+
92+
# Create release and publish to crates.io
93+
release:
94+
name: Create Release and Publish
95+
needs: build-binaries
96+
runs-on: ubuntu-latest
97+
environment: publish
98+
permissions:
99+
contents: write
100+
101+
steps:
102+
- uses: actions/checkout@v4
103+
with:
104+
fetch-depth: 0 # Need full history for changelog
105+
106+
- name: Check if test release
107+
id: check_test
108+
run: |
109+
if [[ "${{ github.ref_name }}" == *-test ]]; then
110+
echo "is_test=true" >> $GITHUB_OUTPUT
111+
echo "This is a test release"
112+
else
113+
echo "is_test=false" >> $GITHUB_OUTPUT
114+
echo "This is a production release"
115+
fi
116+
117+
- name: Install Rust
118+
uses: dtolnay/rust-toolchain@stable
119+
with:
120+
toolchain: stable
121+
122+
- name: Setup Rust cache
123+
uses: Swatinem/rust-cache@v2
124+
with:
125+
shared-key: ${{ runner.os }}
126+
127+
- name: Verify version matches tag
128+
if: steps.check_test.outputs.is_test == 'false'
129+
run: |
130+
# Extract version from Cargo.toml
131+
CARGO_VERSION=$(grep -E '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
132+
133+
# Get the git tag without the 'v' prefix
134+
TAG_VERSION=${GITHUB_REF_NAME#v}
135+
136+
echo "Cargo.toml version: $CARGO_VERSION"
137+
echo "Git tag version: $TAG_VERSION"
138+
139+
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
140+
echo "Error: Version mismatch!"
141+
echo "Cargo.toml has version $CARGO_VERSION but git tag is $GITHUB_REF_NAME"
142+
exit 1
143+
fi
144+
145+
echo "Version check passed!"
146+
147+
- name: Download all artifacts
148+
uses: actions/download-artifact@v4
149+
with:
150+
path: artifacts
151+
152+
- name: Generate changelog
153+
id: changelog
154+
run: |
155+
# Get the current tag
156+
CURRENT_TAG="${GITHUB_REF_NAME}"
157+
158+
# Get the previous tag
159+
PREVIOUS_TAG=$(git describe --tags --abbrev=0 ${CURRENT_TAG}^ 2>/dev/null || echo "")
160+
161+
# Generate changelog
162+
if [ -z "$PREVIOUS_TAG" ]; then
163+
echo "First release!"
164+
CHANGELOG="Initial release of httpjail"
165+
else
166+
echo "Generating changelog from $PREVIOUS_TAG to $CURRENT_TAG"
167+
168+
# Get commit messages between tags
169+
CHANGELOG=$(git log --pretty=format:"- %s (%h)" ${PREVIOUS_TAG}..${CURRENT_TAG})
170+
fi
171+
172+
# Save to file for release body
173+
if [[ "${{ github.ref_name }}" == *-test ]]; then
174+
TEST_WARNING="## ⚠️ TEST RELEASE\n\nThis is a test release for validation purposes. Please use official releases for production.\n\n"
175+
else
176+
TEST_WARNING=""
177+
fi
178+
179+
cat > RELEASE_NOTES.md << EOF
180+
${TEST_WARNING}## What's Changed
181+
182+
$CHANGELOG
183+
184+
## Downloads
185+
186+
### Linux
187+
- x86_64: httpjail-${CURRENT_TAG#v}-linux-x86_64.tar.gz
188+
- ARM64: httpjail-${CURRENT_TAG#v}-linux-aarch64.tar.gz
189+
190+
### macOS
191+
- Intel: httpjail-${CURRENT_TAG#v}-macos-x86_64.tar.gz
192+
- Apple Silicon: httpjail-${CURRENT_TAG#v}-macos-aarch64.tar.gz
193+
194+
## Installation
195+
196+
Download the appropriate tarball for your platform, extract it, and place the binary in your PATH:
197+
198+
\`\`\`bash
199+
tar xzf httpjail-*.tar.gz
200+
sudo mv httpjail-*/httpjail /usr/local/bin/
201+
\`\`\`
202+
203+
Or install from crates.io:
204+
205+
\`\`\`bash
206+
cargo install httpjail
207+
\`\`\`
208+
EOF
209+
210+
echo "PREVIOUS_TAG=$PREVIOUS_TAG" >> $GITHUB_ENV
211+
212+
- name: Create GitHub Release
213+
uses: softprops/action-gh-release@v1
214+
with:
215+
body_path: RELEASE_NOTES.md
216+
files: artifacts/**/*.tar.gz
217+
draft: ${{ steps.check_test.outputs.is_test == 'true' }}
218+
prerelease: ${{ steps.check_test.outputs.is_test == 'true' }}
219+
env:
220+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
221+
222+
- name: Publish to crates.io
223+
if: steps.check_test.outputs.is_test == 'false'
224+
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
225+
env:
226+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

0 commit comments

Comments
 (0)