@@ -140,7 +140,8 @@ jobs:
140140 runs-on : [self-hosted, linux, x64]
141141 timeout-minutes : 120
142142 env :
143- DOCKERHUB_IMAGE : docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
143+ DOCKERHUB_IMAGE : docker.io/fosrl/cli
144+ DOCKERHUB_IMAGE2 : docker.io/fosrl/pangolin-cli
144145 GHCR_IMAGE : ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
145146 IMAGE_LICENSE : ${{ github.event.repository.license.spdx_id || 'NOASSERTION' }}
146147 IMAGE_CREATED : ${{ needs.pre-run.outputs.image_created }}
@@ -257,6 +258,7 @@ jobs:
257258 set -euo pipefail
258259 echo "GHCR_IMAGE=${GHCR_IMAGE,,}" >> "$GITHUB_ENV"
259260 echo "DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE,,}" >> "$GITHUB_ENV"
261+ echo "DOCKERHUB_IMAGE2=${DOCKERHUB_IMAGE2,,}" >> "$GITHUB_ENV"
260262
261263 - name : Set up Docker Buildx
262264 uses : docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
@@ -273,6 +275,7 @@ jobs:
273275 tags : |
274276 ${{ env.GHCR_IMAGE }}:amd64-${{ env.TAG }}
275277 ${{ env.DOCKERHUB_IMAGE }}:amd64-${{ env.TAG }}
278+ ${{ env.DOCKERHUB_IMAGE2 }}:amd64-${{ env.TAG }}
276279 labels : |
277280 org.opencontainers.image.title=${{ github.event.repository.name }}
278281 org.opencontainers.image.version=${{ env.TAG }}
@@ -298,7 +301,8 @@ jobs:
298301 runs-on : [self-hosted, linux, arm64] # NOTE: ensure label exists on runner
299302 timeout-minutes : 120
300303 env :
301- DOCKERHUB_IMAGE : docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
304+ DOCKERHUB_IMAGE : docker.io/fosrl/cli
305+ DOCKERHUB_IMAGE2 : docker.io/fosrl/pangolin-cli
302306 GHCR_IMAGE : ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
303307 IMAGE_LICENSE : ${{ github.event.repository.license.spdx_id || 'NOASSERTION' }}
304308 IMAGE_CREATED : ${{ needs.pre-run.outputs.image_created }}
@@ -382,6 +386,7 @@ jobs:
382386 set -euo pipefail
383387 echo "GHCR_IMAGE=${GHCR_IMAGE,,}" >> "$GITHUB_ENV"
384388 echo "DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE,,}" >> "$GITHUB_ENV"
389+ echo "DOCKERHUB_IMAGE2=${DOCKERHUB_IMAGE2,,}" >> "$GITHUB_ENV"
385390
386391 - name : Set up Docker Buildx
387392 uses : docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
@@ -398,6 +403,7 @@ jobs:
398403 tags : |
399404 ${{ env.GHCR_IMAGE }}:arm64-${{ env.TAG }}
400405 ${{ env.DOCKERHUB_IMAGE }}:arm64-${{ env.TAG }}
406+ ${{ env.DOCKERHUB_IMAGE2 }}:arm64-${{ env.TAG }}
401407 labels : |
402408 org.opencontainers.image.title=${{ github.event.repository.name }}
403409 org.opencontainers.image.version=${{ env.TAG }}
@@ -423,7 +429,8 @@ jobs:
423429 runs-on : [self-hosted, linux, arm64]
424430 timeout-minutes : 120
425431 env :
426- DOCKERHUB_IMAGE : docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
432+ DOCKERHUB_IMAGE : docker.io/fosrl/cli
433+ DOCKERHUB_IMAGE2 : docker.io/fosrl/pangolin-cli
427434 GHCR_IMAGE : ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
428435 IMAGE_LICENSE : ${{ github.event.repository.license.spdx_id || 'NOASSERTION' }}
429436 IMAGE_CREATED : ${{ needs.pre-run.outputs.image_created }}
@@ -497,6 +504,7 @@ jobs:
497504 set -euo pipefail
498505 echo "GHCR_IMAGE=${GHCR_IMAGE,,}" >> "$GITHUB_ENV"
499506 echo "DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE,,}" >> "$GITHUB_ENV"
507+ echo "DOCKERHUB_IMAGE2=${DOCKERHUB_IMAGE2,,}" >> "$GITHUB_ENV"
500508
501509 - name : Set up QEMU
502510 uses : docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
@@ -515,6 +523,7 @@ jobs:
515523 tags : |
516524 ${{ env.GHCR_IMAGE }}:armv7-${{ env.TAG }}
517525 ${{ env.DOCKERHUB_IMAGE }}:armv7-${{ env.TAG }}
526+ ${{ env.DOCKERHUB_IMAGE2 }}:armv7-${{ env.TAG }}
518527 labels : |
519528 org.opencontainers.image.title=${{ github.event.repository.name }}
520529 org.opencontainers.image.version=${{ env.TAG }}
@@ -540,7 +549,8 @@ jobs:
540549 runs-on : [self-hosted, linux, x64] # NOTE: ensure label exists on runner
541550 timeout-minutes : 30
542551 env :
543- DOCKERHUB_IMAGE : docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
552+ DOCKERHUB_IMAGE : docker.io/fosrl/cli
553+ DOCKERHUB_IMAGE2 : docker.io/fosrl/pangolin-cli
544554 GHCR_IMAGE : ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
545555 TAG : ${{ needs.build-amd.outputs.tag }}
546556 IS_RC : ${{ needs.build-amd.outputs.is_rc }}
@@ -570,6 +580,7 @@ jobs:
570580 set -euo pipefail
571581 echo "GHCR_IMAGE=${GHCR_IMAGE,,}" >> "$GITHUB_ENV"
572582 echo "DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE,,}" >> "$GITHUB_ENV"
583+ echo "DOCKERHUB_IMAGE2=${DOCKERHUB_IMAGE2,,}" >> "$GITHUB_ENV"
573584
574585 - name : Set up Docker Buildx (needed for imagetools)
575586 uses : docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
@@ -594,6 +605,16 @@ jobs:
594605 "${DOCKERHUB_IMAGE}:arm64-${TAG}" \
595606 "${DOCKERHUB_IMAGE}:armv7-${TAG}"
596607
608+ - name : Create & push multi-arch index (Docker Hub pangolin-cli :TAG) via imagetools
609+ shell : bash
610+ run : |
611+ set -euo pipefail
612+ docker buildx imagetools create \
613+ -t "${DOCKERHUB_IMAGE2}:${TAG}" \
614+ "${DOCKERHUB_IMAGE2}:amd64-${TAG}" \
615+ "${DOCKERHUB_IMAGE2}:arm64-${TAG}" \
616+ "${DOCKERHUB_IMAGE2}:armv7-${TAG}"
617+
597618 # Additional tags for non-RC releases: latest, major, minor (always)
598619 - name : Publish additional tags (non-RC only) via imagetools
599620 if : ${{ env.IS_RC != 'true' }}
@@ -617,6 +638,13 @@ jobs:
617638 "${DOCKERHUB_IMAGE}:amd64-${TAG}" \
618639 "${DOCKERHUB_IMAGE}:arm64-${TAG}" \
619640 "${DOCKERHUB_IMAGE}:armv7-${TAG}"
641+
642+ echo "Publishing Docker Hub pangolin-cli tag ${t} -> ${TAG}"
643+ docker buildx imagetools create \
644+ -t "${DOCKERHUB_IMAGE2}:${t}" \
645+ "${DOCKERHUB_IMAGE2}:amd64-${TAG}" \
646+ "${DOCKERHUB_IMAGE2}:arm64-${TAG}" \
647+ "${DOCKERHUB_IMAGE2}:armv7-${TAG}"
620648 done
621649
622650 # ---------------------------------------------------------------------------
@@ -629,7 +657,8 @@ jobs:
629657 runs-on : [self-hosted, linux, x64] # NOTE: ensure label exists on runner
630658 timeout-minutes : 120
631659 env :
632- DOCKERHUB_IMAGE : docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
660+ DOCKERHUB_IMAGE : docker.io/fosrl/cli
661+ DOCKERHUB_IMAGE2 : docker.io/fosrl/pangolin-cli
633662 GHCR_IMAGE : ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
634663 TAG : ${{ needs.build-amd.outputs.tag }}
635664 IS_RC : ${{ needs.build-amd.outputs.is_rc }}
@@ -675,6 +704,7 @@ jobs:
675704 set -euo pipefail
676705 echo "GHCR_IMAGE=${GHCR_IMAGE,,}" >> "$GITHUB_ENV"
677706 echo "DOCKERHUB_IMAGE=${DOCKERHUB_IMAGE,,}" >> "$GITHUB_ENV"
707+ echo "DOCKERHUB_IMAGE2=${DOCKERHUB_IMAGE2,,}" >> "$GITHUB_ENV"
678708
679709 - name : Ensure jq is installed
680710 shell : bash
@@ -724,6 +754,11 @@ jobs:
724754 echo "DH_REF=${DOCKERHUB_IMAGE}@${DH_DIGEST}" >> "$GITHUB_ENV"
725755 echo "DH_DIGEST=${DH_DIGEST}" >> "$GITHUB_ENV"
726756 echo "Resolved DH_REF=${DOCKERHUB_IMAGE}@${DH_DIGEST}"
757+
758+ DH2_DIGEST="$(get_digest "${DOCKERHUB_IMAGE2}:${TAG}")"
759+ echo "DH2_REF=${DOCKERHUB_IMAGE2}@${DH2_DIGEST}" >> "$GITHUB_ENV"
760+ echo "DH2_DIGEST=${DH2_DIGEST}" >> "$GITHUB_ENV"
761+ echo "Resolved DH2_REF=${DOCKERHUB_IMAGE2}@${DH2_DIGEST}"
727762 fi
728763
729764 - name : Attest build provenance (GHCR) (digest)
@@ -739,11 +774,21 @@ jobs:
739774 if : ${{ env.DH_DIGEST != '' }}
740775 uses : actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
741776 with :
742- subject-name : index.docker.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
777+ subject-name : index.docker.io/fosrl/cli
743778 subject-digest : ${{ env.DH_DIGEST }}
744779 push-to-registry : true
745780 show-summary : true
746781
782+ - name : Attest build provenance (Docker Hub pangolin-cli)
783+ continue-on-error : true
784+ if : ${{ env.DH2_DIGEST != '' }}
785+ uses : actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
786+ with :
787+ subject-name : index.docker.io/fosrl/pangolin-cli
788+ subject-digest : ${{ env.DH2_DIGEST }}
789+ push-to-registry : true
790+ show-summary : true
791+
747792 - name : Install cosign
748793 uses : sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
749794 with :
@@ -814,6 +859,22 @@ jobs:
814859 --predicate sbom.spdx.json \
815860 "${DH_REF}"
816861
862+ - name : Create SBOM attestation (Docker Hub pangolin-cli, key)
863+ continue-on-error : true
864+ env :
865+ COSIGN_YES : " true"
866+ COSIGN_PRIVATE_KEY : ${{ secrets.COSIGN_PRIVATE_KEY }}
867+ COSIGN_PASSWORD : ${{ secrets.COSIGN_PASSWORD }}
868+ COSIGN_DOCKER_MEDIA_TYPES : " 1"
869+ shell : bash
870+ run : |
871+ set -euo pipefail
872+ cosign attest \
873+ --key env://COSIGN_PRIVATE_KEY \
874+ --type spdxjson \
875+ --predicate sbom.spdx.json \
876+ "${DH2_REF}"
877+
817878 - name : Keyless sign & verify GHCR digest (OIDC)
818879 env :
819880 COSIGN_YES : " true"
@@ -855,6 +916,18 @@ jobs:
855916 set -euo pipefail
856917 cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${DH_REF}"
857918
919+ - name : Sign Docker Hub pangolin-cli digest (key, recursive)
920+ continue-on-error : true
921+ env :
922+ COSIGN_YES : " true"
923+ COSIGN_PRIVATE_KEY : ${{ secrets.COSIGN_PRIVATE_KEY }}
924+ COSIGN_PASSWORD : ${{ secrets.COSIGN_PASSWORD }}
925+ COSIGN_DOCKER_MEDIA_TYPES : " 1"
926+ shell : bash
927+ run : |
928+ set -euo pipefail
929+ cosign sign --key env://COSIGN_PRIVATE_KEY --recursive "${DH2_REF}"
930+
858931 - name : Keyless sign & verify Docker Hub digest (OIDC)
859932 continue-on-error : true
860933 if : ${{ env.DH_REF != '' }}
@@ -871,6 +944,22 @@ jobs:
871944 --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
872945 "${DH_REF}" -o text
873946
947+ - name : Keyless sign & verify Docker Hub pangolin-cli digest (OIDC)
948+ continue-on-error : true
949+ if : ${{ env.DH2_REF != '' }}
950+ env :
951+ COSIGN_YES : " true"
952+ ISSUER : https://token.actions.githubusercontent.com
953+ COSIGN_DOCKER_MEDIA_TYPES : " 1"
954+ shell : bash
955+ run : |
956+ set -euo pipefail
957+ cosign sign --rekor-url https://rekor.sigstore.dev --recursive "${DH2_REF}"
958+ cosign verify \
959+ --certificate-oidc-issuer "${ISSUER}" \
960+ --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
961+ "${DH2_REF}" -o text
962+
874963 - name : Verify signature (public key) Docker Hub digest + tag
875964 continue-on-error : true
876965 if : ${{ env.DH_REF != '' }}
@@ -883,6 +972,18 @@ jobs:
883972 cosign verify --key env://COSIGN_PUBLIC_KEY "${DH_REF}" -o text
884973 cosign verify --key env://COSIGN_PUBLIC_KEY "${DOCKERHUB_IMAGE}:${TAG}" -o text
885974
975+ - name : Verify signature (public key) Docker Hub pangolin-cli digest + tag
976+ continue-on-error : true
977+ if : ${{ env.DH2_REF != '' }}
978+ env :
979+ COSIGN_PUBLIC_KEY : ${{ secrets.COSIGN_PUBLIC_KEY }}
980+ COSIGN_DOCKER_MEDIA_TYPES : " 1"
981+ shell : bash
982+ run : |
983+ set -euo pipefail
984+ cosign verify --key env://COSIGN_PUBLIC_KEY "${DH2_REF}" -o text
985+ cosign verify --key env://COSIGN_PUBLIC_KEY "${DOCKERHUB_IMAGE2}:${TAG}" -o text
986+
886987 - name : Build binaries
887988 env :
888989 CGO_ENABLED : " 0"
@@ -905,7 +1006,7 @@ jobs:
9051006 body : |
9061007 ## Container Images
9071008 - GHCR: `${{ env.GHCR_REF }}`
908- - Docker Hub: `${{ env.DH_REF || 'N/A' }}`
1009+ - Docker Hub: `${{ env.DH2_REF || env. DH_REF || 'N/A' }}`
9091010 **Tag:** `${{ env.TAG }}`
9101011
9111012 # ---------------------------------------------------------------------------
0 commit comments