adding image-tag output for use in additional jobs (#26)

This commit is contained in:
Bret Fisher
2023-04-13 03:47:58 -04:00
committed by GitHub
parent 16d24ad29a
commit c75484b7e3
4 changed files with 46 additions and 91 deletions

2
.github/linters/actionlint.yaml vendored Normal file
View File

@@ -0,0 +1,2 @@
config-variables:
- SLACK_CHANNEL_ID

View File

@@ -1,61 +0,0 @@
---
# THIS IS NOT A TEMPLATE.
# This is just for testing the repo itself.
# This calls the reusable workflow from its local file path.
name: Docker Build with Promotion
on:
push:
branches:
- main
paths-ignore:
- 'README.md'
- '.github/linters/**'
pull_request:
paths-ignore:
- 'README.md'
- '.github/linters/**'
# cancel any previously-started, yet still active runs of this workflow on the same branch
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
permissions:
contents: read
packages: write
pull-requests: write
jobs:
# run this job on every push to a PR
# it will push images to GHCR, but not DockerHub
docker-build-pr:
name: Call Build on PR
if: github.event_name == 'pull_request'
uses: ./.github/workflows/reusable-docker-build.yaml
with:
dockerhub-enable: false
ghcr-enable: true
push: true
image-names: |
ghcr.io/${{ github.repository }}
# run this job on every push to the default branch (including merges and tags)
# it will push images to GHCR and DockerHub
# tags will also include ones like `stable-<date>-<sha>` and `latest`
docker-build-merge:
name: Call Build on Push
# this if is filtered to only the main branch push event (see events at top)
if: github.event_name == 'push'
uses: ./.github/workflows/reusable-docker-build.yaml
secrets:
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
dockerhub-enable: true
ghcr-enable: true
push: true
image-names: |
docker.io/${{ github.repository }}
ghcr.io/${{ github.repository }}

View File

@@ -92,7 +92,6 @@ on:
description: Build stage to target description: Build stage to target
required: false required: false
type: string type: string
secrets: secrets:
dockerhub-username: dockerhub-username:
@@ -103,10 +102,9 @@ on:
required: false required: false
outputs: outputs:
ghcr-tag: image-tag:
description: "single-use tag for ghcr.io" description: "single-use image tag for GHA runs"
value: ${{ jobs.build-image.outputs.ghcr-tag }} value: ${{ jobs.build-image.outputs.image-tag }}
# permissions: GITHUB_TOKEN are better set by the **calling** workflow # permissions: GITHUB_TOKEN are better set by the **calling** workflow
# but we'll set defaults here for reference # but we'll set defaults here for reference
@@ -126,36 +124,36 @@ jobs:
outputs: outputs:
# only outputs the unique gha- image tag that's unique to each GHA run # only outputs the unique gha- image tag that's unique to each GHA run
ghcr-tag: ${{ steps.ghcr-tag.outputs.tag }} image-tag: ${{ steps.image-tag.outputs.image-tag }}
steps: steps:
-
# we need qemu and buildx so we can build multiple platforms later # we need qemu and buildx so we can build multiple platforms later
name: Set up QEMU - name: Set up QEMU
id: qemu id: qemu
uses: docker/setup-qemu-action@v2.1.0 uses: docker/setup-qemu-action@v2.1.0
-
# BuildKit (used with `docker buildx`) is the best way to build images # BuildKit (used with `docker buildx`) is the best way to build images
name: Set up Docker Buildx - name: Set up Docker Buildx
id: buildx id: buildx
uses: docker/setup-buildx-action@v2.5.0 uses: docker/setup-buildx-action@v2.5.0
-
name: Login to DockerHub - name: Login to DockerHub
if: inputs.dockerhub-enable if: inputs.dockerhub-enable
uses: docker/login-action@v2.1.0 uses: docker/login-action@v2.1.0
with: with:
username: ${{ secrets.dockerhub-username }} username: ${{ secrets.dockerhub-username }}
password: ${{ secrets.dockerhub-token }} password: ${{ secrets.dockerhub-token }}
-
name: Login to GHCR - name: Login to GHCR
if: inputs.ghcr-enable if: inputs.ghcr-enable
uses: docker/login-action@v2.1.0 uses: docker/login-action@v2.1.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
-
name: Docker meta - name: Docker meta
id: docker_meta id: docker_meta
uses: docker/metadata-action@v4.3.0 uses: docker/metadata-action@v4.3.0
with: with:
@@ -163,12 +161,12 @@ jobs:
images: ${{ inputs.image-names }} images: ${{ inputs.image-names }}
flavor: ${{ inputs.flavor-rules }} flavor: ${{ inputs.flavor-rules }}
tags: ${{ inputs.tag-rules }} tags: ${{ inputs.tag-rules }}
-
# this will build the images, once per platform, # this will build the images, once per platform,
# then push to one or more registries (based on image list above in docker_meta) # then push to one or more registries (based on image list above in docker_meta)
# NOTE: this will not push if a PR is from a fork, where secrets are not available # NOTE: this will not push if a PR is from a fork, where secrets are not available
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ # https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
name: Docker Build and Push - name: Docker Build and Push
id: build_image id: build_image
uses: docker/build-push-action@v4.0.0 uses: docker/build-push-action@v4.0.0
with: with:
@@ -189,10 +187,10 @@ jobs:
# https://docs.docker.com/build/attestations/attestation-storage/ # https://docs.docker.com/build/attestations/attestation-storage/
provenance: true provenance: true
sbom: true sbom: true
-
# If PR, put image tags in the PR comments # If PR, put image tags in the PR comments
# from https://github.com/marketplace/actions/create-or-update-comment # from https://github.com/marketplace/actions/create-or-update-comment
name: Find comment for image tags - name: Find comment for image tags
uses: peter-evans/find-comment@v2.3.0 uses: peter-evans/find-comment@v2.3.0
if: github.event_name == 'pull_request' && inputs.comment-enable if: github.event_name == 'pull_request' && inputs.comment-enable
id: fc id: fc
@@ -220,8 +218,13 @@ jobs:
``` ```
edit-mode: replace edit-mode: replace
- name: Find the gha-run-based image tag we just pushed to ghcr.io # for dependent jobs, we need to output the unique tag for this GHA run
id: ghcr-tag # based on the docker_meta tag priority rules, the highest priority tag
# will be sent to this output
# this step output is sent to job output, which is sent to workflow output
# use this tag in another job with needs.<job-name>.outputs.image-tag
- name: Find the primary image tag we just pushed, and output it
id: image-tag
run: | run: |
# shellcheck disable=SC2086 # shellcheck disable=SC2086
echo "tag=gha-${{ github.run_id }}" >> $GITHUB_OUTPUT echo "image-tag=${{ steps.docker_meta.outputs.version }}" >> $GITHUB_OUTPUT

View File

@@ -1,11 +1,11 @@
# Template Repo: Docker Build and Push GitHub Actions Workflow # Template: Docker Build and Push GitHub Actions Workflow
[![Lint Code Base](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml/badge.svg)](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml) [![Lint Code Base](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml/badge.svg)](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml)
[![Docker Build](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-local-docker-build.yaml/badge.svg)](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-local-docker-build.yaml) [![Docker Build](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-local-docker-build.yaml/badge.svg)](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-local-docker-build.yaml)
A Reusable Workflow of the Docker GitHub Actions steps. Enhanced with learnings from production use. A Reusable Workflow of the Docker GitHub Actions steps. Enhanced with learnings from production use.
> ⚠️ **DO NOT call this workflow directly**, rather, use it as a template repo and fork it for your own reusable workflow. I might change this workflow at anytime, based on new GHA features or learnings, and your calling workflow might break. ⚠️ > ⚠️ **DO NOT call this workflow directly**, rather, use it as a template repository and fork it for your own reusable workflow. I might change this workflow at anytime, based on new GHA features or learnings, and your calling workflow might break. ⚠️
## Reasons to use this workflow ## Reasons to use this workflow
@@ -13,29 +13,40 @@ A Reusable Workflow of the Docker GitHub Actions steps. Enhanced with learnings
2. Provides inline docs based on real-world usage of this workflow. 2. Provides inline docs based on real-world usage of this workflow.
3. Gives you inputs so you can reuse this workflow across many repositories and only needing the full workflow stored in a central repository. 3. Gives you inputs so you can reuse this workflow across many repositories and only needing the full workflow stored in a central repository.
4. New in 2023: Adds [SBOM and Provenance](https://docs.docker.com/build/attestations/) metadata to your images. 4. New in 2023: Adds [SBOM and Provenance](https://docs.docker.com/build/attestations/) metadata to your images.
5. New in 2023: [Example template](./templates/call-docker-build-promote.yaml) to use the reusable workflow twice, in a "image promotion" style of dual registries (one for devs and PRs, one for production after PR merges) 5. New in 2023: [Example template](./templates/call-docker-build-promote.yaml) to use the reusable workflow twice, in an "image promotion" style of dual registries (one for devs and PRs, one for production after PR merges)
## Steps to adopt this workflow ## Steps to adopt this workflow
1. Fork this repository and tweak the reusable workflow to your liking: [.github/workflows/reusable-docker-build.yaml](.github/workflows/reusable-docker-build.yaml) 1. Fork this repository and tweak the reusable workflow to your liking: [.github/workflows/reusable-docker-build.yaml](.github/workflows/reusable-docker-build.yaml)
2. Copy my "calling" workflow [`templates/call-docker-build.yaml`](templates/call-docker-build.yaml) to all the repos you want to build images in, and change it to point to the forked workflow above. 2. Copy my "calling" workflow [`templates/call-docker-build.yaml`](templates/call-docker-build.yaml) to all the repositories you want to build images in and change it to point to the forked workflow above.
## "But what does this workflow really do beyond just `docker build`?" ## "But what does this workflow really do beyond just `docker build`?"
1. Clone the repository 1. Clone the repository
2. Setup QEMU for multi-platform building (buildx) via docker/setup-qemu-action 2. Setup QEMU for multi-platform building (via buildx) via docker/setup-qemu-action
3. Setup buildx for awesome and fast building via docker/setup-buildx-action 3. Setup buildx for awesome and fast building via docker/setup-buildx-action
4. Log into Docker Hub and/or GHCR 4. Log into Docker Hub and/or GHCR
5. Add labels and tags via docker/metadata-action 5. Add labels and tags via docker/metadata-action
6. Build and push image via docker/build-push-action with GitHub-based layer caching 6. Build and push image via docker/build-push-action with GitHub-based layer caching
7. Reports tags and labels in the PR comments 7. Reports tags and labels in the PR comments
## This repository is part of my example DevOps repos on GitHub Actions ## What other ways can I use this workflow?
I have a more advanced example of using this reusable workflow to do a "promotion" style workflow of:
1. On PR creation, build and push to a "dev" registry (GHCR)
2. On PR merge, build and push to a "prod" registry (Docker Hub)
3. Create a GitOps YAML update PR to update image tags
4. Notify of GitOps PR creation in Slack
I've added that example to my [github-actions-templates](https://github.com/BretFisher/github-actions-templates) repository. It calls the reusable `reusable-docker-build.yaml` file in this repository.
## This repository is part of my example DevOps repositories on GitHub Actions
- [bretfisher/github-actions-templates](https://github.com/BretFisher/github-actions-templates) - Main reusable templates repository - [bretfisher/github-actions-templates](https://github.com/BretFisher/github-actions-templates) - Main reusable templates repository
- [bretfisher/super-linter-workflow](https://github.com/BretFisher/super-linter-workflow) - Reusable linter workflow - [bretfisher/super-linter-workflow](https://github.com/BretFisher/super-linter-workflow) - Reusable linter workflow
- (you are here) [bretfisher/docker-build-workflow](https://github.com/BretFisher/docker-build-workflow)- Reusable docker build workflow - (you are here) [bretfisher/docker-build-workflow](https://github.com/BretFisher/docker-build-workflow)- Reusable docker build workflow
- [bretfisher/docker-ci-automation](https://github.com/BretFisher/docker-ci-automation) - Step by step video and example of a Docker CI workflow - [bretfisher/docker-ci-automation](https://github.com/BretFisher/docker-ci-automation) - Step-by-step video and example of a Docker CI workflow
- [My full list of container examples and tools](https://github.com/bretfisher) - [My full list of container examples and tools](https://github.com/bretfisher)
## More reading ## More reading