Scheduled Release Cut #32
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: Scheduled Release Cut | |
| on: | |
| schedule: | |
| # Every Monday at 8:30 AM UTC (2:00 PM IST) | |
| # Biweekly cadence enforced via ISO week number check in job | |
| - cron: "30 8 * * 1" | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Override release version (e.g., 1.70.0). If empty, auto-determines next minor version." | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| jobs: | |
| check-schedule: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_run: ${{ steps.check.outputs.should_run }} | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: audit | |
| - name: Check biweekly schedule | |
| id: check | |
| env: | |
| PAUSE_AUTO_RELEASE: ${{ vars.PAUSE_AUTO_RELEASE }} | |
| RELEASE_WEEK_PARITY: ${{ vars.RELEASE_WEEK_PARITY }} | |
| run: | | |
| # Check for release freeze (skip for manual dispatch) | |
| if [ "${{ github.event_name }}" != "workflow_dispatch" ] && [ "$PAUSE_AUTO_RELEASE" = "true" ]; then | |
| echo "Auto release is paused - skipping" | |
| echo "should_run=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| else | |
| WEEK_NUM=$(date +%V) | |
| # RELEASE_WEEK_PARITY: "even" (default) or "odd" | |
| PARITY="${RELEASE_WEEK_PARITY:-even}" | |
| if [ "$PARITY" = "odd" ]; then | |
| EXPECTED_REMAINDER=1 | |
| else | |
| EXPECTED_REMAINDER=0 | |
| fi | |
| if [ $((WEEK_NUM % 2)) -eq $EXPECTED_REMAINDER ]; then | |
| echo "Release week (ISO week $WEEK_NUM, parity=$PARITY) - proceeding" | |
| echo "should_run=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Skipping - not a release week (ISO week $WEEK_NUM, parity=$PARITY)" | |
| echo "should_run=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| fi | |
| release-cut: | |
| needs: check-schedule | |
| if: needs.check-schedule.outputs.should_run == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: audit | |
| - name: Create app token | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| with: | |
| app-id: ${{ vars.RELEASE_APP_ID }} | |
| private-key: ${{ secrets.RELEASE_PRIVATE_KEY }} | |
| permission-contents: write | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Determine next version | |
| id: version | |
| env: | |
| VERSION_OVERRIDE: ${{ github.event.inputs.version }} | |
| run: | | |
| if [ -n "$VERSION_OVERRIDE" ]; then | |
| VERSION="$VERSION_OVERRIDE" | |
| else | |
| # Get the latest release tag (stable, non-prerelease) | |
| LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1) | |
| if [ -z "$LATEST_TAG" ]; then | |
| echo "::error::No release tags found" | |
| exit 1 | |
| fi | |
| echo "Latest release tag: $LATEST_TAG" | |
| MAJOR=$(echo "$LATEST_TAG" | sed 's/v//' | cut -d. -f1) | |
| MINOR=$(echo "$LATEST_TAG" | sed 's/v//' | cut -d. -f2) | |
| NEXT_MINOR=$((MINOR + 1)) | |
| VERSION="${MAJOR}.${NEXT_MINOR}.0" | |
| fi | |
| MAJOR=$(echo "$VERSION" | cut -d. -f1) | |
| MINOR=$(echo "$VERSION" | cut -d. -f2) | |
| BRANCH="release/${MAJOR}.${MINOR}.x" | |
| PRERELEASE_BRANCH="prerelease/${MAJOR}.${MINOR}.0-rc.1" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" | |
| echo "prerelease_branch=$PRERELEASE_BRANCH" >> "$GITHUB_OUTPUT" | |
| echo "Next version: $VERSION, Branch: $BRANCH, Prerelease Branch: $PRERELEASE_BRANCH" | |
| - name: Create release branch | |
| id: create-branch | |
| run: | | |
| BRANCH="${{ steps.version.outputs.branch }}" | |
| if git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then | |
| echo "Branch $BRANCH already exists, skipping creation" | |
| echo "created=false" >> "$GITHUB_OUTPUT" | |
| else | |
| git checkout -b "$BRANCH" | |
| git push origin "$BRANCH" | |
| echo "Created and pushed branch: $BRANCH" | |
| echo "created=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Create prerelease branch | |
| id: create-prerelease-branch | |
| run: | | |
| PRERELEASE_BRANCH="${{ steps.version.outputs.prerelease_branch }}" | |
| if git ls-remote --heads origin "$PRERELEASE_BRANCH" | grep -q "$PRERELEASE_BRANCH"; then | |
| echo "Branch $PRERELEASE_BRANCH already exists, skipping creation" | |
| echo "created=false" >> "$GITHUB_OUTPUT" | |
| else | |
| git checkout -b "$PRERELEASE_BRANCH" | |
| git push origin "$PRERELEASE_BRANCH" | |
| echo "Created and pushed branch: $PRERELEASE_BRANCH" | |
| echo "created=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Notify Slack | |
| uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 | |
| with: | |
| method: chat.postMessage | |
| token: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} | |
| payload: | | |
| channel: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} | |
| blocks: | |
| - type: header | |
| text: | |
| type: plain_text | |
| text: "${{ steps.create-branch.outputs.created == 'true' && format('Release Cut: v{0}', steps.version.outputs.version) || format('Release Cut Skipped: v{0}', steps.version.outputs.version) }}" | |
| - type: section | |
| text: | |
| type: mrkdwn | |
| text: "${{ steps.create-branch.outputs.created == 'true' && format('*Branch:* `{0}`\n*Version:* `{1}`\n*Cut from:* `master`', steps.version.outputs.branch, steps.version.outputs.version) || format('Branch `{0}` already exists. No action taken.', steps.version.outputs.branch) }}" | |
| - type: section | |
| text: | |
| type: mrkdwn | |
| text: "${{ steps.create-prerelease-branch.outputs.created == 'true' && format('*Prerelease Branch:* `{0}`', steps.version.outputs.prerelease_branch) || format('Prerelease branch `{0}` already exists. No action taken.', steps.version.outputs.prerelease_branch) }}" |