name: Release
on:
workflow_dispatch:
inputs:
ref:
description: "git ref to release (can be a branch or a commit hash)"
required: true
default: "main"
type: string
jobs:
check:
runs-on: ubuntu-latest
outputs:
ref: ${{ steps.plan.outputs.ref }}
first: ${{ steps.plan.outputs.first }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with:
ref: ${{ inputs.ref }}
persist-credentials: false
- name: Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libudev-dev clang llvm-dev libclang-dev pkg-config libssl-dev
- name: Compute release plan
id: plan
env:
GH_TOKEN: ${{ github.token }}
run: |
first=""
work=false
echo "## Release plan" >> "${GITHUB_STEP_SUMMARY}"
for crate in jetstreamer-utils jetstreamer-firehose jetstreamer-plugin jetstreamer; do
version="$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "'"${crate}"'") | .version')"
if [ -z "${version}" ] || [ "${version}" = "null" ]; then
echo "Could not resolve version for crate: ${crate}"
exit 1
fi
tag="${crate}@v${version}"
todo=""
if ! curl -fsSL --retry 3 -H "User-Agent: jetstreamer-release-workflow (github.com/anza-xyz/jetstreamer)" \
"https://crates.io/api/v1/crates/${crate}/${version}" 2>/dev/null | jq -e '.version.num == "'"${version}"'"' >/dev/null 2>&1; then
todo="publish"
if [ -z "${first}" ]; then
first="${crate}"
fi
fi
if ! git ls-remote --exit-code --tags origin "refs/tags/${tag}" >/dev/null 2>&1; then
todo="${todo:+${todo}, }tag"
fi
if ! gh release view "${tag}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
todo="${todo:+${todo}, }github release"
fi
if [ -n "${todo}" ]; then
work=true
echo "- \`${tag}\`: needs ${todo}" >> "${GITHUB_STEP_SUMMARY}"
else
echo "- \`${tag}\`: fully released, will skip" >> "${GITHUB_STEP_SUMMARY}"
fi
done
if [ "${work}" = "false" ]; then
echo "Every crate at the current version is already fully released. Bump versions first."
exit 1
fi
echo "first=${first}" >> "${GITHUB_OUTPUT}"
echo "ref=$(git rev-parse HEAD)" >> "${GITHUB_OUTPUT}"
- name: Cargo publish dry run (first unpublished crate)
if: steps.plan.outputs.first != ''
run: cargo publish -p "${FIRST}" --dry-run
env:
FIRST: ${{ steps.plan.outputs.first }}
publish:
runs-on: ubuntu-latest
environment: prod
needs: check
permissions:
id-token: write
contents: write
attestations: write
artifact-metadata: write
steps:
- name: Create github app token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 id: app-token
with:
client-id: ${{ vars.CLIENT_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Set git config
run: |
git config --global user.email "${APP_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
git config --global user.name "${APP_SLUG}[bot]"
git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf https://github.com/
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
APP_ID: ${{ vars.APP_ID }}
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with:
token: ${{ steps.app-token.outputs.token }}
persist-credentials: false
ref: ${{ needs.check.outputs.ref }}
- name: Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libudev-dev clang llvm-dev libclang-dev pkg-config libssl-dev
- name: Create crate token (jetstreamer-utils)
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 id: auth-utils
- name: Release jetstreamer-utils
id: release-utils
run: .github/scripts/release-crate.sh jetstreamer-utils
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth-utils.outputs.token }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Generate SLSA provenance (jetstreamer-utils)
if: steps.release-utils.outputs.published == 'true'
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with:
subject-path: target/package/jetstreamer-utils-*.crate
- name: Create crate token (jetstreamer-firehose)
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 id: auth-firehose
- name: Release jetstreamer-firehose
id: release-firehose
run: .github/scripts/release-crate.sh jetstreamer-firehose
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth-firehose.outputs.token }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Generate SLSA provenance (jetstreamer-firehose)
if: steps.release-firehose.outputs.published == 'true'
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with:
subject-path: target/package/jetstreamer-firehose-*.crate
- name: Create crate token (jetstreamer-plugin)
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 id: auth-plugin
- name: Release jetstreamer-plugin
id: release-plugin
run: .github/scripts/release-crate.sh jetstreamer-plugin
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth-plugin.outputs.token }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Generate SLSA provenance (jetstreamer-plugin)
if: steps.release-plugin.outputs.published == 'true'
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with:
subject-path: target/package/jetstreamer-plugin-*.crate
- name: Create crate token (jetstreamer)
uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 id: auth-jetstreamer
- name: Release jetstreamer
id: release-jetstreamer
run: .github/scripts/release-crate.sh jetstreamer
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth-jetstreamer.outputs.token }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Generate SLSA provenance (jetstreamer)
if: steps.release-jetstreamer.outputs.published == 'true'
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 with:
subject-path: target/package/jetstreamer-[0-9]*.crate