Skip to content

Add local build/test workflow for container images (#2) #1

Add local build/test workflow for container images (#2)

Add local build/test workflow for container images (#2) #1

Workflow file for this run

# Build and push minotaur container images to GHCR
#
# Builds multi-arch images (linux/amd64 + linux/arm64) for:
# - minotaur-base: Foundation with Claude Code and dev tools
# - minotaur-typescript: TypeScript/Node.js development
# - minotaur-rust: Rust development
#
# Triggers:
# - Push to images/** directory
# - Weekly on Mondays at 00:00 UTC (security updates)
# - Manual workflow dispatch
name: Container Images
on:
push:
branches: [main]
paths:
- 'images/**'
- '.github/workflows/images.yml'
schedule:
# Weekly rebuild for security updates (Mondays at 00:00 UTC)
- cron: '0 0 * * 1'
workflow_dispatch:
inputs:
force_rebuild:
description: 'Force rebuild all images (ignore cache)'
required: false
type: boolean
default: false
env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ghcr.io/${{ github.repository_owner }}/minotaur
jobs:
build-base:
name: Build base image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
digest: ${{ steps.build.outputs.digest }}
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
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_PREFIX }}-base
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=
type=schedule,pattern={{date 'YYYYMMDD'}}
- name: Build and push base image
id: build
uses: docker/build-push-action@v6
with:
context: ./images/base
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
no-cache: ${{ inputs.force_rebuild || false }}
build-language-images:
name: Build ${{ matrix.image }} image
runs-on: ubuntu-latest
needs: build-base
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- image: typescript
context: ./images/typescript
- image: rust
context: ./images/rust
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
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_PREFIX }}-${{ matrix.image }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=
type=schedule,pattern={{date 'YYYYMMDD'}}
- name: Build and push ${{ matrix.image }} image
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ env.IMAGE_PREFIX }}-base@${{ needs.build-base.outputs.digest }}
cache-from: type=gha
cache-to: type=gha,mode=max
no-cache: ${{ inputs.force_rebuild || false }}
verify:
name: Verify images
runs-on: ubuntu-latest
needs: [build-base, build-language-images]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Pull images
run: |
docker pull ${{ env.IMAGE_PREFIX }}-base:latest
docker pull ${{ env.IMAGE_PREFIX }}-typescript:latest
docker pull ${{ env.IMAGE_PREFIX }}-rust:latest
- name: Tag images for local testing
run: |
docker tag ${{ env.IMAGE_PREFIX }}-base:latest minotaur-base
docker tag ${{ env.IMAGE_PREFIX }}-typescript:latest minotaur-typescript
docker tag ${{ env.IMAGE_PREFIX }}-rust:latest minotaur-rust
- name: Run verification tests
run: ./images/build.sh --test-only