Release v0.1.3 #8
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 }} |