Skip to content

Merge pull request #46 from instructa/codex/release-1.7.3 #34

Merge pull request #46 from instructa/codex/release-1.7.3

Merge pull request #46 from instructa/codex/release-1.7.3 #34

Workflow file for this run

name: Release
on:
push:
tags:
- "v*"
permissions: {}
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
create-release:
name: Create Draft Release
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Verify release versions are consistent
env:
TAG: ${{ github.ref_name }}
run: |
crate_version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n 1)"
if [ "v$crate_version" != "$TAG" ]; then
echo "tag $TAG does not match Cargo.toml version $crate_version" >&2
exit 1
fi
for manifest in \
package.json \
plugins/planr/.codex-plugin/plugin.json \
plugins/planr/.claude-plugin/plugin.json \
.cursor-plugin/plugin.json; do
manifest_version="$(jq -r .version "$manifest")"
if [ "$manifest_version" != "$crate_version" ]; then
echo "$manifest version $manifest_version does not match Cargo.toml version $crate_version; release with scripts/release.sh" >&2
exit 1
fi
done
if ! grep -q "^## \[$crate_version\]" CHANGELOG.md; then
echo "CHANGELOG.md has no '## [$crate_version]' section; release with scripts/release.sh" >&2
exit 1
fi
- name: Create draft release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "release $TAG already exists; reusing"
else
# Pre-release tags (v1.2.0-alpha.1) are marked as GitHub
# prereleases so `latest` and the curl installer stay on stable.
prerelease_flag=""
case "$TAG" in
*-*) prerelease_flag="--prerelease" ;;
esac
gh release create "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--draft \
$prerelease_flag \
--title "planr $TAG" \
--generate-notes
fi
build:
name: Build ${{ matrix.target }}
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- target: darwin-arm64
rust_target: aarch64-apple-darwin
runner: macos-14
- target: darwin-x86_64
rust_target: x86_64-apple-darwin
runner: macos-14
- target: linux-x86_64
rust_target: x86_64-unknown-linux-musl
runner: ubuntu-24.04
- target: linux-arm64
rust_target: aarch64-unknown-linux-musl
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install Rust target
if: ${{ startsWith(matrix.target, 'darwin-') }}
run: rustup target add ${{ matrix.rust_target }}
- name: Build release artifact
env:
PLANR_TARGET: ${{ matrix.target }}
PLANR_CARGO_TARGET: ${{ matrix.rust_target }}
run: |
case "$PLANR_TARGET" in
linux-*) scripts/build-linux-release.sh ;;
darwin-*) scripts/build-release.sh ;;
*) echo "unsupported release target: $PLANR_TARGET" >&2; exit 1 ;;
esac
- name: Smoke-test binary
env:
PLANR_CARGO_TARGET: ${{ matrix.rust_target }}
TAG: ${{ github.ref_name }}
run: |
reported="$("./target/$PLANR_CARGO_TARGET/release/planr" --version)"
expected="planr ${TAG#v}"
if [ "$reported" != "$expected" ]; then
echo "$PLANR_CARGO_TARGET binary reports '$reported', expected '$expected'" >&2
exit 1
fi
echo "$PLANR_CARGO_TARGET runtime proof: $reported"
- name: Verify portable Linux artifact
if: ${{ startsWith(matrix.target, 'linux-') }}
env:
PLANR_TARGET: ${{ matrix.target }}
PLANR_CARGO_TARGET: ${{ matrix.rust_target }}
run: scripts/verify-linux-release-artifact.sh
- name: Upload release asset
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
PLANR_TARGET: ${{ matrix.target }}
run: |
gh release upload "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--clobber \
"dist/planr-$PLANR_TARGET.tar.gz"
finalize:
name: Publish Checksums And Release
needs: build
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Download release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
mkdir -p assets
gh release download "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--pattern 'planr-*.tar.gz' \
--dir assets
- name: Generate aggregated SHA256SUMS
run: |
cd assets
sha256sum planr-*.tar.gz > SHA256SUMS
cat SHA256SUMS
- name: Upload checksums and publish
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
gh release upload "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--clobber \
assets/SHA256SUMS
gh release edit "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--draft=false
- name: Save checksums for tap job
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: sha256sums
path: assets/SHA256SUMS
npm-publish:
name: Publish npm Package
needs: finalize
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
if: ${{ vars.NPM_PUBLISH_ENABLED == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
registry-url: https://registry.npmjs.org
package-manager-cache: false
- name: Download release assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
run: |
mkdir -p assets
gh release download "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--pattern 'planr-*.tar.gz' \
--pattern 'SHA256SUMS' \
--dir assets
- name: Verify asset checksums
run: |
cd assets
sha256sum -c SHA256SUMS
- name: Bundle platform binaries
env:
TAG: ${{ github.ref_name }}
run: |
version="${TAG#v}"
for target in darwin-arm64 darwin-x86_64 linux-x86_64 linux-arm64; do
mkdir -p "extract/$target" "npm/native/$target"
tar -xzf "assets/planr-$target.tar.gz" -C "extract/$target"
install -m 755 "extract/$target/planr" "npm/native/$target/planr"
done
reported="$(./npm/native/linux-x86_64/planr --version)"
if [ "$reported" != "planr $version" ]; then
echo "bundled binary reports '$reported', expected 'planr $version'" >&2
exit 1
fi
node npm/bin/planr.js --version
- name: Publish to npm
env:
TAG: ${{ github.ref_name }}
run: |
# Pre-releases publish under the `alpha` dist-tag so plain
# `npm install -g planr` keeps resolving to the stable line;
# testers opt in with `npm install -g planr@alpha`.
case "$TAG" in
*-*) npm publish --access public --tag alpha ;;
*) npm publish --access public ;;
esac
homebrew-tap:
name: Update Homebrew Tap
needs: finalize
runs-on: ubuntu-24.04
permissions: {}
# The tap has no channel concept: pre-release tags never move it.
if: ${{ vars.HOMEBREW_TAP_ENABLED == 'true' && !contains(github.ref_name, '-') }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Download checksums
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: sha256sums
path: assets
- name: Generate formula
env:
TAG: ${{ github.ref_name }}
run: |
version="${TAG#v}"
scripts/generate-formula.sh "$version" assets/SHA256SUMS > planr.rb
cat planr.rb
- name: Push formula to tap
env:
TAP_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }}
# `brew install instructa/tap/planr` resolves to this repo name.
TAP_REPO: instructa/homebrew-tap
TAG: ${{ github.ref_name }}
run: |
if [ -z "$TAP_TOKEN" ]; then
echo "TAP_GITHUB_TOKEN secret is not configured; skipping tap update" >&2
exit 1
fi
git clone "https://x-access-token:${TAP_TOKEN}@github.com/${TAP_REPO}.git" tap
mkdir -p tap/Formula
cp planr.rb tap/Formula/planr.rb
cd tap
git config user.name "planr-release-bot"
git config user.email "release-bot@users.noreply.github.com"
git add Formula/planr.rb
if git diff --cached --quiet; then
echo "formula unchanged; nothing to push"
else
git commit -m "planr ${TAG}"
git push origin HEAD
fi