Skip to content

fix(tinacms): send the same TinaCloud token from editorial workflow a… #805

fix(tinacms): send the same TinaCloud token from editorial workflow a…

fix(tinacms): send the same TinaCloud token from editorial workflow a… #805

Workflow file for this run

name: Publish
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:
inputs:
test_graphql_update:
description: 'Test the @tinacms/graphql update flow to tinacloud'
required: false
default: false
type: boolean
test_version:
description: 'Version to simulate (e.g., 2.2.0)'
required: false
default: '2.2.0'
type: string
concurrency: ${{ github.workflow }}-${{ github.ref }}
# Least-privilege default; jobs that publish opt into the writes they need.
permissions:
contents: read
jobs:
publish-tagged-pr:
if: >
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.fork == false &&
contains(github.event.pull_request.labels.*.name, 'tagged') &&
github.event.pull_request.title != 'Version Packages'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC authentication with npm
pull-requests: write
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Check out code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 2
- name: Setup Node.js environment
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
registry-url: "https://registry.npmjs.org"
- name: Upgrade npm for OIDC support
run: npm install -g npm@$(node -p "require('./package.json').engines.npm")
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
name: Install pnpm
id: pnpm-install
with:
package_json_file: package.json
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Build Types
run: pnpm types
- name: Publish tagged PR
run: |
echo running on branch ${BRANCH_NAME}
pnpm version:snapshot $(echo ${{ github.sha }} | cut -c1-7)
# Re-pin to workspace:* so snapshots publish exact internal versions —
# caret prerelease ranges can resolve to a different snapshot batch.
git diff --name-only -- '*package.json' | xargs -r sed -i 's/"workspace:\^"/"workspace:*"/g'
pnpm publish -r --tag ${BRANCH_NAME} --no-git-checks --access public
echo "Published NPM tag: $BRANCH_NAME" >> $GITHUB_STEP_SUMMARY
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
NPM_CONFIG_PROVENANCE: true
- name: Get published package versions
id: package-versions
run: |
set -e
echo "🔍 Checking for modified package.json files..."
# Find all modified package.json files (uncommitted changes from version:snapshot)
modified_packages=$(git diff --name-only | grep 'package\.json$' || true)
if [ -z "$modified_packages" ]; then
echo "⚠️ No modified package.json files found"
echo "packages_csv=" >> $GITHUB_OUTPUT
exit 0
fi
echo "📦 Found modified package.json files:"
echo "$modified_packages"
# Build a CSV with one package per line (package,version)
packages_csv=""
for pkg_file in $modified_packages; do
if [ -f "$pkg_file" ]; then
pkg_name=$(jq -r '.name' "$pkg_file")
pkg_version=$(jq -r '.version' "$pkg_file")
if [ "$pkg_name" != "null" ] && [ "$pkg_version" != "null" ]; then
echo " Found: $pkg_name@$pkg_version"
if [ -n "$packages_csv" ]; then
packages_csv="${packages_csv}"$'\n'
fi
packages_csv="${packages_csv}${pkg_name},${pkg_version}"
fi
fi
done
echo "📋 Generated CSV:"
echo "$packages_csv"
# Use heredoc for multiline output
echo "packages_csv<<EOF" >> $GITHUB_OUTPUT
echo "$packages_csv" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Comment on PR with install instructions
if: steps.package-versions.outputs.packages_csv != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PACKAGES_CSV: ${{ steps.package-versions.outputs.packages_csv }}
with:
script: |
console.log('🔍 Starting PR comment script...');
if (
!context.payload ||
!context.payload.pull_request ||
!context.payload.pull_request.head ||
!context.payload.pull_request.head.ref ||
!context.payload.pull_request.number
) {
throw new Error('Missing pull_request context. Cannot comment on PR.');
}
const packagesCsv = process.env.PACKAGES_CSV;
console.log('📦 Packages CSV:', packagesCsv);
// Parse CSV format: one line per package "name,version"
const packages = packagesCsv.trim().split('\n').map(line => {
const [name, version] = line.split(',');
return { name, version };
});
console.log('✅ Parsed packages:', packages);
const branchName = context.payload.pull_request.head.ref;
console.log('🌿 Branch name:', branchName);
let packagesSection = '\n**Published Packages:**\n';
for (const pkg of packages) {
packagesSection += `- \`${pkg.name}@${pkg.version}\`\n`;
}
console.log('📝 Generated packages section:', packagesSection);
// Generate install commands using actual versions
let installCommands = packages.map(pkg => `pnpm add ${pkg.name}@${pkg.version}`).join('\n');
const comment = `## 📦 Tagged Release Published
Your tagged PR has been published! You can install the packages using their version tags:
\`\`\`bash
${installCommands}
\`\`\`
${packagesSection}
**Commit:** \`${context.sha}\`
`;
console.log('💬 Posting comment to PR #' + context.payload.pull_request.number);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: comment
});
console.log('✅ Comment posted successfully!');
build:
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # Required for OIDC authentication with npm
pull-requests: write
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Generate a token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: generate-token
with:
# uses https://github.com/organizations/tinacms/settings/apps/release-bot-allow-prs-and-push
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_APP_SECRET }}
- name: Check out code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
token: ${{ steps.generate-token.outputs.token }}
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
- name: Setup Node.js environment
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
registry-url: "https://registry.npmjs.org"
- name: Upgrade npm for OIDC support
run: npm install -g npm@$(node -p "require('./package.json').engines.npm")
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
name: Install pnpm
id: pnpm-install
with:
package_json_file: package.json
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Build Types
run: pnpm types
- name: Setup git credentials
run: |
git config --global user.email "bot@tina.io"
git config --global user.name "Tina Release Bot"
- name: Create release pull request or publish packages
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0
id: changesets
with:
version: pnpm run version
publish: pnpm run publish
createGithubReleases: true
setupGitUser: false
# github-api mode makes GitHub create and sign the Version Packages
# commit server-side, satisfying main's required-signatures rule
commitMode: github-api
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
NPM_CONFIG_PROVENANCE: true
- name: Release to @dev channel
if: steps.changesets.outputs.hasChangesets == 'true'
run: |
# Hard reset (not checkout) so the snapshot runs against the pristine
# release commit. changesets/action's github-api commit mode leaves the
# version bumps uncommitted in the working tree; a plain checkout keeps
# them, so `version:snapshot` finds no changesets and publishes the real
# release version to the beta tag, which then blocks the latest publish.
git reset --hard ${{ github.sha }}
pnpm version:snapshot $(echo ${{ github.sha }} | cut -c1-7)
# Re-pin to workspace:* so snapshots publish exact internal versions —
# caret prerelease ranges can resolve to a different snapshot batch.
git diff --name-only -- '*package.json' | xargs -r sed -i 's/"workspace:\^"/"workspace:*"/g'
# Sync the lockfile with the re-pinned manifests so the deps check
# in `pnpm run` passes. Offline: the sync must never resolve
# anything new — workspace re-pins don't need the registry.
pnpm install --lockfile-only --no-frozen-lockfile --offline
pnpm run publish:beta
echo "A release PR has been created: <https://github.com/tinacms/tinacms/pull/${{ steps.changesets.outputs.pullRequestNumber }}>" >> $GITHUB_STEP_SUMMARY
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
NPM_CONFIG_PROVENANCE: true
- name: Has TinaCMS been published
id: newTinaCMSVersion
if: steps.changesets.outputs.published == 'true'
run: |
# $publishedPackages is a json array of [{"name": "@xx/xx", "version": "1.2.0"}]
# work out if tinacms has been published and output the version number
newTinaCMSVersion=$(echo $publishedPackages | jq -r '.[] | select(.name == "tinacms") | .version')
if [ -z "$newTinaCMSVersion" ]; then
echo "❌ TinaCMS not published" >> $GITHUB_STEP_SUMMARY
else
echo "🚀 A new version of TinaCMS was released: $newTinaCMSVersion" >> $GITHUB_STEP_SUMMARY
fi
echo "newTinaCMSVersion=$newTinaCMSVersion" >> $GITHUB_OUTPUT
env:
publishedPackages: ${{ steps.changesets.outputs.publishedPackages }}
- name: Publish release notes
if: steps.newTinaCMSVersion.outputs.newTinaCMSVersion != ''
uses: benc-uk/workflow-dispatch@31e2b3319479a63f0ab15bf800eff9e913504e26 # v1.3.2
with:
ref: main
workflow: main-generate-release-notes.yml
inputs: |
{
"release_name": "${{ steps.newTinaCMSVersion.outputs.newTinaCMSVersion }}"
}
token: ${{ steps.generate-token.outputs.token }}
- name: Trigger starter template builds
if: steps.changesets.outputs.published == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PUBLISHED_PACKAGES: ${{ steps.changesets.outputs.publishedPackages }}
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'build-starter-templates.yml',
ref: 'main',
inputs: {
published_packages: process.env.PUBLISHED_PACKAGES || '[]'
}
});
console.log('Triggered starter template builds with published packages');
- name: Generate token for tinacloud
if: steps.changesets.outputs.published == 'true'
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: tinacloud-token
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_APP_SECRET }}
repositories: tinacloud
- name: Notify tinacloud of published packages
if: steps.changesets.outputs.published == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
publishedPackages: ${{ steps.changesets.outputs.publishedPackages }}
with:
github-token: ${{ steps.tinacloud-token.outputs.token }}
script: |
const publishedPackages = JSON.parse(process.env.publishedPackages);
console.log(`Notifying tinacloud of ${publishedPackages.length} published packages`);
console.log(publishedPackages.map(p => ` ${p.name}@${p.version}`).join('\n'));
// Trigger a repository dispatch event in the tinacloud repo
await github.rest.repos.createDispatchEvent({
owner: 'tinacms',
repo: 'tinacloud',
event_type: 'tinacms-release',
client_payload: {
packages: publishedPackages,
source_repo: 'tinacms/tinacms',
source_sha: context.sha
}
});
console.log('✅ Repository dispatch event sent to tinacloud');
core.summary.addRaw(`\n🔄 Notified tinacloud of ${publishedPackages.length} published packages`);
await core.summary.write();
- name: Summary
if: steps.newTinaCMSVersion.outputs.newTinaCMSVersion == '' && steps.changesets.outputs.hasChangesets == 'false'
run: |
echo "❌ Nothing was published" >> $GITHUB_STEP_SUMMARY
# Test job for manually triggering the tinacloud update flow
test-tinacloud-update:
if: github.event_name == 'workflow_dispatch' && inputs.test_graphql_update == true
runs-on: ubuntu-latest
steps:
- name: Generate token for tinacloud
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: tinacloud-token
with:
app-id: ${{ secrets.BOT_APP_ID }}
private-key: ${{ secrets.BOT_APP_SECRET }}
repositories: tinacloud
- name: Trigger tinacloud update (test mode)
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ steps.tinacloud-token.outputs.token }}
script: |
const version = '${{ inputs.test_version }}';
// Simulate a release with the test version
const packages = [
{ name: '@tinacms/graphql', version: version }
];
console.log(`[TEST] Notifying tinacloud of test packages:`);
packages.forEach(p => console.log(` ${p.name}@${p.version}`));
await github.rest.repos.createDispatchEvent({
owner: 'tinacms',
repo: 'tinacloud',
event_type: 'tinacms-release',
client_payload: {
packages: packages,
source_repo: 'tinacms/tinacms',
source_sha: context.sha
}
});
console.log('✅ Repository dispatch event sent to tinacloud');
core.summary.addRaw(`## Test Mode\n\n🔄 Notified tinacloud of test release\n- @tinacms/graphql@${version}`);
await core.summary.write();