name: Publish
on:
push:
branches: [main]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
concurrency:
group: publish
cancel-in-progress: false
jobs:
check:
name: Check release needed
runs-on: ubuntu-latest
outputs:
version: ${{ steps.check.outputs.version }}
release: ${{ steps.check.outputs.release }}
steps:
- uses: actions/checkout@v4
- name: Compare Cargo.toml version against crates.io
id: check
run: |
VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
# The sparse index needs no auth and serves one JSON line per
# published version. A 404 means the crate has never been
# published, which also means "release".
if curl -sf "https://index.crates.io/fi/xe/fixed_analytics" \
| jq -e --arg v "$VERSION" 'select(.vers == $v)' > /dev/null; then
echo "release=false" >> "$GITHUB_OUTPUT"
echo "v$VERSION is already on crates.io — nothing to release"
else
echo "release=true" >> "$GITHUB_OUTPUT"
echo "v$VERSION is not on crates.io — releasing"
fi
test:
name: Pre-publish Tests
needs: check
if: needs.check.outputs.release == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --features std
- run: cargo test --no-default-features
- run: cargo doc --no-deps --features std
env:
RUSTDOCFLAGS: -Dwarnings
release:
name: Tag, publish, and release
needs: [check, test]
if: needs.check.outputs.release == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
env:
VERSION: ${{ needs.check.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Create tag if missing
run: |
if git ls-remote --tags origin "refs/tags/v$VERSION" | grep -q .; then
echo "Tag v$VERSION already exists, keeping it"
else
git tag "v$VERSION"
git push origin "v$VERSION"
fi
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ needs.check.outputs.version }}
generate_release_notes: true
body: |
## Installation
```toml
[dependencies]
fixed_analytics = "${{ needs.check.outputs.version }}"
```
For `no_std` environments:
```toml
[dependencies]
fixed_analytics = { version = "${{ needs.check.outputs.version }}", default-features = false }
```