Skip to content

Commit 6101dab

Browse files
committed
Add rebase CI
1 parent 01217ac commit 6101dab

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

.github/scripts/push.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
upstream_repo=$1
6+
base_repo=$2
7+
output_branches=$3
8+
9+
git remote add upstream "${upstream_repo}" || true
10+
git fetch upstream master
11+
12+
# push each branch
13+
while IFS= read -r branch || [[ -n $branch ]]; do
14+
git checkout "${branch}"
15+
echo "git push -f ${base_repo} ${branch}"
16+
# git push -f "${base_repo}" "${branch}"
17+
done < <(echo "${output_branches}")
18+

.github/scripts/rebase.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
upstream_repo=$1
6+
7+
git remote add upstream "${upstream_repo}" || true
8+
git fetch upstream master
9+
10+
output_branches=()
11+
12+
# rebase each branch
13+
mkdir -p rebase
14+
while IFS= read -r branch || [[ -n $branch ]]; do
15+
(
16+
git checkout "${branch}"
17+
common_ancestor=$(git merge-base "${branch}" "master")
18+
[ -e rebase/"${branch}" ] && exit 1
19+
mkdir -p rebase/"${branch}"
20+
cd rebase/"${branch}"
21+
echo "${common_ancestor}" > BASE_COMMIT
22+
git format-patch "${common_ancestor}".."${branch}"
23+
if compgen -G "*.patch" > /dev/null; then
24+
git reset --hard "upstream/master"
25+
git am --3way *.patch
26+
fi
27+
)
28+
output_branches+=( "${branch}" )
29+
done < <(gh pr list --label rebase --state open --json headRefName --template '{{range .}}{{tablerow .headRefName}}{{end}}')
30+
31+
# sync master with upstream
32+
git checkout master
33+
git reset --hard upstream/master
34+
output_branches+=( "master" )
35+
36+
(
37+
IFS=$'\n'
38+
echo "${output_branches[*]}"
39+
)
40+

.github/workflows/rebase.yaml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Rebase against upstream
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
issues: write
11+
12+
jobs:
13+
rebase:
14+
name: Rebase now!
15+
runs-on: ubuntu-latest
16+
env:
17+
UPSTREAM_REPO: https://github.com/haskell/cabal.git
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
persist-credentials: false
24+
25+
- run: |
26+
set -eux
27+
28+
gh repo set-default stable-haskell/cabal
29+
30+
# required to apply patches
31+
git config user.email "[email protected]"
32+
git config user.name "GitHub CI"
33+
34+
# this does not push
35+
branches=$(bash .github/scripts/rebase.sh ${{ env.UPSTREAM_REPO }})
36+
37+
# now push
38+
bash .github/scripts/push.sh ${{ env.UPSTREAM_REPO }} https://${{ secrets.REBASE_PAT }}@github.com/${{ github.repository }}.git "${branches}"
39+
shell: bash
40+
env:
41+
GH_TOKEN: ${{ github.token }}
42+
43+
44+
# create an issue with a link to the workflow run on failure
45+
- if: failure()
46+
run: |
47+
set -eux
48+
gh repo set-default stable-haskell/cabal
49+
for issue in $(gh issue list --label rebase-failure --json url -q '.[] | .url') ; do
50+
gh issue close "${issue}"
51+
done
52+
gh issue create --title "Rebase failed on $(date -u +"%Y-%m-%d")" --label rebase-failure --body "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
53+
env:
54+
GH_TOKEN: ${{ github.token }}
55+
56+
# we always want the original repo and the patches that were applied
57+
# for debugging and backup reasons
58+
- if: always()
59+
run: |
60+
git checkout -f master || true
61+
git archive master > backup.tar
62+
tar -rf backup.tar .git rebase
63+
- if: always()
64+
name: Upload backup
65+
uses: actions/upload-artifact@v4
66+
with:
67+
if-no-files-found: error
68+
retention-days: 7
69+
name: backup
70+
path: |
71+
./backup.tar

0 commit comments

Comments
 (0)