Container tests workflow (ddev/ddev)
The Container tests workflow from ddev/ddev, explained and optimized by Latchkey.
CI health: B - good
Run this on Latchkey for self-healing, caching, and up to 58% lower cost.
Grade your own workflow free or run it on Latchkey →What it does
This is the Container tests workflow from the ddev/ddev repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Container tests
defaults:
run:
shell: bash
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
# Only run when something changes in the actual containers
paths:
- "containers/**"
- ".github/workflows/**"
- "!.github/workflows/docs**"
schedule:
- cron: '01 00 * * *'
workflow_dispatch:
inputs:
debug_enabled:
description: 'Run the build with tmate set "debug_enabled"'
type: boolean
required: false
default: false
testargs:
description: Add specific test to run like -run TestEnvironmentVariables or -run "(TestDdevFullSite.*|Test.*Pull)"
required: false
default: ""
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DDEV_IGNORE_EXPIRING_KEYS: ${{ vars.DDEV_IGNORE_EXPIRING_KEYS || 'true' }}
DDEV_MAX_DAYS_BEFORE_CERT_EXPIRATION: ${{ vars.DDEV_MAX_DAYS_BEFORE_CERT_EXPIRATION || '90' }}
permissions:
contents: read
jobs:
container-build-and-test:
name: ${{ matrix.os }} - Test container ${{ matrix.containers }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-24.04]
containers: [dbserver, webserver, others]
steps:
- uses: actions/checkout@v7
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@main
with:
brew-gh-api-token: ${{ secrets.GITHUB_TOKEN }}
setup-sandbox: true
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
github-token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
- name: Install test dependencies (linux-setup.sh)
if: matrix.os == 'ubuntu-24.04'
run: ./.github/workflows/linux-setup.sh
- uses: actions/setup-go@v6
with:
go-version: '>=1.23'
check-latest: true
# MySQL 8.0/8.4 images build FROM dhi.io/mysql (Docker Hardened Images),
# which requires authentication. Only available when org secrets are
# present (not on fork PRs). See ddev/ddev#7962.
# Github seems already to be logged in with user `githubactions`, which makes this unnecessary.
# - name: Login to dhi.io (Docker Hardened Images)
# if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }}
# uses: docker/login-action@v4
# with:
# registry: dhi.io
# username: ${{ vars.DOCKERHUB_USERNAME }}
# password: ${{ env.DOCKERHUB_TOKEN }}
- name: Build and test container ${{ matrix.containers }}
run: |
source ~/.bashrc
docker version
docker info
mkcert --version
set -eu -o pipefail
if [[ "${{ matrix.containers }}" == "dbserver" ]]; then
pushd containers/ddev-dbserver
echo "--- Test container dbserver"
time make test DOCKER_ARGS="--no-cache"
popd
elif [[ "${{ matrix.containers }}" == "webserver" ]]; then
pushd containers/ddev-webserver
echo "--- Test container ddev-webserver"
time make test DOCKER_ARGS="--no-cache"
popd
elif [[ "${{ matrix.containers }}" == "others" ]]; then
for dir in ddev-ssh-agent ddev-traefik-router ddev-xhgui test-ssh-server
do pushd containers/$dir
echo "--- Test container $dir"
time make test DOCKER_ARGS=--no-cache
popd
done
fi
set +eu
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Container tests defaults: run: shell: bash on: push: branches: [ main ] pull_request: branches: [ main ] # Only run when something changes in the actual containers paths: - "containers/**" - ".github/workflows/**" - "!.github/workflows/docs**" schedule: - cron: '01 00 * * *' workflow_dispatch: inputs: debug_enabled: description: 'Run the build with tmate set "debug_enabled"' type: boolean required: false default: false testargs: description: Add specific test to run like -run TestEnvironmentVariables or -run "(TestDdevFullSite.*|Test.*Pull)" required: false default: "" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: DDEV_IGNORE_EXPIRING_KEYS: ${{ vars.DDEV_IGNORE_EXPIRING_KEYS || 'true' }} DDEV_MAX_DAYS_BEFORE_CERT_EXPIRATION: ${{ vars.DDEV_MAX_DAYS_BEFORE_CERT_EXPIRATION || '90' }} permissions: contents: read jobs: container-build-and-test: timeout-minutes: 30 name: ${{ matrix.os }} - Test container ${{ matrix.containers }} runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-24.04] containers: [dbserver, webserver, others] steps: - uses: actions/checkout@v7 - name: Set up Homebrew id: set-up-homebrew uses: Homebrew/actions/setup-homebrew@main with: brew-gh-api-token: ${{ secrets.GITHUB_TOKEN }} setup-sandbox: true - name: Setup tmate session uses: mxschmitt/action-tmate@v3 with: limit-access-to-actor: true github-token: ${{ secrets.GITHUB_TOKEN }} if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - name: Install test dependencies (linux-setup.sh) if: matrix.os == 'ubuntu-24.04' run: ./.github/workflows/linux-setup.sh - uses: actions/setup-go@v6 with: go-version: '>=1.23' check-latest: true # MySQL 8.0/8.4 images build FROM dhi.io/mysql (Docker Hardened Images), # which requires authentication. Only available when org secrets are # present (not on fork PRs). See ddev/ddev#7962. # Github seems already to be logged in with user `githubactions`, which makes this unnecessary. # - name: Login to dhi.io (Docker Hardened Images) # if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }} # uses: docker/login-action@v4 # with: # registry: dhi.io # username: ${{ vars.DOCKERHUB_USERNAME }} # password: ${{ env.DOCKERHUB_TOKEN }} - name: Build and test container ${{ matrix.containers }} run: | source ~/.bashrc docker version docker info mkcert --version set -eu -o pipefail if [[ "${{ matrix.containers }}" == "dbserver" ]]; then pushd containers/ddev-dbserver echo "--- Test container dbserver" time make test DOCKER_ARGS="--no-cache" popd elif [[ "${{ matrix.containers }}" == "webserver" ]]; then pushd containers/ddev-webserver echo "--- Test container ddev-webserver" time make test DOCKER_ARGS="--no-cache" popd elif [[ "${{ matrix.containers }}" == "others" ]]; then for dir in ddev-ssh-agent ddev-traefik-router ddev-xhgui test-ssh-server do pushd containers/$dir echo "--- Test container $dir" time make test DOCKER_ARGS=--no-cache popd done fi set +eu
What changed
- Add a job timeout so a hung step cannot burn hours of runner time.
3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 1 job (3 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.