From 56ffbd97fda16008d02180a460211829354f1094 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 19 Jul 2024 14:47:35 -0700 Subject: [PATCH] [workflows] Avoid usage of access token in issue-write.yml (#94011) This adds a new composite workflow that allows you to download artifacts from other workflows without using an access token. actions/download-artifact from GitHub requires an access token in order to download artifacts from a different workflow, which is why we can't use it here if we want to avoid using a token. See https://github.com/actions/download-artifact?tab=readme-ov-file#download-artifacts-from-other-workflow-runs-or-repositories --- .github/workflows/issue-write.yml | 19 +++-- .../unprivileged-download-artifact/action.yml | 81 +++++++++++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/unprivileged-download-artifact/action.yml diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml index d4814a2fe901..5334157a7fd2 100644 --- a/.github/workflows/issue-write.yml +++ b/.github/workflows/issue-write.yml @@ -24,14 +24,21 @@ jobs: github.event.workflow_run.conclusion == 'failure' ) steps: - - name: 'Download artifact' - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + - name: Fetch Sources + uses: actions/checkout@v4 + with: + sparse-checkout: | + .github/workflows/unprivileged-download-artifact/action.yml + sparse-checkout-cone-mode: false + - name: 'Download artifact' + uses: ./.github/workflows/unprivileged-download-artifact + id: download-artifact with: - github-token: ${{ secrets.ISSUE_WRITE_DOWNLOAD_ARTIFACT }} run-id: ${{ github.event.workflow_run.id }} - name: workflow-args + artifact-name: workflow-args - name: 'Comment on PR' + if: steps.download-artifact.outputs.artifact-id != '' uses: actions/github-script@v3 with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -144,5 +151,7 @@ jobs: }); - name: Dump comments file - if: always() + if: >- + always() && + steps.download-artifact.outputs.artifact-id != '' run: cat comments diff --git a/.github/workflows/unprivileged-download-artifact/action.yml b/.github/workflows/unprivileged-download-artifact/action.yml new file mode 100644 index 000000000000..9d8fb59a67c0 --- /dev/null +++ b/.github/workflows/unprivileged-download-artifact/action.yml @@ -0,0 +1,81 @@ +name: Unprivileged Download Artifact +description: >- + Download artifacts from another workflow run without using an access token. +inputs: + run-id: + description: >- + The run-id for the workflow run that you want to download the artifact + from. If ommitted it will download the most recently created artifact + from the repo with the artifact-name. + required: false + artifact-name: + desciption: The name of the artifact to download. + required: true + + +outputs: + filename: + description: >- + The filename of the downloaded artifact or the empty string if the + artifact was not found. + value: ${{ steps.download-artifact.outputs.filename }} + artifact-id: + description: "The id of the artifact being downloaded." + value: ${{ steps.artifact-url.outputs.id }} + + +runs: + using: "composite" + steps: + - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 + id: artifact-url + with: + script: | + var response; + if (!"${{ inputs.run-id }}") { + response = await github.rest.actions.listArtifactsForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + name: "${{ inputs.artifact-name }}" + }) + } else { + response = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: "${{ inputs.run-id }}", + name: "${{ inputs.artifact-name }}" + }) + } + + console.log(response) + + for (artifact of response.data.artifacts) { + console.log(artifact); + } + + if (response.data.artifacts.length == 0) { + console.log("Could not find artifact ${{ inputs.artifact-name }} for workflow run ${{ inputs.run-id }}") + return; + } + + const url_response = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: response.data.artifacts[0].id, + archive_format: "zip" + }) + + core.setOutput("url", url_response.url); + core.setOutput("id", response.data.artifacts[0].id); + + - shell: bash + if: steps.artifact-url.outputs.url != '' + id: download-artifact + run: | + curl -L -o ${{ inputs.artifact-name }}.zip "${{ steps.artifact-url.outputs.url }}" + echo "filename=${{ inputs.artifact-name }}.zip" >> $GITHUB_OUTPUT + + - shell: bash + if: steps.download-artifact.outputs.filename != '' + run: | + unzip ${{ steps.download-artifact.outputs.filename }}