Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build multi-arch image including Windows #5

Merged
merged 4 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
name: Test & Build multi-arch Docker Image

on:
push:
branches: [ main ]
pull_request:

env:
IMAGE_REPOSITORY: testcontainers/helloworld

jobs:
test-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go version

- name: go-mod verify
run: go mod verify

- name: go-mod tidy
run: go mod tidy

- name: go-build
env:
GOOS: linux
run: go build

- name: go-test
run: go test -v ./...

test-windows:
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go version

- name: go-mod verify
run: go mod verify

- name: go-mod tidy
run: go mod tidy

- name: go-build
env:
GOOS: windows
run: go build

# TODO enable tests on Windows
# Currently doesn't succeed, see https://github.com/testcontainers/testcontainers-go/issues/948
# - name: go-test
# run: go test -v ./...

build-image-linux:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go version

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@a64d0487d7069df33b279515d35d60fa80e2ea62
with:
images: ${{ env.IMAGE_REPOSITORY }}
tags: |
type=sha,format=long
flavor: |
suffix=-linux

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2

- name: Docker info
run: docker info
- name: Buildx inspect
run: docker buildx inspect

- name: Build and push image
uses: docker/build-push-action@v6
with:
context: .
file: linux/Dockerfile
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v6
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

build-image-windows:
strategy:
matrix:
os-version:
- ltsc2019
- ltsc2022
runs-on: windows-2022
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@a64d0487d7069df33b279515d35d60fa80e2ea62
with:
images: ${{ env.IMAGE_REPOSITORY }}
tags: |
type=sha,format=long
flavor: |
suffix=-windows.${{ matrix.os-version }}

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Docker info
run: docker info

- name: Build image
run: |
docker build -f windows/Dockerfile --build-arg BASE_IMAGE=mcr.microsoft.com/windows/nanoserver:${{ matrix.os-version }} -t ${{ steps.meta.outputs.tags }} .

- name: Push image
run: |
docker push ${{ steps.meta.outputs.tags }}

publish-multi-arch-image:
needs:
- test-linux
- test-windows
- build-image-linux
- build-image-windows
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@a64d0487d7069df33b279515d35d60fa80e2ea62
with:
images: ${{ env.IMAGE_REPOSITORY }}
tags: |
type=sha,format=long

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v2

- name: Docker info
run: docker info
- name: Buildx inspect
run: docker buildx inspect

- name: Get os version for nanoserver:ltsc2019
run: >-
full_version=$(docker manifest inspect mcr.microsoft.com/windows/nanoserver:ltsc2019 | jq -r '.manifests[]|.platform|."os.version"'| sed 's@.*:@@') || true;
echo "OS_VERSION_ltsc2019=${full_version}" >> $GITHUB_ENV;

- name: Get os version for nanoserver:ltsc2022
run: >-
full_version=$(docker manifest inspect mcr.microsoft.com/windows/nanoserver:ltsc2022 | jq -r '.manifests[]|.platform|."os.version"'| sed 's@.*:@@') || true;
echo "OS_VERSION_ltsc2022=${full_version}" >> $GITHUB_ENV;

- name: Docker Manifest
run: >-
target_image=${{ steps.meta.outputs.tags }};
linux_manifest=$(docker manifest inspect ${target_image}-linux);
linux_digests=$(docker manifest inspect ${target_image}-linux | jq -r '.manifests[].digest');
manifest_list=${linux_digests//sha256:/${target_image%%:*}@sha256:};
manifest_list+=" ${target_image}-windows.ltsc2019";
manifest_list+=" ${target_image}-windows.ltsc2022";
docker manifest create ${target_image} ${manifest_list};
docker manifest annotate \
--os-version ${OS_VERSION_ltsc2019} \
--os windows \
--arch amd64 \
${target_image} "${target_image}-windows.ltsc2019";
docker manifest annotate \
--os-version ${OS_VERSION_ltsc2022} \
--os windows \
--arch amd64 \
${target_image} "${target_image}-windows.ltsc2022";
docker manifest push ${target_image};

check-published-image:
runs-on: ubuntu-latest
needs:
- publish-multi-arch-image
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@a64d0487d7069df33b279515d35d60fa80e2ea62
with:
images: ${{ env.IMAGE_REPOSITORY }}
tags: |
type=sha,format=long

- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Print multi-arch manifest
run: |
docker manifest inspect --verbose ${{ steps.meta.outputs.tags }} > manifest_complete.json
cat manifest_complete.json | jq ".[].Descriptor.platform" | jq "(.architecture + \"_\" + .os + \"_\") + .\"os.version\"" | sort | uniq > architectures_actual.txt

- name: Check multi-arch manifest
run: |
cat architectures_actual.txt
cat supported-architectures.txt | sort | uniq > architectures_expected.txt
# we're counting the entries only, because windows os.version numbers change too frequently
# exclude manifest entries with "unknown" architectures
diff <(echo "$(cat architectures_expected.txt | wc -l)") <(echo "$(cat architectures_actual.txt | grep -v unknown_unknown_ | wc -l)")

build:
runs-on: ubuntu-latest
needs:
- test-linux
- test-windows
steps:
- name: Finish
run: |
echo "All tests passed"
24 changes: 0 additions & 24 deletions .github/workflows/docker-build.yml

This file was deleted.

Loading