From a63e0a2a8af969602f55319fd9e96be0349d38ba Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Thu, 8 Feb 2024 20:41:00 +0000 Subject: [PATCH 1/2] Improved support for commenting when course timings change. This * Works with the GitHub permissions model (at least in local testing on another temporary repo) * Only comments when the timings actually change --- .github/workflows/course-schedule-comment.yml | 68 +++++++++++++++++++ .github/workflows/course-schedule.yml | 28 ++++++++ 2 files changed, 96 insertions(+) create mode 100644 .github/workflows/course-schedule-comment.yml create mode 100644 .github/workflows/course-schedule.yml diff --git a/.github/workflows/course-schedule-comment.yml b/.github/workflows/course-schedule-comment.yml new file mode 100644 index 000000000000..cee008469d5f --- /dev/null +++ b/.github/workflows/course-schedule-comment.yml @@ -0,0 +1,68 @@ +# Based on https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ +# +# This runs with the full repo permissions, but checks out the upstream branch, not the PR. +# Do not run arbitrary code from the PR here! +name: Comment PR with Course Schedule +on: + workflow_run: + workflows: ["Generate Course Schedule"] + types: [completed] + +jobs: + upload: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + steps: + - name: "Checkout" + uses: actions/checkout@v4 + + - name: "Setup Rust cache" + uses: ./.github/workflows/setup-rust-cache + + - name: "Generate Schedule on upstream branch" + run: | + mkdir -p ./course-schedule + cargo run -p mdbook-course --bin course-schedule > upstream-schedule + + - name: "Download artifact from PR workflow" + uses: actions/github-script@v7.0.1 + 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 == "course-schedule" + })[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}}/course-schedule.zip', Buffer.from(download.data)); + + - name: "Unzip artifact" + run: unzip course-schedule.zip + + - name: "Comment on PR if schedules differ" + uses: actions/github-script@v7.0.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + var upstream = fs.readFileSync('upstream-schedule').toString(); + var schedule = fs.readFileSync('schedule').toString(); + if (upstream != schedule) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.workflow_run.pull_requests[0].number, + body: schedule, + }); + } diff --git a/.github/workflows/course-schedule.yml b/.github/workflows/course-schedule.yml new file mode 100644 index 000000000000..894ac0130ddc --- /dev/null +++ b/.github/workflows/course-schedule.yml @@ -0,0 +1,28 @@ +# Based on https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ +name: Generate Course Schedule + +on: + pull_request: + paths: + - "src/**.md" + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust cache + uses: ./.github/workflows/setup-rust-cache + + - name: Generate Schedule + run: | + mkdir -p ./course-schedule + cargo run -p mdbook-course --bin course-schedule > course-schedule/schedule + + - uses: actions/upload-artifact@v4 + with: + name: course-schedule + path: course-schedule/ From 0f39e2e56794712340ff3a7957e0a63ac9672a0d Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Fri, 9 Feb 2024 16:15:15 +0000 Subject: [PATCH 2/2] include PR number in the artifact --- .github/workflows/course-schedule-comment.yml | 6 ++++-- .github/workflows/course-schedule.yml | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/course-schedule-comment.yml b/.github/workflows/course-schedule-comment.yml index cee008469d5f..e5201d6ac38e 100644 --- a/.github/workflows/course-schedule-comment.yml +++ b/.github/workflows/course-schedule-comment.yml @@ -23,10 +23,11 @@ jobs: - name: "Generate Schedule on upstream branch" run: | - mkdir -p ./course-schedule cargo run -p mdbook-course --bin course-schedule > upstream-schedule - name: "Download artifact from PR workflow" + # actions/download-artifact@v4 cannot do this without being given a PAT, although that + # is not required for public forked repositories. uses: actions/github-script@v7.0.1 with: script: | @@ -56,13 +57,14 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | var fs = require('fs'); + var pr_number = Number(fs.readFileSync('pr-number')); var upstream = fs.readFileSync('upstream-schedule').toString(); var schedule = fs.readFileSync('schedule').toString(); if (upstream != schedule) { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: context.payload.workflow_run.pull_requests[0].number, + issue_number: pr_number, body: schedule, }); } diff --git a/.github/workflows/course-schedule.yml b/.github/workflows/course-schedule.yml index 894ac0130ddc..c109f06d0bfa 100644 --- a/.github/workflows/course-schedule.yml +++ b/.github/workflows/course-schedule.yml @@ -22,6 +22,13 @@ jobs: mkdir -p ./course-schedule cargo run -p mdbook-course --bin course-schedule > course-schedule/schedule + # GitHub does not provide a reliable way to determine the PR number from which + # a workflow_run was triggered (https://github.com/orgs/community/discussions/25220), + # so we'll do the slightly awkward thing and put that in the artifact. This means + # schedules could potentially be spammed to any PR in the repository, but that is + # not an awful outcome (and clear, reportable evidence of abuse). + echo ${{ github.event.number }} > ./course-schedule/pr-number + - uses: actions/upload-artifact@v4 with: name: course-schedule