Skip to content

feat: diarization speaker-ID follow-ups + CI buildcache (#915) + Ensu… #794

feat: diarization speaker-ID follow-ups + CI buildcache (#915) + Ensu…

feat: diarization speaker-ID follow-ups + CI buildcache (#915) + Ensu… #794

Workflow file for this run

name: Docker Build & Test
on:
push:
branches: [ "main", "release/2.4", "release/2.5", "release/2.6" ]
paths:
- 'docker/pipeline/Dockerfile'
- '.dockerignore'
- 'pyproject.toml'
- '**.py'
- '.github/workflows/docker.yml'
# Fast Docker build runs on PRs when Docker-related files change
# Full Docker validation still runs on merge to main
pull_request:
branches: [ "main", "release/2.4", "release/2.5", "release/2.6" ]
paths:
- 'docker/pipeline/Dockerfile'
- '.dockerignore'
- 'pyproject.toml'
- '**.py'
- '.github/workflows/docker.yml'
# Manual trigger so build-logic changes (free-disk steps, buildx opts) can be
# validated without touching a Dockerfile/source path.
workflow_dispatch:
permissions:
contents: read
packages: write # push/pull the GHCR registry build cache (ghcr.io/<owner>/podcast-scraper-buildcache)
# Newer push to same (workflow, ref) cancels the in-progress run — Docker
# build is expensive (ML variant ~17 min) and the old run's image is
# obsolete the moment the new commit lands.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Fast Docker build for PRs (LLM-only variant, sub-3 min target)
# Builds LLM-only variant for fast feedback on PRs
# Most code changes affect both variants, so LLM-only is sufficient for PR validation
docker-build-fast:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Free disk space
# #703: cold pipeline (ml) builds tip over the runner's free-disk
# threshold even with dotnet/android/ghc removed. Also nuke
# /opt/hostedtoolcache (CodeQL, Java, Swift, Boost) — pure docker
# builds don't need any hosted-tool runtimes.
run: |
echo "before:"
df -h /
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /home/linuxbrew/.linuxbrew \
/opt/hostedtoolcache /usr/share/swift /usr/local/share/boost \
/usr/local/lib/node_modules /usr/local/.ghcup /usr/lib/google-cloud-sdk \
/usr/local/share/powershell /usr/local/share/chromium /opt/microsoft /opt/az || true
sudo swapoff -a || true
sudo rm -f /swapfile /mnt/swapfile || true
sudo apt-get clean || true
sudo rm -rf /var/lib/apt/lists/* || true
docker image prune -af || true
echo "after:"
df -h /
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
driver-opts: |
image=moby/buildkit:latest
- name: Log in to GHCR (registry build cache)
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image (LLM-only variant, fast)
uses: docker/build-push-action@v7
with:
context: .
file: docker/pipeline/Dockerfile
build-args: |
INSTALL_EXTRAS=
push: false
load: true
tags: podcast-scraper:test-llm
# Build cache lives in GHCR (registry), not GHA — keeps the ~9 GB ml-models GHA
# cache from being evicted under the 10 GB cap (#915). cache-from only here;
# docker-build-full maintains the cache.
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/podcast-scraper-buildcache:llm-only
- name: Test Docker image (help command)
run: |
docker run --rm podcast-scraper:test-llm --help
- name: Test Docker image (version check)
run: |
docker run --rm podcast-scraper:test-llm --version
- name: Test Docker image (no args - should show config file error)
run: |
output=$(docker run --rm podcast-scraper:test-llm 2>&1 || true)
echo "$output" | grep -q "Config file not found"
- name: Validate Dockerfile with hadolint
run: |
docker run --rm -v "$(pwd):/workspace" -w /workspace hadolint/hadolint:latest hadolint docker/pipeline/Dockerfile
# Full Docker build for main branch (both variants in parallel)
# Builds both LLM-only and ML-enabled variants to ensure full validation
docker-build-full:
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/release/2.4' || github.ref == 'refs/heads/release/2.5' || github.ref == 'refs/heads/release/2.6')
runs-on: ubuntu-latest
strategy:
matrix:
include:
- name: llm-only
tag: podcast-scraper:test-llm
build_args: "INSTALL_EXTRAS="
- name: ml
tag: podcast-scraper:test
build_args: "INSTALL_EXTRAS=ml\nPRELOAD_ML_MODELS=true"
steps:
- uses: actions/checkout@v6
- name: Free disk space
# #703: cold pipeline (ml) builds tip over the runner's free-disk
# threshold even with dotnet/android/ghc removed. Also nuke
# /opt/hostedtoolcache (CodeQL, Java, Swift, Boost) — pure docker
# builds don't need any hosted-tool runtimes.
run: |
echo "before:"
df -h /
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /home/linuxbrew/.linuxbrew \
/opt/hostedtoolcache /usr/share/swift /usr/local/share/boost \
/usr/local/lib/node_modules /usr/local/.ghcup /usr/lib/google-cloud-sdk \
/usr/local/share/powershell /usr/local/share/chromium /opt/microsoft /opt/az || true
sudo swapoff -a || true
sudo rm -f /swapfile /mnt/swapfile || true
sudo apt-get clean || true
sudo rm -rf /var/lib/apt/lists/* || true
docker image prune -af || true
echo "after:"
df -h /
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
driver-opts: |
image=moby/buildkit:latest
- name: Log in to GHCR (registry build cache)
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image (${{ matrix.name }})
uses: docker/build-push-action@v7
with:
context: .
file: docker/pipeline/Dockerfile
build-args: |
${{ matrix.build_args }}
push: false
load: true
tags: ${{ matrix.tag }}
# Build cache lives in GHCR (registry), not GHA, so the ~9 GB ml-models GHA cache
# isn't evicted under the 10 GB cap (#915). This job maintains the cache (snyk-docker
# reuses it read-only). mode=min keeps the export small.
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/podcast-scraper-buildcache:${{ matrix.name }}
cache-to: type=registry,mode=min,ref=ghcr.io/${{ github.repository_owner }}/podcast-scraper-buildcache:${{ matrix.name }}
- name: Test Docker image (${{ matrix.name }} - help command)
run: |
docker run --rm ${{ matrix.tag }} --help
- name: Test Docker image (${{ matrix.name }} - version check)
run: |
docker run --rm ${{ matrix.tag }} --version
- name: Test Docker image (${{ matrix.name }} - no args - should show config file error)
run: |
output=$(docker run --rm ${{ matrix.tag }} 2>&1 || true)
echo "$output" | grep -q "Config file not found"
- name: Validate Dockerfile with hadolint
if: matrix.name == 'llm-only'
run: |
docker run --rm -v "$(pwd):/workspace" -w /workspace hadolint/hadolint:latest hadolint docker/pipeline/Dockerfile