adding image-tag output for use in additional jobs (#26)
This commit is contained in:
2
.github/linters/actionlint.yaml
vendored
Normal file
2
.github/linters/actionlint.yaml
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
config-variables:
|
||||||
|
- SLACK_CHANNEL_ID
|
||||||
@@ -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 }}
|
|
||||||
49
.github/workflows/reusable-docker-build.yaml
vendored
49
.github/workflows/reusable-docker-build.yaml
vendored
@@ -93,7 +93,6 @@ on:
|
|||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
dockerhub-username:
|
dockerhub-username:
|
||||||
description: Docker Hub username
|
description: Docker Hub 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
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -1,11 +1,11 @@
|
|||||||
# Template Repo: Docker Build and Push GitHub Actions Workflow
|
# Template: Docker Build and Push GitHub Actions Workflow
|
||||||
|
|
||||||
[](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml)
|
[](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-super-linter.yaml)
|
||||||
[](https://github.com/BretFisher/docker-build-workflow/actions/workflows/call-local-docker-build.yaml)
|
[](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
|
||||||
|
|||||||
Reference in New Issue
Block a user