Skip to content

Release v0.1.0-beta.6 #3

Release v0.1.0-beta.6

Release v0.1.0-beta.6 #3

Workflow file for this run

# Manual distribution workflow. Push a v* tag first; `Release Prepare` runs the
# test suite and builds the fsck binaries. Then run this workflow with that tag
# and the successful prepare run ID.
#
# The GitHub Release consumes the prepare run's artifacts, so a failed publish
# or release stage is retried by re-dispatching with only that stage enabled —
# the tests and the binaries are never rebuilt to fix a crates.io timeout or a
# bad release body.
#
# Stages:
# publish_crate -> crates.io (single crate; verifying publish)
# github_release -> GitHub Release with the fsck binaries attached
#
# Each stage is idempotent: an already-indexed version is skipped, the release
# is overwritten in place. Re-running is safe.
#
# Required secret: CARGO_REGISTRY_TOKEN.
name: Release
run-name: Release ${{ inputs.tag }}
on:
workflow_dispatch:
inputs:
tag:
description: "Release tag to publish, e.g. v0.1.0"
required: true
type: string
prepare_run_id:
description: "Successful Release Prepare run ID holding the binaries"
required: true
type: string
publish_crate:
description: "Publish pagedb to crates.io"
type: boolean
default: true
github_release:
description: "Create the GitHub Release"
type: boolean
default: true
concurrency:
group: release
cancel-in-progress: false
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
# Always runs. Cheap, and it guarantees the dispatched tag still means what
# the prepare run assumed it meant.
validate-version:
uses: ./.github/workflows/release-validate.yml
with:
ref: ${{ inputs.tag }}
# ── crates.io ────────────────────────────────────────────────────────────────
# pagedb is a single leaf crate — no publish-order tiers. A verifying publish
# (no --no-verify) is the strongest guarantee the uploaded tarball builds from
# a clean checkout, and there is no inter-crate index race to skip it for.
publish-crate:
name: Publish to crates.io
needs: validate-version
if: inputs.publish_crate
runs-on: ubuntu-latest
environment: crates.io
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.tag }}
- name: Install Rust
uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
# The verifying publish compiles the packaged lib + the pagedb-fsck bin
# against crates.io deps. The io-uring VFS backend needs nothing extra,
# but clang/libclang keeps parity with the test image in case a future
# build-dep needs bindgen.
- name: Install LLVM/Clang
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends clang libclang-dev
- name: Set version from tag
run: bash scripts/ci/stamp_version.sh "${{ needs.validate-version.outputs.version }}"
- name: Publish pagedb
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail
VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r '.packages[] | select(.name == "pagedb") | .version')
is_published() {
curl -sf \
-H "User-Agent: pagedb-ci (github.com/nodedb-lab/pagedb)" \
"https://crates.io/api/v1/crates/pagedb/$1" > /dev/null 2>&1
}
if is_published "$VERSION"; then
echo "pagedb@$VERSION already published — skipping"
exit 0
fi
echo "Publishing pagedb@$VERSION..."
# --allow-dirty: stamp_version.sh may have edited Cargo.toml for a
# prerelease tag; the verifying publish still runs.
cargo publish -p pagedb --allow-dirty
# ── GitHub Release ───────────────────────────────────────────────────────────
# Independent of publish-crate: a crates.io outage must not block cutting the
# release, and re-running this stage alone is the fix for a bad release body.
github-release:
name: Create GitHub Release
needs: validate-version
if: inputs.github_release
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.tag }}
fetch-depth: 0
# Runs before the download so a wrong, unfinished, or foreign run is
# rejected without its archives ever reaching the runner.
- name: Verify prepare run
env:
GH_TOKEN: ${{ github.token }}
PREPARE_RUN_ID: ${{ inputs.prepare_run_id }}
run: |
set -euo pipefail
[[ "$PREPARE_RUN_ID" =~ ^[0-9]+$ ]] || {
echo "::error::prepare_run_id must be numeric"
exit 1
}
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"repos/${GITHUB_REPOSITORY}/actions/runs/${PREPARE_RUN_ID}" \
>"$RUNNER_TEMP/prepare-run.json"
bash scripts/ci/verify_prepare_run.sh \
"$RUNNER_TEMP/prepare-run.json" \
"$(git rev-parse HEAD)"
- name: Download fsck artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: "fsck-*"
run-id: ${{ inputs.prepare_run_id }}
github-token: ${{ github.token }}
path: ./artifacts
merge-multiple: true
- name: Verify release artifacts
env:
VERSION: ${{ needs.validate-version.outputs.version }}
run: |
set -euo pipefail
bash scripts/ci/verify_release_artifacts.sh ./artifacts "$VERSION"
# The changelog is the release notes. Auto-generated notes list commit
# subjects, which describe what was done to the code; the changelog
# describes what changed for the person upgrading. `validate-version`
# has already proved this section exists and is non-empty.
- name: Build release notes from the changelog
env:
TAG: ${{ inputs.tag }}
BASE: ${{ needs.validate-version.outputs.base_version }}
run: |
set -euo pipefail
PREVIOUS_TAG=$(git tag --sort=-v:refname 'v*' | grep -v "^${TAG}$" | head -n 1 || true)
bash scripts/ci/changelog_section.sh "$BASE" /tmp/changelog-section.md
{
cat /tmp/changelog-section.md
echo
if [[ -n "$PREVIOUS_TAG" ]]; then
echo "**Full diff:** https://github.com/nodedb-lab/pagedb/compare/${PREVIOUS_TAG}...${TAG}"
else
echo "**Tree:** https://github.com/nodedb-lab/pagedb/tree/${TAG}"
fi
} > /tmp/release-notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
tag_name: ${{ inputs.tag }}
name: pagedb ${{ needs.validate-version.outputs.version }}
body_path: /tmp/release-notes.md
draft: false
prerelease: ${{ needs.validate-version.outputs.is_full_release != 'true' }}
files: artifacts/*
fail_on_unmatched_files: true