Skip to content

Scheduled Release Cut #32

Scheduled Release Cut

Scheduled Release Cut #32

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) }}"