Skip to content

Refactor wtf_transcribe: decompose run() into composable functions, f… #85

Refactor wtf_transcribe: decompose run() into composable functions, f…

Refactor wtf_transcribe: decompose run() into composable functions, f… #85

name: Build and Push Docker images
# CalVer Release Workflow
#
# Automatically creates a CalVer release on every push to main.
# Version format: YYYY.MM.DD (e.g., 2026.01.16)
# If multiple releases happen on the same day, adds sequence: YYYY.MM.DD.2, YYYY.MM.DD.3, etc.
#
# Two separate images are built and pushed for both linux/amd64 and linux/arm64:
# vcon-server-api — lightweight FastAPI/uvicorn image (main deps only)
# vcon-server-conserver — full processing image (main + links + storage deps)
#
# Build strategy: native runners (no QEMU) for maximum speed
# amd64 builds on ubuntu-latest
# arm64 builds on ubuntu-24.04-arm
#
# Docker tags created for each image:
# - CalVer tag (e.g., 2026.01.16) [main only]
# - latest [main only]
# - Branch name (e.g., main)
# - Branch + short sha (e.g., main-a1b2c3d)
on:
push:
branches: [main, release-test, optimize-docker-images]
tags: ['v*']
jobs:
prepare:
runs-on: ubuntu-latest
permissions:
contents: write # needed to create git tags
outputs:
version: ${{ steps.calver.outputs.version }}
short_sha: ${{ steps.git.outputs.short_sha }}
build_time: ${{ steps.git.outputs.build_time }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate CalVer version
id: calver
run: |
TODAY=$(date +"%Y.%m.%d")
EXISTING_TAGS=$(git tag -l "${TODAY}*" | sort -V)
if [ -z "$EXISTING_TAGS" ]; then
VERSION="${TODAY}"
else
LAST_TAG=$(echo "$EXISTING_TAGS" | tail -1)
if [[ "$LAST_TAG" == "$TODAY" ]]; then
VERSION="${TODAY}.2"
elif [[ "$LAST_TAG" =~ ^${TODAY}\.([0-9]+)$ ]]; then
SEQ="${BASH_REMATCH[1]}"
VERSION="${TODAY}.$((SEQ + 1))"
else
VERSION="${TODAY}.2"
fi
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "Generated CalVer version: ${VERSION}"
- name: Get git commit info
id: git
run: |
echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "build_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
- name: Create git tag
if: github.ref == 'refs/heads/main'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git rev-parse "${{ steps.calver.outputs.version }}" >/dev/null 2>&1; then
echo "Tag ${{ steps.calver.outputs.version }} already exists, skipping"
else
git tag -a "${{ steps.calver.outputs.version }}" -m "Release ${{ steps.calver.outputs.version }}"
git push origin "${{ steps.calver.outputs.version }}"
echo "Created and pushed tag ${{ steps.calver.outputs.version }}"
fi
build:
needs: prepare
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- service: api
dockerfile: ./docker/Dockerfile.api
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-api
platform: linux/amd64
platform_tag: amd64
runner: ubuntu-latest
- service: api
dockerfile: ./docker/Dockerfile.api
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-api
platform: linux/arm64
platform_tag: arm64
runner: ubuntu-24.04-arm
- service: conserver
dockerfile: ./docker/Dockerfile.conserver
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-conserver
platform: linux/amd64
platform_tag: amd64
runner: ubuntu-latest
- service: conserver
dockerfile: ./docker/Dockerfile.conserver
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-conserver
platform: linux/arm64
platform_tag: arm64
runner: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Amazon ECR Public
uses: docker/login-action@v3
with:
registry: public.ecr.aws
username: ${{ secrets.AWS_ACCESS_KEY }}
password: ${{ secrets.AWS_SECRET }}
- name: Build and push ${{ matrix.service }} (${{ matrix.platform_tag }})
uses: docker/build-push-action@v5
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: ${{ matrix.platform }}
push: true
cache-from: type=gha,scope=${{ matrix.service }}-${{ matrix.platform_tag }}
cache-to: type=gha,mode=max,scope=${{ matrix.service }}-${{ matrix.platform_tag }}
tags: ${{ matrix.image }}:${{ github.ref_name }}-${{ matrix.platform_tag }}
build-args: |
VCON_SERVER_VERSION=${{ needs.prepare.outputs.version }}
VCON_SERVER_GIT_COMMIT=${{ needs.prepare.outputs.short_sha }}
VCON_SERVER_BUILD_TIME=${{ needs.prepare.outputs.build_time }}
merge:
needs: [prepare, build]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- service: api
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-api
- service: conserver
image: public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-conserver
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Amazon ECR Public
uses: docker/login-action@v3
with:
registry: public.ecr.aws
username: ${{ secrets.AWS_ACCESS_KEY }}
password: ${{ secrets.AWS_SECRET }}
- name: Create multi-arch manifest for ${{ matrix.service }}
env:
IMAGE: ${{ matrix.image }}
VERSION: ${{ needs.prepare.outputs.version }}
SHORT_SHA: ${{ needs.prepare.outputs.short_sha }}
BRANCH: ${{ github.ref_name }}
run: |
AMD64="${IMAGE}:${BRANCH}-amd64"
ARM64="${IMAGE}:${BRANCH}-arm64"
# Branch tag (always)
docker buildx imagetools create --tag "${IMAGE}:${BRANCH}" "${AMD64}" "${ARM64}"
# Branch + sha tag (always)
docker buildx imagetools create --tag "${IMAGE}:${BRANCH}-${SHORT_SHA}" "${AMD64}" "${ARM64}"
# CalVer and latest (main only)
if [ "${BRANCH}" = "main" ]; then
docker buildx imagetools create --tag "${IMAGE}:${VERSION}" "${AMD64}" "${ARM64}"
docker buildx imagetools create --tag "${IMAGE}:latest" "${AMD64}" "${ARM64}"
fi
release:
needs: [prepare, merge]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
permissions:
contents: write
steps:
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.prepare.outputs.version }}
name: Release ${{ needs.prepare.outputs.version }}
body: |
## Release ${{ needs.prepare.outputs.version }}
**Commit:** ${{ needs.prepare.outputs.short_sha }}
**Build Time:** ${{ needs.prepare.outputs.build_time }}
### Docker Images
Both images support `linux/amd64` and `linux/arm64`.
**API service** (FastAPI/uvicorn, lightweight):
```bash
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-api:${{ needs.prepare.outputs.version }}
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-api:latest
```
**Conserver service** (processing pipeline, full dependencies):
```bash
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-conserver:${{ needs.prepare.outputs.version }}
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server-conserver:latest
```
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Summary
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| **Version** | ${{ needs.prepare.outputs.version }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Git Commit** | ${{ needs.prepare.outputs.short_sha }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Build Time** | ${{ needs.prepare.outputs.build_time }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Branch** | ${{ github.ref_name }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Docker Images Built (linux/amd64 + linux/arm64)" >> $GITHUB_STEP_SUMMARY
echo "- \`vcon-server-api\` — API service (main deps only)" >> $GITHUB_STEP_SUMMARY
echo "- \`vcon-server-conserver\` — Conserver service (main + links + storage)" >> $GITHUB_STEP_SUMMARY