name: Publish on: workflow_dispatch: schedule: - cron: '0 8 * * *' release: types: [published] jobs: publish-mcp-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: 24 registry-url: https://registry.npmjs.org/ - 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-mcp-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: 24 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npx playwright install --with-deps - run: npm run lint - run: npm run ctest - run: npm publish publish-mcp-release-registry: # Runs on release (after npm publish succeeds) or via manual workflow_dispatch # (e.g. to retroactively publish a version, in which case publish-mcp-release-npm # is skipped — the always() + result check lets this job still run). if: | always() && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') && needs.publish-mcp-release-npm.result != 'failure' && needs.publish-mcp-release-npm.result != 'cancelled' needs: publish-mcp-release-npm runs-on: ubuntu-latest permissions: contents: read id-token: write # Required for GitHub OIDC auth to the MCP Registry steps: - uses: actions/checkout@v5 - name: Validate server.json version matches package.json run: | node -e " const pkg = require('./package.json'); const server = require('./server.json'); const mismatches = []; if (server.version !== pkg.version) mismatches.push(\`server.version=\${server.version} != package.version=\${pkg.version}\`); for (const p of server.packages) { if (p.version !== pkg.version) mismatches.push(\`packages[\${p.identifier}].version=\${p.version} != package.version=\${pkg.version}\`); } if (mismatches.length) { console.error('server.json is out of sync with package.json:'); for (const m of mismatches) console.error(' ' + m); process.exit(1); } " - name: Install mcp-publisher run: | curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_linux_amd64.tar.gz" \ | tar xz mcp-publisher - name: Authenticate with MCP Registry (GitHub OIDC) run: ./mcp-publisher login github-oidc - name: Publish to MCP Registry run: ./mcp-publisher publish publish-mcp-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@v4 - name: Set up Docker Buildx # Needed for multi-platform builds uses: docker/setup-buildx-action@v4 - name: Azure Login via OIDC uses: azure/login@v3 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@v7 with: file: ./Dockerfile 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@v2 - 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