Files
playwright-mcp/.github/workflows/publish.yml
Joel Verhagen 009aa9275b Add step for publishing to MCP Registry (#1197)
This adds a new step for the `release` event to publish to the Official
MCP Registry.

Summary of changes:
- Add `server.json` which is the MCP Server manifest
  - Used metadata from the GH MCP Registry
  - Used the name `com.microsoft/playwright-mcp`
- Add `publish-release-mcp-registry` job that runs manually
   - Install Microsoft Go for compliant Go crypto
   - Log in to Azure for Key Vault access
   - Publish to the MCP Registry in the `microsoft.com` namespace.
- Add `mcpName` to the `package.json` which the MCP Registry validates.

The publishing requires some secret variables:
- `AZURE_MCP_REGISTRY_CLIENT_ID` - service principal client ID (app ID)
with Get Key and Sign access to a Key Vault
- `AZURE_MCP_REGISTRY_TENANT_ID` - tenant ID for the service principal
(should be a production tenant)
- `AZURE_MCP_REGISTRY_SUBSCRIPTION_ID` - Azure subscription ID holding
the Key Vault
- `KV_NAME` - the Key Vault name, e.g. `mykeyvault`
- `KV_KEY_NAME` - the name of a Key in the Key Vault, needs to be ECDSA
P-384.

I can provide internal documentation for how to set up the service
principal (managed identity is easiest), vault, and key as well as
registering the key so it can be used for the `microsoft.com` namespace.

**Note:** after the new job is proven to work as expected, we can switch
it to automatically running after the `publish-release-npm` job on the
`release` event.
2025-11-17 13:43:07 -08:00

196 lines
6.9 KiB
YAML

name: Publish
on:
workflow_dispatch:
schedule:
- cron: '0 8 * * *'
release:
types: [published]
jobs:
publish-canary-npm:
if: github.event.schedule || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC npm publishing
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 20
registry-url: https://registry.npmjs.org/
# Ensure npm 11.5.1 or later is installed (for OIDC npm publishing)
- name: Update npm
run: npm install -g npm@latest
- name: Get current date
id: date
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Get current version
id: version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
- name: Set canary version
id: canary-version
run: echo "version=${{ steps.version.outputs.version }}-alpha-${{ steps.date.outputs.date }}" >> $GITHUB_OUTPUT
- name: Update package.json version
run: |
npm version ${{ steps.canary-version.outputs.version }} --no-git-tag-version
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run lint
- run: npm run ctest
- name: Publish to npm with next tag
run: npm publish --tag next
publish-release-npm:
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC npm publishing
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 20
registry-url: https://registry.npmjs.org/
# Ensure npm 11.5.1 or later is installed (for OIDC npm publishing)
- name: Update npm
run: npm install -g npm@latest
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run lint
- run: npm run ctest
- run: npm publish
publish-release-docker:
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Needed for OIDC login to Azure
environment: allow-publishing-docker-to-acr
steps:
- uses: actions/checkout@v5
- name: Set up QEMU # Needed for multi-platform builds (e.g., arm64 on amd64 runner)
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx # Needed for multi-platform builds
uses: docker/setup-buildx-action@v3
- name: Azure Login via OIDC
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_DOCKER_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_DOCKER_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_DOCKER_SUBSCRIPTION_ID }}
- name: Login to ACR
run: az acr login --name playwright
- name: Build and push Docker image
id: build-push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile # Adjust path if your Dockerfile is elsewhere
platforms: linux/amd64,linux/arm64
push: true
tags: |
playwright.azurecr.io/public/playwright/mcp:${{ github.event.release.tag_name }}
playwright.azurecr.io/public/playwright/mcp:latest
- uses: oras-project/setup-oras@v1
- name: Set oras tags
run: |
attach_eol_manifest() {
local image="$1"
local today=$(date -u +'%Y-%m-%d')
# oras is re-using Docker credentials, so we don't need to login.
# Following the advice in https://portal.microsofticm.com/imp/v3/incidents/incident/476783820/summary
oras attach --artifact-type application/vnd.microsoft.artifact.lifecycle --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$today" $image
}
# for each tag, attach the eol manifest
for tag in $(echo ${{ steps.build-push.outputs.metadata['image.name'] }} | tr ',' '\n'); do
attach_eol_manifest $tag
done
package-release-extension:
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: write # Needed to upload release assets
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 20
cache: 'npm'
- name: Install extension dependencies
working-directory: ./extension
run: npm ci
- name: Build extension
working-directory: ./extension
run: npm run build
- name: Get extension version
id: get-version
working-directory: ./extension
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
- name: Package extension
working-directory: ./extension
run: |
cd dist
zip -r ../playwright-mcp-extension-${{ steps.get-version.outputs.version }}.zip .
cd ..
- name: Upload extension to release
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release upload ${{github.event.release.tag_name}} ./extension/playwright-mcp-extension-${{ steps.get-version.outputs.version }}.zip
publish-release-mcp-registry:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
environment: allow-mcp-registry-publishing
permissions:
contents: read
id-token: write # Needed for GitHub OIDC authentication
steps:
- uses: actions/checkout@v5
- name: Clone MCP Registry and build publisher tool
shell: pwsh
run: |
cd ${{ runner.temp }}
# Install Microsoft Go
go run github.com/microsoft/go-infra/goinstallscript@v1.1.0
./go-install.ps1 -GitHubActionsPath
# Enable compliant crypto
$env:GOEXPERIMENT = "systemcrypto"
# Clone and build the publisher tool
git clone --branch "v1.3.7" https://github.com/modelcontextprotocol/registry
cd registry
go build -o ${{ runner.temp }}/mcp-publisher ./cmd/publisher
# show help for the tool to ensure it's working
${{ runner.temp }}/mcp-publisher --help
- name: Azure Login via OIDC
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_MCP_REGISTRY_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_MCP_REGISTRY_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_MCP_REGISTRY_SUBSCRIPTION_ID }}
- name: Publish to the MCP Registry
shell: pwsh
run: |
# log in using Key Vault
${{ runner.temp }}/mcp-publisher `
login dns azure-key-vault `
-vault "${{ secrets.KV_NAME }}" -key "${{ secrets.KV_KEY_NAME }}" `
-domain microsoft.com
# publish the server.json
${{ runner.temp }}/mcp-publisher publish ./.mcp/server.json