Skip to content

Commit 4e526a2

Browse files
committed
TO-SPLIT
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent d1846d3 commit 4e526a2

File tree

2 files changed

+83
-106
lines changed

2 files changed

+83
-106
lines changed

.github/workflows/rebase-shears.yml

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ permissions:
2626

2727
env:
2828
BRANCH: ${{ inputs.branch || 'all' }}
29-
PUSH: ${{ github.event_type == 'schedule' && 'true' || inputs.push || 'false' }}
29+
PUSH: ${{ github.event_name == 'schedule' && 'true' || inputs.push || 'false' }}
3030
COPILOT_MODEL: claude-opus-4
3131

3232
jobs:
@@ -78,14 +78,24 @@ jobs:
7878
*) UPSTREAM="upstream/$BRANCH" ;;
7979
esac
8080
81+
echo "::group::Fetching shears/$BRANCH"
8182
git fetch origin "shears/$BRANCH"
83+
echo "::endgroup::"
8284
8385
if test 0 = "$(git rev-list --count "origin/shears/$BRANCH..$UPSTREAM")"; then
84-
echo "Nothing to do: $UPSTREAM has no new commits"
86+
echo "::notice::Nothing to do for shears/$BRANCH: $UPSTREAM has no new commits"
8587
exit 0
8688
fi
8789
88-
./ci/rebase-branch.sh "origin/shears/$BRANCH" "$UPSTREAM" ./ci
90+
echo "::group::Rebasing shears/$BRANCH"
91+
if ./ci/rebase-branch.sh "shears/$BRANCH" "$UPSTREAM" ./ci; then
92+
echo "::endgroup::"
93+
echo "to_push=shears/$BRANCH" >>"$GITHUB_OUTPUT"
94+
else
95+
echo "::endgroup::"
96+
echo "failed_worktrees=$PWD/rebase-worktree-$BRANCH" >>"$GITHUB_OUTPUT"
97+
exit 1
98+
fi
8999
env:
90100
GH_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
91101

@@ -94,60 +104,81 @@ jobs:
94104
if: env.BRANCH == 'all'
95105
shell: bash
96106
run: |
107+
to_push=""
108+
failed_worktrees=""
109+
97110
for BRANCH in seen next main maint; do
98-
echo "::group::Processing shears/$BRANCH"
111+
echo "::group::Fetching shears/$BRANCH"
99112
100113
case "$BRANCH" in
101114
main) UPSTREAM="upstream/master" ;;
102115
*) UPSTREAM="upstream/$BRANCH" ;;
103116
esac
104117
105118
git fetch origin "shears/$BRANCH"
119+
echo "::endgroup::"
106120
107121
if test 0 = "$(git rev-list --count "origin/shears/$BRANCH..$UPSTREAM")"; then
108-
echo "Nothing to do: $UPSTREAM has no new commits"
109-
echo "::endgroup::"
122+
echo "::notice::Nothing to do for shears/$BRANCH: $UPSTREAM has no new commits"
110123
continue
111124
fi
112125
113-
./ci/rebase-branch.sh "origin/shears/$BRANCH" "$UPSTREAM" ./ci || {
126+
worktree="$PWD/rebase-worktree-$BRANCH"
127+
echo "::group::Rebasing shears/$BRANCH"
128+
if ./ci/rebase-branch.sh "shears/$BRANCH" "$UPSTREAM" ./ci; then
114129
echo "::endgroup::"
115-
echo "Rebase failed for shears/$BRANCH"
116-
exit 1
117-
}
118-
echo "::endgroup::"
130+
to_push="${to_push:+$to_push }shears/$BRANCH"
131+
else
132+
echo "::endgroup::"
133+
echo "::error::Rebase failed for shears/$BRANCH"
134+
failed_worktrees="${failed_worktrees:+$failed_worktrees }$worktree"
135+
fi
119136
done
137+
138+
echo "to_push=$to_push" >>"$GITHUB_OUTPUT"
139+
echo "failed_worktrees=$failed_worktrees" >>"$GITHUB_OUTPUT"
140+
141+
# Fail the step if any rebase failed
142+
test -z "$failed_worktrees"
120143
env:
121144
GH_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
122145

