name: Release rload
on:
push:
tags: ["v*.*.*"]
workflow_dispatch:
inputs:
tag:
description: "Release tag (for example v0.2.0)"
required: true
type: string
permissions:
actions: write
contents: write
env:
CARGO_TERM_COLOR: always
jobs:
build-binaries:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
archive: tar.gz
- os: macos-14
target: aarch64-apple-darwin
archive: tar.gz
- os: macos-15-intel
target: x86_64-apple-darwin
archive: tar.gz
- os: windows-2022
target: x86_64-pc-windows-msvc
archive: zip
steps:
- name: Check out release tag
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
fetch-depth: 0
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build release binary
run: cargo build --locked --release --target "${{ matrix.target }}"
- name: Package Unix binary
if: matrix.archive == 'tar.gz'
shell: bash
run: |
set -euo pipefail
version="${RELEASE_TAG#v}"
mkdir "rload-${version}-${{ matrix.target }}"
cp "target/${{ matrix.target }}/release/rload" "rload-${version}-${{ matrix.target }}/rload"
cp README.md LICENSE-MIT LICENSE-APACHE "rload-${version}-${{ matrix.target }}/"
tar -czf "rload-${version}-${{ matrix.target }}.tar.gz" "rload-${version}-${{ matrix.target }}"
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "rload-${version}-${{ matrix.target }}.tar.gz" > "rload-${version}-${{ matrix.target }}.tar.gz.sha256"
else
shasum -a 256 "rload-${version}-${{ matrix.target }}.tar.gz" > "rload-${version}-${{ matrix.target }}.tar.gz.sha256"
fi
- name: Package Windows binary
if: matrix.archive == 'zip'
shell: pwsh
run: |
$version = $env:RELEASE_TAG.TrimStart('v')
$name = "rload-$version-${{ matrix.target }}"
New-Item -ItemType Directory -Path $name | Out-Null
Copy-Item "target/${{ matrix.target }}/release/rload.exe" "$name/rload.exe"
Copy-Item README.md,LICENSE-MIT,LICENSE-APACHE $name
Compress-Archive -Path $name -DestinationPath "$name.zip"
$hash = (Get-FileHash "$name.zip" -Algorithm SHA256).Hash.ToLower()
"$hash $name.zip" | Set-Content "$name.zip.sha256"
- name: Upload binary artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.target }}
path: |
*.tar.gz
*.tar.gz.sha256
*.zip
*.zip.sha256
release:
needs: build-binaries
runs-on: ubuntu-latest
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
steps:
- name: Check out release tag
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
fetch-depth: 0
- name: Validate version and tag
shell: bash
run: |
set -euo pipefail
tag_version="${RELEASE_TAG#v}"
crate_version="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -1)"
test "$tag_version" = "$crate_version" || {
echo "tag $tag_version does not match Cargo.toml $crate_version" >&2
exit 1
}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Verify release
run: ./scripts/release-check.sh
- name: Publish crate
run: cargo publish --locked --token "${{ secrets.CARGO_REGISTRY_TOKEN }}"
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$RELEASE_TAG" --verify-tag --generate-notes --title "$RELEASE_TAG"
- name: Download binary artifacts
uses: actions/download-artifact@v4
with:
pattern: binaries-*
path: dist
merge-multiple: true
- name: Upload precompiled binaries
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload "$RELEASE_TAG" dist/* --clobber
- name: Update Homebrew tap
env:
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
TAP_REPOSITORY: wenhaozhao/homebrew-rload
shell: bash
run: |
set -euo pipefail
version="${RELEASE_TAG#v}"
release_base="https://github.com/${GITHUB_REPOSITORY}/releases/download/${RELEASE_TAG}"
linux_archive="rload-${version}-x86_64-unknown-linux-gnu.tar.gz"
macos_archive="rload-${version}-aarch64-apple-darwin.tar.gz"
macos_intel_archive="rload-${version}-x86_64-apple-darwin.tar.gz"
linux_url="${release_base}/${linux_archive}"
macos_url="${release_base}/${macos_archive}"
macos_intel_url="${release_base}/${macos_intel_archive}"
linux_sha256="$(curl -fsSL "${linux_url}.sha256" | awk '{print $1}')"
macos_sha256="$(curl -fsSL "${macos_url}.sha256" | awk '{print $1}')"
macos_intel_sha256="$(curl -fsSL "${macos_intel_url}.sha256" | awk '{print $1}')"
test "${#linux_sha256}" = 64
test "${#macos_sha256}" = 64
test "${#macos_intel_sha256}" = 64
git clone "https://x-access-token:${TAP_TOKEN}@github.com/${TAP_REPOSITORY}.git" /tmp/homebrew-rload
cd /tmp/homebrew-rload
python3 - "$version" "$linux_url" "$linux_sha256" "$macos_url" "$macos_sha256" "$macos_intel_url" "$macos_intel_sha256" <<'PY'
from pathlib import Path
import sys
version, linux_url, linux_sha256, macos_url, macos_sha256, macos_intel_url, macos_intel_sha256 = sys.argv[1:]
path = Path("Formula/rload.rb")
path.write_text(f'''class Rload < Formula
desc "Rust HTTP load generator with Nginx access-log and JSONL replay"
homepage "https://wenhaozhao.github.io/rload/"
license any_of: ["MIT", "Apache-2.0"]
on_arm do
url "{macos_url}"
sha256 "{macos_sha256}"
end
on_intel do
url "{macos_intel_url}"
sha256 "{macos_intel_sha256}"
end
on_linux do
url "{linux_url}"
sha256 "{linux_sha256}"
end
def install
bin.install "rload"
end
test do
assert_match "rload", shell_output("#{{bin}}/rload --help")
end
end
''')
PY
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add Formula/rload.rb
git commit -m "Update rload to ${version}" || exit 0
git push origin main
- name: Update website version
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
version="${RELEASE_TAG#v}"
git fetch origin main
git worktree add /tmp/rload-main origin/main
cd /tmp/rload-main
python3 - "$version" <<'PY'
from pathlib import Path
import re, sys
version = sys.argv[1]
path = Path("website/index.html")
text = path.read_text()
text = re.sub(r'\b\d+\.\d+\.\d+ 最新版本', f'{version} 最新版本', text)
text = re.sub(r'rload \d+\.\d+\.\d+', f'rload {version}', text)
path.write_text(text)
PY
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add website/index.html
git commit -m "Update website for rload ${version}" || exit 0
git push origin HEAD:main
- name: Deploy updated website
env:
GH_TOKEN: ${{ github.token }}
run: gh workflow run pages.yml --ref main