Skip to content

Commit a895b16

Browse files
committed
Automate subtree update
There should not be a need for manual processes for the first stage of the subtree update, i.e., updating our subtree/library branch. Merge conflicts (which might require a human to intervene) will only happen once attempting to merge from subtree/library back into main. Automation for this stage has been added, will create a PR separate from the above one, and will likely require manual intervention.
1 parent b410f4e commit a895b16

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

.github/workflows/update-subtree.yml

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Subtree Update
2+
3+
on:
4+
schedule:
5+
- cron: '0 14 * * *' # Run at 14:00 UTC every day
6+
workflow_dispatch:
7+
8+
defaults:
9+
run:
10+
shell: bash
11+
12+
jobs:
13+
update-subtree-library:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout Repository
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
path: verify-rust-std
22+
23+
- name: Checkout Kani
24+
uses: actions/checkout@v4
25+
with:
26+
repository: model-checking/kani
27+
path: kani-tmp
28+
29+
- name: Checkout Rust
30+
uses: actions/checkout@v4
31+
with:
32+
repository: rust-lang/rust
33+
fetch-depth: 0
34+
path: rust-tmp
35+
36+
- name: Checkout git-filter-repo
37+
uses: actions/checkout@v4
38+
with:
39+
repository: newren/git-filter-repo
40+
path: git-filter-repo
41+
42+
- name: Fetch Kani toolchain version
43+
run: |
44+
cd kani-tmp
45+
TOOLCHAIN_DATE=$(grep -oP 'channel = "nightly-\K\d{4}-\d{2}-\d{2}' rust-toolchain.toml)
46+
COMMIT_HASH=$(curl https://static.rust-lang.org/dist/$TOOLCHAIN_DATE/channel-rust-nightly-git-commit-hash.txt)
47+
if [ -z "$COMMIT_HASH" ]; then
48+
echo "Could not find commit hash on static.rust-lang.org"
49+
exit 1
50+
fi
51+
echo "Kani toolchain date: ${TOOLCHAIN_DATE}"
52+
echo "TOOLCHAIN_DATE=${TOOLCHAIN_DATE}" >> $GITHUB_ENV
53+
echo "Kani toolchain hash: ${COMMIT_HASH}"
54+
echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV
55+
56+
- name: Update subtree/library locally
57+
run: |
58+
cd rust-tmp
59+
60+
# Ensure "upstream/master" branch contains the target commit
61+
if ! git show ${COMMIT_HASH} --oneline --no-patch; then
62+
echo "Rust commit ${COMMIT_HASH} cannot be found."
63+
exit 1
64+
fi
65+
66+
git checkout ${COMMIT_HASH}
67+
../git-filter-repo/git-filter-repo --subdirectory-filter library --force
68+
git checkout -b subtree/library
69+
70+
cd ../verify-rust-std
71+
git remote add rust-filtered ../rust-tmp/
72+
git fetch rust-filtered
73+
git checkout -b subtree/library rust-filtered/subtree/library
74+
SUBTREE_HEAD_MSG=$(git log --format=%s -n 1 origin/subtree/library)
75+
UPSTREAM_FROM=$(git log --grep="${SUBTREE_HEAD_MSG}" -n 1 --format=%H rust-filtered/subtree/library)
76+
UPSTREAM_HEAD=$(git log --format=%H -n 1 rust-filtered/subtree/library)
77+
if [ "${UPSTREAM_HEAD}" = "${UPSTREAM_FROM}" ]; then
78+
echo "Nothing to do, ${UPSTREAM_FROM} matches ${UPSTREAM_HEAD} (${SUBTREE_HEAD_MSG})"
79+
echo "MERGE_CONFLICTS=noop" >> $GITHUB_ENV
80+
else
81+
git branch --set-upstream-to=origin/subtree/library
82+
git -c user.name=gitbot -c user.email=git@bot rebase
83+
echo "MERGE_CONFLICTS=maybe" >> $GITHUB_ENV
84+
fi
85+
86+
- name: Create Pull Request
87+
if: ${{ env.MERGE_CONFLICTS != 'noop' }}
88+
uses: peter-evans/create-pull-request@v7
89+
with:
90+
title: 'Update subtree/library'
91+
body: |
92+
This is an automated PR to update the subtree/library branch to the changes
93+
up to and including ${{ env.COMMIT_HASH }} of ${{ env.TOOLCHAIN_DATE }}.
94+
branch: update-subtree/library
95+
delete-branch: true
96+
base: subtree/library
97+
path: verify-rust-std
98+
99+
- name: Merge subtree/library changes
100+
if: ${{ env.MERGE_CONFLICTS != 'noop' }}
101+
run: |
102+
cd verify-rust-std
103+
SYNC_BRANCH="sync-${TOOLCHAIN_DATE}"
104+
echo "SYNC_BRANCH=${SYNC_BRANCH}" >> $GITHUB_ENV
105+
git checkout -t -b ${SYNC_BRANCH} origin/main
106+
git submodule update --init
107+
108+
# This command may fail, which will require human intervention.
109+
if ! git \
110+
-c user.name=gitbot -c user.email=git@bot \
111+
subtree merge --prefix=library update-subtree/library --squash; then
112+
echo "MERGE_CONFLICTS=yes" >> $GITHUB_ENV
113+
git -c user.name=gitbot -c user.email=git@bot commit -a -m "Merge from $COMMIT_HASH with conflicts"
114+
else
115+
echo "MERGE_CONFLICTS=no" >> $GITHUB_ENV
116+
fi
117+
118+
sed -i "s/^channel = \"nightly-.*\"/channel = \"${TOOLCHAIN_DATE}\"/" rust-toolchain.toml
119+
git -c user.name=gitbot -c user.email=git@bot \
120+
commit -m "Update toolchain to ${TOOLCHAIN_DATE}" rust-toolchain.toml
121+
122+
- name: Create Pull Request without conflicts
123+
if: ${{ env.MERGE_CONFLICTS == 'no' }}
124+
uses: peter-evans/create-pull-request@v7
125+
with:
126+
title: 'Merge subtree update'
127+
body: |
128+
This is an automated PR to merge library subtree updates
129+
up to and including ${{ env.COMMIT_HASH }} of ${{ env.TOOLCHAIN_DATE }}
130+
into main. This is a clean merge, no conflicts were detected.
131+
branch: ${{ env.SYNC_BRANCH }}
132+
delete-branch: true
133+
base: main
134+
path: verify-rust-std
135+
136+
- name: Create Pull Request with conflicts
137+
if: ${{ env.MERGE_CONFLICTS == 'yes' }}
138+
uses: peter-evans/create-pull-request@v7
139+
with:
140+
title: 'Merge subtree update'
141+
body: |
142+
This is an automated PR to merge library subtree updates
143+
up to and including ${{ env.COMMIT_HASH }} of ${{ env.TOOLCHAIN_DATE }}
144+
into main. `git merge` resulted in conflicts, which require manual resolution.
145+
Files were commited with merge conflict markers.
146+
branch: ${{ env.SYNC_BRANCH }}
147+
delete-branch: true
148+
base: main
149+
path: verify-rust-std

0 commit comments

Comments
 (0)