Being able to download a Github Actions artifact by copy-past the link URL to curl?

2.8k Views Asked by At

We are doing a proof of concept of looking into Github Actions for producing an artifact for a given commit for a legacy system, which we then need to process further in-house so I am looking into how we can do that relatively simply for now to demonstrate that this can work. We are fine with the zip wrapping.

Sample URL for such an artifact as identified by right-clicking on the Artifact in the job page in Actions: https://github.com/tandeday/actions-artifacts/suites/1767549169/artifacts/33720037

I understand that there is a full API for this, and I have successfully used this by hand to localize and download the artifact using a line similar to:

curl -O -J -L -H 'Authorization: token ...'  -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/tandeday/actions-artifacts/actions/artifacts/33720037/zip

I would like to be able to avoid creating an API client for this proof-of-concept, but instead allow the user to just pass in the link from the web page, but I have been unable to locate a simple way to do so.

So question is, how do I with a minimum of coding come from https://github.com/tandeday/actions-artifacts/suites/1767549169/artifacts/33720037 to https://api.github.com/repos/tandeday/actions-artifacts/actions/artifacts/33720037/zip ?

1

There are 1 best solutions below

2
On BEST ANSWER

If you're ok with open-sourcing your repo (scroll further down in this answer if not), you can do this without needing to authenticate if you make a workflow that creates a release upon each commit, then builds your artifact, then uploads that artifact to the release. The trick is to be clever with your release tag's name, which is used in the release URL. A sample workflow is described here. I've modified this slightly to match your sample repo's scenario, and I instead use the first 8 characters of the commit hash in the tag name to generate a predictable but unique URL:

on:
  push:
    # Runs on every pushed commit

name: Upload Release Asset

jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

        # For the sake of simplicity, we'll name the tag and the release with
        # the first 8 chars of the commit SHA:
      - name: Get short SHA
        id: short_sha
        run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"

      - name: Build project # This would actually build your project, using zip for your example date artifact
        run:  |
          date > date.txt
          zip -rT app.zip date.txt
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          # Using short SHA from 2nd step for tag and release name.
          tag_name: ${{steps.short_sha.outputs.sha8}}
          release_name: ${{steps.short_sha.outputs.sha8}}
          draft: false
          prerelease: false
        # Now we upload the artifact we generated in the first step to
        # the release we created in the 3nd step
      - name: Upload Release Asset
        id: upload-release-asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing its ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 
          asset_path: ./app.zip
          asset_name: app.zip
          asset_content_type: application/zip

Then, finally, your asset will be available at a URL with the pattern: github.com/orgname/reponame/releases/download/${short_sha}/app.zip, where short_sha is the first 8 characters of your commit. Since it has this known format, it's easy to generate the URL on the in-house user's side if they have access to the repository (pull from repo, get SHA at head, do some string interpolation, print URL to console).

Test repo workflow

Test release asset

In case your repo must stay private within your org:

Someone wrote up a nice Gist with some shell scripts to grab a release from a private repo - you'll need an access token.

If you don't want to pollute the releases of your repo:

You could modify the above workflow's tag_name and release_name to include an intermediate prefix so it's clear that it's not an actual release. Your URL format will be different if you take this route, though - the bit after /download/ will be your new tag name.