How to check if a docker image is already built on GitHub packages

This question have no answers on stackoverflow and I would appreciate a solution if exists.

Summory of the question:

How can I check if my github workflow allready has build a docker image for this commit?

https://stackoverflow.com/questions/60892354/how-to-check-if-a-version-of-a-github-docker-image-already-exists

Hi @jactor-rises ,

You could use Docker Registry API v2 to list image tags . Then you could compare the tags with the current commit sha. 

The API url for GitHub Package Registry is like: 

https://docker.pkg.github.com/v2/{org}/{repo}/{image_name}/tags/list

Hi,

you can use the Github Packages preview GraphQL API with connection with bash invocation of jq. This is example of how I am doing it.

query:
   'query getDockerImages(\$owner: String!, \$repository: String!) {
    repository(owner: \$owner, name: \$repository) {
     registryPackages(packageType: DOCKER, publicOnly: true, first: 100) {
      nodes {
       name
       version(version: \"latest\") {
         sha256
       }
     }
   }
  }
}

And then something like:

test_array=($(printf "$MATRIX_JSON" | jq -r '.include[] | [.architecture, .osVersionNumber|tostring] | join("_")'))
MISSING=0
for i in ${test_array[@]}
do
 IMAGENAME="${IMAGE_NAME_ROOT}$i"
 IMAGESHA=$(jq -r --arg IMAGENAME "$IMAGENAME" '.data.repository.registryPackages.nodes[] | select(.name == $IMAGENAME).version.sha256 | select(.!=null)' ${INPUT_JSON_FILE})
 if [-z "$IMAGESHA"]; then
  printf "Docker image $IMAGENAME:latest does not exist in registry docker.pkg.github.com/$REPOSITORY_FULL\n"
  ((MISSING=MISSING+1))
  fi
done
if [$MISSING -gt 0]; then
  printf "Registry is missing $MISSING Docker image(s)\n"
  echo ::set-env name=BuildDockerImage::true
else
  printf "All images present in registry, no missing packages waiting to be build\n"
fi

The suggested solutions seems to include lots of coding and such code is hard to maintain. From https://docs.docker.com/registry/spec/api/:

Existing Manifests

The image manifest can be checked for existence with the following url:

<font color="#999999">HEAD /v2/&lt;name&gt;/manifests/&lt;reference&gt;</font>

The name and reference parameter identify the image and are required. The reference may include a tag or digest.

A 404 Not Found response will be returned if the image is unknown to the registry. If the image exists and the response is successful the response will be as follows:

<font color="#999999">200 OK
Content-Length: &lt;length of manifest&gt;
Docker-Content-Digest: &lt;digest&gt;</font>

Would it not be easier to try and get the manifest for a docker image and see if it exists or not? Examples?

Hi @jactor-rises , 

You could use docker registry api to get image manifest for Github Package Registry. 

on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Check package version
      run: |
        manifest=$(curl -X GET https://docker.pkg.github.com/v2/{org}/{repo}/{image name}/manifests/$GITHUB_SHA -u $GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }} | jq '.')
        echo $manifest
1 Like

@yanjingzhu : do you need some special permissions to do this? From output from use of action https://github.com/navikt/bidrag-docker/tree/master/exists (see exists.sh):

1s

1 Run navikt/bidrag-docker/exists@v1

2 with:

3 image_name: bidrag-dokument

4 GITHUB_TOKEN: ***

5 env:

6 IMAGE: docker.pkg.github.com/navikt/bidrag-dokument/bidrag-dokument:d4cc1bcd2ff78387b19db6f15261ba5207beab1c

7/bin/bash /home/runner/work/_actions/navikt/bidrag-docker/v1/exists/dist/…/exists.sh bidrag-dokument

8 % Total % Received % Xferd Average Speed Time Time Time Current

9 Dload Upload Total Spent Left Speed

10

11 0 0 0 0 0 0 0 0 --:–:-- --:–:-- --:–:-- 0

12 0 205 0 0 0 0 0 0 --:–:-- --:–:-- --:–:-- 0

13

14Headere i respons fra https://docker.pkg.github.com/v2/navikt/bidrag-dokument/bidrag-dokument/manifests/d4cc1bcd2ff78387b19db6f15261ba5207beab1c:

15----

16HTTP/1.1 401 Unauthorized

17Content-Security-Policy: default-src ‘none’;

18Docker-Distribution-Api-Version: registry/2.0

19Server: GitHub Registry

20Strict-Transport-Security: max-age=31536000;

21X-Content-Type-Options: nosniff

22X-Frame-Options: DENY

23X-Xss-Protection: 1; mode=block

24Date: Sat, 09 May 2020 08:06:57 GMT

25Content-Length: 205

26Content-Type: text/plain; charset=utf-8

27X-GitHub-Request-Id: 0400:2CD7:6D029:ECA4F:5EB664A1

28

29

30Found 0 mentions of HTTP/1.1\ 404

31unauthorized, assuming not found

When execute curl request, -u  parameter is used to pass user and password. Please make sure the GITHUB_TOKEN is passed to scripts in exists.sh.