Skip to content

Docker Build

Docker Build #1780

Workflow file for this run

name: Docker Build
on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'
jobs:
getversion:
runs-on: ubuntu-latest
name: Obtain ZoneMinder Version
outputs:
build-version: ${{ steps.set-version.outputs.zmversion }}
steps:
- name: Set ZoneMinder Build Version
id: set-version
run: |
if [[ ${GITHUB_REF} == refs/heads/* || ${GITHUB_REF} == refs/pull/* ]]; then
# Build from latest ZoneMinder commit
ZM_VERSION=$(wget \
-qO - https://api.github.com/repos/ZoneMinder/zoneminder/commits/master \
| awk '/sha/{print $4;exit}' FS='[""]')
else
# Build tag
ZM_VERSION=${GITHUB_REF##*/}
fi
echo Building ZoneMinder ${ZM_VERSION}
echo "zmversion=${ZM_VERSION}" >> $GITHUB_OUTPUT
build:
name: Build Docker Image
runs-on: ubuntu-latest
if: ${{ needs.getversion.outputs.build-version != '' }}
needs: getversion
env:
ZM_VERSION: ${{ needs.getversion.outputs.build-version }}
strategy:
matrix:
include:
- arch: linux/386
arch_friendly: i386
s6_arch: i686
- arch: linux/amd64
arch_friendly: amd64
s6_arch: x86_64
- arch: linux/arm/v7
arch_friendly: armv7
s6_arch: armhf
- arch: linux/arm64
arch_friendly: arm64
s6_arch: aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
env.BUILDKIT_STEP_LOG_MAX_SIZE=10000000
env.BUILDKIT_STEP_LOG_MAX_SPEED=100000000
install: true
- name: Cache Docker layers
uses: actions/cache@v4
continue-on-error: true
with:
path: /tmp/.buildx-cache
key: ${{ matrix.arch }}-${{ env.ZM_VERSION }}-${{ github.sha }}
restore-keys: |
${{ matrix.arch }}-${{ env.ZM_VERSION }}-
- name: Build ZoneMinder
run: |
set -x
docker build \
--build-arg ZM_VERSION=${ZM_VERSION} \
--build-arg S6_ARCH=${{ matrix.s6_arch }} \
--tag ci:${{ github.run_number }} \
--platform ${{ matrix.arch }} \
--progress plain \
--file ./Dockerfile \
--cache-from type=local,src=/tmp/.buildx-cache \
--cache-to type=local,dest=/tmp/.buildx-cache-new \
--load \
.
# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Inspect
run: |
set -x
docker image inspect ci:${{ github.run_number }}
- name: Save tarball
run: |
set -x
docker save ci:${{ github.run_number }} | gzip > ci-${{ matrix.arch_friendly }}-${{ github.run_number }}.tar.gz
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: ci-${{ matrix.arch_friendly }}-${{ github.run_number }}
path: ci-${{ matrix.arch_friendly }}-${{ github.run_number }}.tar.gz
test:
needs: build
name: Test Image
runs-on: ubuntu-latest
strategy:
matrix:
arch:
- i386
- amd64
- armv7
- arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Download container artifact
uses: actions/download-artifact@v4
with:
name: ci-${{ matrix.arch }}-${{ github.run_number }}
- name: Import image
run: |
docker load --input ci-${{ matrix.arch }}-${{ github.run_number }}.tar.gz
docker tag ci:${{ github.run_number }} ci:latest
# Fails if zoneminder is not up
- name: Start image twice
timeout-minutes: 5
run: |
set -x
docker compose -f docker-compose.test.yml up &
sleep 60
if [ ! "$(docker ps -q -f name=zoneminder)" ]; then
exit 1
fi
docker compose -f docker-compose.test.yml down
docker compose -f docker-compose.test.yml up &
sleep 60
docker compose -f docker-compose.test.yml down
# Fails if zoneminder fails to stop normally
- name: Start image and stop zoneminder
timeout-minutes: 5
run: |
set -x
docker compose -f docker-compose.test.yml up &
sleep 60
docker stop zoneminder
docker compose -f docker-compose.test.yml down
# Fails if zoneminder doesn't stop when db is down
- name: Start image and stop db
timeout-minutes: 5
run: |
set -x
docker compose -f docker-compose.test.yml up &
sleep 120
docker stop db
sleep 60
if [ "$(docker ps -q -f name=zoneminder)" ]; then
exit 1
fi
release:
needs:
- getversion
- test
name: Upload Release Asset
if: ${{ startsWith(github.ref, 'refs/tags/') }}
runs-on: ubuntu-latest
steps:
- name: Download container artifact
uses: actions/download-artifact@v4
- name: Upload Release Asset
uses: softprops/action-gh-release@v2
with:
files: ci-*/ci-*.tar.gz
body: Automated release of ZoneMinder v${{ needs.getversion.outputs.build-version }}
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish:
name: Publish Image
runs-on: ubuntu-latest
needs:
- getversion
- test
if: ${{ !startsWith(github.ref, 'refs/pull/') && !startsWith(github.ref, 'refs/heads/dependabot/') }}
env:
ZM_VERSION: ${{ needs.getversion.outputs.build-version }}
strategy:
matrix:
arch:
- i386
- amd64
- armv7
- arm64
registry:
- {
url: "https://index.docker.io/v1/",
username: DOCKER_USERNAME,
password: DOCKER_PASSWORD,
repo: yaoa/zoneminder-base
}
- {
url: ghcr.io/zoneminder-containers,
username: GCHR_USERNAME,
password: GHCR_PAT,
repo: ghcr.io/zoneminder-containers/zoneminder-base
}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download container artifact
uses: actions/download-artifact@v4
with:
name: ci-${{ matrix.arch }}-${{ github.run_number }}
- name: Import image
run: |
docker load --input ci-${{ matrix.arch }}-${{ github.run_number }}.tar.gz
- name: Docker login
run: |
docker login ${{ matrix.registry.url }} -u ${{ secrets[matrix.registry.username] }} -p ${{ secrets[matrix.registry.password] }}
# Main gets pushed to branch name and nightly
# Tags get latest and ref name (aka the tag name)
# push to ref name
- name: Push image (ref)
if: ${{ startsWith(github.ref, 'refs/heads/') }}
run: |
./publish.py \
--tag ${GITHUB_REF##*/} \
--repo ${{ matrix.registry.repo }} \
--image \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }} \
--arch ${{ matrix.arch }} \
--image-name ci:${{ github.run_number }}
# push main branch to nightly tag
- name: Push image (nightly)
if: ${{ github.ref == 'refs/heads/main' }}
run: |
./publish.py \
--tag nightly \
--repo ${{ matrix.registry.repo }} \
--image \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }} \
--arch ${{ matrix.arch }} \
--image-name ci:${{ github.run_number }}
# if its tagged, push to tag name and latest
- name: Push image (tag)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: |
./publish.py \
--tag ${GITHUB_REF##*/} \
--repo ${{ matrix.registry.repo }} \
--image \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }} \
--arch ${{ matrix.arch }} \
--image-name ci:${{ github.run_number }} \
--latest
# if its tagged, push to release
- name: Push image (tag)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: |
./publish.py \
--tag release \
--repo ${{ matrix.registry.repo }} \
--image \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }} \
--arch ${{ matrix.arch }} \
--image-name ci:${{ github.run_number }}
create_manifest:
name: Create Manifest
runs-on: ubuntu-latest
needs:
- getversion
- publish
env:
ZM_VERSION: ${{ needs.getversion.outputs.build-version }}
DOCKER_CLI_EXPERIMENTAL: "enabled"
strategy:
matrix:
registry:
- {
url: "https://index.docker.io/v1/",
username: DOCKER_USERNAME,
password: DOCKER_PASSWORD,
repo: yaoa/zoneminder-base
}
- {
url: ghcr.io/zoneminder-containers,
username: GCHR_USERNAME,
password: GHCR_PAT,
repo: ghcr.io/zoneminder-containers/zoneminder-base
}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Docker login
run: |
docker login ${{ matrix.registry.url }} -u ${{ secrets[matrix.registry.username] }} -p ${{ secrets[matrix.registry.password] }}
# Main gets pushed to branch name and nightly
# Tags get latest and ref name (aka the tag name)
# push to ref name
- name: Push image (ref)
if: ${{ startsWith(github.ref, 'refs/heads/') }}
run: |
./publish.py \
--tag ${GITHUB_REF##*/} \
--repo ${{ matrix.registry.repo }} \
--manifest \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }}
# push main branch to nightly tag
- name: Push image (nightly)
if: ${{ github.ref == 'refs/heads/main' }}
run: |
./publish.py \
--tag nightly \
--repo ${{ matrix.registry.repo }} \
--manifest \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }}
# if its tagged, push to tag name and latest
- name: Push image (tag)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: |
./publish.py \
--tag ${GITHUB_REF##*/} \
--repo ${{ matrix.registry.repo }} \
--manifest \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }} \
--latest
# if its tagged, push to release
- name: Push image (tag)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: |
./publish.py \
--tag release \
--repo ${{ matrix.registry.repo }} \
--manifest \
--github-sha ${ZM_VERSION} \
--run-number ${{ github.run_number }}
dispatch:
name: Dispatch event to eventserver-base
runs-on: ubuntu-latest
needs:
- getversion
- create_manifest
steps:
- name: Trigger ES Build
run: |
curl -XPOST \
-u "${{ secrets.GCHR_USERNAME}}:${{secrets.GHCR_PAT}}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" https://api.github.com/repos/zoneminder-containers/eventserver-base/dispatches \
--data '{"event_type": "build_image", "client_payload": {"zm_version": "${{ needs.getversion.outputs.build-version }}", "tagged": "${{ startsWith(github.ref, 'refs/tags/') }}"}}'
echo "Dispatch Successful"