Skip to content

Merge pull request #13 from hypurrquant/qa/2026-05-05-v0.13.0-validation #372

Merge pull request #13 from hypurrquant/qa/2026-05-05-v0.13.0-validation

Merge pull request #13 from hypurrquant/qa/2026-05-05-v0.13.0-validation #372

Workflow file for this run

name: CI
on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
name: Build & Test
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22, 24]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Type check (tsc strict)
run: pnpm run build
- name: SKILL.md version sync check
# Fails the PR if package.json bumped without re-running
# scripts/sync-skill-version.mjs. Catches drift between the npm
# package version and the agent-skill bundle's declared version.
run: node scripts/sync-skill-version.mjs --check
- name: Unit tests
run: pnpm test
- name: Integration tests (mainnet public read-only — non-fatal)
# Hits live HL/PAC/LT/Aster public APIs (market list, prices, funding).
# Marked continue-on-error: a single venue outage shouldn't block CI.
# Failure surfaces as a yellow check; investigate manually if persistent.
continue-on-error: true
run: pnpm test:integration
- name: Package smoke test
run: |
set -euxo pipefail
pnpm pack
TARBALL=$(ls perp-cli-*.tgz)
# Verify all bins exist in the package
tar -tzf "$TARBALL" | grep 'dist/index.js'
tar -tzf "$TARBALL" | grep 'dist/mcp-server.js'
tar -tzf "$TARBALL" | grep 'dist/guardrail/perp-guardrail.js'
# Verify SKILL bundle ships (agent surface)
tar -tzf "$TARBALL" | grep 'skills/perp-cli/SKILL.md'
# Install and verify bins actually run
mkdir -p /tmp/smoke-test
cd /tmp/smoke-test
npm init -y > /dev/null 2>&1
npm install "$GITHUB_WORKSPACE/$TARBALL" > /dev/null 2>&1
# --version must match package.json (catches sync-skill-version /
# build mismatch silently shipping a stale dist)
INSTALLED_VERSION=$(npx perp --version)
EXPECTED_VERSION=$(node -p "require('$GITHUB_WORKSPACE/package.json').version")
if [ "$INSTALLED_VERSION" != "$EXPECTED_VERSION" ]; then
echo "::error::Version mismatch: installed=$INSTALLED_VERSION expected=$EXPECTED_VERSION"
exit 1
fi
npx perp --help > /dev/null
# MCP server JSONRPC initialize ping (catches startup regressions
# like missing tools/resources/prompts capabilities or import errors).
INIT_REQ='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"ci","version":"1"}}}'
INIT_RESP=$(echo "$INIT_REQ" | timeout 10 npx perp-mcp 2>/dev/null | head -1)
echo "MCP initialize response: $INIT_RESP"
echo "$INIT_RESP" | grep -q '"result"' || { echo "::error::MCP initialize failed"; exit 1; }
echo "$INIT_RESP" | grep -q "\"version\":\"$EXPECTED_VERSION\"" || { echo "::error::MCP version mismatch"; exit 1; }
release:
name: GitHub Release
needs: build-and-test
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
id: changelog
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$PREV_TAG" ]; then
LOG=$(git log --oneline "$PREV_TAG"..HEAD -- ':!.omc' ':!.github')
else
LOG=$(git log --oneline -20)
fi
echo "changelog<<EOF" >> "$GITHUB_OUTPUT"
echo "$LOG" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
body: |
## Changes
${{ steps.changelog.outputs.changelog }}
**npm:** `npm install -g perp-cli@${{ github.ref_name }}`
**MCP:** `npx -y -p perp-cli perp-mcp`