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-ids: description: "The id of the artifact being downloaded." value: ${{ steps.artifact-url.outputs.ids }} runs: using: "composite" steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: INPUTS_ARTIFACT_NAME: ${{ inputs.artifact-name }} INPUTS_RUN_ID: ${{ inputs.run-id }} id: artifact-url with: script: | var response; if (!process.env.INPUTS_RUN_ID) { response = await github.rest.actions.listArtifactsForRepo({ owner: context.repo.owner, repo: context.repo.repo, }) } else { response = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, run_id: process.env.INPUTS_RUN_ID, }) } console.log(response) // Jobs rerun uploads fresh artifacts alongside the old ones with the // same name, keep only the newest per name so downloads don't clobber. latest_by_name = new Map() for (artifact of response.data.artifacts) { if (!artifact.name.startsWith(process.env.INPUTS_ARTIFACT_NAME)) { continue } existing = latest_by_name.get(artifact.name) if (!existing || new Date(artifact.created_at) > new Date(existing.created_at)) { latest_by_name.set(artifact.name, artifact) } } artifacts_to_download = Array.from(latest_by_name.values()) for (artifact of artifacts_to_download) { console.log(artifact); } if (artifacts_to_download.length == 0) { console.log(`Could not find artifacts starting with name ${process.env.INPUTS_ARTIFACT_NAME} for workflow run ${process.env.INPUTS_RUN_ID}`) return; } artifact_ids = [] artifact_urls = [] artifact_names = [] for (artifact_to_download of artifacts_to_download) { const url_response = await github.rest.actions.downloadArtifact({ owner: context.repo.owner, repo: context.repo.repo, artifact_id: artifact_to_download.id, archive_format: "zip" }) artifact_ids.push(artifact_to_download.id) artifact_urls.push(url_response.url) artifact_names.push(artifact_to_download.name) } core.setOutput("urls", artifact_urls.join(" ")); core.setOutput("ids", artifact_ids.join(" ")); core.setOutput("names", artifact_names.join(" ")); - shell: bash if: steps.artifact-url.outputs.urls != '' id: download-artifact env: ARTIFACT_URLS: ${{ steps.artifact-url.outputs.urls }} ARTIFACT_NAMES: ${{ steps.artifact-url.outputs.names }} run: | artifact_urls=($ARTIFACT_URLS) artifact_names=($ARTIFACT_NAMES) for i in "${!artifact_urls[@]}"; do curl -L -o "${artifact_names[$i]}.zip" "${artifact_urls[$i]}" done - shell: bash if: steps.artifact-url.outputs.names != '' env: ARTIFACT_NAMES: ${{ steps.artifact-url.outputs.names }} run: | artifact_names=($ARTIFACT_NAMES) for name in "${artifact_names[@]}"; do unzip "${name}.zip" done