Skip to content

pikachat release

pikachat release #4

name: pikachat release
on:
push:
tags:
- "pikachat-v*"
workflow_dispatch:
inputs:
version:
description: "Version to release (e.g. 0.5.1) — must already be bumped on master"
required: true
type: string
permissions:
contents: write
jobs:
authorize:
runs-on: ubuntu-latest
environment:
name: release
steps:
- name: Enforce allowed release actors
run: |
set -euo pipefail
case "${GITHUB_ACTOR}" in
justinmoon|futurepaul|benthecarman|AnthonyRonning) ;;
*)
echo "error: actor '${GITHUB_ACTOR}' is not allowed to run release workflow"
exit 1
;;
esac
tag-release:
if: github.event_name == 'workflow_dispatch'
needs: authorize
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.tag.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
ref: master
- name: Validate and tag
id: tag
run: |
set -euo pipefail
version="${{ inputs.version }}"
tag="pikachat-v${version}"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "error: version must be x.y.z (got: $version)"
exit 1
fi
# Verify the version is already bumped in source files
cargo_version=$(sed -n 's/^version = "\(.*\)"/\1/p' cli/Cargo.toml)
if [ "$cargo_version" != "$version" ]; then
echo "error: Cargo.toml version is $cargo_version but expected $version"
echo "hint: bump versions first via PR, then run this workflow"
exit 1
fi
pkg_version=$(node -p "require('./pikachat-openclaw/openclaw/extensions/pikachat-openclaw/package.json').version")
if [ "$pkg_version" != "$version" ]; then
echo "error: package.json version is $pkg_version but expected $version"
echo "hint: bump versions first via PR, then run this workflow"
exit 1
fi
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null 2>&1; then
echo "error: tag already exists: $tag"
exit 1
fi
git tag "$tag"
git push origin "$tag"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
resolve-tag:
needs: [authorize, tag-release]
if: always() && needs.authorize.result == 'success'
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.resolve.outputs.tag }}
steps:
- name: Resolve tag
id: resolve
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ needs.tag-release.outputs.tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
fi
build-linux:
needs: resolve-tag
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
asset_name: pikachat-x86_64-linux
runner: ubuntu-22.04
- target: aarch64-unknown-linux-gnu
asset_name: pikachat-aarch64-linux
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.resolve-tag.outputs.tag }}
- uses: dtolnay/rust-toolchain@stable
- name: Add target
run: rustup target add "${{ matrix.target }}"
- name: Build binary
run: cargo build -p pikachat --release --target "${{ matrix.target }}"
- name: Stage artifact
run: |
mkdir -p dist
cp "target/${{ matrix.target }}/release/pikachat" "dist/${{ matrix.asset_name }}"
chmod +x "dist/${{ matrix.asset_name }}"
sha256sum "dist/${{ matrix.asset_name }}" > "dist/${{ matrix.asset_name }}.sha256"
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: |
dist/${{ matrix.asset_name }}
dist/${{ matrix.asset_name }}.sha256
if-no-files-found: error
build-macos:
needs: resolve-tag
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-apple-darwin
asset_name: pikachat-x86_64-darwin
- target: aarch64-apple-darwin
asset_name: pikachat-aarch64-darwin
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.resolve-tag.outputs.tag }}
- uses: dtolnay/rust-toolchain@stable
- name: Add target
run: rustup target add "${{ matrix.target }}"
- name: Build binary
run: cargo build -p pikachat --release --target "${{ matrix.target }}"
- name: Stage artifact
run: |
mkdir -p dist
cp "target/${{ matrix.target }}/release/pikachat" "dist/${{ matrix.asset_name }}"
chmod +x "dist/${{ matrix.asset_name }}"
shasum -a 256 "dist/${{ matrix.asset_name }}" > "dist/${{ matrix.asset_name }}.sha256"
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: |
dist/${{ matrix.asset_name }}
dist/${{ matrix.asset_name }}.sha256
if-no-files-found: error
publish-release:
needs:
- resolve-tag
- build-linux
- build-macos
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
pattern: pikachat-*
merge-multiple: true
path: dist
- name: Publish GitHub release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.resolve-tag.outputs.tag }}
files: dist/*
publish-npm:
needs:
- resolve-tag
- publish-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.resolve-tag.outputs.tag }}
- uses: actions/setup-node@v4
with:
node-version: "22"
registry-url: "https://registry.npmjs.org"
- name: Publish to npm
working-directory: pikachat-openclaw/openclaw/extensions/pikachat-openclaw
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}