Skip to content

Commit

Permalink
✨ Support building multi-platform images
Browse files Browse the repository at this point in the history
  • Loading branch information
elgohr committed Apr 1, 2021
1 parent f7aca2f commit 13c6c46
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ LABEL "maintainer"="Lars Gohr"

RUN apk update \
&& apk upgrade \
&& apk add --no-cache git
&& apk add --no-cache git sudo

ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Expand All @@ -14,6 +14,7 @@ RUN apk add --no-cache coreutils bats
ADD test.bats /test.bats
ADD mock.sh /usr/local/bin/docker
ADD mock.sh /usr/bin/date
ADD mock.sh /usr/bin/sudo
RUN /test.bats

FROM runtime
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@ with:
no_push: ${{ github.event_name == 'push' }}
```

### platforms
Use `platforms` when you want to build a multi-platform image (separated by comma).

```yaml
with:
name: myDocker/repository
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
platforms: linux/amd64,linux/arm64
```

### Tags

This action supports multiple options that tags are handled.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ inputs:
tags:
description: 'Use tags when you want to bring your own tags (separated by comma)'
required: false
platforms:
description: 'Use platforms to build multi-platform images (separated by comma)'
required: false
tag_names:
description: 'Use tag_names when you want to push tags/release by their git name'
required: false
Expand Down
16 changes: 15 additions & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ main() {
sanitize "${INPUT_PASSWORD}" "password"
fi

if uses "${INPUT_PLATFORMS}"; then
enableExperimentalDocker
fi

registryToLower
nameToLower

Expand Down Expand Up @@ -84,6 +88,11 @@ sanitize() {
fi
}

enableExperimentalDocker() {
echo $'{"experimental": true}' | sudo dd status=none of=/etc/docker/daemon.json
sudo service docker restart
}

registryToLower(){
INPUT_REGISTRY=$(echo "${INPUT_REGISTRY}" | tr '[A-Z]' '[a-z]')
}
Expand Down Expand Up @@ -190,7 +199,12 @@ build() {
for TAG in ${TAGS}; do
BUILD_TAGS="${BUILD_TAGS}-t ${INPUT_NAME}:${TAG} "
done
docker build ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} ${BUILD_TAGS} ${CONTEXT}
if uses "${INPUT_PLATFORMS}"; then
local PLATFORMS="--platform ${INPUT_PLATFORMS}"
docker buildx build ${PLATFORMS} ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} ${BUILD_TAGS} ${CONTEXT}
else
docker build ${INPUT_BUILDOPTIONS} ${BUILDPARAMS} ${BUILD_TAGS} ${CONTEXT}
fi
}

push() {
Expand Down
20 changes: 20 additions & 0 deletions test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ setup(){

declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
['sudo']=""
) > mockReturns

export GITHUB_REF='refs/heads/master'
Expand All @@ -20,6 +21,7 @@ teardown() {
unset INPUT_DOCKERFILE
unset INPUT_REGISTRY
unset INPUT_CACHE
unset INPUT_PLATFORMS
unset GITHUB_SHA
unset INPUT_PULL_REQUESTS
unset MOCK_ERROR_CONDITION
Expand Down Expand Up @@ -654,6 +656,24 @@ teardown() {
/usr/local/bin/docker logout"
}

@test "it supports building multiple platforms" {
export GITHUB_REF='refs/heads/main'
export INPUT_PLATFORMS='linux/amd64,linux/arm64'

run /entrypoint.sh

expectStdOutContains "::set-output name=tag::latest"

expectMockCalledContains "/usr/bin/sudo dd status=none of=/etc/docker/daemon.json
/usr/bin/sudo service docker restart
/usr/local/bin/docker login -u USERNAME --password-stdin
/usr/local/bin/docker buildx build --platform linux/amd64,linux/arm64 -t my/repository:latest .
/usr/local/bin/docker push my/repository:latest
/usr/local/bin/docker inspect --format={{index .RepoDigests 0}} my/repository:latest
/usr/local/bin/docker logout"
expectMockArgs '/usr/bin/sudo {"experimental": true}'
}

expectStdOutIs() {
local expected=$(echo "${1}" | tr -d '\n')
local got=$(echo "${output}" | tr -d '\n')
Expand Down

0 comments on commit 13c6c46

Please sign in to comment.