Skip to content

Release and Template #298

Release and Template

Release and Template #298

name: Release and Template
on:
# Run automatically only after the Tests workflow succeeds on main
workflow_run:
workflows: ["Tests"]
types: [completed]
# Allow manual runs if needed
workflow_dispatch:
permissions:
contents: write
jobs:
release:
# If triggered by workflow_run, require success on main; always allow manual dispatch
if: >-
${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main') }}
runs-on: ubuntu-latest
outputs:
published: ${{ steps.changesets.outputs.published }}
publishedPackages: ${{ steps.changesets.outputs.publishedPackages }}
releaseVersion: ${{ steps.release_version.outputs.version }}
releaseNotes: ${{ steps.release_notes.outputs.payload }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# When triggered by workflow_run, check out the tested commit
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: https://registry.npmjs.org
cache: "npm"
scope: "@canopy-iiif"
always-auth: true
- name: Install dependencies
run: |
npm config set fund false
npm config set audit false
npm ci --no-audit --no-fund || npm install --no-audit --no-fund
- name: Changesets release
id: changesets
uses: changesets/action@v1
with:
publish: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Resolve release version
id: release_version
if: steps.changesets.outputs.published == 'true'
run: |
VERSION=$(node -p "require('./packages/app/package.json').version")
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Read release notes from docs data
id: release_notes
if: steps.changesets.outputs.published == 'true'
run: |
NOTES=$(node packages/helpers/release-notes-from-docs.js "${{ steps.release_version.outputs.version }}")
{
echo 'payload<<EOF'
echo "$NOTES"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Publish GitHub release
if: steps.changesets.outputs.published == 'true'
uses: actions/github-script@v7
env:
RELEASE_VERSION: ${{ steps.release_version.outputs.version }}
RELEASE_NOTES: ${{ steps.release_notes.outputs.payload }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const notes = JSON.parse(process.env.RELEASE_NOTES || '{}');
const version = process.env.RELEASE_VERSION;
const tag = `v${version}`;
const body = notes.body && notes.body.trim()
? notes.body.trim()
: 'Release details are tracked in content/docs/releases/releases.data.mjs.';
const name = `v${version}`;
try {
const existing = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag,
});
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: existing.data.id,
tag_name: tag,
name,
body,
draft: false,
prerelease: false,
});
} catch (error) {
if (error.status !== 404) throw error;
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name,
body,
draft: false,
prerelease: false,
});
}
template:
needs: release
if: needs.release.result == 'success' && needs.release.outputs.published == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- name: Install dependencies
run: |
npm config set fund false
npm config set audit false
npm ci --no-audit --no-fund || npm install --no-audit --no-fund
- name: Build template commit message
id: template_commit
run: |
MESSAGE=$(node -e "const notes = process.env.NOTES ? JSON.parse(process.env.NOTES) : {}; const summary = notes.summary ? ' – ' + notes.summary : ''; const version = process.env.VERSION || ''; process.stdout.write('Update template for v' + version + summary);")
{
echo 'text<<EOF'
echo "$MESSAGE"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
env:
VERSION: ${{ needs.release.outputs.releaseVersion }}
NOTES: ${{ needs.release.outputs.releaseNotes }}
- name: Resolve published version
id: ver
run: |
echo "APP=$(npm view @canopy-iiif/app version || echo '')" >> $GITHUB_OUTPUT
- name: Prepare clean template
env:
APP_VERSION: ${{ steps.ver.outputs.APP }}
run: node packages/helpers/template/prepare-template.js
- name: Push to template repository (main)
env:
TEMPLATE_PUSH_TOKEN: ${{ secrets.TEMPLATE_PUSH_TOKEN }}
TARGET_REPO: nulib-ds/canopy-template
TEMPLATE_COMMIT_MESSAGE: ${{ steps.template_commit.outputs.text }}
run: node packages/helpers/template/push-template.js
template-i18n:
needs: release
if: needs.release.result == 'success' && needs.release.outputs.published == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- name: Install dependencies
run: |
npm config set fund false
npm config set audit false
npm ci --no-audit --no-fund || npm install --no-audit --no-fund
- name: Build template commit message
id: template_i18n_commit
run: |
MESSAGE=$(node -e "const notes = process.env.NOTES ? JSON.parse(process.env.NOTES) : {}; const summary = notes.summary ? ' – ' + notes.summary : ''; const version = process.env.VERSION || ''; process.stdout.write('Update template-i18n for v' + version + summary);")
{
echo 'text<<EOF'
echo "$MESSAGE"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
env:
VERSION: ${{ needs.release.outputs.releaseVersion }}
NOTES: ${{ needs.release.outputs.releaseNotes }}
- name: Resolve published version
id: ver_i18n
run: |
echo "APP=$(npm view @canopy-iiif/app version || echo '')" >> $GITHUB_OUTPUT
- name: Prepare clean template (i18n)
env:
APP_VERSION: ${{ steps.ver_i18n.outputs.APP }}
TEMPLATE_SOURCE_DIR: packages/helpers/template-i18n
TEMPLATE_OUT_DIR: .template-i18n-build
run: node packages/helpers/template/prepare-template.js
- name: Push to template-i18n repository (main)
env:
TEMPLATE_PUSH_TOKEN: ${{ secrets.TEMPLATE_I18N_PUSH_TOKEN }}
TARGET_REPO: nulib-ds/canopy-template-i18n
TEMPLATE_COMMIT_MESSAGE: ${{ steps.template_i18n_commit.outputs.text }}
TEMPLATE_OUT_DIR: .template-i18n-build
run: node packages/helpers/template/push-template.js