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