Skip to content

Commit

Permalink
[Merge] [#17] Build, test, and publish images with composite actions
Browse files Browse the repository at this point in the history
Restructured workflows to use composite actions for testing and publishing images to promote more modular code structure. Also modified image-publishing workflow such that image tests are run before pushing image to Docker Hub
  • Loading branch information
nathan-hess authored Jun 12, 2022
2 parents 7219515 + 5255c43 commit cb20b0f
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 190 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/check-required-images/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Check Required Images Composite Action
description: Verifies that Docker image(s) are available on the system (as shown by `docker images`)

inputs:
required_images:
description: Space-separated list of images which need to be available (as shown by `docker images`)
required: false
default: ''

runs:
using: composite
steps:
- name: Check for Docker Images
shell: bash
run: |
echo "Checking for required Docker images..."
num_missing_imgs=0
for image in $(echo "${{ inputs.required_images }}"); do
if [[ "$(docker images -q "${image}")" == "" ]]; then
echo "Required image \"${image}\" does not exist"
num_missing_imgs=$((num_missing_imgs+1))
fi
done
if [ "$num_missing_imgs" -eq "0" ]; then
echo "All required images found"
exit 0
else
printf "Missing ${num_missing_imgs} required image(s)\n"
exit 1
fi
50 changes: 50 additions & 0 deletions .github/workflows/docker-build-push/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Docker Build-Push Composite Action
description: Wrapper for Docker Build-Push Action

inputs:
user:
description: Image default user privilege level (standard or root)
required: true
context:
description: Context when building Docker images
required: true
load:
description: Whether to make image available locally on the runner
required: true
push:
description: Whether to publish image to Docker Hub
required: true
tags:
description: List of tags after building image
required: true
required_images:
description: Space-separated list of images which need to be available (as shown by `docker images`)
required: false
default: ''

runs:
using: composite
steps:
- name: Check for Required Images
uses: './.github/workflows/check-required-images'
with:
required_images: ${{ inputs.required_images }}

- name: Build and Publish Docker Image
if: ${{ success() }}
uses: docker/build-push-action@v2
with:
context: ${{ inputs.context }}
load: ${{ inputs.load == 'true' }}
push: ${{ inputs.push == 'true' }}
tags: ${{ inputs.tags }}
build-args: |
BASE_DOCKER_REPO=${{ env.DOCKER_HUB_REPO }}
BASE_TAG=${{ env.TAG_BASE_ROOT }}
UBUNTU_VERSION=${{ env.CONTAINER_UBUNTU_VERSION }}
USERNAME=${{ env.CONTAINER_USERNAME }}
PASSWORD=${{ env.CONTAINER_PASSWORD }}
UID=${{ env.CONTAINER_UID }}
GID=${{ env.CONTAINER_GID }}
TIMEZONE=${{ env.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=${{ inputs.user }}
132 changes: 43 additions & 89 deletions .github/workflows/docker-hub-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- '.github/workflows/docker-hub-publish.yml'
- '.github/workflows/**'
- 'dockerfile**'
- '.env'
tags-ignore:
Expand All @@ -15,104 +15,58 @@ on:
workflow_dispatch:

jobs:
setup:
name: Build Environment Setup
build:
name: Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3

- name: Load Environment Variables
run: cat .env >> $GITHUB_ENV
outputs:
DOCKER_HUB_REPO: ${{ env.DOCKER_HUB_REPO }}
TAG_BASE_STANDARD: ${{ env.TAG_BASE_STANDARD }}
TAG_BASE_ROOT: ${{ env.TAG_BASE_ROOT }}
TAG_FULL_STANDARD: ${{ env.TAG_FULL_STANDARD }}
TAG_FULL_ROOT: ${{ env.TAG_FULL_ROOT }}
CONTAINER_UBUNTU_VERSION: ${{ env.CONTAINER_UBUNTU_VERSION }}
CONTAINER_USERNAME: ${{ env.CONTAINER_USERNAME }}
CONTAINER_PASSWORD: ${{ env.CONTAINER_PASSWORD }}
CONTAINER_UID: ${{ env.CONTAINER_UID }}
CONTAINER_GID: ${{ env.CONTAINER_GID }}
CONTAINER_TIMEZONE: ${{ env.CONTAINER_TIMEZONE }}
- name: Set Up Runner
uses: './.github/workflows/setup'

build-base:
name: Docker Hub - base - ${{ matrix.user }}
needs: setup
if: ${{ success() }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
user: [standard]
tag: ['${{ needs.setup.outputs.TAG_BASE_STANDARD }}']
include:
- user: root
tag: ${{ needs.setup.outputs.TAG_BASE_ROOT }}
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3

- name: Log in to Docker Hub
uses: docker/login-action@v1
- name: Publish Docker Image - base - standard
if: ${{ always() }}
uses: './.github/workflows/test-publish'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
user: standard
docker_build_context: dockerfile_base/
publish_repo: ${{ env.DOCKER_HUB_REPO }}
publish_tag: ${{ env.TAG_BASE_STANDARD }}
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Build and Publish Docker Image
uses: docker/build-push-action@v2
- name: Publish Docker Image - base - root
if: ${{ always() }}
uses: './.github/workflows/test-publish'
with:
context: ./dockerfile_base/
push: true
tags: ${{ needs.setup.outputs.DOCKER_HUB_REPO }}:${{ matrix.tag }}
build-args: |
BASE_DOCKER_REPO=${{ needs.setup.outputs.DOCKER_HUB_REPO }}
BASE_TAG=${{ needs.setup.outputs.TAG_BASE_ROOT }}
UBUNTU_VERSION=${{ needs.setup.outputs.CONTAINER_UBUNTU_VERSION }}
USERNAME=${{ needs.setup.outputs.CONTAINER_USERNAME }}
PASSWORD=${{ needs.setup.outputs.CONTAINER_PASSWORD }}
UID=${{ needs.setup.outputs.CONTAINER_UID }}
GID=${{ needs.setup.outputs.CONTAINER_GID }}
TIMEZONE=${{ needs.setup.outputs.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=${{ matrix.user }}
build-full:
name: Docker Hub - full - ${{ matrix.user }}
needs: [setup, build-base]
if: ${{ success() }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
user: [standard]
tag: ['${{ needs.setup.outputs.TAG_FULL_STANDARD }}']
include:
- user: root
tag: ${{ needs.setup.outputs.TAG_FULL_ROOT }}
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3
user: root
docker_build_context: dockerfile_base/
publish_repo: ${{ env.DOCKER_HUB_REPO }}
publish_tag: ${{ env.TAG_BASE_ROOT }}
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Log in to Docker Hub
uses: docker/login-action@v1
- name: Publish Docker Image - full - standard
if: ${{ always() }}
uses: './.github/workflows/test-publish'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
user: standard
docker_build_context: dockerfile_full/
publish_repo: ${{ env.DOCKER_HUB_REPO }}
publish_tag: ${{ env.TAG_FULL_STANDARD }}
required_images: ${{ env.DOCKER_HUB_REPO }}:${{ env.TAG_BASE_ROOT }}
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Build and Publish Docker Image
uses: docker/build-push-action@v2
- name: Publish Docker Image - full - root
if: ${{ always() }}
uses: './.github/workflows/test-publish'
with:
context: ./dockerfile_full/
push: true
tags: ${{ needs.setup.outputs.DOCKER_HUB_REPO }}:${{ matrix.tag }}
build-args: |
BASE_DOCKER_REPO=${{ needs.setup.outputs.DOCKER_HUB_REPO }}
BASE_TAG=${{ needs.setup.outputs.TAG_BASE_ROOT }}
UBUNTU_VERSION=${{ needs.setup.outputs.CONTAINER_UBUNTU_VERSION }}
USERNAME=${{ needs.setup.outputs.CONTAINER_USERNAME }}
PASSWORD=${{ needs.setup.outputs.CONTAINER_PASSWORD }}
UID=${{ needs.setup.outputs.CONTAINER_UID }}
GID=${{ needs.setup.outputs.CONTAINER_GID }}
TIMEZONE=${{ needs.setup.outputs.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=${{ matrix.user }}
user: root
docker_build_context: dockerfile_full/
publish_repo: ${{ env.DOCKER_HUB_REPO }}
publish_tag: ${{ env.TAG_FULL_ROOT }}
required_images: ${{ env.DOCKER_HUB_REPO }}:${{ env.TAG_BASE_ROOT }}
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }}
139 changes: 38 additions & 101 deletions .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,121 +2,58 @@ name: Docker Image Testing

on:
push:
branches:
- '**'
branches-ignore:
- main
tags-ignore:
- '**'
workflow_dispatch:

jobs:
setup:
name: Build Environment Setup
test:
name: Docker Test
runs-on: ubuntu-latest
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3

- name: Load Environment Variables
run: cat .env >> $GITHUB_ENV
outputs:
DOCKER_HUB_REPO: ${{ env.DOCKER_HUB_REPO }}
TAG_BASE_STANDARD: ${{ env.TAG_BASE_STANDARD }}
TAG_BASE_ROOT: ${{ env.TAG_BASE_ROOT }}
TAG_FULL_STANDARD: ${{ env.TAG_FULL_STANDARD }}
TAG_FULL_ROOT: ${{ env.TAG_FULL_ROOT }}
CONTAINER_UBUNTU_VERSION: ${{ env.CONTAINER_UBUNTU_VERSION }}
CONTAINER_USERNAME: ${{ env.CONTAINER_USERNAME }}
CONTAINER_PASSWORD: ${{ env.CONTAINER_PASSWORD }}
CONTAINER_UID: ${{ env.CONTAINER_UID }}
CONTAINER_GID: ${{ env.CONTAINER_GID }}
CONTAINER_TIMEZONE: ${{ env.CONTAINER_TIMEZONE }}
- name: Set Up Runner
uses: './.github/workflows/setup'

test-base:
name: Docker Test - base - ${{ matrix.user }}
needs: setup
if: ${{ success() }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
user: [standard]
sudo: ["sudo"]
include:
- user: root
sudo: ""
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3

- name: Build Docker Image - base
uses: docker/build-push-action@v2
- name: Test Docker Image - base - standard
if: ${{ always() }}
uses: './.github/workflows/test'
with:
context: ./dockerfile_base/
push: false
tags: test
build-args: |
BASE_DOCKER_REPO=${{ needs.setup.outputs.DOCKER_HUB_REPO }}
UBUNTU_VERSION=${{ needs.setup.outputs.CONTAINER_UBUNTU_VERSION }}
USERNAME=${{ needs.setup.outputs.CONTAINER_USERNAME }}
PASSWORD=${{ needs.setup.outputs.CONTAINER_PASSWORD }}
UID=${{ needs.setup.outputs.CONTAINER_UID }}
GID=${{ needs.setup.outputs.CONTAINER_GID }}
TIMEZONE=${{ needs.setup.outputs.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=${{ matrix.user }}
- name: Test Docker Image
run: |
docker run --rm -v $GITHUB_WORKSPACE:/host test /bin/bash -c "${{ matrix.sudo }} /etc/startup.sh && bash /host/dockerfile_base/image_tests/run_tests.sh ${{ matrix.user }}"
user: standard
docker_build_context: dockerfile_base/

test-full:
name: Docker Test - full - ${{ matrix.user }}
needs: setup
if: ${{ success() }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
user: [standard]
sudo: ["sudo"]
include:
- user: root
sudo: ""
steps:
- name: Check Out Repository Files
uses: actions/checkout@v3

- name: Build Docker Image - base root
uses: docker/build-push-action@v2
- name: Test Docker Image - base - root
if: ${{ always() }}
uses: './.github/workflows/test'
with:
context: ./dockerfile_base/
push: false
tags: ${{ needs.setup.outputs.DOCKER_HUB_REPO }}:${{ needs.setup.outputs.TAG_BASE_ROOT }}
build-args: |
BASE_DOCKER_REPO=${{ needs.setup.outputs.DOCKER_HUB_REPO }}
UBUNTU_VERSION=${{ needs.setup.outputs.CONTAINER_UBUNTU_VERSION }}
USERNAME=${{ needs.setup.outputs.CONTAINER_USERNAME }}
PASSWORD=${{ needs.setup.outputs.CONTAINER_PASSWORD }}
UID=${{ needs.setup.outputs.CONTAINER_UID }}
GID=${{ needs.setup.outputs.CONTAINER_GID }}
TIMEZONE=${{ needs.setup.outputs.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=root
user: root
docker_build_context: dockerfile_base/

- name: Build Docker Image - full
uses: docker/build-push-action@v2
- name: Build Image - base/root (full image dependency)
uses: './.github/workflows/docker-build-push'
with:
user: root
context: dockerfile_base/
load: 'true'
push: 'false'
tags: ${{ env.DOCKER_HUB_REPO }}:${{ env.TAG_BASE_ROOT }}

- name: Test Docker Image - full - standard
if: ${{ always() }}
uses: './.github/workflows/test'
with:
context: ./dockerfile_full/
push: false
tags: test
build-args: |
BASE_DOCKER_REPO=${{ needs.setup.outputs.DOCKER_HUB_REPO }}
BASE_TAG=${{ needs.setup.outputs.TAG_BASE_ROOT }}
USERNAME=${{ needs.setup.outputs.CONTAINER_USERNAME }}
PASSWORD=${{ needs.setup.outputs.CONTAINER_PASSWORD }}
UID=${{ needs.setup.outputs.CONTAINER_UID }}
GID=${{ needs.setup.outputs.CONTAINER_GID }}
TIMEZONE=${{ needs.setup.outputs.CONTAINER_TIMEZONE }}
USER_PRIVILEGE_LEVEL=${{ matrix.user }}
user: standard
docker_build_context: dockerfile_full/
required_images: ${{ env.DOCKER_HUB_REPO }}:${{ env.TAG_BASE_ROOT }}

- name: Test Docker Image
run: |
docker run --rm -v $GITHUB_WORKSPACE:/host test /bin/bash -c "${{ matrix.sudo }} /etc/startup.sh && python3 /host/dockerfile_full/image_tests/run_tests_${{ matrix.user }}.py"
- name: Test Docker Image - full - root
if: ${{ always() }}
uses: './.github/workflows/test'
with:
user: root
docker_build_context: dockerfile_full/
required_images: ${{ env.DOCKER_HUB_REPO }}:${{ env.TAG_BASE_ROOT }}
Loading

0 comments on commit cb20b0f

Please sign in to comment.