# D: Manual Dispatch # M: Merge release PR # C: Commit # ┌───────────┐ ┌─────────────┐ ┌────────────────┐ # │Development├──D──►RC-Unreleased│ ┌──►Final-Unreleased│ # └───────────┘ └─┬─────────▲─┘ │ └─┬────────────▲─┘ # │ │ │ │ │ # M C D M C # │ │ │ │ │ # ┌▼─────────┴┐ │ ┌▼────────────┴┐ # │RC-Released├───┘ │Final-Released│ # └───────────┘ └──────────────┘ name: Release Cycle on: push: branches: - release-v* workflow_dispatch: {} concurrency: ${{ github.workflow }}-${{ github.ref }} jobs: state: name: Check state permissions: pull-requests: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up environment uses: ./.github/actions/setup - id: state name: Get state uses: actions/github-script@v6 env: TRIGGERING_ACTOR: ${{ github.triggering_actor }} with: result-encoding: string script: await require('./scripts/release/workflow/state.js')({ github, context, core }) outputs: # Job Flags start: ${{ steps.state.outputs.start }} changesets: ${{ steps.state.outputs.changesets }} promote: ${{ steps.state.outputs.promote }} publish: ${{ steps.state.outputs.publish }} merge: ${{ steps.state.outputs.merge }} # Global variables is_prerelease: ${{ steps.state.outputs.is_prerelease }} start: needs: state name: Start new release candidate permissions: contents: write actions: write if: needs.state.outputs.start == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up environment uses: ./.github/actions/setup - run: bash scripts/git-user-config.sh - id: start name: Create branch with release candidate run: bash scripts/release/workflow/start.sh - name: Re-run workflow uses: actions/github-script@v6 env: REF: ${{ steps.start.outputs.branch }} with: script: await require('./scripts/release/workflow/rerun.js')({ github, context }) promote: needs: state name: Promote to final release permissions: contents: write actions: write if: needs.state.outputs.promote == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up environment uses: ./.github/actions/setup - run: bash scripts/git-user-config.sh - name: Exit prerelease state if: needs.state.outputs.is_prerelease == 'true' run: bash scripts/release/workflow/exit-prerelease.sh - name: Re-run workflow uses: actions/github-script@v6 with: script: await require('./scripts/release/workflow/rerun.js')({ github, context }) changesets: needs: state name: Update PR to release permissions: contents: write pull-requests: write if: needs.state.outputs.changesets == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # To get all tags - name: Set up environment uses: ./.github/actions/setup - name: Set release title uses: actions/github-script@v6 with: result-encoding: string script: await require('./scripts/release/workflow/set-changesets-pr-title.js')({ core }) - name: Create PR uses: changesets/action@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PRERELEASE: ${{ needs.state.outputs.is_prerelease }} with: version: npm run version title: ${{ env.TITLE }} commit: ${{ env.TITLE }} body: | # Wait for support on this https://github.com/changesets/action/pull/250 This is an automated PR for releasing ${{ github.repository }} Check [CHANGELOG.md](${{ github.repository }}/CHANGELOG.md) publish: needs: state name: Publish to npm environment: npm permissions: contents: write if: needs.state.outputs.publish == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up environment uses: ./.github/actions/setup - id: pack name: Pack run: bash scripts/release/workflow/pack.sh env: PRERELEASE: ${{ needs.state.outputs.is_prerelease }} - name: Upload tarball artifact uses: actions/upload-artifact@v3 with: name: ${{ github.ref_name }} path: ${{ steps.pack.outputs.tarball }} - name: Publish run: bash scripts/release/workflow/publish.sh env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} TARBALL: ${{ steps.pack.outputs.tarball }} TAG: ${{ steps.pack.outputs.tag }} - name: Create Github Release uses: actions/github-script@v6 env: PRERELEASE: ${{ needs.state.outputs.is_prerelease }} with: script: await require('./scripts/release/workflow/github-release.js')({ github, context }) outputs: tarball_name: ${{ steps.pack.outputs.tarball_name }} integrity_check: needs: publish name: Tarball Integrity Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Download tarball artifact id: artifact # Replace with actions/upload-artifact@v3 when # https://github.com/actions/download-artifact/pull/194 gets released uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b with: name: ${{ github.ref_name }} - name: Check integrity run: bash scripts/release/workflow/integrity-check.sh env: TARBALL: ${{ steps.artifact.outputs.download-path }}/${{ needs.publish.outputs.tarball_name }} merge: needs: state name: Create PR back to master permissions: contents: write pull-requests: write if: needs.state.outputs.merge == 'true' runs-on: ubuntu-latest env: MERGE_BRANCH: merge/${{ github.ref_name }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # All branches - name: Set up environment uses: ./.github/actions/setup - run: bash scripts/git-user-config.sh - name: Create branch to merge run: | git checkout -B "$MERGE_BRANCH" "$GITHUB_REF_NAME" git push -f origin "$MERGE_BRANCH" - name: Create PR back to master uses: actions/github-script@v6 with: script: | await github.rest.pulls.create({ owner: context.repo.owner, repo: context.repo.repo, head: process.env.MERGE_BRANCH, base: 'master', title: '${{ format('Merge {0} branch', github.ref_name) }}' });