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: concurrency: ${{ github.workflow }} jobs: namespaces: runs-on: ubuntu-latest outputs: docker-hub: ${{ secrets.DOCKER_HUB_NAMESPACE || github.repository_owner }} ghcr: ${{ github.repository_owner }} steps: - run: true credentials: runs-on: ubuntu-latest outputs: ghcr: ${{ steps.ghcr.outcome == 'success' }} docker-hub: ${{ steps.docker-hub.outcome == 'success' }} steps: - name: Docker Hub id: docker-hub run: if [ ${{ secrets.DOCKER_HUB_USERNAME == null || secrets.DOCKER_HUB_TOKEN == null }} = true ]; then exit 1; fi continue-on-error: true - name: GitHub Container Registry id: ghcr run: if [ ${{ secrets.GHCR_USERNAME == null || secrets.GHCR_TOKEN == null }} = true ]; then exit 1; fi continue-on-error: true architectures: runs-on: ubuntu-latest outputs: json: ${{ steps.import.outputs.json }} steps: - name: Checkout uses: actions/checkout@v2 - name: Import from architectures.yml id: import shell: python run: | import yaml, json with open('architectures.yml', 'r') as file: architectures = yaml.safe_load(file) print('::set-output name=json::' + json.dumps(architectures)) docker: needs: - namespaces - credentials - architectures runs-on: ubuntu-latest strategy: max-parallel: 1 # takes advantage of caching between jobs matrix: architecture: ${{ fromJSON(needs.architectures.outputs.json) }} target: # ordered from biggest to smallest to take advantage of the registry cache - dev - build steps: - name: Login to Docker Hub id: docker-hub-login if: ${{ needs.credentials.outputs.docker-hub == 'true' }} uses: docker/login-action@v1 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Login to GitHub Container Registry id: ghcr-login if: ${{ needs.credentials.outputs.ghcr == 'true' }} uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ secrets.GHCR_USERNAME }} password: ${{ secrets.GHCR_TOKEN }} - name: Prepare variables id: vars run: | REPOSITORY_NAME=zmk-${{ matrix.target }}-${{ matrix.architecture }} echo ::set-output name=repository-name::${REPOSITORY_NAME} CANDIDATE_TAG=${{ github.sha }} echo ::set-output name=candidate-tag::${CANDIDATE_TAG} VERSIONS_TAG=${{ 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=${MAJOR_MINOR} echo ::set-output name=latest-tag::${LATEST_TAG} RELEASE_TRIGGER_TAG=${{ env.zephyr-version }}-${{ env.zephyr-sdk-version }} echo ::set-output name=release-trigger-tag::${RELEASE_TAG} - 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 }} org.opencontainers.image.revision=${{ github.sha }} tags: | docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} cache-from: type=registry,ref=docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ env.cache-repository-name }}:dev cache-to: ${{ (steps.docker-hub-login.outcome == 'success') && (matrix.target == 'dev') && format('type=registry,ref=docker.io/{0}/{1}:{2},mode=max', needs.namespaces.outputs.docker-hub, env.cache-repository-name, 'dev') || null }} push: ${{ steps.docker-hub-login.outcome == 'success' }} - name: Release (pull candidate, tag, push) if: ${{ github.ref == format('refs/tags/{0}', steps.vars.outputs.release-trigger-tag) }} 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/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker tag docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.versions-tag }} docker tag docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.latest-tag }} docker tag docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker tag docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.versions-tag }} docker tag docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.latest-tag }} docker push docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker push docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.versions-tag }} docker push docker.io/${{ needs.namespaces.outputs.docker-hub }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.latest-tag }} docker push ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.candidate-tag }} docker push ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.versions-tag }} docker push ghcr.io/${{ needs.namespaces.outputs.ghcr }}/${{ steps.vars.outputs.repository-name }}:${{ steps.vars.outputs.latest-tag }} git-tag: needs: - docker if: ${{ startsWith(github.ref, 'refs/tags') }} runs-on: ubuntu-latest 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} RELEASE_TRIGGER_TAG=${{ env.zephyr-version }}-${{ env.zephyr-sdk-version }} echo ::set-output name=release-trigger-tag::${RELEASE_TAG} - name: Checkout uses: actions/checkout@v2 if: ${{ github.ref == format('refs/tags/{0}', steps.vars.outputs.release-trigger-tag) }} - name: Tag if: ${{ github.ref == format('refs/tags/{0}', steps.vars.outputs.release-trigger-tag) }} env: TAG: ${{ steps.vars.outputs.major-minor }} run: | git tag ${TAG} git push -f origin ${TAG}