[pull] main from tinacms:main #205
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
| 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 }} | |
| 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@v4 | |
| with: | |
| fetch-depth: 2 | |
| - name: Setup Node.js environment | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: ".nvmrc" | |
| registry-url: "https://registry.npmjs.org" | |
| - name: Upgrade npm for OIDC support | |
| run: npm install -g npm@latest | |
| - uses: pnpm/action-setup@v4 | |
| 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@v4 | |
| 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 | |
| - 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) | |
| 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 }} | |
| - 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@v7 | |
| 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); | |
| const comment = `## 📦 Tagged Release Published | |
| Your tagged PR has been published! You can now install the packages using: | |
| \`\`\`bash | |
| pnpm add packagename@${branchName} | |
| \`\`\` | |
| Published packages: | |
| ${packagesSection} | |
| **Tag:** \`${branchName}\` | |
| **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@v1 | |
| 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@v4 | |
| 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@v4 | |
| with: | |
| node-version-file: ".nvmrc" | |
| registry-url: "https://registry.npmjs.org" | |
| - name: Upgrade npm for OIDC support | |
| run: npm install -g npm@latest | |
| - uses: pnpm/action-setup@v4 | |
| 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@v4 | |
| 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 | |
| - 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@v1 | |
| id: changesets | |
| with: | |
| version: pnpm run version | |
| publish: pnpm run publish | |
| createGithubReleases: true | |
| setupGitUser: false | |
| env: | |
| GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} | |
| NPM_CONFIG_PROVENANCE: true | |
| - name: Release to @dev channel | |
| if: steps.changesets.outputs.hasChangesets == 'true' | |
| run: | | |
| git checkout ${{ github.sha }} | |
| pnpm version:snapshot $(echo ${{ github.sha }} | cut -c1-7) | |
| 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@v1 | |
| with: | |
| ref: main | |
| workflow: main-generate-release-notes.yml | |
| inputs: | | |
| { | |
| "release_name": "${{ steps.newTinaCMSVersion.outputs.newTinaCMSVersion }}" | |
| } | |
| token: ${{ steps.generate-token.outputs.token }} | |
| - name: Generate token for tinacloud | |
| if: steps.changesets.outputs.published == 'true' | |
| uses: actions/create-github-app-token@v1 | |
| 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@v7 | |
| 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@v1 | |
| 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@v7 | |
| 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(); |