forked from OffchainLabs/nitro
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9350aa5
commit 2045b0f
Showing
2 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
name: Cherry-pick commits and open PR | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- integration | ||
types: | ||
- closed | ||
workflow_dispatch: | ||
inputs: | ||
mode: | ||
description: "Choose operation mode: 'reset' to start fresh, 'continue' to resume from existing branch" | ||
required: true | ||
default: "continue" | ||
|
||
jobs: | ||
cherry-pick-and-create-pr: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Set up Git | ||
run: | | ||
git config user.name "github-actions[bot]" | ||
git config user.email "github-actions[bot]@users.noreply.github.com" | ||
- name: Fetch all branches | ||
run: git fetch --all | ||
|
||
- name: Check if PR already exists | ||
id: check-pr | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
const { data: pulls } = await github.pulls.list({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
head: `${context.repo.owner}:cherry-pick-integration-celestia` | ||
}); | ||
if (pulls.length > 0) { | ||
core.setOutput('pr_exists', 'true'); | ||
core.setOutput('pr_url', pulls[0].html_url); | ||
} else { | ||
core.setOutput('pr_exists', 'false'); | ||
} | ||
- name: Run Cherry-pick Script in reset mode | ||
if: github.event_name == 'pull_request' && github.event.pull_request.merged == true && steps.check-pr.outputs.pr_exists == 'false' | ||
run: | | ||
./scripts/cherry-pick-integration.sh reset | ||
- name: Run Cherry-pick Script in continue mode | ||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && steps.check-pr.outputs.pr_exists == 'false') | ||
run: | | ||
./scripts/cherry-pick-integration.sh continue | ||
- name: Log existing PR | ||
if: steps.check-pr.outputs.pr_exists == 'true' | ||
run: | | ||
echo "A PR already exists: ${{ steps.check-pr.outputs.pr_url }}. No new PR will be created." |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#!/usr/bin/env bash | ||
|
||
# A script to automate the cherry-picking of commits from the "integration" branch | ||
# into the "celestia-integration" branch with support for conflict resolution. | ||
# | ||
# USAGE: | ||
# ./cherry-pick-integration.sh [MODE] | ||
# | ||
# PARAMETERS: | ||
# MODE: | ||
# - reset: | ||
# - Deletes the existing "cherry-pick-integration-celestia" branch (if it exists). | ||
# - Recreates the branch from the "celestia-integration" branch. | ||
# - Starts cherry-picking commits from the "integration" branch from the beginning. | ||
# - continue: | ||
# - Resumes from the current state of the "cherry-pick-integration-celestia" branch. | ||
# - Skips commits that have already been cherry-picked or resolved. | ||
# - Continues with unprocessed commits. | ||
# | ||
# PROCESS: | ||
# 1. Fetches the latest updates from the remote repository for both branches. | ||
# 2. Depending on the MODE: | ||
# - In "reset" mode: | ||
# - Deletes and recreates the branch "cherry-pick-integration-celestia". | ||
# - In "continue" mode: | ||
# - Uses the existing "cherry-pick-integration-celestia" branch or creates it if missing. | ||
# 3. Cherry-picks all new commits from the "integration" branch to the target branch: | ||
# - Skips already cherry-picked commits by checking commit logs. | ||
# - Pushes unresolved conflicts to the branch for manual resolution. | ||
# - If no conflicts occur, pushes the updated branch automatically. | ||
# 4. Exits with a non-zero status if conflicts are encountered. | ||
# | ||
# ERROR HANDLING: | ||
# - If a conflict occurs during cherry-pick, the script: | ||
# - Aborts the current cherry-pick operation. | ||
# - Stages the conflict state and pushes it to the branch for manual resolution. | ||
# - Exits with an error message instructing the user to resolve the conflicts. | ||
# | ||
# EXAMPLES: | ||
# 1. Start fresh and reapply all commits: | ||
# ./cherry-pick-to-celestia.sh reset | ||
# | ||
# 2. Continue cherry-picking from where it left off: | ||
# ./cherry-pick-to-celestia.sh continue | ||
# | ||
|
||
set -e | ||
|
||
MODE=$1 | ||
BRANCH_NAME="cherry-pick-integration-celestia" | ||
INTEGRATION_BRANCH="integration" | ||
TARGET_BRANCH="celestia-integration" | ||
|
||
function is_commit_processed() { | ||
local commit=$1 | ||
local marker="Cherry-picked from commit $commit" | ||
git log $BRANCH_NAME --grep="$marker" -q | ||
} | ||
|
||
function init_branch() { | ||
if [ "$MODE" == "reset" ]; then | ||
echo "Reset mode: Re-creating branch $BRANCH_NAME from $TARGET_BRANCH" | ||
git branch -D $BRANCH_NAME || echo "Branch $BRANCH_NAME does not exist locally. Skipping deletion." | ||
git checkout origin/$TARGET_BRANCH | ||
git checkout -B $BRANCH_NAME | ||
git push --set-upstream origin $BRANCH_NAME | ||
elif [ "$MODE" == "continue" ]; then | ||
echo "Continue mode: Reusing existing branch $BRANCH_NAME" | ||
git checkout $BRANCH_NAME || { | ||
echo "Branch $BRANCH_NAME does not exist locally. Creating from $TARGET_BRANCH." | ||
git checkout origin/$TARGET_BRANCH | ||
git checkout -B $BRANCH_NAME | ||
} | ||
else | ||
echo "Invalid mode. Use 'reset' or 'continue'." | ||
exit 1 | ||
fi | ||
} | ||
|
||
function cherry_pick_commits() { | ||
echo "Fetching latest commits from $INTEGRATION_BRANCH and $TARGET_BRANCH" | ||
git fetch origin $INTEGRATION_BRANCH $TARGET_BRANCH | ||
|
||
local last_merged_commit=$(git log -1 --pretty=format:"%H" origin/$INTEGRATION_BRANCH) | ||
local pr_commits=$(git log origin/$TARGET_BRANCH..$last_merged_commit --pretty=format:"%H" --) | ||
|
||
echo "Cherry-picking commits from $INTEGRATION_BRANCH to $BRANCH_NAME" | ||
for commit in $pr_commits; do | ||
if is_commit_processed $commit; then | ||
echo "Commit $commit already processed. Skipping." | ||
continue | ||
fi | ||
|
||
echo "Cherry-picking commit $commit" | ||
if ! git cherry-pick $commit; then | ||
echo "Conflict detected during cherry-pick of $commit." | ||
git status | ||
git cherry-pick --abort | ||
|
||
echo "Saving conflict state for manual resolution." | ||
git add . | ||
git commit -m "WIP: Resolve conflicts from cherry-pick of $commit (Cherry-picked from commit $commit)" || echo "No changes to commit." | ||
git push --force origin $BRANCH_NAME | ||
|
||
echo "Conflicts pushed to branch $BRANCH_NAME. Exiting for manual resolution." | ||
echo "Don't reset any commit and please resolve conflicts directly. Use \`git commit --amend --no-edit\` after resolving" | ||
exit 1 | ||
fi | ||
|
||
git commit --amend -m "$(git log -1 --pretty=%B)$'\n\n'Cherry-picked from commit $commit" | ||
done | ||
|
||
git push --force origin $BRANCH_NAME | ||
} | ||
|
||
function main() { | ||
echo "Running Cherry-pick Script with MODE=$MODE" | ||
init_branch | ||
cherry_pick_commits | ||
echo "Cherry-pick completed successfully." | ||
} | ||
|
||
main | ||
|