Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
.docker
.git
.gitignore
.github
.claude
.pytest_cache
.vscode
__pycache__
Expand All @@ -17,8 +19,6 @@ build
*.log
*.swp
*.swo
*.pyc
*.pyo
*.DS_Store
*.idea
*.coverage
Expand All @@ -27,6 +27,8 @@ docs
examples
htmlcov
test-reports
tests
redis_data
venv
config.yml
docker-compose.dev.yml
232 changes: 149 additions & 83 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,82 +1,81 @@
name: Build and Push Docker image
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.
#
# Docker tags created:
# - CalVer tag (e.g., 2026.01.16)
# 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)
# - Git short hash (e.g., main-a1b2c3d)
# - latest (for main branch only)
# - Branch + short sha (e.g., main-a1b2c3d)

on:
push:
branches: [main, release-test]
branches: [main, release-test, optimize-docker-images]
tags: ['v*']

jobs:
build:
prepare:
runs-on: ubuntu-latest
permissions:
contents: write # Need write for creating tags
packages: write

contents: write
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 # Fetch all history for tags
fetch-depth: 0

- name: Generate CalVer version
id: calver
run: |
# Get today's date in YYYY.MM.DD format
TODAY=$(date +"%Y.%m.%d")

# Get all existing tags for today
EXISTING_TAGS=$(git tag -l "${TODAY}*" | sort -V)

if [ -z "$EXISTING_TAGS" ]; then
# No tags for today, use base date
VERSION="${TODAY}"
else
# Find the highest sequence number
LAST_TAG=$(echo "$EXISTING_TAGS" | tail -1)

if [[ "$LAST_TAG" == "$TODAY" ]]; then
# First tag was just the date, next is .2
VERSION="${TODAY}.2"
elif [[ "$LAST_TAG" =~ ^${TODAY}\.([0-9]+)$ ]]; then
# Extract sequence number and increment
SEQ="${BASH_REMATCH[1]}"
NEXT_SEQ=$((SEQ + 1))
VERSION="${TODAY}.${NEXT_SEQ}"
else
# Fallback
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 "full_sha=$(git rev-parse 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"

# Check if tag already exists

if git rev-parse "${{ steps.calver.outputs.version }}" >/dev/null 2>&1; then
echo "Tag ${{ steps.calver.outputs.version }} already exists, skipping"
else
Expand All @@ -85,6 +84,44 @@ jobs:
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

Expand All @@ -95,70 +132,100 @@ jobs:
username: ${{ secrets.AWS_ACCESS_KEY }}
password: ${{ secrets.AWS_SECRET }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server
tags: |
# CalVer tag (e.g., 2026.01.16)
type=raw,value=${{ steps.calver.outputs.version }},enable=${{ github.ref == 'refs/heads/main' }}
# Branch name
type=ref,event=branch
# PR number
type=ref,event=pr
# Semver tags (for manual v* tags)
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
# Git sha with branch prefix
type=sha,prefix={{branch}}-
# Latest tag for main branch
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}

- name: Build and push Docker image
- name: Build and push ${{ matrix.service }} (${{ matrix.platform_tag }})
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile
platforms: linux/amd64
file: ${{ matrix.dockerfile }}
platforms: ${{ matrix.platform }}
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
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=${{ steps.calver.outputs.version }}
VCON_SERVER_GIT_COMMIT=${{ steps.git.outputs.short_sha }}
VCON_SERVER_BUILD_TIME=${{ steps.git.outputs.build_time }}
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
if: github.ref == 'refs/heads/main'
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.calver.outputs.version }}
name: Release ${{ steps.calver.outputs.version }}
tag_name: ${{ needs.prepare.outputs.version }}
name: Release ${{ needs.prepare.outputs.version }}
body: |
## Release ${{ steps.calver.outputs.version }}
**Commit:** ${{ steps.git.outputs.short_sha }}
**Build Time:** ${{ steps.git.outputs.build_time }}
## Release ${{ needs.prepare.outputs.version }}

**Commit:** ${{ needs.prepare.outputs.short_sha }}
**Build Time:** ${{ needs.prepare.outputs.build_time }}

### Docker Images

Pull using CalVer:
```bash
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server:${{ steps.calver.outputs.version }}
```

Pull using git hash:

Both images support `linux/amd64` and `linux/arm64`.

**API service** (FastAPI/uvicorn, lightweight):
```bash
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server:main-${{ steps.git.outputs.short_sha }}
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
```
Pull latest:

**Conserver service** (processing pipeline, full dependencies):
```bash
docker pull public.ecr.aws/r4g1k2s3/vcon-dev/vcon-server:latest
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
Expand All @@ -171,12 +238,11 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| **Version** | ${{ steps.calver.outputs.version }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Git Commit** | ${{ steps.git.outputs.short_sha }} |" >> $GITHUB_STEP_SUMMARY
echo "| **Build Time** | ${{ steps.git.outputs.build_time }} |" >> $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 Tags" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ tmp
.qodo

traefik/
redis_data/
Loading