Files
Anthias/.github/workflows/docker-build.yaml

174 lines
5.2 KiB
YAML

name: Docker Image Build
on:
push:
branches:
- master
paths:
- '**'
- '!.editorconfig'
- '!webview/**'
- '!website/**'
- '!.github/workflows/deploy-website.yaml'
- '!.github/workflows/build-webview.yaml'
- '!.github/workflows/build-balena-disk-image.yaml'
- '!.github/workflows/python-lint.yaml'
- '!.github/workflows/generate-openapi-schema.yml'
- '!.github/workflows/docker-test.yml'
- '!.github/pull_request_template.md'
- '!.github/dependabot.yml'
- '!.github/release.yml'
- '!CONTRIBUTING.md'
- '!README.md'
- '!docs/**'
- '!bin/install.sh'
- '!bin/upgrade_containers.sh'
- '!bin/start_development_server.sh'
- '!tests/**'
- '!docker/Dockerfile.dev'
- '!.cursor/**'
jobs:
run-tests:
uses: ./.github/workflows/docker-test.yaml
buildx:
needs: run-tests
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi4-64', 'pi5', 'x86']
service: ['server', 'celery', 'redis', 'websocket', 'nginx', 'viewer', 'wifi-connect']
python-version: ["3.11"]
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: '0.9.17'
- name: Install dependencies
run: |
uv venv
uv pip install --group docker-image-builder
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:latest
- name: Create and use dedicated builder
run: |
docker buildx create --use --name multiarch-builder
docker buildx inspect --bootstrap
- name: Cache Docker layers
uses: actions/cache@v4
id: cache
with:
path: /tmp/.buildx-cache/${{ matrix.board }}-${{ matrix.service }}
key: buildx-${{ matrix.board }}-${{ matrix.service }}-${{ hashFiles('docker/**/*') }}
restore-keys: |
buildx-${{ matrix.board }}-${{ matrix.service }}-
- name: Inspect cache before build
run: |
ls -la /tmp/.buildx-cache/${{ matrix.board }}-${{ matrix.service }} || true
- name: Login to Docker Hub
if: success() && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Container
env:
DOCKER_BUILDKIT: 1
BUILDKIT_PROGRESS: plain
run: |
uv run python -m tools.image_builder \
--build-target=${{ matrix.board }} \
--service=${{ matrix.service }} \
--push
- name: Inspect cache after build
run: |
ls -la /tmp/.buildx-cache/${{ matrix.board }}-${{ matrix.service }} || true
balena:
if: ${{ github.ref == 'refs/heads/master' }}
needs: buildx
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi5']
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set Docker tag
run: |
echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
if [ "${{ matrix.board }}" == "pi4" ]; then
echo "BOARD=${{ matrix.board }}-64" >> "$GITHUB_ENV"
else
echo "BOARD=${{ matrix.board }}" >> "$GITHUB_ENV"
fi
echo "SHM_SIZE=256mb" >> "$GITHUB_ENV"
- name: Prepare Balena file
run: |
# Generate a docker-compose file for Balena with the correct board
mkdir -p balena-deploy
# Copy in the Balena yaml file
cp balena.yml balena-deploy/
# Generate the docker-compose file
envsubst < docker-compose.balena.yml.tmpl > balena-deploy/docker-compose.yml
# Remove bind mounts to `/dev/vchiq` for Raspberry Pi 5
if [ "${{ matrix.board }}" == "pi5" ]; then
sed -i '/devices:/ {N; /\n.*\/dev\/vchiq:\/dev\/vchiq/d}' \
balena-deploy/docker-compose.yml
fi
- uses: balena-io/deploy-to-balena-action@master
id: build
continue-on-error: true
with:
balena_token: ${{ secrets.BALENA_TOKEN }}
fleet: screenly_ose/anthias-${{ matrix.board }}
source: balena-deploy
- name: Sleep random sleep before retry
if: ${{ failure() && steps.build.conclusion == 'failure' }}
run: |
sleep $((120 + RANDOM % 900));
# Balena deploy often fails with 'ESOCKETTIMEDOUT'.
# This adds some retry logic.
- uses: balena-io/deploy-to-balena-action@master
id: build-retry
if: ${{ failure() && steps.build.conclusion == 'failure' }}
with:
balena_token: ${{ secrets.BALENA_TOKEN }}
fleet: screenly_ose/anthias-${{ matrix.board }}
source: balena-deploy