summaryrefslogtreecommitdiff
path: root/.github/workflows/multi-arch-build.yaml
blob: 41ef3f3a63475dbc43c799a1fd9c9fccd4df11a3 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
name: build multi-arch images

on:
  # Upstream podman tends to be very active, with many merges per day.
  # Only run this daily via cron schedule, or manually, not by branch push.
  schedule:
    - cron:  '0 8 * * *'
  # allows to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  multi:
    name: multi-arch Podman build
    env:
      PODMAN_QUAY_REGISTRY: quay.io/podman
      CONTAINERS_QUAY_REGISTRY: quay.io/containers
      # list of architectures for build
      PLATFORMS: linux/amd64,linux/s390x,linux/ppc64le,linux/arm64

    # build several images (upstream, testing, stable) in parallel
    strategy:
      matrix:
        # Builds are located under contrib/podmanimage/<source> directory
        source:
          - upstream
          - testing
          - stable
    runs-on: ubuntu-latest
    # internal registry caches build for inspection before push
    services:
      registry:
        image: quay.io/libpod/registry:2
        ports:
          - 5000:5000
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
        with:
          driver-opts: network=host
          install: true

      - name: Build and locally push Podman
        uses: docker/build-push-action@v2
        with:
          context: contrib/podmanimage/${{ matrix.source }}
          file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile
          platforms: ${{ env.PLATFORMS }}
          push: true
          tags: localhost:5000/podman/${{ matrix.source }}

      # Simple verification that container works + grab version number
      - name: amd64 container sniff test
        id: sniff_test
        run: |
          VERSION_OUTPUT="$(docker run localhost:5000/podman/${{ matrix.source }} \
                            podman --storage-driver=vfs version)"
          echo "$VERSION_OUTPUT"
          VERSION=$(grep -Em1 '^Version: ' <<<"$VERSION_OUTPUT" | awk '{print $2}')
          test -n "$VERSION"
          echo "::set-output name=version::${VERSION}"

      # Generate image FQINs, labels, check whether to push
      - name: Generate image information
        id: image_info
        run: |
          VERSION='v${{ steps.sniff_test.outputs.version }}'
          # workaround vim syntax-hilighting bug: '
          if [[ "${{ matrix.source }}" == 'stable' ]]; then
            # quay.io/podman/stable:vX.X.X
            ALLTAGS=$(skopeo list-tags \
                      docker://$PODMAN_QUAY_REGISTRY/stable | \
                      jq -r '.Tags[]')
            PUSH="false"
            if fgrep -qx "$VERSION" <<<"$ALLTAGS"; then
                PUSH="true"
            fi

            FQIN="$PODMAN_QUAY_REGISTRY/stable:$VERSION"
            # Only push if version tag does not exist
            if [[ "$PUSH" == "true" ]]; then
              echo "Will push $FQIN"
              echo "::set-output name=podman_push::${PUSH}"
              echo "::set-output name=podman_fqin::${FQIN}"
            else
              echo "Not pushing, $FQIN already exists."
            fi

            # quay.io/containers/podman:vX.X.X
            unset ALLTAGS
            ALLTAGS=$(skopeo list-tags \
                      docker://$CONTAINERS_QUAY_REGISTRY/podman | \
                      jq -r '.Tags[]')
            PUSH="false"
            if fgrep -qx "$VERSION" <<<"$ALLTAGS"; then
                PUSH="true"
            fi

            FQIN="$CONTAINERS_QUAY_REGISTRY/podman:$VERSION"
            # Only push if version tag does not exist
            if [[ "$PUSH" == "true" ]]; then
              echo "Will push $FQIN"
              echo "::set-output name=containers_push::${PUSH}"
              echo "::set-output name=containers_fqin::$FQIN"
            else
              echo "Not pushing, $FQIN already exists."
            fi
          elif [[ "${{ matrix.source }}" == 'testing' ]]; then
            P_FQIN="$PODMAN_QUAY_REGISTRY/testing:master"
            echo "Will push $P_FQIN"
            echo "::set-output name=podman_fqin::${P_FQIN}"
            echo '::set-output name=podman_push::true'
          elif [[ "${{ matrix.source }}" == 'upstream' ]]; then
            P_FQIN="$PODMAN_QUAY_REGISTRY/upstream:master"
            C_FQIN="$CONTAINERS_QUAY_REGISTRY/podman:master"
            echo "Will push $P_FQIN and $C_FQIN"
            echo "::set-output name=podman_fqin::${P_FQIN}"
            echo "::set-output name=containers_fqin::${C_FQIN}"
            # Always push 'master' tag
            echo '::set-output name=podman_push::true'
            echo '::set-output name=containers_push::true'
          else
            echo "::error ::Unknown matrix value ${{ matrix.source }}"
            exit 1
          fi

      - name: Define LABELS multi-line env. var. value
        run: |
          # This is a really hacky/strange workflow idiom, required
          # for setting multi-line $LABELS value for consumption in
          # a future step.
          # https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#multiline-strings
          cat << EOF | tee -a $GITHUB_ENV
          LABELS<<DELIMITER
          org.opencontainers.image.source=https://github.com/${{ github.repository }}.git
          org.opencontainers.image.revision=${{ github.sha }}
          org.opencontainers.image.created=$(date -u --iso-8601=seconds)
          DELIMITER
          EOF

      # Separate steps to login and push for podman and containers quay
      # repositories are required, because 2 sets of credentials are used and `docker
      # login` as well as `podman login` do not support having 2 different
      # credential sets for 1 registry.
      # At the same time reuse of non-shell steps is not supported by Github Actions
      # via anchors or composite actions

      # Push to 'podman' Quay repo for stable, testing. and upstream
      - name: Login to 'podman' Quay registry
        uses: docker/login-action@v1
        if: ${{ steps.image_info.outputs.podman_push == 'true' }}
        with:
          registry: ${{ env.PODMAN_QUAY_REGISTRY }}
          # N/B: Secrets are not passed to workflows that are triggered
          #      by a pull request from a fork
          username: ${{ secrets.PODMAN_QUAY_USERNAME }}
          password: ${{ secrets.PODMAN_QUAY_PASSWORD }}

      - name: Push images to 'podman' Quay
        uses: docker/build-push-action@v2
        if: ${{ steps.image_info.outputs.podman_push == 'true' }}
        with:
          cache-from: type=registry,ref=localhost:5000/podman/${{ matrix.source }}
          cache-to: type=inline
          context: contrib/podmanimage/${{ matrix.source }}
          file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile
          platforms: ${{ env.PLATFORMS }}
          push: true
          tags: ${{ steps.image_info.outputs.podman_fqin }}
          labels: |
            ${{ env.LABELS }}

      # Push to 'containers' Quay repo only stable podman
      - name: Login to 'containers' Quay registry
        if: ${{ steps.image_info.outputs.containers_push == 'true' }}
        uses: docker/login-action@v1
        with:
          registry: ${{ env.CONTAINERS_QUAY_REGISTRY}}
          username: ${{ secrets.CONTAINERS_QUAY_USERNAME }}
          password: ${{ secrets.CONTAINERS_QUAY_PASSWORD }}

      - name: Push images to 'containers' Quay
        if: ${{ steps.image_info.outputs.containers_push == 'true' }}
        uses: docker/build-push-action@v2
        with:
          cache-from: type=registry,ref=localhost:5000/podman/${{ matrix.source }}
          cache-to: type=inline
          context: contrib/podmanimage/${{ matrix.source }}
          file: ./contrib/podmanimage/${{ matrix.source }}/Dockerfile
          platforms: ${{ env.PLATFORMS }}
          push: true
          tags: ${{ steps.image_info.outputs.containers_fqin }}
          labels: |
            ${{ env.LABELS }}