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
|
name: Build Docker Image
on:
push:
branches: [ 'master' ]
tags: [ 'v*' ]
workflow_dispatch:
env:
REGISTRY: docker.io
IMAGE_NAME: tdiary/tdiary
jobs:
build:
strategy:
matrix:
include:
- runner: ubuntu-latest
platform: linux/amd64
arch: amd64
- runner: ubuntu-24.04-arm
platform: linux/arm64
arch: arm64
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
outputs:
image-digest-amd64: ${{ steps.build-amd64.outputs.digest }}
image-digest-arm64: ${{ steps.build-arm64.outputs.digest }}
metadata: ${{ steps.meta.outputs.json }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker-container
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
flavor: |
latest=false
- name: Build and push Docker image (AMD64)
id: build-amd64
if: matrix.arch == 'amd64'
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: ${{ matrix.platform }}
provenance: false
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true
- name: Build and push Docker image (ARM64)
id: build-arm64
if: matrix.arch == 'arm64'
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: ${{ matrix.platform }}
provenance: false
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true
merge:
runs-on: ubuntu-latest
needs: build
permissions:
contents: read
packages: write
steps:
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Create and push manifest
run: |
# Extract metadata from build job
METADATA='${{ needs.build.outputs.metadata }}'
echo "Metadata: $METADATA"
TAGS=$(echo "$METADATA" | jq -r '.tags[]')
echo "Generated tags:"
echo "$TAGS"
if [ -z "$TAGS" ]; then
echo "No tags generated, exiting"
exit 1
fi
# Get digests from build outputs
AMD64_DIGEST="${{ needs.build.outputs.image-digest-amd64 }}"
ARM64_DIGEST="${{ needs.build.outputs.image-digest-arm64 }}"
echo "AMD64 Digest: $AMD64_DIGEST"
echo "ARM64 Digest: $ARM64_DIGEST"
# Create and push manifest for each tag
for tag in $TAGS; do
echo "Creating manifest for $tag"
docker manifest create $tag \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$AMD64_DIGEST \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$ARM64_DIGEST
docker manifest annotate $tag \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$AMD64_DIGEST \
--os linux --arch amd64
docker manifest annotate $tag \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@$ARM64_DIGEST \
--os linux --arch arm64
docker manifest push $tag
done
- name: Test Docker image
run: |
# Extract metadata from build job
METADATA='${{ needs.build.outputs.metadata }}'
TAGS=$(echo "$METADATA" | jq -r '.tags[]')
echo "Created tags:"
for tag in $TAGS; do
echo " - $tag"
if docker manifest inspect $tag >/dev/null 2>&1; then
echo " ✓ Multi-arch manifest verified"
docker manifest inspect $tag | jq -r '.manifests[].platform | "\(.architecture)/\(.os)"' | sed 's/^/ /'
else
echo " ✗ Manifest verification failed"
fi
done
|