From 3d7de7bf5a655f19eb4e244df5ed55b8ac188a72 Mon Sep 17 00:00:00 2001 From: Mark McCulloh Date: Thu, 24 Aug 2023 13:06:54 -0400 Subject: [PATCH] chore(repo): ensure the self mutation updater actual does a real merge commit (#3946) The change introduced in https://github.com/winglang/wing/pull/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)*. --- .github/workflows/build.yml | 26 +----------- .github/workflows/mutation.yml | 76 ++++++++++++++++++++++++---------- libs/wingcompiler/package.json | 2 +- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d132eb423c0..ffd302b784a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,25 +102,6 @@ jobs: name: dist path: dist/* - # Create patch to go from the PR head to the merge commit - - name: Create git patch for merge - if: github.event_name == 'pull_request' - id: diff - run: | - git diff --binary --patch ${{ github.event.pull_request.head.sha }} ${{ github.sha }} > update.diff - if [ -s update.diff ]; then - echo "Diff found, creating a patch to apply later" - cat update.diff - echo "diff=true" >> $GITHUB_OUTPUT - fi - - - name: Upload patch - if: steps.diff.outputs.diff == 'true' - uses: actions/upload-artifact@v3 - with: - name: update.diff - path: update.diff - test: name: Test timeout-minutes: 30 @@ -312,11 +293,8 @@ jobs: run: | PATCH_COUNT=0 for f in $(find ./*.diff/*.diff); do - # Exclude update.diff since we don't want to fail if the PR is just not up to date - if [ "$f" != "./update.diff/update.diff" ]; then - PATCH_COUNT=$((PATCH_COUNT + 1)) - cat $f - fi + PATCH_COUNT=$((PATCH_COUNT + 1)) + cat $f done if [ $PATCH_COUNT -gt 0 ]; then echo "Found $PATCH_COUNT patches, build failed. A self-mutation should happen soon." diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml index b1a9fe408e1..302a440d5b2 100644 --- a/.github/workflows/mutation.yml +++ b/.github/workflows/mutation.yml @@ -21,8 +21,7 @@ permissions: jobs: mutate: runs-on: ubuntu-latest - # Run if the workflow run is a pull request - if: github.event.workflow_run.conclusion == 'failure' && (!contains(fromJSON('["main", "dev"]'), github.event.workflow_run.head_branch) || github.event.workflow_run.head_repository.fork) + 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) steps: - name: Download artifacts id: download-artifacts @@ -57,18 +56,65 @@ jobs: run: | git config --global core.hooksPath /dev/null + - name: Update PR Branch + uses: actions/github-script@v6 + if: github.event.workflow_run.event == 'pull_request' && steps.download-artifacts.outputs.found_artifact == 'true' + with: + github-token: ${{ secrets.MUTATION_TOKEN }} + script: | + // use API to get the PR data since we can't rely on the context across forks + const pulls = await github.rest.pulls.list({ + per_page: 1, + owner: context.repo.owner, + repo: context.repo.repo, + head: `${context.payload.workflow_run.head_repository.full_name}:${context.payload.workflow_run.head_branch}` + }); + + const prContextData = pulls.data[0]; + const prNumber = prContextData.number; + const originalSha = prContextData.head.sha; + + try { + console.log("Updating PR branch"); + await github.rest.pulls.updateBranch({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + console.log("PR branch updated"); + + let updatedSha = originalSha; + let retries = 0; + const MAX_RETRIES = 10; + while (updatedSha == originalSha && retries++ < MAX_RETRIES) { + console.log(`Waiting for PR branch to update (attempt ${retries}/${MAX_RETRIES})`); + + await new Promise(r => setTimeout(r, 500)); + const updatedPR = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber + }); + updatedSha = updatedPR.data.head.sha; + } + } catch (error) { + // The branch is already up to date or can't otherwise be updated + // That's fine, we tried our best + console.warn(error); + } + - name: Checkout Workflow Branch if: steps.download-artifacts.outputs.found_artifact == 'true' uses: actions/checkout@v3 with: - token: ${{secrets.MUTATION_TOKEN}} + token: ${{ secrets.MUTATION_TOKEN }} ref: ${{ github.event.workflow_run.head_branch }} repository: ${{ github.event.workflow_run.head_repository.full_name }} path: repo - id: self_mutation if: steps.download-artifacts.outputs.found_artifact == 'true' - name: Apply downloaded pathes + name: Apply downloaded patches working-directory: repo env: HEAD_REF: ${{ github.event.workflow_run.head_branch }} @@ -76,29 +122,12 @@ jobs: git config user.name "monada-bot[bot]" git config user.email "monabot@monada.co" - # if ../patches/update.diff/update.diff exists, apply it first - UPDATE_PATCH_FILE="../patches/update.diff/update.diff" - if [ -f $UPDATE_PATCH_FILE ]; then - echo "Updating branch" - git apply --binary $UPDATE_PATCH_FILE - if [ $? -eq 0 ]; then - git add --all - git commit -s -m "Merge branch 'main' into $HEAD_REF" - echo "Patch applied successfully" - rm $UPDATE_PATCH_FILE - else - echo "Patch failed to apply" - cat $UPDATE_PATCH_FILE - exit 1 - fi - fi - for f in $(find ../patches/*.diff/*.diff); do echo "Applying $f" git apply --binary $f if [ $? -eq 0 ]; then git add --all - git commit -s -m "chore: self mutation ($f)" + git commit -s -m "chore: self mutation ($(basename $f))" echo "Patch applied successfully" rm $f else @@ -116,12 +145,13 @@ jobs: with: github-token: ${{ secrets.MUTATION_TOKEN }} script: | + // use API to get the PR number since we can't rely on the context across forks const pulls = await github.rest.pulls.list({ + per_page: 1, owner: context.repo.owner, repo: context.repo.repo, head: `${context.payload.workflow_run.head_repository.full_name}:${context.payload.workflow_run.head_branch}` }); - const prNumber = pulls.data[0].number; const labels = ["⚠️ pr/review-mutation"]; diff --git a/libs/wingcompiler/package.json b/libs/wingcompiler/package.json index 469da4c9287..49c9cd2cc4c 100644 --- a/libs/wingcompiler/package.json +++ b/libs/wingcompiler/package.json @@ -17,7 +17,7 @@ "url": "git+https://github.com/winglang/wing.git" }, "scripts": { - "compile:copy-wingc-wasm": "cp ../../target/wasm32-wasi/release/wingc.wasm . && cp wingc.wasm ../../dist/wingc.wasm", + "compile:copy-wingc-wasm": "cp ../../target/wasm32-wasi/release/wingc.wasm . && mkdir -p ../../dist && cp wingc.wasm ../../dist/wingc.wasm", "compile": "tsup-node", "watch": "tsup-node --watch", "test": "vitest run --passWithNoTests",