Skip to content

Release v0.1.3

Release v0.1.3 #8

Workflow file for this run

# Publish to crates.io on version tags.
#
# Pipeline: benchmark.yml (which calls test.yml) must pass before publishing.
# This ensures no release ships with a regression or failing test.
name: Release
run-name: Release ${{ github.ref_name }}
on:
push:
tags:
- "v*"
concurrency:
group: release
cancel-in-progress: false
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
benchmark:
name: Benchmark Suite
uses: ./.github/workflows/benchmark.yml
validate-version:
name: Validate Version Tag
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Validate tag against workspace version
id: version
run: |
TAG="${GITHUB_REF_NAME}"
TAG_VERSION="${TAG#v}"
CARGO_VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r '.packages[] | select(.name == "fluxbench") | .version')
CARGO_BASE=$(echo "$CARGO_VERSION" | grep -oP '^\d+\.\d+\.\d+')
echo "Tag version: $TAG_VERSION"
echo "Cargo.toml version: $CARGO_VERSION"
echo "Cargo.toml base: $CARGO_BASE"
if [[ ! "$TAG_VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-[a-zA-Z]+\.[0-9]+)?$ ]]; then
echo "::error::Invalid tag format '$TAG'. Expected: vX.Y.Z or vX.Y.Z-label.N"
exit 1
fi
TAG_BASE="${BASH_REMATCH[1]}"
if [[ "$TAG_BASE" != "$CARGO_BASE" ]]; then
echo "::error::Base version mismatch! Tag '$TAG_BASE' != Cargo.toml '$CARGO_BASE'"
exit 1
fi
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
publish:
name: Publish to crates.io
needs: [validate-version, benchmark]
runs-on: ubuntu-latest
environment: crates-io
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
# Update [workspace.package] version and all fluxbench-* dependency
# versions in [workspace.dependencies] to match the tag.
- name: Set version from tag
run: |
VERSION="${{ needs.validate-version.outputs.version }}"
CURRENT=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[] | select(.name == "fluxbench") | .version')
if [[ "$VERSION" != "$CURRENT" ]]; then
# Update workspace.package version (first occurrence)
sed -i "0,/^version = \".*\"/s//version = \"$VERSION\"/" Cargo.toml
# Update all fluxbench-* dependency versions
sed -i "s/\(fluxbench[a-z-]* = { path = \"[^\"]*\", version = \"\)[^\"]*\"/\1=$VERSION\"/" Cargo.toml
echo "Updated all versions: $CURRENT -> $VERSION"
else
echo "Version already matches, no change needed"
fi
# Publish workspace crates in dependency tiers.
# Each tier is published in parallel, then we wait for all to be available
# before moving to the next tier. Skips already-published crates.
- name: Publish to crates.io
run: |
# Tiers: each tier's deps are satisfied by previous tiers
TIER1="fluxbench-ipc fluxbench-macros fluxbench-stats"
TIER2="fluxbench-core"
TIER3="fluxbench-logic"
TIER4="fluxbench-report"
TIER5="fluxbench-cli"
TIER6="fluxbench"
is_published() {
cargo search "$1" --limit 1 2>/dev/null | grep -q "\"$2\""
}
wait_for() {
local crate="$1" version="$2"
echo -n " Waiting for $crate@$version..."
for i in $(seq 1 60); do
if is_published "$crate" "$version"; then
echo " ready"
return 0
fi
sleep 5
done
echo " timed out!"
return 1
}
publish_tier() {
local tier_name="$1"; shift
local crates=("$@")
local need_wait=()
echo "::group::Tier: $tier_name"
for crate in "${crates[@]}"; do
VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r --arg name "$crate" '.packages[] | select(.name == $name) | .version')
if is_published "$crate" "$VERSION"; then
echo " ✓ $crate@$VERSION already published"
else
echo " Publishing $crate@$VERSION..."
cargo publish -p "$crate" --allow-dirty --no-verify
need_wait+=("$crate:$VERSION")
fi
done
for entry in "${need_wait[@]}"; do
wait_for "${entry%%:*}" "${entry##*:}"
done
echo "::endgroup::"
}
publish_tier "1 (no deps)" $TIER1
publish_tier "2 (core)" $TIER2
publish_tier "3 (logic)" $TIER3
publish_tier "4 (report)" $TIER4
publish_tier "5 (cli)" $TIER5
publish_tier "6 (fluxbench)" $TIER6
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}