diff --git a/.github/workflows/resyntax-analyze.yml b/.github/workflows/resyntax-analyze.yml new file mode 100644 index 0000000000..fac83d217e --- /dev/null +++ b/.github/workflows/resyntax-analyze.yml @@ -0,0 +1,54 @@ +name: Resyntax Analysis + +# The Resyntax integration is split into two phases: a workflow that analyzes the code and uploads +# the analysis as an artifact, and a workflow that downloads the analysis artifact and creates a +# review of the pull request. This split is for permissions reasons; the analysis workflow checks out +# the pull request branch and compiles it, executing arbitrary code as it does so. For that reason, +# the first workflow has read-only permissions in the github repository. The second workflow only +# downloads the pull request review artifact and submits it, and it executes with read-write permissions +# without executing any code in the repository. This division of responsibilities allows Resyntax to +# safely analyze pull requests from forks. This strategy is outlined in the following article: +# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + +on: + pull_request: + types: + - opened + - edited + - reopened + - synchronize + - ready_for_review + +jobs: + analyze: + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: Checkout code + uses: actions/checkout@v3.0.2 + # See https://github.com/actions/checkout/issues/118. + with: + fetch-depth: 0 + - name: Install Racket + uses: Bogdanp/setup-racket@v1.8.1 + with: + version: current + packages: resyntax + local_catalogs: $GITHUB_WORKSPACE + dest: '"${HOME}/racketdist-current-CS"' + sudo: never + - name: Register local packages + run: | + raco pkg install -i --auto --no-setup --skip-installed scribble-test scribble-doc + raco pkg update --auto --no-setup scribble-text-lib scribble-html-lib scribble-lib scribble-doc scribble-test scribble + - name: Install local packages + run: raco setup --pkgs scribble scribble-doc scribble-html-lib scribble-lib scribble-test scribble-text-lib + - name: Analyze changed files + run: xvfb-run racket -l- resyntax/cli analyze --local-git-repository . "origin/${GITHUB_BASE_REF}" --output-as-github-review --output-to-file ./resyntax-review.json + - name: Upload analysis artifact + uses: actions/upload-artifact@v3.1.0 + with: + name: resyntax-review + path: resyntax-review.json diff --git a/.github/workflows/resyntax-submit-review.yml b/.github/workflows/resyntax-submit-review.yml new file mode 100644 index 0000000000..70307c975b --- /dev/null +++ b/.github/workflows/resyntax-submit-review.yml @@ -0,0 +1,56 @@ +name: Resyntax Review Submission + +# The Resyntax integration is split into two workflows. See ./resyntax-analyze.yml for details about +# why it works this way. + +on: + workflow_run: + workflows: ["Resyntax Analysis"] + types: + - completed + +jobs: + review: + runs-on: ubuntu-latest + if: > + ${{ github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v3.0.2 + - name: Download Resyntax analysis + # This uses a github script instead of the download-artifact action because + # that action doesn't work for artifacts uploaded by other workflows. See + # https://github.com/actions/download-artifact/issues/130 for more info. + uses: actions/github-script@v6.1.0 + with: + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{github.event.workflow_run.id}}, + }); + var matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "resyntax-review" + })[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/resyntax-review.zip', Buffer.from(download.data)); + - run: unzip resyntax-review.zip + - name: Create pull request review + uses: actions/github-script@v6.1.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var create_review_request = require('./resyntax-review.json'); + await github.rest.pulls.createReview(create_review_request);