2

There are two releases that can be obtained from a GitHub repo (Binary Releases and Package Releases) as shown below:

GitHub SS

I want to use Ansible to retrieve Package Releases from my GitHub Repo

I did some searching on Ansible docs and found a collection community.general.github_release but this gives the latest Release binaries of the repo and not Package Releases.

Can anyone help if they know a collection that can fetch Package Releases from GitHub ?

Appreciate any help. Thanks

Danny Varod
  • 17,324
  • 5
  • 69
  • 111
Mervin Hemaraju
  • 1,921
  • 2
  • 22
  • 71

2 Answers2

2

The community.general.github_release Ansible role is part of the ansible-collections/community.general code.

Its source code source_control/github/github_release.py shows that is is using github3.py, the library for using GitHub's REST API.
Specifically, the latest_release endpoint (code here) uses the GET /repos/{owner}/{repo}/releases/latest REST API.

However, a "Package Release" is, for github3.py (used by the Ansible role), an asset, with an ID you can find in a github3.repos.release.Release: the original_assets will give you all the assets id.

You would therefore need to write a role similar to latest_release, using the version returned by latest_release in order to call github3.repos.release.Release, get the assets ID and download the one you need using asset(asset_id)

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I have no experience in writing a custom role but I'll see in it. Thank you so much – Mervin Hemaraju Jan 16 '21 at 18:46
  • I really don't think this is correct. The "assets" are only available off of a "release". These are the files that you would see in each "release". If there are no releases (as in the example that the question uses), then the API will simply return an empty array, and there's no way to proceed further. Perhaps I'm wrong, but as far as I can tell, API access to *packages* (which are a relatively new feature) is only available in the Github v4 GraphQL API (also a *relatively* new feature). – NotTheDr01ds Jan 16 '21 at 20:13
  • @NotTheDr01ds Possible indeed: I was confused by the term asset in https://docs.github.com/en/github/administering-a-repository/about-releases. There is no mention of "package(s)" in https://docs.github.com/en/rest/reference/repos#releases. – VonC Jan 16 '21 at 20:16
2

You can use Github GraphQL API (as shown in this question and this one) such as:

  #
  # Tasks that may be included in an Ansible playbook or role depending on your needs
  #

  # Some variables to define to identify your repository
  # They may be set as playbook or role variables as well
  # You'll need a Bearer token (see https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token)
  - set_fact:
      bearer_token: YOUR_BEARER_TOKEN
      repository_name: repository-name
      repository_owner: repository-owner

  - name: Retrieve packages for repository
    uri:
      url: https://api.github.com/graphql
      method: POST
      body: '{"query":
          "query { repository(name: \"{{ repository_name }}\", owner: \"{{ repository_owner }}\") {
            packages(first:10) { nodes { name, packageType, latestVersion {
              version, files(first:100) { nodes { url } }
            } } }
          }
        }"'
      headers:
        Content-Type: application/json
        Accept: "application/vnd.github.packages-preview+json"
        Authorization: "bearer {{ bearer_token }}"
    register: github_packages_json

This will provide an output like:

  {
    "json": {
        "data": {
            "repository": {
                "packages": {
                    "nodes": [
                        {
                            "latestVersion": {
                                "files": {
                                    "nodes": [
                                        {
                                            "url": "https://pkg.githubusercontent.com/xxx/some-url"
                                        },
                                        {
                                            "url": "https://pkg.githubusercontent.com/xxx/another-url"
                                        }
                                    ]
                                },
                                "version": "my-package-1.2.3"
                            },
                            "name": "my-package",
                            "packageType": "DOCKER"
                        }
                    ]
                }
            }
        }
    },
}

Depending on packageType you may need to perform different action. For example, a DOCKER packageType would require you to pull the image such as:

  - name: pull docker
    shell: docker pull docker.pkg.github.com/{{ repository_owner | lower }}/{{ repository_name }}/{{ docker_image_name }}:{{ docker_image_version }}
    vars:
      docker_image_name: "{{ github_packages_json.json.data.repository.packages.nodes[0].name }}"
      docker_image_version: "{{ github_packages_json.json.data.repository.packages.nodes[0].latestVersion.version }}"

Pierre B.
  • 11,612
  • 1
  • 37
  • 58