|
1 | | -name: Build and Push Docker Image to Docker Hub |
| 1 | +name: Build, Attest (SBOM/Provenance) & Sign to Docker Hub |
2 | 2 |
|
3 | 3 | on: |
4 | 4 | workflow_call: |
5 | 5 | inputs: |
6 | 6 | image_name: |
7 | | - description: "Name of the Docker image to build and push" |
| 7 | + description: "Docker image name (e.g. user/repo)" |
8 | 8 | required: true |
9 | 9 | type: string |
10 | 10 | image_tags: |
11 | | - description: "Comma-separated list of tags for the Docker image" |
| 11 | + description: "Comma-separated list of tags" |
12 | 12 | required: true |
13 | 13 | type: string |
14 | 14 | dockerfile: |
15 | 15 | description: "Path to the Dockerfile" |
16 | 16 | required: true |
17 | 17 | type: string |
18 | 18 | context: |
19 | | - description: "Build context for the Docker image" |
| 19 | + description: "Build context" |
20 | 20 | required: true |
21 | 21 | type: string |
22 | 22 | build-args: |
|
26 | 26 | secrets: |
27 | 27 | dockerhub_registry: |
28 | 28 | required: true |
29 | | - description: "Docker Hub registry URL (e.g., docker.io)" |
| 29 | + description: "Docker Hub registry (e.g. docker.io)" |
30 | 30 | dockerhub_username: |
31 | 31 | required: true |
32 | 32 | description: "Docker Hub username" |
33 | 33 | dockerhub_password: |
34 | 34 | required: true |
35 | 35 | description: "Docker Hub password" |
36 | 36 |
|
| 37 | +permissions: |
| 38 | + # Needed for keyless signing with Cosign and checkout |
| 39 | + id-token: write |
| 40 | + contents: read |
| 41 | + |
37 | 42 | jobs: |
38 | 43 | build-and-push: |
39 | 44 | runs-on: ubuntu-latest |
| 45 | + env: |
| 46 | + REGISTRY: ${{ secrets.dockerhub_registry }} |
| 47 | + IMAGE_NAME: ${{ inputs.image_name }} |
40 | 48 | steps: |
41 | | - - name: Set Docker Image Tags |
| 49 | + - name: Compute Docker image tags |
42 | 50 | id: set-tags |
43 | 51 | run: | |
| 52 | + set -euo pipefail |
44 | 53 | TAGS="${{ inputs.image_tags }}" |
45 | | - REGISTRY="${{ secrets.dockerhub_registry }}/${{ inputs.image_name }}" |
46 | 54 | IFS=',' read -ra ELEMENTS <<< "$TAGS" |
47 | 55 | TAGS_FIXED="" |
48 | 56 | for ELEMENT in "${ELEMENTS[@]}"; do |
49 | | - TAGS_FIXED+="$REGISTRY:$ELEMENT," |
| 57 | + TAGS_FIXED+="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$ELEMENT," |
50 | 58 | done |
51 | 59 | TAGS_FIXED=${TAGS_FIXED%,} |
52 | 60 | echo "tags_fixed=$TAGS_FIXED" >> $GITHUB_ENV |
53 | 61 |
|
54 | 62 | - name: Checkout |
55 | | - uses: actions/checkout@v2 |
| 63 | + uses: actions/checkout@v4 |
56 | 64 |
|
57 | 65 | - name: Set up QEMU |
58 | 66 | uses: docker/setup-qemu-action@v3 |
59 | 67 |
|
60 | 68 | - name: Set up Docker Buildx |
61 | 69 | uses: docker/setup-buildx-action@v3 |
62 | 70 |
|
63 | | - - name: Login to Docker Hub |
| 71 | + - name: Log in to Docker Hub |
64 | 72 | uses: docker/login-action@v3 |
65 | 73 | with: |
66 | 74 | username: ${{ secrets.dockerhub_username }} |
67 | 75 | password: ${{ secrets.dockerhub_password }} |
68 | 76 |
|
69 | | - - name: Build and Push |
70 | | - uses: docker/build-push-action@v5 |
| 77 | + # Buildx will push: |
| 78 | + # - Image (your tags) |
| 79 | + # - SBOM as an OCI referrer (sbom: true) |
| 80 | + # - SLSA provenance as an OCI referrer (provenance: true) |
| 81 | + - name: Build & Push (with SBOM & provenance) |
| 82 | + id: build |
| 83 | + uses: docker/build-push-action@v6 |
71 | 84 | with: |
72 | 85 | file: ${{ inputs.dockerfile }} |
73 | 86 | context: ${{ inputs.context }} |
74 | 87 | push: true |
75 | 88 | tags: ${{ env.tags_fixed }} |
76 | | - build-args: ${{ inputs.build-args }} |
| 89 | + # Input name has a hyphen → use index notation |
| 90 | + build-args: ${{ inputs['build-args'] }} |
| 91 | + sbom: true |
| 92 | + provenance: true # or 'provenance: mode=max' if you prefer |
| 93 | + |
| 94 | + - name: Install Cosign |
| 95 | + uses: sigstore/cosign-installer@v3 |
| 96 | + |
| 97 | + - name: Cosign sign image by digest (keyless OIDC) |
| 98 | + env: |
| 99 | + IMAGE_REF: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} |
| 100 | + DIGEST: ${{ steps.build.outputs.digest }} |
| 101 | + run: | |
| 102 | + set -euo pipefail |
| 103 | + echo "Signing $IMAGE_REF@$DIGEST" |
| 104 | + cosign sign --yes "$IMAGE_REF@$DIGEST" |
0 commit comments