123-
- name: Create recovery archive on failure
124-
if: failure() && (steps.rebase-single.outputs.worktree || steps.rebase-all.outputs.worktree)
146+
- name: Create worktree bundles and archives
147+
if: always()
125148
shell: bash
126149
run: |
127-
worktree="${{ steps.rebase-single.outputs.worktree || steps.rebase-all.outputs.worktree }}"
128-
cd "$worktree"
129-
git bundle create recovery.bundle HEAD REBASE_HEAD refs/rewritten/* 2>/dev/null || true
130-
tar -czf recovery-archive.tar.gz .
150+
set -x
151+
mkdir -p upload
152+
153+
# Bundles for successful branches (no worktree needed)
154+
for branch in ${{ steps.rebase-single.outputs.to_push }} ${{ steps.rebase-all.outputs.to_push }}; do
155+
name=${branch##*/}
156+
git bundle create "upload/$name.bundle" "$branch" ^origin/main
157+
done
158+
159+
# Bundles and archives for failed branches
160+
for worktree in ${{ steps.rebase-single.outputs.failed_worktrees }} ${{ steps.rebase-all.outputs.failed_worktrees }}; do
161+
test -d "$worktree" || continue
162+
name=${worktree##*rebase-worktree-}
163+
cd "$worktree"
164+
git for-each-ref --format='%(refname)' |
165+
grep -v '^refs/tags/' |
166+
sed 's,^refs/remotes/origin/,^refs/remotes/origin/,' |
167+
git bundle create "$GITHUB_WORKSPACE/upload/$name.bundle" --stdin HEAD
168+
tar -czf "$GITHUB_WORKSPACE/upload/$name.tar.gz" .
169+
cd "$GITHUB_WORKSPACE"
170+
done
131171
132-
- name: Upload recovery archive on failure
133-
if: failure() && (steps.rebase-single.outputs.worktree || steps.rebase-all.outputs.worktree)
172+
- name: Upload bundles and worktrees
173+
if: always()
134174
uses: actions/upload-artifact@v4
135175
with:
136-
name: recovery-archive
137-
path: "${{ steps.rebase-single.outputs.worktree || steps.rebase-all.outputs.worktree }}/recovery-archive.tar.gz"
176+
name: bundles-and-worktrees
177+
path: upload/
178+
if-no-files-found: warn
138179

139180
- name: Push results
140-
if: env.PUSH == 'true'
181+
if: env.PUSH == 'true' && (steps.rebase-single.outputs.to_push || steps.rebase-all.outputs.to_push)
141182
shell: bash
142183
run: |
143-
# Find all worktrees created by the script and push them
144-
for worktree in /tmp/tmp.*; do
145-
if test -d "$worktree/.git" || test -f "$worktree/.git"; then
146-
cd "$worktree"
147-
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
148-
if test -n "$BRANCH" && test "$BRANCH" != "HEAD"; then
149-
echo "Pushing $BRANCH..."
150-
git push --force origin "HEAD:$BRANCH"
151-
fi
152-
fi
153-
done
184+
git push --force origin ${{ steps.rebase-single.outputs.to_push }} ${{ steps.rebase-all.outputs.to_push }}

ci/rebase-branch.sh

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
# Usage: rebase-branch.sh <shears-branch> <upstream-branch> [<scripts-dir>]
66
#
77
# Parameters:
8-
# shears-branch - The branch to rebase (e.g., origin/shears/seen)
8+
# shears-branch - The branch to rebase (e.g., shears/seen)
99
# upstream-branch - The upstream branch to rebase onto (e.g., upstream/seen)
1010
# scripts-dir - Optional: directory containing this script and agents
1111
# (defaults to the directory containing this script)
1212
#
1313
# Preconditions:
1414
# - Must be run from a git repository
15-
# - shears-branch and upstream-branch must be fetched
15+
# - origin/<shears-branch> and <upstream-branch> must be fetched
1616
# - GH_TOKEN or GITHUB_TOKEN must be set for AI resolution
1717
#
1818
# Outputs:
@@ -82,53 +82,6 @@ generate_log_l_commands () {
8282
}
8383

8484
# Function to create recovery bundle on failure
85-
create_recovery_archive () {
86-
local ai_output=$1
87-
local archive_dir=$(mktemp -d)
88-
local bundle_file="$archive_dir/recovery.bundle"
89-
local archive_file="${WORKTREE_DIR}/recovery-archive.tar.gz"
90-
91-
echo "::group::Creating recovery archive"
92-
93-
# Collect refs: HEAD, REBASE_HEAD, and all refs/rewritten/*
94-
{
95-
echo HEAD
96-
echo REBASE_HEAD
97-
git for-each-ref --format='%(refname)' refs/rewritten/
98-
} >"$archive_dir/refs-to-bundle.txt"
99-
100-
# Create bundle with all progress (may fail if refs don't exist yet)
101-
if ! git bundle create "$bundle_file" --stdin <"$archive_dir/refs-to-bundle.txt"; then
102-
echo "::warning::Could not create recovery bundle"
103-
fi
104-
105-
# Copy the conflict report if it exists
106-
if test -f "$REPORT_FILE"; then
107-
cp "$REPORT_FILE" "$archive_dir/"
108-
fi
109-
110-
# Save the AI output that caused failure
111-
echo "$ai_output" >"$archive_dir/ai-output.txt"
112-
113-
# Save rebase state if it exists
114-
if test -d .git/rebase-merge; then
115-
cp -r .git/rebase-merge "$archive_dir/"
116-
fi
117-
118-
# Create archive with working tree and recovery files
119-
tar -czf "$archive_file" -C "$WORKTREE_DIR" . -C "$archive_dir" .
120-
121-
rm -rf "$archive_dir"
122-
123-
echo "Recovery archive created: $archive_file"
124-
echo "::endgroup::"
125-
126-
# Output for GitHub Actions artifact upload
127-
if test -n "$GITHUB_OUTPUT"; then
128-
echo "recovery_archive=$archive_file" >>"$GITHUB_OUTPUT"
129-
fi
130-
}
131-
13285
# Function to resolve a single conflict with AI
13386
resolve_conflict_with_ai () {
13487
# Get REBASE_HEAD info once
@@ -285,7 +238,6 @@ $(tail -50 make.log)
285238
\`\`\`
286239
287240
BUILD_FAIL_EOF
288-
create_recovery_archive "$retry_output"
289241
exit 2
290242
fi
291243
echo "::endgroup::"
@@ -307,7 +259,6 @@ $ai_output
307259
\`\`\`
308260
309261
EOF
310-
create_recovery_archive "$ai_output"
311262
exit 2
312263
;;
313264
*)
@@ -323,7 +274,6 @@ $ai_output
323274
\`\`\`
324275
325276
EOF
326-
create_recovery_archive "$ai_output"
327277
exit 2
328278
;;
329279
esac
@@ -383,29 +333,26 @@ command -v copilot >/dev/null 2>&1 || die "copilot CLI not found in PATH"
383333
test -n "${GH_TOKEN:-${GITHUB_TOKEN:-}}" ||
384334
die "GH_TOKEN or GITHUB_TOKEN must be set"
385335

386-
# Validate branches exist
387-
git rev-parse --verify "$SHEARS_BRANCH" >/dev/null 2>&1 ||
388-
die "Branch not found: $SHEARS_BRANCH"
336+
# Validate branches exist (shears branch is fetched as origin/<branch>)
337+
git rev-parse --verify "origin/$SHEARS_BRANCH" >/dev/null 2>&1 ||
338+
die "Branch not found: origin/$SHEARS_BRANCH"
389339
git rev-parse --verify "$UPSTREAM_BRANCH" >/dev/null 2>&1 ||
390340
die "Branch not found: $UPSTREAM_BRANCH"
391341

392-
# Set up worktree
393-
WORKTREE_DIR=$(mktemp -d)
342+
# Set up worktree in current directory, named after the branch
343+
WORKTREE_DIR="$PWD/rebase-worktree-${SHEARS_BRANCH##*/}"
394344
REPORT_FILE="$WORKTREE_DIR/conflict-report.md"
395-
trap 'git worktree remove --force "$WORKTREE_DIR"' EXIT
396345

397346
# Output worktree path early so recovery steps can find it on failure
398347
if test -n "$GITHUB_OUTPUT"; then
399348
echo "worktree=$WORKTREE_DIR" >>"$GITHUB_OUTPUT"
400349
fi
401350

402-
# Extract local branch name from origin/shears/foo -> shears/foo
403-
LOCAL_BRANCH=${SHEARS_BRANCH#origin/}
404-
405-
echo "::group::Setup"
351+
echo "::group::Setup worktree"
406352
echo "Creating worktree at $WORKTREE_DIR..."
407-
git worktree add -b "$LOCAL_BRANCH" "$WORKTREE_DIR" "$SHEARS_BRANCH"
353+
git worktree add -B "$SHEARS_BRANCH" "$WORKTREE_DIR" "origin/$SHEARS_BRANCH"
408354
cd "$WORKTREE_DIR"
355+
echo "::endgroup::"
409356

410357
# Find the old marker
411358
OLD_MARKER=$(git rev-parse "HEAD^{/Start.the.merging-rebase}") ||
@@ -414,21 +361,21 @@ OLD_UPSTREAM=$(git rev-parse "$OLD_MARKER^1")
414361
NEW_UPSTREAM=$(git rev-parse "$UPSTREAM_BRANCH")
415362
TIP_OID=$(git rev-parse HEAD)
416363

417-
echo "Old marker: $OLD_MARKER"
418-
echo "Old upstream: $OLD_UPSTREAM"
419-
echo "New upstream: $NEW_UPSTREAM"
420-
echo "Current tip: $TIP_OID"
421-
echo "::endgroup::"
364+
echo "::notice::Old marker: $OLD_MARKER"
365+
echo "::notice::Old upstream: $OLD_UPSTREAM"
366+
echo "::notice::New upstream: $NEW_UPSTREAM"
367+
echo "::notice::Current tip: $TIP_OID"
422368

423369
# Check if shears branch is behind GfW main (commits in main not in shears)
424370
# The second parent of the marker points to the GfW branch tip at marker creation time
425371
GFW_MAIN_BRANCH="origin/main"
426372
BEHIND_COUNT=$(git rev-list --count "$TIP_OID..$GFW_MAIN_BRANCH" || echo "0")
427373

428374
if test "$BEHIND_COUNT" -gt 0; then
429-
echo "::group::Syncing $BEHIND_COUNT commits from $GFW_MAIN_BRANCH"
375+
echo "::notice::Syncing $BEHIND_COUNT commits from $GFW_MAIN_BRANCH"
376+
echo "::group::Sync rebase from $GFW_MAIN_BRANCH"
430377
run_rebase_with_ai -r HEAD "$GFW_MAIN_BRANCH"
431-
git checkout -B "$LOCAL_BRANCH"
378+
git checkout -B "$SHEARS_BRANCH"
432379
TIP_OID=$(git rev-parse HEAD)
433380
echo "::endgroup::"
434381
fi
@@ -504,10 +451,9 @@ EOF
504451

505452
echo "Rebase completed: $(git rev-parse --short HEAD)"
506453
cat "$REPORT_FILE"
507-
echo "To push: cd $WORKTREE_DIR && git push --force origin HEAD:${SHEARS_BRANCH##*/}"
454+
echo "To push: git push --force origin $(git rev-parse HEAD):$SHEARS_BRANCH"
508455

509-
# For GitHub Actions: output variables (worktree already output early)
456+
# For GitHub Actions: output report path
510457
if test -n "$GITHUB_OUTPUT"; then
511458
echo "report=$REPORT_FILE" >>"$GITHUB_OUTPUT"
512-
echo "head=$(git rev-parse HEAD)" >>"$GITHUB_OUTPUT"
513459
fi

0 commit comments

Comments
 (0)