[pull] main from Comfy-Org:main #14
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 Branch Create | |
| on: | |
| pull_request: | |
| types: [closed] | |
| branches: [main] | |
| paths: | |
| - 'package.json' | |
| jobs: | |
| create-release-branch: | |
| runs-on: ubuntu-latest | |
| if: > | |
| github.event.pull_request.merged == true && | |
| contains(github.event.pull_request.labels.*.name, 'Release') | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.PR_GH_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version-file: '.nvmrc' | |
| - name: Check version bump type | |
| id: check_version | |
| run: | | |
| # Get current version from main | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| # Remove 'v' prefix if present (shouldn't be in package.json, but defensive) | |
| CURRENT_VERSION=${CURRENT_VERSION#v} | |
| echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| # Validate version format | |
| if ! [[ "$CURRENT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
| echo "ERROR: Invalid version format: $CURRENT_VERSION" | |
| exit 1 | |
| fi | |
| # Extract major and minor versions | |
| MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1) | |
| MINOR=$(echo $CURRENT_VERSION | cut -d. -f2) | |
| PATCH=$(echo $CURRENT_VERSION | cut -d. -f3 | cut -d- -f1) | |
| echo "major=$MAJOR" >> $GITHUB_OUTPUT | |
| echo "minor=$MINOR" >> $GITHUB_OUTPUT | |
| echo "patch=$PATCH" >> $GITHUB_OUTPUT | |
| # Get previous version from the commit before the merge | |
| git checkout HEAD^1 | |
| PREV_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "0.0.0") | |
| # Remove 'v' prefix if present | |
| PREV_VERSION=${PREV_VERSION#v} | |
| # Validate previous version format | |
| if ! [[ "$PREV_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then | |
| echo "WARNING: Invalid previous version format: $PREV_VERSION, using 0.0.0" | |
| PREV_VERSION="0.0.0" | |
| fi | |
| PREV_MINOR=$(echo $PREV_VERSION | cut -d. -f2) | |
| echo "prev_version=$PREV_VERSION" >> $GITHUB_OUTPUT | |
| echo "prev_minor=$PREV_MINOR" >> $GITHUB_OUTPUT | |
| BASE_COMMIT=$(git rev-parse HEAD) | |
| echo "base_commit=$BASE_COMMIT" >> $GITHUB_OUTPUT | |
| # Get previous major version for comparison | |
| PREV_MAJOR=$(echo $PREV_VERSION | cut -d. -f1) | |
| # Check if current version is a pre-release | |
| if [[ "$CURRENT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+- ]]; then | |
| IS_PRERELEASE=true | |
| else | |
| IS_PRERELEASE=false | |
| fi | |
| # Check if this was a minor version bump or major version bump | |
| # But skip if it's a pre-release version | |
| if [[ "$IS_PRERELEASE" == "true" ]]; then | |
| echo "is_minor_bump=false" >> $GITHUB_OUTPUT | |
| echo "reason=prerelease version" >> $GITHUB_OUTPUT | |
| elif [[ "$MAJOR" -gt "$PREV_MAJOR" && "$MINOR" == "0" && "$PATCH" == "0" ]]; then | |
| # Major version bump (e.g., 1.99.x → 2.0.0) | |
| echo "is_minor_bump=true" >> $GITHUB_OUTPUT | |
| BRANCH_BASE="${PREV_MAJOR}.${PREV_MINOR}" | |
| echo "branch_base=$BRANCH_BASE" >> $GITHUB_OUTPUT | |
| elif [[ "$MAJOR" == "$PREV_MAJOR" && "$MINOR" -gt "$PREV_MINOR" && "$PATCH" == "0" ]]; then | |
| # Minor version bump (e.g., 1.23.x → 1.24.0) | |
| echo "is_minor_bump=true" >> $GITHUB_OUTPUT | |
| BRANCH_BASE="${MAJOR}.${PREV_MINOR}" | |
| echo "branch_base=$BRANCH_BASE" >> $GITHUB_OUTPUT | |
| else | |
| echo "is_minor_bump=false" >> $GITHUB_OUTPUT | |
| fi | |
| # Return to main branch | |
| git checkout main | |
| - name: Create release branches | |
| id: create_branches | |
| if: steps.check_version.outputs.is_minor_bump == 'true' | |
| run: | | |
| BRANCH_BASE="${{ steps.check_version.outputs.branch_base }}" | |
| PREV_VERSION="${{ steps.check_version.outputs.prev_version }}" | |
| if [[ -z "$BRANCH_BASE" ]]; then | |
| echo "::error::Branch base not set; unable to determine release branches" | |
| exit 1 | |
| fi | |
| BASE_COMMIT="${{ steps.check_version.outputs.base_commit }}" | |
| if [[ -z "$BASE_COMMIT" ]]; then | |
| echo "::error::Base commit not provided; cannot create release branches" | |
| exit 1 | |
| fi | |
| RESULTS_FILE=$(mktemp) | |
| trap 'rm -f "$RESULTS_FILE"' EXIT | |
| for PREFIX in core cloud; do | |
| BRANCH_NAME="${PREFIX}/${BRANCH_BASE}" | |
| if git ls-remote --exit-code --heads origin \ | |
| "$BRANCH_NAME" >/dev/null 2>&1; then | |
| echo "⚠️ Branch $BRANCH_NAME already exists" | |
| echo "ℹ️ Skipping creation for $BRANCH_NAME" | |
| STATUS="exists" | |
| else | |
| # Create branch from the commit BEFORE the version bump | |
| if ! git push origin "$BASE_COMMIT:refs/heads/$BRANCH_NAME"; then | |
| echo "::error::Failed to push release branch $BRANCH_NAME" | |
| exit 1 | |
| fi | |
| echo "✅ Created release branch: $BRANCH_NAME" | |
| STATUS="created" | |
| fi | |
| echo "$BRANCH_NAME|$STATUS|$PREV_VERSION" >> "$RESULTS_FILE" | |
| done | |
| { | |
| echo "results<<EOF" | |
| cat "$RESULTS_FILE" | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Ensure release labels | |
| if: steps.check_version.outputs.is_minor_bump == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.PR_GH_TOKEN || secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| BRANCH_BASE="${{ steps.check_version.outputs.branch_base }}" | |
| if [[ -z "$BRANCH_BASE" ]]; then | |
| echo "::error::Branch base not set; unable to manage labels" | |
| exit 1 | |
| fi | |
| declare -A COLORS=( | |
| [core]="4361ee" | |
| [cloud]="4f6ef5" | |
| ) | |
| for PREFIX in core cloud; do | |
| LABEL="${PREFIX}/${BRANCH_BASE}" | |
| COLOR="${COLORS[$PREFIX]}" | |
| DESCRIPTION="Backport PRs for ${PREFIX} ${BRANCH_BASE}" | |
| if gh label view "$LABEL" >/dev/null 2>&1; then | |
| gh label edit "$LABEL" \ | |
| --color "$COLOR" \ | |
| --description "$DESCRIPTION" | |
| echo "🔄 Updated label $LABEL" | |
| else | |
| gh label create "$LABEL" \ | |
| --color "$COLOR" \ | |
| --description "$DESCRIPTION" | |
| echo "✨ Created label $LABEL" | |
| fi | |
| done | |
| MIN_LABELS_TO_KEEP=3 | |
| MAX_LABELS_TO_FETCH=200 | |
| for PREFIX in core cloud; do | |
| mapfile -t LABELS < <( | |
| gh label list \ | |
| --json name \ | |
| --limit "$MAX_LABELS_TO_FETCH" \ | |
| --jq '.[].name' | | |
| grep -E "^${PREFIX}/[0-9]+\.[0-9]+$" | | |
| sort -t/ -k2,2V | |
| ) | |
| TOTAL=${#LABELS[@]} | |
| if (( TOTAL <= MIN_LABELS_TO_KEEP )); then | |
| echo "ℹ️ Nothing to prune for $PREFIX labels" | |
| continue | |
| fi | |
| REMOVE_COUNT=$((TOTAL - MIN_LABELS_TO_KEEP)) | |
| if (( REMOVE_COUNT > 1 )); then | |
| REMOVE_COUNT=1 | |
| fi | |
| for ((i=0; i<REMOVE_COUNT; i++)); do | |
| OLD_LABEL="${LABELS[$i]}" | |
| gh label delete "$OLD_LABEL" --yes | |
| echo "🗑️ Removed old label $OLD_LABEL" | |
| done | |
| done | |
| - name: Post summary | |
| if: always() && steps.check_version.outputs.is_minor_bump == 'true' | |
| run: | | |
| CURRENT_VERSION="${{ steps.check_version.outputs.current_version }}" | |
| RESULTS="${{ steps.create_branches.outputs.results }}" | |
| if [[ -z "$RESULTS" ]]; then | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| ## 🌿 Release Branch Summary | |
| Release branch creation skipped; no eligible branches were found. | |
| EOF | |
| exit 0 | |
| fi | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| ## 🌿 Release Branch Summary | |
| - **Main branch**: \`$CURRENT_VERSION\` (active development) | |
| ### Branch Status | |
| EOF | |
| while IFS='|' read -r BRANCH STATUS PREV_VERSION; do | |
| if [[ "$STATUS" == "created" ]]; then | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| - \`$BRANCH\` created from version \`$PREV_VERSION\` | |
| EOF | |
| else | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| - \`$BRANCH\` already existed (based on version \`$PREV_VERSION\`) | |
| EOF | |
| fi | |
| done <<< "$RESULTS" | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| ### Branch Policy | |
| Release branches are feature-frozen and only accept: | |
| - 🐛 Bug fixes | |
| - 🔒 Security patches | |
| - 📚 Documentation updates | |
| All new features should continue to be developed against \`main\`. | |
| ### Backporting Changes | |
| To backport a fix: | |
| 1. Create your fix on \`main\` first | |
| 2. Cherry-pick to the target release branch | |
| 3. Create a PR targeting that branch | |
| 4. Apply the matching \`core/x.y\` or \`cloud/x.y\` label | |
| EOF |