Skip to content

Docker Image CI

Docker Image CI #606

Workflow file for this run

name: Docker Image CI
on:
workflow_dispatch:
push:
branches:
- $default-branch
- development
- master
tags:
- "*.*.*-*"
# Run tests for any PRs
pull_request:
schedule:
- cron: "43 10 * * 4"
env:
IMAGE_NAME: calcardbackup
jobs:
codespell:
name: codespell
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Codespell
uses: codespell-project/actions-codespell@master
with:
ignore_words_list: ro,rw
skip: .git
check_filenames: true
check_hidden: true
super-linter:
name: super-linter
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# super-linter needs the full git history to get the
# list of files that changed across commits
fetch-depth: 0
- name: Lint Code Base
uses: super-linter/super-linter@v7
env:
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shiftleft:
name: shiftleft
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Perform ShiftLeft Scan
uses: ShiftLeftSecurity/scan-action@master
env:
WORKSPACE: ""
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SCAN_AUTO_BUILD: true
with:
output: reports
# Scan auto-detects the languages in your project. To override uncomment the below variable and set the type
# type: credscan,java
# type: python
- name: Upload report
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: reports
test-build:
needs:
- codespell
- super-linter
- shiftleft
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Build the Docker image
id: docker_test
uses: docker/build-push-action@v6
with:
builder: ${{ steps.buildx.outputs.name }}
push: false
outputs: type=docker,dest=/tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
tags: localhost:5000/foobar/${{ env.IMAGE_NAME }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
context: .
file: ./Dockerfile
platforms: linux/amd64
build-args: |
BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
BUILD_VERSION="$(git describe --tags)"
VCS_REF="$(git rev-parse --short HEAD)"
VCS_URL="$(git config --get remote.origin.url)"
VCS_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
test:
name: Run test
needs:
- test-build
strategy:
fail-fast: false
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp
- name: Load image and push to local registry
run: |
docker load --input /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
docker image ls -a
docker push localhost:5000/foobar/${{ env.IMAGE_NAME }}
- name: Inspect the Docker image
run: |
docker buildx imagetools inspect localhost:5000/foobar/${{ env.IMAGE_NAME }}
- name: Test the Docker image
run: |
CONTAINER_OUTPUT="$(docker run --rm -t localhost:5000/foobar/${{ env.IMAGE_NAME }} /opt/calcardbackup/calcardbackup -h)"
# shellcheck disable=SC2086
TEST_STRING="$(echo ${CONTAINER_OUTPUT} | grep -c 'START calcardbackup')"
if ! [ "${TEST_STRING}" = "1" ]; then exit 1; fi
dockle:
name: Run Dockle tests
needs:
- test-build
strategy:
fail-fast: false
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp
- name: Load image and push to local registry
run: |
docker load --input /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
docker image ls -a
docker push localhost:5000/foobar/${{ env.IMAGE_NAME }}
- name: Run dockle container image linter
uses: goodwithtech/dockle-action@v0.1.2
with:
image: "registry:5000/foobar/${{ env.IMAGE_NAME }}"
insecure: true
format: "sarif"
exit-code: "1"
exit-level: "warn"
ignore: "CIS-DI-0001,CIS-DI-0010,DKL-DI-0006"
output: sarif-reports
- name: Upload Reports
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "sarif-reports"
trivy:
name: Run Trivy tests
needs:
- test-build
strategy:
fail-fast: false
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp
- name: Load image and push to local registry
run: |
docker load --input /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
docker image ls -a
docker push localhost:5000/foobar/${{ env.IMAGE_NAME }}
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: localhost:5000/foobar/${{ env.IMAGE_NAME }}
format: "template"
template: "@/contrib/sarif.tpl"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
- name: Upload Reports
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "trivy-results.sarif"
anchore:
name: Run Anchore tests
needs:
- test-build
strategy:
fail-fast: false
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp
- name: Load image and push to local registry
run: |
docker load --input /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
docker image ls -a
docker push localhost:5000/foobar/${{ env.IMAGE_NAME }}
- name: Run the Anchore scan action itself with GitHub Advanced Security code scanning integration enabled
uses: anchore/scan-action@main
with:
image: localhost:5000/foobar/${{ env.IMAGE_NAME }}
acs-report-enable: true
fail-build: false
- name: Move reports
run: mkdir -p sarif-reports && cp ./*results.sarif ./sarif-reports/
- name: Upload Reports
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "sarif-reports"
release-docker:
name: Release Docker images
needs:
- test
- dockle
- trivy
- anchore
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare
id: prep
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }}
run: |
USER="${GITHUB_REPOSITORY_OWNER}"
IMAGE_NAME="$(echo '${{ github.repository }}' | awk -F '/' '{print $2}' | sed s/docker-//)"
DOCKER_IMAGE="${USER}/${IMAGE_NAME}"
VERSION=edge
# running on a tag
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
fi
# running on a branch
if [[ "$GITHUB_REF" == refs/heads/* ]]; then
VERSION="${GITHUB_REF#refs/heads/}"
fi
# running on schedule
# shellcheck disable=SC2050
if [ "${{ github.event_name }}" = "schedule" ]; then
VERSION=nightly
fi
# running on master branch
if [ "$VERSION" = "master" ]; then
VERSION=latest
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ "$VERSION" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\-[0-9]{1,3}$ ]]; then
REALEASE_TAG=true
fi
TAGS_INT="$TAGS"
TAGS=""
if [ "$DOCKERHUB_USERNAME" != '' ] && [ "$DOCKERHUB_TOKEN" != '' ]; then
if [ "$REALEASE_TAG" = "true" ]; then
TAGS="$TAGS_INT,${DOCKER_IMAGE}:latest"
else
TAGS="$TAGS_INT"
fi
fi
if [ "$GITHUB_TOKEN" != '' ]; then
if [ "$REALEASE_TAG" = "true" ]; then
TAGS="$TAGS,ghcr.io/$TAGS_INT,ghcr.io/${DOCKER_IMAGE}:latest"
else
TAGS="$TAGS,ghcr.io/$TAGS_INT"
fi
fi
if [ "$QUAY_USERNAME" != '' ] && [ "$QUAY_TOKEN" != '' ]; then
if [ "$REALEASE_TAG" = "true" ]; then
TAGS="$TAGS,quay.io/$TAGS_INT,quay.io/${DOCKER_IMAGE}:latest"
else
TAGS="$TAGS,quay.io/$TAGS_INT"
fi
fi
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}-${{ github.run_number }}
path: /tmp
- name: Load image from test job
run: |
docker load --input /tmp/${{ env.IMAGE_NAME }}-${{ github.run_number }}.tar
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to ghcr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name != 'pull_request' && env.GITHUB_TOKEN != '' }}
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${USER}
password: ${{ env.GITHUB_TOKEN }}
- name: Login to DockerHub Container Registry
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
if: ${{ github.event_name != 'pull_request' && env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
uses: docker/login-action@v3
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Login to Quay Container Registry
env:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }}
if: ${{ github.event_name != 'pull_request' && env.QUAY_USERNAME != '' && env.QUAY_TOKEN != '' }}
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ env.QUAY_USERNAME }}
password: ${{ env.QUAY_TOKEN }}
- name: Test
id: docker_test
uses: docker/build-push-action@v6
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
platforms: linux/amd64
build-args: |
BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
BUILD_VERSION="$(git describe --tags)"
VCS_REF="$(git rev-parse --short HEAD)"
VCS_URL="$(git config --get remote.origin.url)"
VCS_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
- name: Build and push
id: docker_build
uses: docker/build-push-action@v6
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: |
${{ steps.prep.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
build-args: |
BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
BUILD_VERSION="$(git describe --tags)"
VCS_REF="$(git rev-parse --short HEAD)"
VCS_URL="$(git config --get remote.origin.url)"
VCS_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}