mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Fixes 'create-release-branch' workflow. The script was emitting a multiline output using `echo "results<<'EOF'" … echo "EOF"`. GitHub treats the opening delimiter literally (`'EOF'` with quotes). Because the closing line omits the quotes, the runner never sees a matching terminator, so it aborts the file-command write and marks the step as failed even though the preceding git pushes succeeded. Example of error: https://github.com/Comfy-Org/ComfyUI_frontend/actions/runs/19520246619/job/55881876566 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6878-fix-workflow-that-creates-release-branch-fails-2b46d73d365081549651eacacd5cbfec) by [Unito](https://www.unito.io)
282 lines
9.3 KiB
YAML
282 lines
9.3 KiB
YAML
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@v5
|
||
with:
|
||
fetch-depth: 0
|
||
token: ${{ secrets.PR_GH_TOKEN || secrets.GITHUB_TOKEN }}
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 'lts/*'
|
||
|
||
- 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
|