Updates for allhands (#3)

This commit is contained in:
Bret Fisher
2022-05-02 15:40:42 -04:00
committed by GitHub
parent 4678180549
commit 1820843fc8
10 changed files with 511 additions and 163 deletions

View File

@@ -1,3 +1,11 @@
# README: https://github.com/hadolint/hadolint
# Often it's a good idea to do inline disables rather that repo-wide in this file.
# Example of inline Dockerfile rules:
# hadolint ignore=DL3018
#RUN apk add --no-cache git
# or just ignore rules repo-wide
ignored: ignored:
- DL3003 #ignore that we use cd sometimes - DL3003 #ignore that we use cd sometimes
- DL3006 #image pin versions - DL3006 #image pin versions
@@ -7,4 +15,28 @@ ignored:
- DL3028 #gem install pin versions - DL3028 #gem install pin versions
- DL3059 #multiple consecutive runs - DL3059 #multiple consecutive runs
- DL4006 #we don't need pipefail in this - DL4006 #we don't need pipefail in this
- SC2016 #we want single quotes sometimes - SC2016 #we want single quotes sometimes
# FULL TEMPLATE
# failure-threshold: string # name of threshold level (error | warning | info | style | ignore | none)
# format: string # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy)
# ignored: [string] # list of rules
# label-schema: # See Linting Labels below for specific label-schema details
# author: string # Your name
# contact: string # email address
# created: timestamp # rfc3339 datetime
# version: string # semver
# documentation: string # url
# git-revision: string # hash
# license: string # spdx
# no-color: boolean # true | false
# no-fail: boolean # true | false
# override:
# error: [string] # list of rules
# warning: [string] # list of rules
# info: [string] # list of rules
# style: [string] # list of rules
# strict-labels: boolean # true | false
# disable-ignore-pragma: boolean # true | false
# trustedRegistries: string | [string] # registry or list of registries

View File

@@ -1,7 +1,9 @@
# MD013/line-length - Line length # MD013/line-length - Line length
MD013: MD013:
# Number of characters # Number of characters, default is 80
line_length: 150 # I'm OK with long lines. All editors now have wordwrap
line_length: 9999
# Number of characters for headings # Number of characters for headings
heading_line_length: 100 heading_line_length: 100
code_blocks: false # check code blocks?
code_blocks: false

53
.github/linters/.yaml-lint.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
---
###########################################
# These are the rules used for #
# linting all the yaml files in the stack #
# NOTE: #
# You can disable line with: #
# # yamllint disable-line #
###########################################
rules:
braces:
level: warning
min-spaces-inside: 0
max-spaces-inside: 0
min-spaces-inside-empty: 1
max-spaces-inside-empty: 5
brackets:
level: warning
min-spaces-inside: 0
max-spaces-inside: 0
min-spaces-inside-empty: 1
max-spaces-inside-empty: 5
colons:
level: warning
max-spaces-before: 0
max-spaces-after: 1
commas:
level: warning
max-spaces-before: 0
min-spaces-after: 1
max-spaces-after: 1
comments: disable
comments-indentation: disable
document-end: disable
document-start: disable
empty-lines:
level: warning
max: 2
max-start: 0
max-end: 0
hyphens:
level: warning
max-spaces-after: 1
indentation:
level: warning
spaces: consistent
indent-sequences: true
check-multi-line-strings: false
key-duplicates: enable
line-length: disable
new-line-at-end-of-file: disable
new-lines:
type: unix
trailing-spaces: disable

View File

@@ -0,0 +1,82 @@
---
# THIS IS NOT A TEMPLATE.
# This is just for linting the gha-workflows repo itself.
# We call the reusable workflow from its file path.
name: Docker Build
on:
push:
branches:
- main
# don't rebuild image if someone only edited unrelated files
paths-ignore:
- 'README.md'
- '.github/linters/**'
pull_request:
# don't rebuild image if someone only edited unrelated files
paths-ignore:
- 'README.md'
- '.github/linters/**'
jobs:
call-docker-build:
name: Call Docker Build
uses: ./.github/workflows/reusable-docker-build.yaml
permissions:
contents: read
packages: write # needed to push docker image to ghcr.io
pull-requests: write # needed to create and update comments in PRs
secrets:
# Only needed if with:dockerhub-enable is true below
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
# Only needed if with:dockerhub-enable is true below
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
### REQUIRED
### ENABLE ONE OR BOTH REGISTRIES
### tell docker where to push.
### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below
dockerhub-enable: true
ghcr-enable: true
### REQUIRED
### A list of the account/repo names for docker build. List should match what's enabled above
### defaults to:
image-names: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
### REQUIRED set rules for tagging images, based on special action syntax:
### https://github.com/docker/metadata-action#tags-input
### defaults to:
tag-rules: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=pr
type=ref,event=branch
type=semver,pattern={{version}}
### path to where docker should copy files into image
### defaults to root of repository (.)
# context: .
### Dockerfile alternate name. Default is Dockerfile (relative to context path)
# file: Containerfile
### build stage to target, defaults to empty, which builds to last stage in Dockerfile
# target:
### platforms to build for, defaults to linux/amd64
### other options: linux/amd64,linux/arm64,linux/arm/v7
# platforms: linux/amd64
### Create a PR comment with image tags and labels
### defaults to false
# comment-enable: false

View File

@@ -1,4 +1,5 @@
--- ---
# template source: https://github.com/bretfisher/super-linter-workflow/blob/main/templates/call-super-linter.yaml
name: Lint Code Base name: Lint Code Base
on: on:
@@ -12,21 +13,25 @@ jobs:
call-super-linter: call-super-linter:
name: Call Super-Linter name: Call Super-Linter
# use Reusable Workflows to call my linter config remotely
# https://docs.github.com/en/actions/learn-github-actions/reusing-workflows
permissions: permissions:
contents: read # clone the repo to lint contents: read # clone the repo to lint
statuses: write #read/write to repo custom statuses statuses: write #read/write to repo custom statuses
#FIXME: customize uri to point to your forked linter repository ### use Reusable Workflows to call my workflow remotely
uses: bretfisher/super-linter-workflow/.github/workflows/super-linter.yaml@main ### https://docs.github.com/en/actions/learn-github-actions/reusing-workflows
### you can also call workflows from inside the same repo via file path
#FIXME: customize uri to point to your own linter repository
uses: bretfisher/super-linter-workflow/.github/workflows/reusable-super-linter.yaml@main
# Optional settings examples ### Optional settings examples
# with: # with:
### For a DevOps-focused repository. Prevents some code-language linters from running
### defaults to false
# devops-only: false # devops-only: false
### A regex to exclude files from linting
### defaults to empty
# filter-regex-exclude: html/.* # filter-regex-exclude: html/.*

View File

@@ -1,147 +0,0 @@
---
name: Docker Build and Push Image
on:
# we want pull requests so we can build(test) but not push to image registry
pull_request:
branches:
- 'main'
# only build when important files change
paths-ignore:
- 'README.md'
- '.github/workflows/linter.yml'
- '.github/linters/**'
push:
branches:
- 'main'
# only build when important files change
paths-ignore:
- 'README.md'
- '.github/workflows/linter.yml'
- '.github/linters/**'
schedule:
# re-run monthly to keep image fresh with upstream base images
# NOTE: GH will stop cron jobs in a stale repo (60 days)
# https://docs.github.com/en/actions/managing-workflow-runs/disabling-and-enabling-a-workflow
- cron: '0 12 15 * *'
# run whenever we want!
# workflow_dispatch:
# REUSABLE WORKFLOW with INPUTS
# to keep this workflow simple, assumptions are made:
# - only able to push to Docker Hub and or GHCR
# - Image name is name of GitHub repo
# - Dockerfile is in root of repo, named 'Dockerfile'
# - Builds on PR with tag of `prNUMBER` (same tag each PR push)
# - Builds on push to main branch with tag of `latest`
# ???? what else
workflow_call:
# allow reuse of this workflow in other repos
inputs:
# TODO: allow dynamic docker hub and ghcr
dockerhub-enabled:
description: Push images to Docker Hub
type: boolean
ghcr-enabled:
dockerhub-username:
description: Docker Hub username
required: false
type: string
context:
description: Docker context (path) to start build from
required: false
type: string
default: .
target:
description: Build stage to target
required: false
type: string
platforms:
description: Platforms to build for
required: false
type: string
# common ones: linux/amd64,linux/arm64,linux/arm/v7
default: linux/amd64
# TODO: does this work in calling repos?
image-names:
description: A list of the account/repo names for docker build
required: false
type: string
# the default will tag it same as repo name (for hub.docker.com) and
# ghcr.io/
default: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
secrets:
dockerhub-token:
description: Docker Hub token
required: false
jobs:
build-and-push-image:
name: Build+Push
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
# we need qemu and buildx so we can build multiple platforms later
name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v1.2.0
-
# BuildKit (used with `docker buildx`) is the best way to build images
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
if: ${{ inputs.dockerhub-enabled }}
uses: docker/login-action@v1
with:
username: ${{ inputs.dockerhub-username }}
password: ${{ secrets.dockerhub-token }}
-
name: Login to GHCR
if: ${{ inputs.ghcr-enabled }}
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v3.8.0
with:
# list of Docker images to use as base name for tags
images: ${{ inputs.image-names }}
flavor: |
latest=false
tags: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=pr,prefix=pr
-
# this will build the images, once per platform,
# then push to both Docker Hub and GHCR
name: Docker Build and Push
id: docker_build_and_push
uses: docker/build-push-action@v2
with:
platforms: ${{ inputs.platforms }}
context: ${{ inputs.context }}
target: ${{ inputs.target }}
builder: ${{ steps.buildx.outputs.name }}
# it uses github cache API for faster builds:
# https://github.com/crazy-max/docker-build-push-action/blob/master/docs/advanced/cache.md#cache-backend-api
cache-from: type=gha
cache-to: type=gha,mode=max
# for an approved pull_request, only push pr-specific tags
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
-
name: Show image digest
run: echo ${{ steps.docker_build_and_push.outputs.digest }}

View File

@@ -0,0 +1,205 @@
---
name: Docker Build and Push
on:
# REUSABLE WORKFLOW with INPUTS
# to keep this workflow simple, assumptions are made:
# - only able to push to Docker Hub and/or GHCR (GHCR by default)
# - Builds on PR with tag of `prNUMBER` (same tag each PR push)
# - Builds on push to main branch with tag of `latest`
# - Builds on tag push with semver
workflow_call:
# allow reuse of this workflow in other repos
inputs:
dockerhub-enable:
description: Log into Docker Hub
required: false
default: false
type: boolean
ghcr-enable:
description: Log into GHCR
required: false
default: true
type: boolean
comment-enable:
description: Create a PR comment with image tags and labels
required: false
default: false
type: boolean
context:
description: Docker context (path) to start build from
required: false
type: string
default: .
file:
description: Dockerfile to build, relative to context path
required: false
type: string
target:
description: Build stage to target
required: false
type: string
platforms:
description: Platforms to build for
required: false
type: string
# common ones: linux/amd64,linux/arm64,linux/arm/v7
default: linux/amd64
# TODO: does this work in calling repos?
image-names:
description: A list of the account/repo names for docker build
required: true
type: string
tag-rules:
# https://github.com/marketplace/actions/docker-metadata-action#tags-input
description: Use docker-metadata action to create tags from a key-value pair list in CSV format
required: true
type: string
default: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=pr
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=gha-${{ github.run_id }}
flavor-rules:
# https://github.com/marketplace/actions/docker-metadata-action#flavor-input
description: Three rules to (optionally) set for tag-rules, latest, prefix, and suffix
required: false
type: string
default: |
latest=false
secrets:
dockerhub-username:
description: Docker Hub username
required: false
dockerhub-token:
description: Docker Hub token
required: false
outputs:
image-tags:
description: "all tags from docker build"
value: ${{ jobs.build-image.outputs.image-tags }}
ghcr-tag:
description: "single-use tag for ghcr.io"
value: ${{ jobs.build-image.outputs.ghcr-tag }}
# permissions: GITHUB_TOKEN are better set by the **calling** workflow
# but we'll set defaults here for reference
# https://docs.github.com/en/actions/using-workflows/reusing-workflows#supported-keywords-for-jobs-that-call-a-reusable-workflow
permissions:
contents: read
packages: write # needed to push docker image to ghcr.io
pull-requests: write # needed to create and update comments in PRs
jobs:
build-image:
name: Build+Push
runs-on: ubuntu-latest
outputs:
# all tags from docker build
image-tags: ${{ steps.docker_meta.outputs.tags }}
# only outputs the unique gha- image tag that's unique to each build
ghcr-tag: ${{ steps.ghcr-tag.outputs.tag }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
# we need qemu and buildx so we can build multiple platforms later
name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v1
-
# BuildKit (used with `docker buildx`) is the best way to build images
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
if: inputs.dockerhub-enable
uses: docker/login-action@v1
with:
username: ${{ secrets.dockerhub-username }}
password: ${{ secrets.dockerhub-token }}
-
name: Login to GHCR
if: inputs.ghcr-enable
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Docker meta
id: docker_meta
uses: docker/metadata-action@v3
with:
# list of Docker images to use as base name for tags
images: ${{ inputs.image-names }}
flavor: ${{ inputs.flavor-rules }}
tags: ${{ inputs.tag-rules }}
-
# this will build the images, once per platform,
# then push to one or more registries (based on image list above in docker_meta)
name: Docker Build and Push
id: build_image
uses: docker/build-push-action@v2
with:
platforms: ${{ inputs.platforms }}
context: ${{ inputs.context }}
file: ${{ inputs.file }}
target: ${{ inputs.target }}
builder: ${{ steps.buildx.outputs.name }}
# it uses github cache API for faster builds:
# https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#cache-backend-api
cache-from: type=gha
cache-to: type=gha,mode=max
push: true
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
-
# If PR, put image tags in the PR comments
# from https://github.com/marketplace/actions/create-or-update-comment
name: Find comment for image tags
uses: peter-evans/find-comment@v1
if: github.event_name == 'pull_request' && inputs.comment-enable
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Docker image tag(s) pushed
# If PR, put image tags in the PR comments
- name: Create or update comment for image tags
uses: peter-evans/create-or-update-comment@v1
if: github.event_name == 'pull_request' && inputs.comment-enable
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
Docker image tag(s) pushed:
```text
${{ steps.docker_meta.outputs.tags }}
```
Labels added to images:
```text
${{ steps.docker_meta.outputs.labels }}
```
edit-mode: replace
- name: Find the gha-run-based image tag we just pushed to ghcr.io
id: ghcr-tag
run: |
echo '::echo::on'
echo "::set-output name=tag::gha-${{ github.run_id }}"

12
Dockerfile Normal file
View File

@@ -0,0 +1,12 @@
# sample dockerfile for testing call-docker-build.yaml
FROM alpine:edge
RUN apk add --no-cache curl
WORKDIR /test
COPY . .
ENTRYPOINT ["curl"]
CMD ["--help"]

View File

@@ -6,14 +6,38 @@ A Reusable Workflow of the Docker GitHub Actions steps. Enhanced with learnings
1. Easier to start with than hand-building all the Docker Actions into a single workflow. 1. Easier to start with than hand-building all the Docker Actions into a single workflow.
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 3. Gives you inputs so you can reuse this workflow across many repositories and only needing the full workflow stored in a central repository.
and only needing the full workflow stored in a central repository.
## Basic workflow steps ## 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)
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.
## "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 (buildx) via docker/setup-qemu-action
3. Setup buildx (the best image builder) 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 6. Build and push image via docker/build-push-action with layer caching
7. Reports tags and labels in the PR comments
## This repository is part of my example repos on GitHub Actions
- [bretfisher/github-actions-templates](https://github.com/BretFisher/github-actions-templates) - Main repository
- [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
- [bretfisher/allhands22](https://github.com/BretFisher/github-actions-templates) - Step by step example of a Docker workflow
- [My full list of container examples and tools](https://github.com/bretfisher)
## More reading
- [Docker Build/Push Action advanced examples](https://github.com/docker/build-push-action/tree/master/docs/advanced)
- [My full list of container examples and tools](https://github.com/bretfisher)
## 🎉🎉🎉 Join my container DevOps community 🎉🎉🎉
- [My "Vital DevOps" Discord server](https://devops.fan)
- [My weekly YouTube Live show](https://bret.live)
- [My courses and coupons](https://www.bretfisher.com/courses)

View File

@@ -0,0 +1,80 @@
---
# template source: https://github.com/bretfisher/docker-build-workflow/blob/main/templates/call-docker-build.yaml
name: Docker Build
on:
push:
branches:
- main
# don't rebuild image if someone only edited unrelated files
paths-ignore:
- 'README.md'
- '.github/linters/**'
pull_request:
# don't rebuild image if someone only edited unrelated files
paths-ignore:
- 'README.md'
- '.github/linters/**'
jobs:
call-docker-build:
name: Call Docker Build
uses: bretfisher/docker-build-workflow/.github/workflows/reusable-docker-build.yaml@main
permissions:
contents: read
packages: write # needed to push docker image to ghcr.io
pull-requests: write # needed to create and update comments in PRs
secrets:
# Only needed if with:dockerhub-enable is true below
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
# Only needed if with:dockerhub-enable is true below
# https://hub.docker.com/settings/security
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
### REQUIRED
### ENABLE ONE OR BOTH REGISTRIES
### tell docker where to push.
### NOTE if Docker Hub is set to true, you must set secrets above and also add account/repo/tags below
dockerhub-enable: true
ghcr-enable: true
### REQUIRED
### A list of the account/repo names for docker build. List should match what's enabled above
### defaults to:
image-names: |
ghcr.io/${{ github.repository }}
### REQUIRED set rules for tagging images, based on special action syntax:
### https://github.com/docker/metadata-action#tags-input
### defaults to:
tag-rules: |
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=pr
type=ref,event=branch
type=semver,pattern={{version}}
### path to where docker should copy files into image
### defaults to root of repository (.)
# context: .
### Dockerfile alternate name. Default is Dockerfile (relative to context path)
# file: Containerfile
### build stage to target, defaults to empty, which builds to last stage in Dockerfile
# target:
### platforms to build for, defaults to linux/amd64
### other options: linux/amd64,linux/arm64,linux/arm/v7
# platforms: linux/amd64
### Create a PR comment with image tags and labels
### defaults to false
# comment-enable: false