name: Publish systemless crate
on:
push:
branches:
- main
- master
paths:
- Cargo.toml
- Cargo.lock
- README.md
- src/**
- assets/**
- .github/workflows/publish.yml
workflow_dispatch:
inputs:
force:
description: "Publish and update systemless-web even if Cargo.toml version did not change in this event"
required: false
default: false
type: boolean
permissions:
contents: read
concurrency:
group: publish-systemless
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Linux audio dependencies
run: |
sudo apt-get update
sudo apt-get install -y pkg-config libasound2-dev
- name: Detect crate version bump
id: version
env:
EVENT_NAME: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
FORCE: ${{ inputs.force || false }}
run: |
set -euo pipefail
version=$(
sed -n '0,/^version = /s/^version = "\(.*\)"/\1/p' Cargo.toml
)
if [ -z "$version" ]; then
echo "Could not read package version from Cargo.toml" >&2
exit 1
fi
previous_version=""
if [ "$EVENT_NAME" = "push" ] && [ -n "$BEFORE_SHA" ] && git cat-file -e "$BEFORE_SHA:Cargo.toml" 2>/dev/null; then
previous_version=$(
git show "$BEFORE_SHA:Cargo.toml" \
| sed -n '0,/^version = /s/^version = "\(.*\)"/\1/p'
)
fi
should_release=false
if [ "$FORCE" = "true" ]; then
should_release=true
elif [ "$EVENT_NAME" = "push" ] && [ "$version" != "$previous_version" ]; then
should_release=true
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "previous_version=$previous_version" >> "$GITHUB_OUTPUT"
echo "should_release=$should_release" >> "$GITHUB_OUTPUT"
- name: Dry-run package publish
if: steps.version.outputs.should_release == 'true'
run: cargo publish --locked --dry-run
- name: Validate crates.io token
if: steps.version.outputs.should_release == 'true'
env:
SYSTEMLESS_CRATES_TOKEN: ${{ secrets.SYSTEMLESS_CRATES_TOKEN }}
run: |
if [ -z "$SYSTEMLESS_CRATES_TOKEN" ]; then
echo "SYSTEMLESS_CRATES_TOKEN must contain the crates.io API token" >&2
exit 1
fi
- name: Publish crate
if: steps.version.outputs.should_release == 'true'
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.SYSTEMLESS_CRATES_TOKEN }}
run: |
set +e
output=$(cargo publish --locked 2>&1)
status=$?
set -e
echo "$output"
if [ "$status" -eq 0 ]; then
exit 0
fi
if echo "$output" | grep -Eiq 'already uploaded|already exists|previously uploaded|crate version .* is already'; then
echo "systemless ${{ steps.version.outputs.version }} is already published; continuing."
exit 0
fi
exit "$status"
- name: Update systemless-web dependency
if: steps.version.outputs.should_release == 'true'
env:
SYSTEMLESS_WEB_GITHUB_TOKEN: ${{ secrets.SYSTEMLESS_WEB_GITHUB_TOKEN }}
SYSTEMLESS_WEB_REPOSITORY: benletchford/systemless-web
SYSTEMLESS_WEB_REF: master
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
if [ -z "$SYSTEMLESS_WEB_GITHUB_TOKEN" ]; then
echo "SYSTEMLESS_WEB_GITHUB_TOKEN is required to update systemless-web" >&2
exit 1
fi
web_dir="$RUNNER_TEMP/systemless-web"
rm -rf "$web_dir"
git clone \
--branch "$SYSTEMLESS_WEB_REF" \
--single-branch \
"https://x-access-token:${SYSTEMLESS_WEB_GITHUB_TOKEN}@github.com/${SYSTEMLESS_WEB_REPOSITORY}.git" \
"$web_dir"
cd "$web_dir"
for attempt in $(seq 1 20); do
if cargo add "systemless@$VERSION" --no-default-features; then
break
fi
if [ "$attempt" = "20" ]; then
echo "systemless $VERSION did not become available in the crates.io index in time" >&2
exit 1
fi
echo "systemless $VERSION is not available in the crates.io index yet; retrying ($attempt/20)..."
sleep 15
done
if git diff --quiet -- Cargo.toml Cargo.lock; then
echo "systemless-web is already resolved to systemless $VERSION"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock
git commit -m "Update systemless to $VERSION"
git push origin "HEAD:$SYSTEMLESS_WEB_REF"