Skip to content

Merge pull request #3 from Minitour/develop #16

Merge pull request #3 from Minitour/develop

Merge pull request #3 from Minitour/develop #16

Workflow file for this run

name: Release
on:
push:
tags:
- "v[0-9]*.[0-9]*.[0-9]*"
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
BINARY_NAME: owl-mcp
permissions:
contents: write # needed to create GitHub Releases
jobs:
# ── 1. Build native binaries ────────────────────────────────────────────────
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
npm_platform: linux-x64
binary: owl-mcp
- target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
npm_platform: linux-arm64
binary: owl-mcp
cross: true # use `cross` for aarch64 cross-compilation
- target: x86_64-apple-darwin
runner: macos-latest
npm_platform: darwin-x64
binary: owl-mcp
- target: aarch64-apple-darwin
runner: macos-latest
npm_platform: darwin-arm64
binary: owl-mcp
- target: x86_64-pc-windows-msvc
runner: windows-latest
npm_platform: win32-x64
binary: owl-mcp.exe
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache Cargo registry and build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-${{ matrix.target }}-cargo-
# Patch Cargo.toml so the compiled binary reports the correct release version
- name: Set Cargo.toml version from tag
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
sed -i.bak "s/^version = \".*\"/version = \"${VERSION}\"/" Cargo.toml
rm -f Cargo.toml.bak
- name: Install cross (Linux ARM64)
if: matrix.cross
run: cargo install cross --locked
- name: Build (cross)
if: matrix.cross
run: cross build --release --target ${{ matrix.target }}
- name: Build (native)
if: "!matrix.cross"
run: cargo build --release --target ${{ matrix.target }}
- name: Stage binary
shell: bash
run: |
mkdir -p staging
cp target/${{ matrix.target }}/release/${{ matrix.binary }} staging/
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.npm_platform }}
path: staging/${{ matrix.binary }}
if-no-files-found: error
# ── 2. Publish to GitHub Releases and npm ───────────────────────────────────
publish:
name: Publish
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"
# Strip the leading 'v' from the tag to get a semver version string
- name: Derive version
id: version
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
# Download every platform binary into its own directory
- name: Download all binary artifacts
uses: actions/download-artifact@v4
with:
path: artifacts # each sub-directory will be binary-<npm_platform>/
- name: Publish platform npm packages
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
VERSION: ${{ steps.version.outputs.VERSION }}
run: |
set -euo pipefail
if [[ -z "${NODE_AUTH_TOKEN:-}" ]]; then
echo "::error::NPM_TOKEN secret is not set. Add it in Settings → Secrets → Actions."
exit 1
fi
echo "Publishing version: ${VERSION}"
echo "Artifact structure:"
ls -la artifacts/
for PLATFORM in linux-x64 linux-arm64 darwin-x64 darwin-arm64 win32-x64; do
case "$PLATFORM" in
linux-x64) BINARY="owl-mcp" ; OS="linux" ; CPU="x64" ;;
linux-arm64) BINARY="owl-mcp" ; OS="linux" ; CPU="arm64" ;;
darwin-x64) BINARY="owl-mcp" ; OS="darwin" ; CPU="x64" ;;
darwin-arm64) BINARY="owl-mcp" ; OS="darwin" ; CPU="arm64" ;;
win32-x64) BINARY="owl-mcp.exe" ; OS="win32" ; CPU="x64" ;;
esac
PKG_NAME="@owl-mcp/owl-mcp-${PLATFORM}"
SRC="artifacts/binary-${PLATFORM}/${BINARY}"
echo "Packaging ${PKG_NAME} from ${SRC}"
mkdir -p "pkg-${PLATFORM}/bin"
cp "$SRC" "pkg-${PLATFORM}/bin/${BINARY}"
chmod +x "pkg-${PLATFORM}/bin/${BINARY}"
cat > "pkg-${PLATFORM}/package.json" <<PKGJSON
{
"name": "${PKG_NAME}",
"version": "${VERSION}",
"description": "owl-mcp native binary for ${OS}/${CPU}",
"os": ["${OS}"],
"cpu": ["${CPU}"],
"license": "MIT",
"files": ["bin"]
}
PKGJSON
set +e
OUTPUT=$(npm publish "./pkg-${PLATFORM}" --access public 2>&1)
EXIT_CODE=$?
set -e
if [ $EXIT_CODE -ne 0 ]; then
if echo "$OUTPUT" | grep -qi "previously published version"; then
echo "Skipping ${PKG_NAME}@${VERSION} (already published)"
else
echo "$OUTPUT" >&2
exit $EXIT_CODE
fi
else
echo "$OUTPUT"
fi
sleep 10
done
- name: Update main package version and publish
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
VERSION: ${{ steps.version.outputs.VERSION }}
run: |
set -euo pipefail
cd npm
# Single source of truth: copy repo README for npm package page
cp ../README.md README.md
# Pin all optional dependency versions to the newly released version
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.version = process.env.VERSION;
for (const k of Object.keys(pkg.optionalDependencies || {})) {
pkg.optionalDependencies[k] = process.env.VERSION;
}
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
set +e
OUTPUT=$(npm publish --access public 2>&1)
EXIT_CODE=$?
set -e
if [ $EXIT_CODE -ne 0 ]; then
if echo "$OUTPUT" | grep -qi "previously published version"; then
echo "Skipping owl-mcp@${VERSION} (already published)"
else
echo "$OUTPUT" >&2
exit $EXIT_CODE
fi
else
echo "$OUTPUT"
fi
- name: Delete existing release (if re-running)
env:
GH_TOKEN: ${{ github.token }}
run: gh release delete "${{ github.ref_name }}" --yes --cleanup-tag=false 2>/dev/null || true
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "v${{ steps.version.outputs.VERSION }}"
generate_release_notes: true