Streamline 'shadow-dom' directive #133
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
# Run `pnpm changeset` before running this workflow | |
name: Release – Stable | |
permissions: | |
contents: write | |
packages: write | |
pull-requests: write | |
id-token: write | |
deployments: write | |
on: | |
push: | |
branches: | |
- main | |
workflow_dispatch: | |
inputs: | |
dry_run: | |
description: 'Skip publish and deployment steps for validation only' | |
required: false | |
default: false | |
type: boolean | |
concurrency: ${{ github.workflow }}-${{ github.ref }} | |
jobs: | |
release: | |
name: Release – Stable | |
runs-on: ubuntu-22.04 | |
environment: stable | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/setup | |
with: | |
node-version: '18' | |
- name: Build and test | |
run: | | |
pnpm turbo run compile | |
pnpm turbo run test | |
- name: Publish packages to npm | |
id: changesets | |
uses: changesets/action@v1 | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }} | |
with: | |
publish: pnpm -r --filter ./programs/cli --filter ./programs/create --filter ./programs/develop publish --access public --provenance --no-git-checks | |
commit: "chore: version packages" | |
title: "chore: version packages" | |
createGithubReleases: true | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
- name: Debug npm auth (stable) | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published != 'true' }} | |
env: | |
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
run: | | |
echo "Registry: $(npm config get registry)" | |
npm whoami || true | |
test -n "$NODE_AUTH_TOKEN" || (echo "NODE_AUTH_TOKEN missing" && exit 1) | |
- name: Collect versions | |
id: versions | |
run: | | |
node -e "const fs=require('fs');function v(p){return JSON.parse(fs.readFileSync(p,'utf8')).version;}const obj={'extension':v('programs/cli/package.json'),'extension-create':v('programs/create/package.json'),'extension-develop':v('programs/develop/package.json')};process.stdout.write('versions='+JSON.stringify(obj));" >> $GITHUB_OUTPUT | |
- name: Collect npm info (stable) | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published == 'true' }} | |
id: npm | |
run: | | |
node -e " | |
const { execSync } = require('child_process'); | |
const versions = JSON.parse(process.env.VERSIONS || '{}'); | |
const pkgs = ['extension','extension-create','extension-develop']; | |
const out = {}; | |
for (const name of pkgs) { | |
const v = versions[name]; | |
if (!v) continue; | |
const info = JSON.parse(execSync('npm view ' + name + '@' + v + ' version dist.tarball gitHead --json').toString()); | |
const tags = JSON.parse(execSync('npm view ' + name + ' dist-tags --json').toString()); | |
out[name] = { version: info.version, tarball: info.dist?.tarball, gitHead: info.gitHead, distTags: tags }; | |
} | |
process.stdout.write('info='+JSON.stringify(out)); | |
" >> $GITHUB_OUTPUT | |
env: | |
VERSIONS: ${{ steps.versions.outputs.versions }} | |
- name: Verify dist-tags (stable) | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published == 'true' }} | |
run: | | |
node -e " | |
const { execSync } = require('child_process'); | |
const versions = JSON.parse(process.env.VERSIONS || '{}'); | |
const pkgs = ['extension','extension-create','extension-develop']; | |
for (const name of pkgs) { | |
const expected = versions[name]; | |
if (!expected) continue; | |
const tags = JSON.parse(execSync('npm view ' + name + ' dist-tags --json').toString()); | |
if (tags.latest !== expected) { | |
console.error(`[stable] Dist-tag mismatch for ${name}: latest=${tags.latest} expected=${expected}`); | |
process.exit(1); | |
} | |
} | |
console.log('Stable dist-tags verified.'); | |
" | |
env: | |
VERSIONS: ${{ steps.versions.outputs.versions }} | |
# Note: We now append aggregated changelog to the GitHub Release body instead of committing root CHANGELOG. | |
- name: Render aggregated changelog | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published == 'true' }} | |
id: agg | |
run: | | |
node ./scripts/render-aggregated-changelog.cjs > aggregated.md || true | |
echo "body<<EOF" >> $GITHUB_OUTPUT | |
echo "### Aggregated package changelog" >> $GITHUB_OUTPUT | |
cat aggregated.md >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
- name: Append to latest GitHub Release body | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published == 'true' }} | |
uses: actions/github-script@v7 | |
env: | |
AGG_BODY: ${{ steps.agg.outputs.body }} | |
with: | |
script: | | |
const { owner, repo } = context.repo; | |
const latest = await github.rest.repos.getLatestRelease({ owner, repo }); | |
const current = latest.data.body || ''; | |
const agg = process.env.AGG_BODY || ''; | |
const toName = (tag) => { | |
const version = (tag || '').replace(/^v/, ''); | |
const d = new Date(); | |
const month = d.toLocaleString('en-US', { month: 'long' }); | |
const day = String(d.getDate()).padStart(2, '0'); | |
const year = d.getFullYear(); | |
return `${version} (${month} ${day}, ${year})`; | |
}; | |
const releaseName = toName(latest.data.tag_name || latest.data.name || ''); | |
await github.rest.repos.updateRelease({ | |
owner, repo, | |
release_id: latest.data.id, | |
body: current ? `${current}\n\n${agg}` : agg, | |
name: releaseName, | |
draft: false, | |
prerelease: false | |
}); | |
- name: Create deployment (stable) | |
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) && steps.changesets.outputs.published == 'true' }} | |
uses: actions/github-script@v7 | |
env: | |
VERSIONS: ${{ steps.versions.outputs.versions }} | |
NPM_INFO: ${{ steps.npm.outputs.info }} | |
with: | |
script: | | |
const { owner, repo } = context.repo; | |
const payload = { | |
channel: 'stable', | |
distTag: 'latest', | |
versions: JSON.parse(process.env.VERSIONS || '{}'), | |
npm: JSON.parse(process.env.NPM_INFO || '{}') | |
}; | |
const ref = context.sha; | |
const dep = await github.rest.repos.createDeployment({ | |
owner, repo, ref, | |
environment: 'stable', | |
auto_merge: false, | |
required_contexts: [], | |
transient_environment: false, | |
description: `Published to npm (stable)`, | |
payload: JSON.stringify(payload) | |
}); | |
const ext = payload.versions['extension']; | |
const envUrl = ext ? `https://www.npmjs.com/package/extension/v/${ext}` : undefined; | |
const desc = `extension ${payload.versions['extension']}, extension-create ${payload.versions['extension-create']}, extension-develop ${payload.versions['extension-develop']}`; | |
await github.rest.repos.createDeploymentStatus({ | |
owner, repo, deployment_id: dep.data.id, | |
state: 'success', | |
log_url: `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`, | |
environment_url: envUrl, | |
description: desc | |
}) |