zmk-docker/.github/workflows/containers.yml
innovaker 7b71139613 feat: add guards for absent registry credentials
The original design assumed that every user would configure login credentials with appropriate write permissions for the Docker Hub repository.  Consequently, forks or pull requests fail on the first step.

This change allows the build to complete without login credentials.  It skips pushing the cache or pushing the candidate image.

The release (docker tag) step still requires login credentials and fails if they are absent.  This guarantees that git tagging is only possible once all images have been pushed out to all container registries.

PR: #24
2021-05-17 19:19:23 +01:00

148 lines
7.2 KiB
YAML

name: Containers
env:
zephyr-version: 2.4.0
zephyr-sdk-version: 0.11.4
cache-repository-name: zmk-docker-cache
on:
push:
pull_request:
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest
strategy:
max-parallel: 1 # takes advantage of caching between types
matrix:
architecture:
- arm
target: # ordered from biggest to smallest to take advantage of the registry cache
- dev
- build
steps:
- name: Check for GitHub Container Registry credentials (secrets)
id: ghcr-credentials
run: if [ ${{ secrets.GHCR_USERNAME == null || secrets.GHCR_TOKEN == null }} = true ]; then exit 1; fi
continue-on-error: true
- name: Login to GitHub Container Registry
id: ghcr-login
if: ${{ steps.ghcr-credentials.outcome == 'success' }}
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USERNAME }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Check for Docker Hub credentials (secrets)
id: docker-hub-credentials
run: if [ ${{ secrets.DOCKER_HUB_USERNAME == null || secrets.DOCKER_HUB_TOKEN == null }} = true ]; then exit 1; fi
continue-on-error: true
- name: Login to Docker Hub
id: docker-hub-login
if: ${{ steps.docker-hub-credentials.outcome == 'success' }}
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Prepare variables
id: vars
env:
DOCKER_HUB_NAMESPACE: ${{ secrets.DOCKER_HUB_NAMESPACE || github.repository_owner }}
run: |
echo ::set-output name=docker-hub-namespace::${DOCKER_HUB_NAMESPACE}
NAME=zmk-${{ matrix.target }}-${{ matrix.architecture }}
echo ::set-output name=name::${NAME}
CANDIDATE_TAG=${NAME}:${{ github.sha }}
echo ::set-output name=candidate-tag::${CANDIDATE_TAG}
VERSIONS_TAG=${NAME}:${{ env.zephyr-version }}-${{ env.zephyr-sdk-version }}
echo ::set-output name=versions-tag::${VERSIONS_TAG}
MAJOR=$(echo ${{ env.zephyr-version }} | cut -d'.' -f 1)
MINOR=$(echo ${{ env.zephyr-version }} | cut -d'.' -f 2)
MAJOR_MINOR=${MAJOR}.${MINOR}
echo ::set-output name=major-minor::${MAJOR_MINOR}
LATEST_TAG=${NAME}:${MAJOR_MINOR}
echo ::set-output name=latest-tag::${LATEST_TAG}
TAG_TRIGGER_REF=refs/tags/${{ env.zephyr-version }}-${{ env.zephyr-sdk-version }}
echo ::set-output name=tag-trigger-ref::${TAG_TRIGGER_REF}
- name: Set up QEMU
if: ${{ !startsWith(github.ref, 'refs/tags') }}
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
if: ${{ !startsWith(github.ref, 'refs/tags') }}
uses: docker/setup-buildx-action@v1
- name: Build and push (candidate)
id: build-push
if: ${{ !startsWith(github.ref, 'refs/tags') }}
uses: docker/build-push-action@v2
with:
target: ${{ matrix.target }}
build-args: |
ZEPHYR_VERSION=${{ env.zephyr-version }}
ARCHITECTURE=${{ matrix.architecture }}
ZEPHYR_SDK_VERSION=${{ env.zephyr-sdk-version }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
tags: |
docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }}
cache-from: type=registry,ref=docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ env.cache-repository-name }}:dev
cache-to: ${{ (steps.docker-hub-login.outcome == 'success') && format('type=registry,ref=docker.io/{0}/{1}:{2},mode=max', steps.vars.outputs.docker-hub-namespace, env.cache-repository-name, matrix.target) || null }}
push: ${{ steps.docker-hub-login.outcome == 'success' }}
- name: Image digest
if: ${{ !startsWith(github.ref, 'refs/tags') }}
run: echo ${{ steps.build-push.outputs.digest }}
- name: Release (pull candidate, tag, push)
if: ${{ github.ref == steps.vars.outputs.tag-trigger-ref }}
run: |
if [ "${{ steps.docker-hub-login.outcome }}" != "success" ]; then
echo "Docker Hub must be authenticated to perform a release!"
exit 1
fi
if [ "${{ steps.ghcr-login.outcome }}" != "success" ]; then
echo "GitHub Container Registry must be authenticated to perform a release!"
exit 1
fi
docker pull docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }}
docker tag docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }} docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.versions-tag }}
docker tag docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }} docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.latest-tag }}
docker tag docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.candidate-tag }}
docker tag docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.versions-tag }}
docker tag docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.latest-tag }}
docker push docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.candidate-tag }}
docker push docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.versions-tag }}
docker push docker.io/${{ steps.vars.outputs.docker-hub-namespace }}/${{ steps.vars.outputs.latest-tag }}
docker push ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.candidate-tag }}
docker push ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.versions-tag }}
docker push ghcr.io/${{ github.repository_owner }}/${{ steps.vars.outputs.latest-tag }}
git:
runs-on: ubuntu-latest
needs: docker
if: ${{ startsWith(github.ref, 'refs/tags') }}
steps:
- name: Prepare variables
id: vars
run: |
MAJOR=$(echo ${{ env.zephyr-version }} | cut -d'.' -f 1)
MINOR=$(echo ${{ env.zephyr-version }} | cut -d'.' -f 2)
MAJOR_MINOR=${MAJOR}.${MINOR}
echo ::set-output name=major-minor::${MAJOR_MINOR}
TAG_TRIGGER_REF=refs/tags/${{ env.zephyr-version }}-${{ env.zephyr-sdk-version }}
echo ::set-output name=tag-trigger-ref::${TAG_TRIGGER_REF}
- name: Checkout
uses: actions/checkout@v2
if: ${{ github.ref == steps.vars.outputs.tag-trigger-ref }}
- name: Tag
if: ${{ github.ref == steps.vars.outputs.tag-trigger-ref }}
env:
TAG: ${{ steps.vars.outputs.major-minor }}
run: |
git tag ${TAG}
git push -f origin ${TAG}