Skip to content

[workflows] Avoid usage of access token in issue-write.yml #94011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 19, 2024

Conversation

tstellar
Copy link
Collaborator

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

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
@llvmbot
Copy link
Member

llvmbot commented May 31, 2024

@llvm/pr-subscribers-github-workflow

Author: Tom Stellard (tstellar)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/94011.diff

2 Files Affected:

  • (modified) .github/workflows/issue-write.yml (+13-3)
  • (added) .github/workflows/unprivileged-download-artifact/action.yml (+70)
diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml
index e003be006c4e1..a057d75501484 100644
--- a/.github/workflows/issue-write.yml
+++ b/.github/workflows/issue-write.yml
@@ -19,12 +19,22 @@ jobs:
     if: >
       github.event.workflow_run.event == 'pull_request'
     steps:
+      - 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: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
+        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: Unpack Artifact
+        run: |
+          unzip ${{ steps.download-artifact.outputs.filename }}
 
       - name: 'Comment on PR'
         uses: actions/github-script@v3
diff --git a/.github/workflows/unprivileged-download-artifact/action.yml b/.github/workflows/unprivileged-download-artifact/action.yml
new file mode 100644
index 0000000000000..d4aaf462d3027
--- /dev/null
+++ b/.github/workflows/unprivileged-download-artifact/action.yml
@@ -0,0 +1,70 @@
+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 ommited 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

Copy link
Contributor

@bader bader left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
I'm not an expert in GitHub Actions scripts, so it's better to get the feedback from @boomanaiden154.

@tstellar
Copy link
Collaborator Author

Ping.

Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nits.

Is there additional context for why this change is needed? I remember seeing something, but can't find it now.

We should also probably figure out what we want to support for downstreams versus what we don't. This is a decent chunk of additional complexity for something that I don't believe has any upstream benefit.

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 ommited it will download the most recently created artifact from the repo with the artifact-name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to wrap this to 80 characters?


- name: Unpack Artifact
run: |
unzip ${{ steps.download-artifact.outputs.filename }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this in the action similar to how download-artifact does it?

@bader
Copy link
Contributor

bader commented Jul 17, 2024

Is there additional context for why this change is needed? I remember seeing something, but can't find it now.

This discussion has the context for this change - #80495 (comment).

@boomanaiden154
Copy link
Contributor

This discussion has the context for this change - #80495 (comment).

Ah, thanks.

@tstellar Is there another advantage to having this upstream rather than just documenting somewhere what tokens need to be setup/with what permissions for the workflows to work?

@tstellar
Copy link
Collaborator Author

@tstellar Is there another advantage to having this upstream rather than just documenting somewhere what tokens need to be setup/with what permissions for the workflows to work?

The advantage for upstream is that it's one less secret for us to maintain.

@tstellar
Copy link
Collaborator Author

@tstellar Is there another advantage to having this upstream rather than just documenting somewhere what tokens need to be setup/with what permissions for the workflows to work?

The advantage for upstream is that it's one less secret for us to maintain.

And also composite actions don't have access to secrets, so if you want to download an artifact in a composite action you need to add an extra parameter for the secret.

@boomanaiden154
Copy link
Contributor

The advantage for upstream is that it's one less secret for us to maintain.

And also composite actions don't have access to secrets, so if you want to download an artifact in a composite action you need to add an extra parameter for the secret.

Makes sense. It would be nice if Github would allow this in the upstream action, but maybe the security argument there makes sense.

@tstellar tstellar merged commit 56ffbd9 into llvm:main Jul 19, 2024
5 checks passed
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
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

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251441
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants