fix(pi): let agent submit any markdown plan file by path #852
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| inputs: | |
| dry-run: | |
| description: Validate build and npm publish without uploading | |
| type: boolean | |
| default: true | |
| permissions: | |
| contents: read | |
| env: | |
| DRY_RUN: ${{ !(startsWith(github.ref, 'refs/tags/') || inputs.dry-run == 'false') }} | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: 1.3.11 | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Generate Pi extension shared copies | |
| run: bash apps/pi-extension/vendor.sh | |
| - name: Type check | |
| run: bun run typecheck | |
| - name: Run tests | |
| run: bun test | |
| build: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| # Build job has NO id-token / attestations permissions. Compilation | |
| # itself doesn't need OIDC minting — those capabilities live in the | |
| # separate `attest` job below, which only runs on tag pushes. This | |
| # ensures PR dry-runs (which exercise `bun install` + compile) never | |
| # have OIDC minting available, closing the narrow-but-real | |
| # "trusted-contributor compromise lets a malicious build step mint | |
| # a repo-identity OIDC token" attack surface. | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: 1.3.11 | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Build UI | |
| run: | | |
| bun run build:review | |
| bun run build:hook | |
| - name: Compile binaries (cross-compile all targets) | |
| run: | | |
| # macOS ARM64 | |
| bun build apps/hook/server/index.ts --compile --target=bun-darwin-arm64 --outfile plannotator-darwin-arm64 | |
| sha256sum plannotator-darwin-arm64 > plannotator-darwin-arm64.sha256 | |
| # macOS x64 | |
| bun build apps/hook/server/index.ts --compile --target=bun-darwin-x64 --outfile plannotator-darwin-x64 | |
| sha256sum plannotator-darwin-x64 > plannotator-darwin-x64.sha256 | |
| # Linux x64 | |
| bun build apps/hook/server/index.ts --compile --target=bun-linux-x64 --outfile plannotator-linux-x64 | |
| sha256sum plannotator-linux-x64 > plannotator-linux-x64.sha256 | |
| # Linux ARM64 | |
| bun build apps/hook/server/index.ts --compile --target=bun-linux-arm64 --outfile plannotator-linux-arm64 | |
| sha256sum plannotator-linux-arm64 > plannotator-linux-arm64.sha256 | |
| # Windows x64 | |
| bun build apps/hook/server/index.ts --compile --target=bun-windows-x64 --outfile plannotator-win32-x64.exe | |
| sha256sum plannotator-win32-x64.exe > plannotator-win32-x64.exe.sha256 | |
| # Windows ARM64 (native, via bun-windows-arm64 — stable since Bun v1.3.10) | |
| bun build apps/hook/server/index.ts --compile --target=bun-windows-arm64 --outfile plannotator-win32-arm64.exe | |
| sha256sum plannotator-win32-arm64.exe > plannotator-win32-arm64.exe.sha256 | |
| # Paste service binaries | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-darwin-arm64 --outfile plannotator-paste-darwin-arm64 | |
| sha256sum plannotator-paste-darwin-arm64 > plannotator-paste-darwin-arm64.sha256 | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-darwin-x64 --outfile plannotator-paste-darwin-x64 | |
| sha256sum plannotator-paste-darwin-x64 > plannotator-paste-darwin-x64.sha256 | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-linux-x64 --outfile plannotator-paste-linux-x64 | |
| sha256sum plannotator-paste-linux-x64 > plannotator-paste-linux-x64.sha256 | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-linux-arm64 --outfile plannotator-paste-linux-arm64 | |
| sha256sum plannotator-paste-linux-arm64 > plannotator-paste-linux-arm64.sha256 | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-windows-x64 --outfile plannotator-paste-win32-x64.exe | |
| sha256sum plannotator-paste-win32-x64.exe > plannotator-paste-win32-x64.exe.sha256 | |
| bun build apps/paste-service/targets/bun.ts --compile --target=bun-windows-arm64 --outfile plannotator-paste-win32-arm64.exe | |
| sha256sum plannotator-paste-win32-arm64.exe > plannotator-paste-win32-arm64.exe.sha256 | |
| - name: Smoke-test linux-x64 binary | |
| run: | | |
| chmod +x plannotator-linux-x64 | |
| # 1. --help: proves binary loads and arg parsing works | |
| ./plannotator-linux-x64 --help | |
| # Helper: start server, poll endpoint for 200, kill | |
| smoke_test_server() { | |
| local LABEL="$1" PORT="$2" ENDPOINT="$3" | |
| shift 3 | |
| # Start the binary in background | |
| PLANNOTATOR_PORT=$PORT "$@" & | |
| local PID=$! | |
| # Poll until the API responds (up to 10s) | |
| local OK=0 | |
| for i in $(seq 1 20); do | |
| if curl -sf "http://localhost:${PORT}${ENDPOINT}" -o /dev/null 2>/dev/null; then | |
| OK=1; break | |
| fi | |
| sleep 0.5 | |
| done | |
| kill $PID 2>/dev/null; wait $PID 2>/dev/null || true | |
| if [ "$OK" = "0" ]; then | |
| echo "FAIL: $LABEL did not respond on :${PORT}${ENDPOINT}" | |
| exit 1 | |
| fi | |
| echo "OK: $LABEL — :${PORT}${ENDPOINT} responded" | |
| } | |
| # 2. review: exercises full server startup (imports, bundled HTML, git diff, HTTP) | |
| smoke_test_server "plannotator review" 19500 "/api/diff" \ | |
| ./plannotator-linux-x64 review | |
| # 3. annotate: exercises annotate server path with a real file | |
| smoke_test_server "plannotator annotate" 19501 "/api/plan" \ | |
| ./plannotator-linux-x64 annotate README.md | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: binaries | |
| path: | | |
| plannotator-* | |
| !*.ts | |
| attest: | |
| # Isolated attestation job — runs on tag pushes only and holds the | |
| # OIDC minting + attestations-write capabilities that the build job | |
| # used to have. Splitting this out means PR builds and non-tag pushes | |
| # never get id-token: write granted, closing the trusted-contributor | |
| # compromise window where a malicious build step could mint a | |
| # repo-identity OIDC token. The attestation is produced against the | |
| # same binaries the build job uploaded; attest-build-provenance | |
| # publishes the signed bundle to GitHub's attestation store, so the | |
| # release job downstream doesn't need any new artifact handling. | |
| needs: build | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - name: Download binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: binaries | |
| - name: Generate SLSA build provenance attestation | |
| uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 | |
| with: | |
| subject-path: | | |
| plannotator-darwin-arm64 | |
| plannotator-darwin-x64 | |
| plannotator-linux-x64 | |
| plannotator-linux-arm64 | |
| plannotator-win32-x64.exe | |
| plannotator-win32-arm64.exe | |
| plannotator-paste-darwin-arm64 | |
| plannotator-paste-darwin-x64 | |
| plannotator-paste-linux-x64 | |
| plannotator-paste-linux-arm64 | |
| plannotator-paste-win32-x64.exe | |
| plannotator-paste-win32-arm64.exe | |
| release: | |
| # Depends on `attest` so the signed provenance exists before the | |
| # GitHub Release is published — otherwise there'd be a window where | |
| # users could pull the binary and `gh attestation verify` would | |
| # race-fail. `needs: attest` implicitly requires `build` too. | |
| needs: attest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Download artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: binaries | |
| path: artifacts | |
| - name: List artifacts | |
| run: ls -la artifacts/ | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 | |
| with: | |
| files: artifacts/* | |
| generate_release_notes: true | |
| draft: false | |
| prerelease: ${{ contains(github.ref, '-') }} | |
| npm-publish: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: 1.3.11 | |
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | |
| with: | |
| node-version: 24 | |
| registry-url: https://registry.npmjs.org | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Build packages | |
| run: | | |
| bun run build:review | |
| bun run build:hook | |
| bun run build:opencode | |
| bun run build:pi | |
| - name: Publish @plannotator/opencode | |
| working-directory: apps/opencode-plugin | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| bun pm pack | |
| if [[ "$DRY_RUN" == "false" ]]; then | |
| npm publish *.tgz --provenance --access public | |
| fi | |
| - name: Publish @plannotator/pi-extension | |
| working-directory: apps/pi-extension | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| bun pm pack | |
| if [[ "$DRY_RUN" == "false" ]]; then | |
| npm publish *.tgz --provenance --access public | |
| fi |