Skip to content

Commit 3d7de7b

Browse files
authored
chore(repo): ensure the self mutation updater actual does a real merge commit (#3946)
The change introduced in #3922 technically works, but the result is confusing because the patch applied is not an actual merge commit. So Github shows those changes as if you made them. This PR instead does the mutation update via the github API. The downside of this (other than the obvious complexity) is that technically the updated branch can be newer than the one the diffs were created against. I would rather have that problem than the one we have now. Change has been tested in my fork here https://github.com/MarkMcCulloh/wing-distributed-workflow/pull/5 *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
1 parent bd45fd5 commit 3d7de7b

File tree

3 files changed

+56
-48
lines changed

3 files changed

+56
-48
lines changed

.github/workflows/build.yml

+2-24
Original file line numberDiff line numberDiff line change
@@ -102,25 +102,6 @@ jobs:
102102
name: dist
103103
path: dist/*
104104

105-
# Create patch to go from the PR head to the merge commit
106-
- name: Create git patch for merge
107-
if: github.event_name == 'pull_request'
108-
id: diff
109-
run: |
110-
git diff --binary --patch ${{ github.event.pull_request.head.sha }} ${{ github.sha }} > update.diff
111-
if [ -s update.diff ]; then
112-
echo "Diff found, creating a patch to apply later"
113-
cat update.diff
114-
echo "diff=true" >> $GITHUB_OUTPUT
115-
fi
116-
117-
- name: Upload patch
118-
if: steps.diff.outputs.diff == 'true'
119-
uses: actions/upload-artifact@v3
120-
with:
121-
name: update.diff
122-
path: update.diff
123-
124105
test:
125106
name: Test
126107
timeout-minutes: 30
@@ -312,11 +293,8 @@ jobs:
312293
run: |
313294
PATCH_COUNT=0
314295
for f in $(find ./*.diff/*.diff); do
315-
# Exclude update.diff since we don't want to fail if the PR is just not up to date
316-
if [ "$f" != "./update.diff/update.diff" ]; then
317-
PATCH_COUNT=$((PATCH_COUNT + 1))
318-
cat $f
319-
fi
296+
PATCH_COUNT=$((PATCH_COUNT + 1))
297+
cat $f
320298
done
321299
if [ $PATCH_COUNT -gt 0 ]; then
322300
echo "Found $PATCH_COUNT patches, build failed. A self-mutation should happen soon."

.github/workflows/mutation.yml

+53-23
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ permissions:
2121
jobs:
2222
mutate:
2323
runs-on: ubuntu-latest
24-
# Run if the workflow run is a pull request
25-
if: github.event.workflow_run.conclusion == 'failure' && (!contains(fromJSON('["main", "dev"]'), github.event.workflow_run.head_branch) || github.event.workflow_run.head_repository.fork)
24+
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'failure' && (!contains(fromJSON('["main", "dev"]'), github.event.workflow_run.head_branch) || github.event.workflow_run.head_repository.fork)
2625
steps:
2726
- name: Download artifacts
2827
id: download-artifacts
@@ -57,48 +56,78 @@ jobs:
5756
run: |
5857
git config --global core.hooksPath /dev/null
5958
59+
- name: Update PR Branch
60+
uses: actions/github-script@v6
61+
if: github.event.workflow_run.event == 'pull_request' && steps.download-artifacts.outputs.found_artifact == 'true'
62+
with:
63+
github-token: ${{ secrets.MUTATION_TOKEN }}
64+
script: |
65+
// use API to get the PR data since we can't rely on the context across forks
66+
const pulls = await github.rest.pulls.list({
67+
per_page: 1,
68+
owner: context.repo.owner,
69+
repo: context.repo.repo,
70+
head: `${context.payload.workflow_run.head_repository.full_name}:${context.payload.workflow_run.head_branch}`
71+
});
72+
73+
const prContextData = pulls.data[0];
74+
const prNumber = prContextData.number;
75+
const originalSha = prContextData.head.sha;
76+
77+
try {
78+
console.log("Updating PR branch");
79+
await github.rest.pulls.updateBranch({
80+
owner: context.repo.owner,
81+
repo: context.repo.repo,
82+
pull_number: prNumber
83+
});
84+
console.log("PR branch updated");
85+
86+
let updatedSha = originalSha;
87+
let retries = 0;
88+
const MAX_RETRIES = 10;
89+
while (updatedSha == originalSha && retries++ < MAX_RETRIES) {
90+
console.log(`Waiting for PR branch to update (attempt ${retries}/${MAX_RETRIES})`);
91+
92+
await new Promise(r => setTimeout(r, 500));
93+
const updatedPR = await github.rest.pulls.get({
94+
owner: context.repo.owner,
95+
repo: context.repo.repo,
96+
pull_number: prNumber
97+
});
98+
updatedSha = updatedPR.data.head.sha;
99+
}
100+
} catch (error) {
101+
// The branch is already up to date or can't otherwise be updated
102+
// That's fine, we tried our best
103+
console.warn(error);
104+
}
105+
60106
- name: Checkout Workflow Branch
61107
if: steps.download-artifacts.outputs.found_artifact == 'true'
62108
uses: actions/checkout@v3
63109
with:
64-
token: ${{secrets.MUTATION_TOKEN}}
110+
token: ${{ secrets.MUTATION_TOKEN }}
65111
ref: ${{ github.event.workflow_run.head_branch }}
66112
repository: ${{ github.event.workflow_run.head_repository.full_name }}
67113
path: repo
68114

69115
- id: self_mutation
70116
if: steps.download-artifacts.outputs.found_artifact == 'true'
71-
name: Apply downloaded pathes
117+
name: Apply downloaded patches
72118
working-directory: repo
73119
env:
74120
HEAD_REF: ${{ github.event.workflow_run.head_branch }}
75121
run: |
76122
git config user.name "monada-bot[bot]"
77123
git config user.email "[email protected]"
78124
79-
# if ../patches/update.diff/update.diff exists, apply it first
80-
UPDATE_PATCH_FILE="../patches/update.diff/update.diff"
81-
if [ -f $UPDATE_PATCH_FILE ]; then
82-
echo "Updating branch"
83-
git apply --binary $UPDATE_PATCH_FILE
84-
if [ $? -eq 0 ]; then
85-
git add --all
86-
git commit -s -m "Merge branch 'main' into $HEAD_REF"
87-
echo "Patch applied successfully"
88-
rm $UPDATE_PATCH_FILE
89-
else
90-
echo "Patch failed to apply"
91-
cat $UPDATE_PATCH_FILE
92-
exit 1
93-
fi
94-
fi
95-
96125
for f in $(find ../patches/*.diff/*.diff); do
97126
echo "Applying $f"
98127
git apply --binary $f
99128
if [ $? -eq 0 ]; then
100129
git add --all
101-
git commit -s -m "chore: self mutation ($f)"
130+
git commit -s -m "chore: self mutation ($(basename $f))"
102131
echo "Patch applied successfully"
103132
rm $f
104133
else
@@ -116,12 +145,13 @@ jobs:
116145
with:
117146
github-token: ${{ secrets.MUTATION_TOKEN }}
118147
script: |
148+
// use API to get the PR number since we can't rely on the context across forks
119149
const pulls = await github.rest.pulls.list({
150+
per_page: 1,
120151
owner: context.repo.owner,
121152
repo: context.repo.repo,
122153
head: `${context.payload.workflow_run.head_repository.full_name}:${context.payload.workflow_run.head_branch}`
123154
});
124-
125155
const prNumber = pulls.data[0].number;
126156
const labels = ["⚠️ pr/review-mutation"];
127157

libs/wingcompiler/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"url": "git+https://github.com/winglang/wing.git"
1818
},
1919
"scripts": {
20-
"compile:copy-wingc-wasm": "cp ../../target/wasm32-wasi/release/wingc.wasm . && cp wingc.wasm ../../dist/wingc.wasm",
20+
"compile:copy-wingc-wasm": "cp ../../target/wasm32-wasi/release/wingc.wasm . && mkdir -p ../../dist && cp wingc.wasm ../../dist/wingc.wasm",
2121
"compile": "tsup-node",
2222
"watch": "tsup-node --watch",
2323
"test": "vitest run --passWithNoTests",

0 commit comments

Comments
 (0)