diff --git a/.github/workflows/preview-release.yml b/.github/workflows/preview-release-on-comment.yml similarity index 72% rename from .github/workflows/preview-release.yml rename to .github/workflows/preview-release-on-comment.yml index 91fbc877d4..5ee357ef3a 100644 --- a/.github/workflows/preview-release.yml +++ b/.github/workflows/preview-release-on-comment.yml @@ -1,18 +1,14 @@ name: Preview Release on Comment - -permissions: - id-token: write - contents: read - pull-requests: write - issues: write +# Reusable workflow that publishes preview releases from PR branches: +# - Checks out the PR branch +# - Publishes snapshot packages to npm with a preview tag +# - Posts workflow status as a comment on the PR on: - issue_comment: - types: [created] + workflow_call: jobs: release-preview-on-comment: - if: github.event.issue.pull_request && startsWith(github.event.comment.body, '[preview_deployment]') runs-on: ubuntu-latest timeout-minutes: 15 @@ -30,15 +26,6 @@ jobs: uses: xt0rted/pull-request-comment-branch@v1 id: comment-branch - - name: Validate branch name - run: | - if [[ ! "$BRANCH_NAME" =~ ^preview/[a-zA-Z0-9_-]+$ ]]; then - echo "Ignoring PR because of the branch name. Exiting workflow." - exit 1 - fi - env: - BRANCH_NAME: ${{ steps.comment-branch.outputs.head_ref }} - - name: Checkout code uses: actions/checkout@v6 with: @@ -53,6 +40,7 @@ jobs: uses: actions/setup-node@v6 with: node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' - name: Get yarn cache id: yarn-cache @@ -68,16 +56,6 @@ jobs: - name: Install dependencies run: yarn install --immutable - - name: Creating .npmrc - run: | - cat << EOF > "$HOME/.npmrc" - provenance=true - email=npmjs@commercetools.com - //registry.npmjs.org/:_authToken=$NPM_TOKEN - EOF - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Building packages run: yarn build @@ -86,10 +64,9 @@ jobs: env: CI: true - # Publish preview releases only if the branch starts with "preview/" and the pr comment contains "[preview_deployment]" - name: Publishing preview releases to npm registry run: | - PREVIEW_TAG=$(echo "$BRANCH_NAME" | sed -e 's/^preview\///') + PREVIEW_TAG=$(echo "$BRANCH_NAME" | sed -e 's/[^a-zA-Z0-9-]/-/g') yarn changeset version --snapshot ${PREVIEW_TAG} yarn changeset publish --tag ${PREVIEW_TAG} env: @@ -103,4 +80,3 @@ jobs: --body "Release workflow ${{ job.status == 'success' && 'succeeded ✅' || 'failed ❌' }}\nSee details: [Workflow Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" env: GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} - diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000000..18f7b2fbe8 --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,94 @@ +name: Publish Release +# Reusable workflow that handles official releases: +# - Versions packages using changesets and publishes to npm +# - Creates GitHub releases +# - Publishes canary releases if no official release was created + +on: + workflow_call: + +jobs: + publish-release: + runs-on: ubuntu-latest + + steps: + # Get GitHub token via the CT Changesets App + - name: Generate GitHub token (via CT Changesets App) + id: generate_github_token + uses: tibdex/github-app-token@v2.1.0 + with: + app_id: ${{ secrets.CT_CHANGESETS_APP_ID }} + private_key: ${{ secrets.CT_CHANGESETS_APP_PEM }} + + - name: Checkout + uses: actions/checkout@v6 + with: + # Pass a personal access token (using our `ct-release-bot` account) to be able to trigger + # other workflows + # https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token + # https://github.community/t/action-does-not-trigger-another-on-push-tag-action/17148/8 + token: ${{ steps.generate_github_token.outputs.token }} + + - name: Setup Node (uses version in .nvmrc) + uses: actions/setup-node@v6 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + + - name: Get yarn cache + id: yarn-cache + run: echo "::set-output name=dir::$(yarn config get cacheFolder)" + + - name: Verify npm version + run: | + npm --version + # Ensure latest npm is installed for trusted publishing (OIDC) + + - uses: actions/cache@v5 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock', 'patches/*.patch') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: yarn install --immutable + + - name: Building packages + run: yarn build + + - name: Building package READMEs + run: yarn generate-readmes + env: + CI: true + + - name: Storing release version for changeset + id: release_version + run: echo "VALUE=$(./scripts/print_release_version.sh)" >> $GITHUB_OUTPUT + shell: bash + env: + GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1.7.0 + with: + commit: 'ci(changesets): version packages' + publish: yarn changeset publish + version: yarn changeset:version-and-format + createGithubReleases: aggregate + githubReleaseName: v${{ steps.release_version.outputs.VALUE }} + githubTagName: v${{ steps.release_version.outputs.VALUE }} + env: + GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} + SKIP_POSTINSTALL_DEV_SETUP: true + + # Publish canary releases only if the packages weren't published already + - name: Publishing canary releases to npm registry + if: steps.changesets.outputs.published != 'true' + run: | + git checkout main + yarn changeset version --snapshot canary + yarn changeset publish --tag canary + env: + GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84388b782b..69452b0093 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,96 +1,30 @@ name: Release +# Entry workflow that coordinates release processes: +# - Publishes official releases when code is pushed to main, adhering to the single workflow, npm trusted publishing/OIDC pattern +# - Publishes preview releases when triggered via PR comment with [preview_deployment] on: push: branches: - main - -permissions: - id-token: write - contents: read + issue_comment: + types: [created] jobs: - release: - runs-on: ubuntu-latest - - steps: - # Get GitHub token via the CT Changesets App - - name: Generate GitHub token (via CT Changesets App) - id: generate_github_token - uses: tibdex/github-app-token@v2.1.0 - with: - app_id: ${{ secrets.CT_CHANGESETS_APP_ID }} - private_key: ${{ secrets.CT_CHANGESETS_APP_PEM }} - - - name: Checkout - uses: actions/checkout@v6 - with: - # Pass a personal access token (using our `ct-release-bot` account) to be able to trigger - # other workflows - # https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token - # https://github.community/t/action-does-not-trigger-another-on-push-tag-action/17148/8 - token: ${{ steps.generate_github_token.outputs.token }} - - - name: Setup Node (uses version in .nvmrc) - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - - - name: Get yarn cache - id: yarn-cache - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - - - name: Verify npm version - run: | - npm --version - # Ensure latest npm is installed for trusted publishing (OIDC) - - - uses: actions/cache@v5 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock', 'patches/*.patch') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Install dependencies - run: yarn install --immutable - - - name: Building packages - run: yarn build - - - name: Building package READMEs - run: yarn generate-readmes - env: - CI: true - - - name: Storing release version for changeset - id: release_version - run: echo "VALUE=$(./scripts/print_release_version.sh)" >> $GITHUB_OUTPUT - shell: bash - env: - GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} - - - name: Create Release Pull Request or Publish to npm - id: changesets - uses: dotansimha/changesets-action@v1.5.2 - with: - commit: 'ci(changesets): version packages' - publish: yarn changeset publish - version: yarn changeset:version-and-format - createGithubReleases: aggregate - githubReleaseName: v${{ steps.release_version.outputs.VALUE }} - githubTagName: v${{ steps.release_version.outputs.VALUE }} - env: - GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} - SKIP_POSTINSTALL_DEV_SETUP: true - - # Publish canary releases only if the packages weren't published already - - name: Publishing canary releases to npm registry - if: steps.changesets.outputs.published != 'true' - run: | - git checkout main - yarn changeset version --snapshot canary - yarn changeset publish --tag canary - env: - GITHUB_TOKEN: ${{ steps.generate_github_token.outputs.token }} + publish-release: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: ./.github/workflows/publish-release.yml + permissions: + id-token: write + contents: read + secrets: inherit + + publish-preview: + if: github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '[preview_deployment]') + uses: ./.github/workflows/preview-release-on-comment.yml + permissions: + id-token: write + contents: read + pull-requests: write + issues: write + secrets: inherit