aboutsummaryrefslogtreecommitdiff
path: root/.github/workflows/publish.yml
blob: 0e10ccae632e11402c9f90398c7fa3e52fea9418 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
name: Publish Docker Image

on:
   push:
      branches:
         - master
         - multi-runner-docker
      tags:
         - v**
   workflow_dispatch:

env:
   REGISTRY: ghcr.io
   IMAGE: ${{ github.repository }}

jobs:
   gen-versions:
      name: Generate tags
      runs-on: ubuntu-24.04
      outputs:
         DOCKER_IMAGE_TAG_JSON: ${{ steps.variables.outputs.DOCKER_IMAGE_TAG_JSON }}
         DOCKER_IMAGE_TAG: ${{ steps.variables.outputs.DOCKER_IMAGE_TAG }}
      steps:
         -  name: Setup variables
            id: variables
            run: |
               # docker/build-push-action supports comma separated tags
               DOCKER_IMAGE_TAG_BASE="$REGISTRY/$IMAGE"
               DOCKER_IMAGE_TAG_JSON="$(
               ( # Every line echoed inside of these parenthesis will result in a version
                  echo dev
                  GH_REF="${{ github.ref }}"
                  # if this is a versioned release, github.ref will start with 'refs/tags/v'
                  # cut off 'refs/tags/v'
                  if [[ $GH_REF == "refs/tags/v"* ]]; then
                     VERSION=$(echo $GH_REF | cut -c 12-)
                     echo latest
                     echo $VERSION
                  fi
               ) | sed -e 's|.*|'"$DOCKER_IMAGE_TAG_BASE"':\0|' | jq -R -s -c 'split("\n") | map(select (. != "" ))')"

               echo "DOCKER_IMAGE_TAG_JSON=$DOCKER_IMAGE_TAG_JSON" >> "$GITHUB_OUTPUT"
               echo "DOCKER_IMAGE_TAG=$(echo "$DOCKER_IMAGE_TAG_JSON" | jq -r 'join(",")')" >> "$GITHUB_OUTPUT"

   publish-base:
      name: Publish ${{ matrix.arch }} image
      strategy:
         matrix:
            include:
               -  arch: arm64
                  os: ubuntu-24.04-arm
               -  arch: amd64
                  os: ubuntu-24.04

      runs-on: ${{ matrix.os }}
      needs:
         - gen-versions
      env:
         ARCH: ${{matrix.arch}}
      permissions:
         packages: write
      steps:
         -  name: Check out the repo
            uses: actions/checkout@v4

         -  name: Log in to ghcr.io
            uses: docker/login-action@v3
            with:
               registry: ghcr.io
               username: ${{ github.actor }}
               password: ${{ secrets.GITHUB_TOKEN }}

         -  name: Enhance tags
            id: variables
            run: |
               echo "DOCKER_IMAGE_TAG=$(echo "$TAG" | jq -r 'map(. + "-${{ matrix.arch }}") | join(",")')" >>"$GITHUB_OUTPUT"
            env:
               TAG: ${{ needs.gen-versions.outputs.DOCKER_IMAGE_TAG_JSON }}
         -  name: Set up Docker Buildx # Even if we don't directly invoke buildx it should set up github action caches, which is nice
            uses: docker/setup-buildx-action@v3
         -  name: Build and push Docker Image
            uses: docker/build-push-action@v6
            id: upload-docker-image
            with:
               context: .
               push: true
               tags: ${{ steps.variables.outputs.DOCKER_IMAGE_TAG }}
               cache-from: type=gha
               cache-to: type=gha,mode=max
         -  name: Write digest
            run: |
               digest="${{ steps.upload-docker-image.outputs.digest }}"
               mkdir -p digests
               touch "digests/${digest#sha256:}"

         -  name: Upload docker image digest
            uses: actions/upload-artifact@v4
            with:
               if-no-files-found: error
               name: digests-${{ matrix.arch }}
               path: digests/*

   publish-multiarch:
      name: Publish multi-arch image
      needs:
         - publish-base
         - gen-versions
      runs-on: ubuntu-24.04
      permissions:
         packages: write
      steps:
         -  name: Download digests
            uses: actions/download-artifact@v4
            with:
               path: digests
               pattern: digests-*
               merge-multiple: true

         -  name: Log in to ghcr.io
            uses: docker/login-action@v3
            with:
               registry: ghcr.io
               username: ${{ github.actor }}
               password: ${{ secrets.GITHUB_TOKEN }}


         -  name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v3

         -  name: Create manifest list
            run: |
               cd digests
               docker buildx imagetools create \
                  `# A -t {tag} for each tag in DOCKER_IMAGE_TAGS` \
                  $(echo '${{ needs.gen-versions.outputs.DOCKER_IMAGE_TAG }}'| tr ',' '\n' | sed -e 's|.*|-t \0|') \
                  `# Then a reference for each of the arches. This uses the fact that printf repeats its format string if it has too many arguments.` \
                  $(printf '${{env.REGISTRY}}/${{ env.IMAGE }}@sha256:%s ' *)