Skip to content

v2.58.0 — Distribution-surface hardening + craft-mcp Desktop bridge #1

v2.58.0 — Distribution-surface hardening + craft-mcp Desktop bridge

v2.58.0 — Distribution-surface hardening + craft-mcp Desktop bridge #1

Workflow file for this run

name: Craft MCP Release
# Builds the craft-mcp .mcpb (DXT) bundle and attaches it to the GitHub release
# as craft-mcp-v<mcpVersion>.mcpb (himalaya-mcp precedent). Claude Desktop
# installs the .mcpb via its own app UI, not brew.
#
# VERSIONING: the .mcpb carries its OWN semver (mcp/package.json, currently
# 0.1.0), independent of the craft plugin version. Deliberately NO
# package.json==tag guard (himalaya-mcp couples them; craft does not) — a craft
# release of v2.57.0 attaches craft-mcp-v0.1.0.mcpb, and that is expected. The
# asset name reflects the bridge's own maturity, not the plugin tag.
#
# SINGLE JOB (build + upload together): both `release: published` and
# `workflow_dispatch` upload, so — unlike himalaya-mcp, which gates its upload
# job on `release` only — there is no path where build runs without upload. A
# split would add an upload-artifact/download-artifact round-trip that no PR or
# local run exercises (it fires only on a real release); keeping it one job lets
# the local `npm run build:mcpb` E2E cover everything but the final upload line.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Existing release tag to attach the .mcpb to (e.g. v2.57.0)'
required: false
type: string
jobs:
release-mcpb:
name: Build & attach .mcpb
runs-on: ubuntu-latest
permissions:
contents: write
defaults:
run:
working-directory: mcp
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: mcp/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build .mcpb bundle
# build:mcpb bundles ../scripts/*.sh + ../governance/ (present in this
# full checkout) and runs `mcpb pack`, which auto-validates the manifest.
run: npm run build:mcpb
- name: Attach .mcpb to release
env:
GH_TOKEN: ${{ github.token }}
# Untrusted input passed via env (not inlined in run:) per hardening.
# On workflow_dispatch, github.event.release is empty — fall back to
# the manual `tag` input.
RELEASE_TAG: ${{ github.event.release.tag_name || github.event.inputs.tag }}
REPO: ${{ github.repository }}
run: |
shopt -s nullglob
MCPB_FILES=(craft-mcp-v*.mcpb)
if [ ${#MCPB_FILES[@]} -eq 0 ]; then
echo "ERROR: No .mcpb file produced — build:mcpb may have failed"
exit 1
fi
if [ -z "$RELEASE_TAG" ]; then
echo "ERROR: No release tag (provide the 'tag' input for workflow_dispatch)"
exit 1
fi
MCPB_FILE="${MCPB_FILES[0]}"
echo "Attaching $MCPB_FILE ($(wc -c < "$MCPB_FILE" | tr -d ' ') bytes) to $RELEASE_TAG"
gh release upload "$RELEASE_TAG" "$MCPB_FILE" --repo "$REPO" --clobber