Release #2
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: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_ticket_key: | |
| description: 'Release Ticket Key (e.g., UIKIT-1234)' | |
| required: true | |
| type: string | |
| is_test: | |
| description: 'Sent by the SDK Release automation; declared so the dispatch is accepted' | |
| required: false | |
| default: false | |
| type: boolean | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: write | |
| env: | |
| BOT_GH_TOKEN: ${{ secrets.SDK_GH_BOT1_TOKEN }} | |
| JIRA_AUTH_USER: ${{ secrets.JIRA_AUTH_USER }} | |
| JIRA_AUTH_API_TOKEN: ${{ secrets.JIRA_AUTH_API_TOKEN }} | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| RELEASE_VERSION: '' # Set by "Extract release version" step | |
| RELEASE_TICKET_KEY: ${{ inputs.release_ticket_key }} | |
| SLACK_RELEASE_CHANNEL_ID: ${{ vars.SLACK_RELEASE_CHANNEL_ID }} | |
| BRANCH_NAME: ${{ github.ref_name }} | |
| REPO_NAME: ${{ github.event.repository.name }} | |
| steps: | |
| - name: Validate branch is a release branch | |
| run: | | |
| if ! printf '%s' "$BRANCH_NAME" | grep -qE '^release/v[0-9]+\.[0-9]+\.[0-9]+$'; then | |
| echo "This workflow must be dispatched from a release/vX.Y.Z branch. Got: '$BRANCH_NAME'" | |
| exit 1 | |
| fi | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| token: ${{ env.BOT_GH_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| cache: 'yarn' | |
| - name: Install dependencies and build | |
| run: | | |
| yarn install --immutable | |
| yarn build | |
| - name: Extract release version | |
| run: | | |
| pip3 install requests | |
| git config --global user.email "sha.sdk_deployment@sendbird.com" | |
| git config --global user.name "sendbird-sdk-deployment" | |
| git clone --depth 1 --branch main https://${{ env.BOT_GH_TOKEN }}@github.com/sendbird/sdk-deployment.git ~/sdk-deployment | |
| release_version=$(python3 ~/sdk-deployment/scripts/v1.2/extract_version.py --branch_name "$BRANCH_NAME") | |
| echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV | |
| - name: Validate CHANGELOG_DRAFT.md is fresh | |
| run: | | |
| export VERSION="$RELEASE_VERSION" | |
| node scripts/check-changelog-draft.js | |
| - name: Finalize CHANGELOG.md date on release branch | |
| run: | | |
| DATE=$(date -u '+%b %d %Y' | tr '[:lower:]' '[:upper:]') | |
| export VERSION="$RELEASE_VERSION" | |
| export DATE | |
| node scripts/update-changelog.js | |
| if git diff --quiet CHANGELOG.md; then | |
| echo "CHANGELOG.md date already up to date; skipping commit." | |
| exit 0 | |
| fi | |
| git config user.email "sha.sdk_deployment@sendbird.com" | |
| git config user.name "sendbird-sdk-deployment" | |
| git add CHANGELOG.md | |
| git commit -m "chore: finalize CHANGELOG.md date for v$RELEASE_VERSION" | |
| git push origin "$BRANCH_NAME" | |
| - name: Wait for required checks on release branch | |
| timeout-minutes: 30 | |
| env: | |
| GH_TOKEN: ${{ env.BOT_GH_TOKEN }} | |
| run: | | |
| # Give GitHub a moment to register the workflow run for the finalize commit | |
| # before watching, otherwise --watch may see no checks and exit 0 immediately. | |
| sleep 15 | |
| gh pr checks "$BRANCH_NAME" --watch --required | |
| - name: Merge release branch to main | |
| run: | | |
| python3 ~/sdk-deployment/scripts/v1.2/github_pr_merge.py \ | |
| --github_api_token "$BOT_GH_TOKEN" \ | |
| --repo_name "$REPO_NAME" \ | |
| --branch_name "$BRANCH_NAME" | |
| git fetch origin main | |
| git switch main | |
| git pull origin main | |
| - name: Rebuild after merge | |
| run: | | |
| yarn install --immutable | |
| yarn build | |
| - name: Publish to npm | |
| run: | | |
| cd ./dist | |
| npm publish --access=public --provenance | |
| - name: Verify npm package publication | |
| run: | | |
| cd ./dist | |
| PACKAGE_NAME=$(node -p "require('./package.json').name") | |
| PACKAGE_VERSION=$(node -p "require('./package.json').version") | |
| max_attempts=6 | |
| attempt=1 | |
| while [ $attempt -le $max_attempts ]; do | |
| if npm view --registry=https://registry.npmjs.org/ "$PACKAGE_NAME@$PACKAGE_VERSION" version > /dev/null 2>&1; then | |
| echo "Package $PACKAGE_NAME@$PACKAGE_VERSION successfully published to npm" | |
| exit 0 | |
| fi | |
| echo "Attempt $attempt/$max_attempts: Package not visible yet. Waiting 20s..." | |
| sleep 20 | |
| attempt=$((attempt + 1)) | |
| done | |
| echo "Package $PACKAGE_NAME@$PACKAGE_VERSION not found on npm registry after $max_attempts attempts" | |
| exit 1 | |
| - name: Create git tag | |
| run: | | |
| git tag "v${{ env.RELEASE_VERSION }}" | |
| git push origin "v${{ env.RELEASE_VERSION }}" | |
| - name: Create GitHub Release | |
| run: | | |
| python3 ~/sdk-deployment/scripts/v1.2/create_github_release.py \ | |
| --github_api_token "$BOT_GH_TOKEN" \ | |
| --repo_name "$REPO_NAME" \ | |
| --tag_name "v${{ env.RELEASE_VERSION }}" \ | |
| --target_commitish main \ | |
| --body_path "$GITHUB_WORKSPACE/CHANGELOG_DRAFT.md" | |
| - name: Slack notification | |
| if: ${{ success() }} | |
| continue-on-error: true | |
| uses: slackapi/slack-github-action@v1.24.0 | |
| env: | |
| SLACK_BOT_TOKEN: ${{ env.SLACK_BOT_TOKEN }} | |
| with: | |
| channel-id: ${{ env.SLACK_RELEASE_CHANNEL_ID }} | |
| payload: | | |
| { | |
| "blocks": [ | |
| { | |
| "type": "section", | |
| "text": { | |
| "type": "mrkdwn", | |
| "text": ":tada: <https://github.com/${{ github.repository }}/releases/tag/v${{ env.RELEASE_VERSION }}|@sendbird/uikit-react ${{ env.RELEASE_VERSION }}> has been released!" | |
| } | |
| } | |
| ] | |
| } | |
| - name: Jira - Transition to RELEASED | |
| if: ${{ success() }} | |
| run: | | |
| python3 ~/sdk-deployment/scripts/v1.2/transit_ticket.py \ | |
| --jira_auth_user "$JIRA_AUTH_USER" \ | |
| --jira_auth_api_token "$JIRA_AUTH_API_TOKEN" \ | |
| --issue_key "$RELEASE_TICKET_KEY" \ | |
| --from_issue_state RELEASING \ | |
| --to_issue_state RELEASED | |
| - name: Jira - Rollback on failure | |
| if: ${{ failure() }} | |
| run: | | |
| if ! python3 -c "import requests" 2>/dev/null; then | |
| echo "Installing requests (not yet available)..." | |
| pip3 install requests | |
| fi | |
| if [ ! -d ~/sdk-deployment ]; then | |
| echo "Cloning sdk-deployment (not yet available)..." | |
| git clone --depth 1 --branch main https://${{ env.BOT_GH_TOKEN }}@github.com/sendbird/sdk-deployment.git ~/sdk-deployment | |
| fi | |
| python3 ~/sdk-deployment/scripts/v1.2/transit_ticket.py \ | |
| --jira_auth_user "$JIRA_AUTH_USER" \ | |
| --jira_auth_api_token "$JIRA_AUTH_API_TOKEN" \ | |
| --issue_key "$RELEASE_TICKET_KEY" \ | |
| --from_issue_state RELEASING \ | |
| --to_issue_state CONDITIONAL_RELEASE_APPROVED |