name: Release
on:
push:
tags:
- "v*"
env:
CARGO_TERM_COLOR: always
jobs:
ci:
name: CI Gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: cargo fmt --check
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy --all-targets -- -D warnings
- name: cargo test
run: cargo test --lib
publish:
name: Publish to crates.io
needs: ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: cargo publish
env:
CARGO_TOKEN_CURRENT: ${{ secrets.CARGO_TOKEN }}
CARGO_TOKEN_LEGACY: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail
VERSION=$(cargo metadata --no-deps --format-version 1 | python3 -c 'import json,sys; print(json.load(sys.stdin)["packages"][0]["version"])')
if curl -fsSL "https://crates.io/api/v1/crates/a3s-memory/${VERSION}" >/dev/null 2>&1; then
echo "a3s-memory ${VERSION} already exists on crates.io, skipping publish."
exit 0
fi
LAST_OUTPUT="No configured crates.io token was available."
attempt_publish() {
local label="$1"
local token="$2"
if [ -z "$token" ]; then
echo "Skipping missing ${label} token."
return 1
fi
echo "Trying ${label} token."
set +e
OUTPUT=$(CARGO_REGISTRY_TOKEN="$token" cargo publish --allow-dirty 2>&1)
STATUS=$?
set -e
echo "$OUTPUT"
LAST_OUTPUT="$OUTPUT"
if [ "$STATUS" -eq 0 ] || echo "$OUTPUT" | grep -Eqi "already (uploaded|exists)"; then
return 0
fi
return 1
}
if attempt_publish legacy "$CARGO_TOKEN_LEGACY"; then
exit 0
fi
if attempt_publish current "$CARGO_TOKEN_CURRENT"; then
exit 0
fi
MESSAGE=$(printf '%s' "$LAST_OUTPUT" | tail -c 1500 | tr '\r\n' ' ' | sed 's/%/%25/g')
echo "::error title=crates.io publish failed::${MESSAGE}"
exit 1
release:
name: GitHub Release
needs: publish
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true