|
| 1 | +# testing : https://github.com/postgis/docker-postgis/pull/432 |
| 2 | +# original author: https://github.com/BowlesCR |
| 3 | + |
| 4 | +# To pin GitHub Actions versions by commit hash: 'pinact run -u --min-age 7' ( https://github.com/suzuki-shunsuke/pinact ) |
| 5 | + |
| 6 | +name: TEST - Docker PostGIS CI |
| 7 | +# Serialize publish-capable runs per ref so scheduled/push/manual runs queue instead of racing. |
| 8 | +concurrency: |
| 9 | + group: test-${{ github.workflow }}-${{ github.ref }} |
| 10 | + cancel-in-progress: false |
| 11 | + |
| 12 | +on: |
| 13 | + push: |
| 14 | + pull_request: |
| 15 | + workflow_dispatch: |
| 16 | + schedule: |
| 17 | + - cron: '15 13 * * *' |
| 18 | + |
| 19 | +# ============================================================================ |
| 20 | +# FOR FORKING: Modify these settings in your forked repository |
| 21 | +# ============================================================================ |
| 22 | +env: |
| 23 | + DOCKERHUB_REPO: postgis/docker-postgis-test |
| 24 | + GITHUB_REPO: postgis/docker-postgis |
| 25 | + LATEST_VERSION: 17-3.5 |
| 26 | + DOCKERHUB_SHORT_DESCRIPTION: "TEST REPO - PostGIS Docker" |
| 27 | + DOCKERHUB_README_PREFIX: "# WARNING: This is a TEST repository ONLY\n\n" |
| 28 | + RUNNER_PLATFORMS_JSON: '["ubuntu-24.04","ubuntu-24.04-arm"]' # Runner platforms used to expand the build matrix |
| 29 | +# |
| 30 | +# Also add these secrets in your repository settings: |
| 31 | +# https://github.com/${GITHUB_REPO}/settings/secrets/actions |
| 32 | +# - secrets.DOCKERHUB_USERNAME |
| 33 | +# - secrets.DOCKERHUB_ACCESS_TOKEN ( READ, Write, Delete access ) |
| 34 | +# ============================================================================ |
| 35 | + |
| 36 | +defaults: |
| 37 | + run: |
| 38 | + shell: bash --noprofile --norc -euo pipefail {0} |
| 39 | + |
| 40 | +jobs: |
| 41 | + |
| 42 | + setup: |
| 43 | + # This job sets up configuration constants and loads the CI matrix from matrix.yml. |
| 44 | + # - Constants: CANONICAL_REPO and SHOULD_PUBLISH flag (fork-friendly configuration) |
| 45 | + # - Matrix: BUILD_TARGETS and BUILD_INCLUDE arrays (automatically generated by ./update.sh) |
| 46 | + name: Setup and Load Configuration |
| 47 | + runs-on: ubuntu-latest |
| 48 | + outputs: |
| 49 | + CANONICAL_REPO: ${{ steps.constants.outputs.CANONICAL_REPO }} |
| 50 | + SHOULD_PUBLISH: ${{ steps.constants.outputs.SHOULD_PUBLISH }} |
| 51 | + BUILD_INCLUDE: ${{ steps.matrix.outputs.BUILD_INCLUDE }} |
| 52 | + BUILD_TARGETS: ${{ steps.matrix.outputs.BUILD_TARGETS }} |
| 53 | + steps: |
| 54 | + - name: Set constants |
| 55 | + id: constants |
| 56 | + env: |
| 57 | + VAR_CANONICAL: ${{ vars.CANONICAL_REPO }} |
| 58 | + run: | |
| 59 | + CANONICAL_REPO="${VAR_CANONICAL:-$GITHUB_REPO}" |
| 60 | + echo "CANONICAL_REPO=$CANONICAL_REPO" >> "$GITHUB_OUTPUT" |
| 61 | +
|
| 62 | + # Compute if we should publish |
| 63 | + if [[ "${{ github.repository }}" == "$CANONICAL_REPO" ]] && \ |
| 64 | + [[ "${{ github.ref }}" == "refs/heads/master" ]] && \ |
| 65 | + [[ "${{ github.event_name }}" != "pull_request" ]]; then |
| 66 | + echo "SHOULD_PUBLISH=true" >> "$GITHUB_OUTPUT" |
| 67 | + else |
| 68 | + echo "SHOULD_PUBLISH=false" >> "$GITHUB_OUTPUT" |
| 69 | + fi |
| 70 | +
|
| 71 | + - name: Checkout repository |
| 72 | + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| 73 | + |
| 74 | + - name: Load and validate matrix |
| 75 | + id: matrix |
| 76 | + run: bash ci/matrix.sh |
| 77 | + |
| 78 | + make-docker-images: |
| 79 | + needs: setup |
| 80 | + strategy: |
| 81 | + matrix: |
| 82 | + include: ${{ fromJSON(needs.setup.outputs.BUILD_INCLUDE) }} |
| 83 | + |
| 84 | + name: "Build:${{ matrix.postgres }}-${{ matrix.postgis }}-${{ matrix.variant }} (${{ contains(matrix.runner-platform, 'arm') && 'arm64' || 'x86-64' }}) Docker image" |
| 85 | + runs-on: ${{ matrix.runner-platform }} |
| 86 | + continue-on-error: ${{ matrix.postgis == 'master' }} |
| 87 | + env: |
| 88 | + VERSION: ${{ matrix.postgres }}-${{ matrix.postgis }} |
| 89 | + VARIANT: ${{ matrix.variant }} |
| 90 | + # the "postgis/postgis" name is the expected test name; ( via ./test/postgis-config.sh ) |
| 91 | + # changing it will break the official-images test script |
| 92 | + # this is only for CI test and not for Docker hub publishing |
| 93 | + CI_IMAGE_TAG: postgis/postgis:ci-${{ github.run_id }}-${{ matrix.postgres }}-${{ matrix.postgis }}-${{ matrix.variant }}-${{ contains(matrix.runner-platform, 'arm') && 'arm' || 'x64' }} |
| 94 | + |
| 95 | + steps: |
| 96 | + - name: Checkout source |
| 97 | + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| 98 | + |
| 99 | + - name: Set up Docker Buildx |
| 100 | + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 |
| 101 | + |
| 102 | + - name: Compute build directory |
| 103 | + run: | |
| 104 | + if [[ "$VARIANT" == "alpine" ]]; then |
| 105 | + echo "BUILD_DIR=$VERSION/alpine" >> "$GITHUB_ENV" |
| 106 | + else |
| 107 | + echo "BUILD_DIR=$VERSION" >> "$GITHUB_ENV" |
| 108 | + fi |
| 109 | +
|
| 110 | + - name: Build Docker image for ${{ env.VERSION }} ${{ env.VARIANT }} |
| 111 | + id: build |
| 112 | + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 |
| 113 | + with: |
| 114 | + context: ${{ env.BUILD_DIR }} |
| 115 | + file: ${{ env.BUILD_DIR }}/Dockerfile |
| 116 | + tags: ${{ env.CI_IMAGE_TAG }} |
| 117 | + load: true |
| 118 | + push: false # don't push until after testing |
| 119 | + |
| 120 | + - name: Check out official-images repo |
| 121 | + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| 122 | + with: |
| 123 | + repository: docker-library/official-images |
| 124 | + path: official-images |
| 125 | + sparse-checkout: | |
| 126 | + test |
| 127 | +
|
| 128 | + - name: Test image with official-images |
| 129 | + run: bash ci/test-image.sh "$CI_IMAGE_TAG" |
| 130 | + |
| 131 | + - name: Login to dockerhub |
| 132 | + id: login-dockerhub |
| 133 | + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 |
| 134 | + if: ${{ needs.setup.outputs.SHOULD_PUBLISH == 'true' }} |
| 135 | + with: |
| 136 | + username: ${{ secrets.DOCKERHUB_USERNAME }} |
| 137 | + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} |
| 138 | + |
| 139 | + - name: Push image by digest |
| 140 | + id: push |
| 141 | + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 |
| 142 | + if: ${{ needs.setup.outputs.SHOULD_PUBLISH == 'true' && steps.login-dockerhub.outcome == 'success' }} |
| 143 | + with: |
| 144 | + context: ${{ env.BUILD_DIR }} |
| 145 | + file: ${{ env.BUILD_DIR }}/Dockerfile |
| 146 | + outputs: type=image,"name=${{ env.DOCKERHUB_REPO }}",push-by-digest=true,name-canonical=true,push=true |
| 147 | + |
| 148 | + - name: Export digest |
| 149 | + if: ${{ steps.push.outcome == 'success' }} |
| 150 | + run: | |
| 151 | + mkdir -p ${{ runner.temp }}/digests |
| 152 | + digest="${{ steps.push.outputs.digest }}" |
| 153 | + touch "${{ runner.temp }}/digests/${digest#sha256:}" |
| 154 | +
|
| 155 | + - name: Upload digests |
| 156 | + if: ${{ steps.push.outcome == 'success' }} |
| 157 | + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 |
| 158 | + with: |
| 159 | + name: digests-${{ github.run_id }}-${{ env.VERSION }}-${{ env.VARIANT }}-${{ matrix.runner-platform }} |
| 160 | + path: ${{ runner.temp }}/digests/* |
| 161 | + if-no-files-found: error |
| 162 | + retention-days: 10 |
| 163 | + |
| 164 | + merge-manifests: |
| 165 | + name: "Merge:${{ matrix.postgres }}-${{ matrix.postgis }}-${{ matrix.variant }} manifests and push to DockerHub" |
| 166 | + needs: [setup, make-docker-images] |
| 167 | + runs-on: ubuntu-24.04-arm # Run on arm runner for manifest merge |
| 168 | + if: ${{ needs.setup.outputs.SHOULD_PUBLISH == 'true' }} |
| 169 | + # Ensure each tag variant is published by only one workflow run at a time to keep manifests consistent. |
| 170 | + concurrency: |
| 171 | + group: merge-${{ matrix.postgres }}-${{ matrix.postgis }}-${{ matrix.variant }} |
| 172 | + cancel-in-progress: false |
| 173 | + continue-on-error: ${{ matrix.postgis == 'master' }} |
| 174 | + env: |
| 175 | + VERSION: ${{ matrix.postgres }}-${{ matrix.postgis }} |
| 176 | + VARIANT: ${{ matrix.variant }} |
| 177 | + strategy: |
| 178 | + matrix: |
| 179 | + include: ${{ fromJSON(needs.setup.outputs.BUILD_TARGETS) }} |
| 180 | + |
| 181 | + steps: |
| 182 | + - name: Checkout source |
| 183 | + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| 184 | + |
| 185 | + - name: Login to dockerhub |
| 186 | + id: login-dockerhub |
| 187 | + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 |
| 188 | + with: |
| 189 | + username: ${{ secrets.DOCKERHUB_USERNAME }} |
| 190 | + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} |
| 191 | + |
| 192 | + - name: Set up Docker Buildx |
| 193 | + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 |
| 194 | + |
| 195 | + - name: Download digests |
| 196 | + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 |
| 197 | + with: |
| 198 | + path: ${{ runner.temp }}/digests |
| 199 | + pattern: digests-${{ github.run_id }}-${{ env.VERSION }}-${{ env.VARIANT }}-* |
| 200 | + merge-multiple: true |
| 201 | + |
| 202 | + - name: Verify digests for all platforms |
| 203 | + working-directory: ${{ runner.temp }}/digests |
| 204 | + run: | |
| 205 | + expected="$(jq 'length' <<< "$RUNNER_PLATFORMS_JSON")" |
| 206 | + found="$(find . -maxdepth 1 -type f | wc -l | tr -d '[:space:]')" |
| 207 | + if [[ "$found" -ne "$expected" ]]; then |
| 208 | + echo "ERROR: Expected ${expected} digest(s) (one per runner platform), found ${found}." |
| 209 | + echo "RUNNER_PLATFORMS_JSON=${RUNNER_PLATFORMS_JSON}" |
| 210 | + ls -la |
| 211 | + exit 1 |
| 212 | + fi |
| 213 | + echo "[OK] Found ${found}/${expected} digests" |
| 214 | +
|
| 215 | + - name: Create manifest list and push |
| 216 | + env: |
| 217 | + MATRIX_TAGS: ${{ matrix.tags }} |
| 218 | + run: | |
| 219 | + build_month="$(date -u +%Y%m)" |
| 220 | + read -r -a tags_arr <<< "$MATRIX_TAGS" |
| 221 | + extra_tags="" |
| 222 | + if [[ "${#tags_arr[@]}" -ge 2 ]]; then |
| 223 | + extra_tags+=" ${tags_arr[1]}-${build_month}" |
| 224 | + fi |
| 225 | + bash ci/push-manifest.sh "${{ env.DOCKERHUB_REPO }}" "${MATRIX_TAGS}${extra_tags}" "${{ runner.temp }}/digests" |
| 226 | +
|
| 227 | + - name: Inspect image # Purely for debugging |
| 228 | + run: | |
| 229 | + sleep 5 |
| 230 | + docker buildx imagetools inspect ${{ env.DOCKERHUB_REPO }}:${{ env.VERSION }}${{ env.VARIANT == 'alpine' && '-alpine' || ''}} |
| 231 | +
|
| 232 | + dockerHubDescription: |
| 233 | + needs: [merge-manifests] |
| 234 | + runs-on: ubuntu-latest |
| 235 | + steps: |
| 236 | + - name: Checkout source |
| 237 | + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 |
| 238 | + |
| 239 | + - name: Prepare README with prefix (create ./_DOCKER-HUB-README.md ) |
| 240 | + run: bash ci/prepare-dockerhub-readme.sh && ls -la ./_DOCKER-HUB-README.md |
| 241 | + |
| 242 | + - name: Debug ./_DOCKER-HUB-README.md |
| 243 | + run: cat ./_DOCKER-HUB-README.md |
| 244 | + - name: Update Docker Hub Description |
| 245 | + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 |
| 246 | + with: |
| 247 | + username: ${{ secrets.DOCKERHUB_USERNAME }} |
| 248 | + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} |
| 249 | + repository: ${{ env.DOCKERHUB_REPO }} |
| 250 | + short-description: "${{ env.DOCKERHUB_SHORT_DESCRIPTION }}" |
| 251 | + readme-filepath: ./_DOCKER-HUB-README.md |
0 commit comments