151 lines
5.9 KiB
YAML
151 lines
5.9 KiB
YAML
name: Cherry Pick
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
pull_request_target:
|
|
types: [closed]
|
|
|
|
jobs:
|
|
cherry-pick:
|
|
# This job will run when a PR is merged with a specific comment,
|
|
# or when a comment is added to an already merged PR.
|
|
runs-on: ubuntu-latest
|
|
# Use pull_request_target so that we can add comments back to the PR
|
|
# if the cherry-pick fails.
|
|
permissions:
|
|
pull-requests: write
|
|
contents: write
|
|
issues: write
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0 # Required to get all history for cherry-picking
|
|
|
|
- name: Extract info and determine trigger
|
|
id: info
|
|
run: |
|
|
# Default to failure unless a valid trigger is found
|
|
echo "valid=false" >> $GITHUB_OUTPUT
|
|
|
|
if [[ "${{ github.event_name }}" == "pull_request_target" && "${{ github.event.pull_request.merged }}" == "true" ]]; then
|
|
echo "Triggered by PR merge"
|
|
PR_NUMBER="${{ github.event.pull_request.number }}"
|
|
|
|
# Check PR body first, then fall back to comments
|
|
TEXT_TO_SEARCH="${{ github.event.pull_request.body }}"
|
|
if [[ ! "$TEXT_TO_SEARCH" =~ /cherry-pick[[:space:]]+(stable|preview) ]]; then
|
|
echo "Command not found in PR body. Checking comments..."
|
|
TEXT_TO_SEARCH=$(gh pr view $PR_NUMBER --json comments -q '.comments[].body' | tail -n 100)
|
|
fi
|
|
|
|
if [[ "$TEXT_TO_SEARCH" =~ /cherry-pick[[:space:]]+(stable|preview) ]]; then
|
|
echo "Found cherry-pick command."
|
|
MERGE_SHA="${{ github.event.pull_request.merge_commit_sha }}"
|
|
# Get the last matching command in the text
|
|
CHANNEL=$(echo "$TEXT_TO_SEARCH" | grep -oP '/cherry-pick[[:space:]]+\K(stable|preview)' | tail -n1)
|
|
|
|
echo "valid=true" >> $GITHUB_OUTPUT
|
|
echo "merge_sha=$MERGE_SHA" >> $GITHUB_OUTPUT
|
|
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
|
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "No cherry-pick command found in PR body or recent comments. Exiting."
|
|
exit 0
|
|
fi
|
|
|
|
elif [[ "${{ github.event_name }}" == "issue_comment" && "${{ github.event.issue.pull_request }}" != "" ]]; then
|
|
echo "Triggered by issue comment"
|
|
COMMENT_BODY="${{ github.event.comment.body }}"
|
|
if [[ ! "$COMMENT_BODY" =~ /cherry-pick[[:space:]]+(stable|preview) ]]; then
|
|
echo "Comment does not contain cherry-pick command. Exiting."
|
|
exit 0
|
|
fi
|
|
|
|
PR_NUMBER="${{ github.event.issue.number }}"
|
|
|
|
# Check if the PR is merged
|
|
MERGE_SHA=$(gh pr view $PR_NUMBER --json mergeCommit -q .mergeCommit.oid)
|
|
if [[ -z "$MERGE_SHA" ]]; then
|
|
echo "PR #$PR_NUMBER is not merged. Exiting."
|
|
exit 0
|
|
fi
|
|
|
|
CHANNEL=$(echo "$COMMENT_BODY" | grep -oP '/cherry-pick[[:space:]]+\K(stable|preview)' | head -n1)
|
|
|
|
echo "valid=true" >> $GITHUB_OUTPUT
|
|
echo "merge_sha=$MERGE_SHA" >> $GITHUB_OUTPUT
|
|
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
|
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
|
|
fi
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Cherry-pick
|
|
if: steps.info.outputs.valid == 'true'
|
|
run: |
|
|
set -e
|
|
|
|
CHANNEL="${{ steps.info.outputs.channel }}"
|
|
MERGE_SHA="${{ steps.info.outputs.merge_sha }}"
|
|
PR_NUMBER="${{ steps.info.outputs.pr_number }}"
|
|
|
|
# Get the latest version for the channel
|
|
echo "Fetching latest version for '$CHANNEL' channel..."
|
|
query=""
|
|
case $CHANNEL in
|
|
stable)
|
|
;;
|
|
preview)
|
|
query="&preview=1"
|
|
;;
|
|
*)
|
|
echo "Invalid channel: $CHANNEL" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
LATEST_VERSION=$(curl -s "https://zed.dev/api/releases/latest?asset=zed&os=macos&arch=aarch64$query" | jq -r .version)
|
|
|
|
if [[ -z "$LATEST_VERSION" ]]; then
|
|
echo "Could not fetch latest version for channel '$CHANNEL'"
|
|
gh pr comment $PR_NUMBER --body "Could not fetch latest version for channel '$CHANNEL' from zed.dev API."
|
|
exit 1
|
|
fi
|
|
echo "Latest version is $LATEST_VERSION"
|
|
|
|
# Construct target branch name (e.g., v0.85.4 -> v0.85.x)
|
|
TARGET_BRANCH=$(echo "$LATEST_VERSION" | sed -E 's/v([0-9]+\.[0-9]+)\..*/v\1.x/')
|
|
echo "Target branch is $TARGET_BRANCH"
|
|
|
|
# Configure git
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
|
|
# Create and push the cherry-pick branch
|
|
NEW_BRANCH="cherry-pick/pr-${PR_NUMBER}-to-${TARGET_BRANCH}"
|
|
|
|
git fetch origin $TARGET_BRANCH
|
|
git checkout -b $NEW_BRANCH "origin/$TARGET_BRANCH"
|
|
|
|
echo "Attempting to cherry-pick $MERGE_SHA..."
|
|
if ! git cherry-pick $MERGE_SHA; then
|
|
echo "Cherry-pick failed. Please resolve conflicts manually."
|
|
gh pr comment $PR_NUMBER --body "Automated cherry-pick to \`$TARGET_BRANCH\` failed due to conflicts. Please resolve them manually."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Pushing new branch $NEW_BRANCH..."
|
|
git push -u origin $NEW_BRANCH
|
|
|
|
# Create the pull request
|
|
echo "Creating pull request..."
|
|
gh pr create \
|
|
--title "Cherry-pick PR #${PR_NUMBER} to ${TARGET_BRANCH}" \
|
|
--body "This PR cherry-picks the changes from #${PR_NUMBER} to the \`$TARGET_BRANCH\` branch." \
|
|
--base $TARGET_BRANCH \
|
|
--head $NEW_BRANCH \
|
|
--reviewer "${{ github.actor }}"
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|