Skip to content

Commit 8c357cf

Browse files
committed
Split Docker build workflow into full and slim variants
Refactored the Docker build workflow by renaming the original workflow to 'docker-build-full.yml' for the full image variant and creating a new 'docker-build-slim.yml' for the slim variant. Each workflow now independently handles its respective build, push, and smoke test logic. Added 'docs/docker-workflows.md' to document the new workflow structure, triggers, image tags, and build behavior for both variants.
1 parent 99fb403 commit 8c357cf

File tree

3 files changed

+351
-56
lines changed

3 files changed

+351
-56
lines changed

.github/workflows/docker-build.yml renamed to .github/workflows/docker-build-full.yml

Lines changed: 17 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Docker Build and Push
1+
name: Docker Build and Push (Full)
22

33
on:
44
push:
@@ -15,7 +15,7 @@ env:
1515
DOCKERHUB_NAMESPACE: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_USERNAME || github.repository_owner }}
1616

1717
jobs:
18-
build-and-push:
18+
build-and-push-full:
1919
runs-on: ubuntu-latest
2020
permissions:
2121
contents: read
@@ -95,8 +95,8 @@ jobs:
9595
username: ${{ github.actor }}
9696
password: ${{ secrets.GITHUB_TOKEN }}
9797

98-
- name: Extract metadata (full variant)
99-
id: meta-full
98+
- name: Extract metadata
99+
id: meta
100100
if: steps.build-config.outputs.push == 'true'
101101
uses: docker/metadata-action@v5
102102
with:
@@ -115,74 +115,34 @@ jobs:
115115
flavor: |
116116
latest=auto
117117
118-
- name: Extract metadata (slim variant)
119-
id: meta-slim
120-
if: steps.build-config.outputs.push == 'true'
121-
uses: docker/metadata-action@v5
122-
with:
123-
images: |
124-
${{ env.DOCKERHUB_NAMESPACE }}/ttsfm
125-
${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
126-
tags: |
127-
type=semver,pattern=v{{version}},suffix=-slim
128-
labels: |
129-
org.opencontainers.image.source=${{ github.repositoryUrl }}
130-
org.opencontainers.image.description=Free TTS API server compatible with OpenAI's TTS API format using openai.fm (slim variant without ffmpeg)
131-
org.opencontainers.image.licenses=MIT
132-
org.opencontainers.image.title=TTSFM - Free TTS API Server (Slim)
133-
org.opencontainers.image.vendor=dbcccc
134-
135-
- name: Set local image metadata (full variant)
136-
id: meta-local-full
118+
- name: Set local image metadata
119+
id: meta-local
137120
if: steps.build-config.outputs.push != 'true'
138121
run: |
139122
echo "tags=${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}:ci-${GITHUB_RUN_ID}-full" >> "$GITHUB_OUTPUT"
140123
echo "labels=org.opencontainers.image.source=${{ github.repositoryUrl }}" >> "$GITHUB_OUTPUT"
141124
142-
- name: Set local image metadata (slim variant)
143-
id: meta-local-slim
144-
if: steps.build-config.outputs.push != 'true'
145-
run: |
146-
echo "tags=${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}:ci-${GITHUB_RUN_ID}-slim" >> "$GITHUB_OUTPUT"
147-
echo "labels=org.opencontainers.image.source=${{ github.repositoryUrl }}" >> "$GITHUB_OUTPUT"
148-
149-
- name: Build and push full image
150-
id: build-and-push-full
125+
- name: Build and push image
126+
id: build-and-push
151127
uses: docker/build-push-action@v5
152128
with:
153129
context: .
154130
platforms: ${{ steps.build-config.outputs.platforms }}
155131
push: ${{ steps.build-config.outputs.push == 'true' }}
156132
load: ${{ steps.build-config.outputs.load == 'true' }}
157-
tags: ${{ steps.meta-full.outputs.tags || steps.meta-local-full.outputs.tags }}
158-
labels: ${{ steps.meta-full.outputs.labels || steps.meta-local-full.outputs.labels }}
133+
tags: ${{ steps.meta.outputs.tags || steps.meta-local.outputs.tags }}
134+
labels: ${{ steps.meta.outputs.labels || steps.meta-local.outputs.labels }}
159135
cache-from: type=gha,scope=full
160136
cache-to: type=gha,mode=max,scope=full
161137
build-args: |
162138
VERSION=${{ steps.version.outputs.version }}
163139
VARIANT=full
164140
165-
- name: Build and push slim image
166-
id: build-and-push-slim
167-
uses: docker/build-push-action@v5
168-
with:
169-
context: .
170-
platforms: ${{ steps.build-config.outputs.platforms }}
171-
push: ${{ steps.build-config.outputs.push == 'true' }}
172-
load: false
173-
tags: ${{ steps.meta-slim.outputs.tags || steps.meta-local-slim.outputs.tags }}
174-
labels: ${{ steps.meta-slim.outputs.labels || steps.meta-local-slim.outputs.labels }}
175-
cache-from: type=gha,scope=slim
176-
cache-to: type=gha,mode=max,scope=slim
177-
build-args: |
178-
VERSION=${{ steps.version.outputs.version }}
179-
VARIANT=slim
180-
181-
- name: Smoke test full image
141+
- name: Smoke test image
182142
if: steps.build-config.outputs.load == 'true'
183143
run: |
184144
set -euo pipefail
185-
IMAGE="${{ steps.meta-local-full.outputs.tags }}"
145+
IMAGE="${{ steps.meta-local.outputs.tags }}"
186146
echo "Running smoke test for full image: $IMAGE"
187147
docker rm -f ttsfm-smoke >/dev/null 2>&1 || true
188148
docker run -d --name ttsfm-smoke -p 127.0.0.1:8000:8000 "$IMAGE"
@@ -204,7 +164,8 @@ jobs:
204164
205165
- name: Show image info
206166
run: |
207-
echo "Full image tags: ${{ steps.meta-full.outputs.tags || steps.meta-local-full.outputs.tags }}"
208-
echo "Full image digest: ${{ steps.build-and-push-full.outputs.digest }}"
209-
echo "Slim image tags: ${{ steps.meta-slim.outputs.tags || steps.meta-local-slim.outputs.tags }}"
210-
echo "Slim image digest: ${{ steps.build-and-push-slim.outputs.digest }}"
167+
echo "Variant: full"
168+
echo "Push enabled: ${{ steps.build-config.outputs.push }}"
169+
echo "Image tags: ${{ steps.meta.outputs.tags || steps.meta-local.outputs.tags }}"
170+
echo "Image digest: ${{ steps.build-and-push.outputs.digest }}"
171+
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
name: Docker Build and Push (Slim)
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
release:
9+
types: [published]
10+
11+
env:
12+
REGISTRY_DOCKERHUB: docker.io
13+
REGISTRY_GHCR: ghcr.io
14+
IMAGE_NAME: ${{ github.repository }}
15+
DOCKERHUB_NAMESPACE: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_USERNAME || github.repository_owner }}
16+
17+
jobs:
18+
build-and-push-slim:
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: read
22+
packages: write
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
27+
- name: Determine build settings
28+
id: build-config
29+
env:
30+
EVENT_NAME: ${{ github.event_name }}
31+
EVENT_ACTION: ${{ github.event.action }}
32+
run: |
33+
if [ "$EVENT_NAME" = "release" ] && [ "$EVENT_ACTION" = "published" ]; then
34+
echo "push=true" >> "$GITHUB_OUTPUT"
35+
echo "platforms=linux/amd64,linux/arm64" >> "$GITHUB_OUTPUT"
36+
echo "load=false" >> "$GITHUB_OUTPUT"
37+
else
38+
echo "push=false" >> "$GITHUB_OUTPUT"
39+
echo "platforms=linux/amd64" >> "$GITHUB_OUTPUT"
40+
echo "load=true" >> "$GITHUB_OUTPUT"
41+
fi
42+
43+
- name: Derive image version
44+
id: version
45+
env:
46+
EVENT_NAME: ${{ github.event_name }}
47+
TAG_NAME: ${{ github.event.release.tag_name }}
48+
REF_NAME: ${{ github.ref_name }}
49+
GITHUB_SHA: ${{ github.sha }}
50+
run: |
51+
version=""
52+
if [ "$EVENT_NAME" = "release" ] && [ -n "$TAG_NAME" ]; then
53+
version="$TAG_NAME"
54+
elif [ -n "$REF_NAME" ]; then
55+
version="$REF_NAME"
56+
fi
57+
version="${version##*/}"
58+
if [ "${version#v}" != "$version" ]; then
59+
version="${version#v}"
60+
fi
61+
if [ -z "$version" ]; then
62+
version="${GITHUB_SHA:0:12}"
63+
fi
64+
if ! echo "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+'; then
65+
safe_branch=$(printf %s "$version" | tr -c 'A-Za-z0-9' '-')
66+
safe_branch=${safe_branch%-}
67+
if [ -z "$safe_branch" ]; then
68+
safe_branch="sha-${GITHUB_SHA:0:12}"
69+
fi
70+
version="0.0.0+${safe_branch}"
71+
fi
72+
echo "version=$version" >> "$GITHUB_OUTPUT"
73+
74+
- name: Set up QEMU
75+
if: steps.build-config.outputs.platforms == 'linux/amd64,linux/arm64'
76+
uses: docker/setup-qemu-action@v3
77+
78+
- name: Set up Docker Buildx
79+
uses: docker/setup-buildx-action@v3
80+
with:
81+
driver: docker-container
82+
83+
- name: Login to Docker Hub
84+
if: steps.build-config.outputs.push == 'true'
85+
uses: docker/login-action@v3
86+
with:
87+
username: ${{ secrets.DOCKERHUB_USERNAME }}
88+
password: ${{ secrets.DOCKERHUB_TOKEN }}
89+
90+
- name: Login to GitHub Container Registry
91+
if: steps.build-config.outputs.push == 'true'
92+
uses: docker/login-action@v3
93+
with:
94+
registry: ${{ env.REGISTRY_GHCR }}
95+
username: ${{ github.actor }}
96+
password: ${{ secrets.GITHUB_TOKEN }}
97+
98+
- name: Extract metadata
99+
id: meta
100+
if: steps.build-config.outputs.push == 'true'
101+
uses: docker/metadata-action@v5
102+
with:
103+
images: |
104+
${{ env.DOCKERHUB_NAMESPACE }}/ttsfm
105+
${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
106+
tags: |
107+
type=semver,pattern=v{{version}},suffix=-slim
108+
type=semver,pattern=v{{major}}.{{minor}},suffix=-slim,enable=${{ !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') }}
109+
labels: |
110+
org.opencontainers.image.source=${{ github.repositoryUrl }}
111+
org.opencontainers.image.description=Free TTS API server compatible with OpenAI's TTS API format using openai.fm (slim variant without ffmpeg)
112+
org.opencontainers.image.licenses=MIT
113+
org.opencontainers.image.title=TTSFM - Free TTS API Server (Slim)
114+
org.opencontainers.image.vendor=dbcccc
115+
116+
- name: Set local image metadata
117+
id: meta-local
118+
if: steps.build-config.outputs.push != 'true'
119+
run: |
120+
echo "tags=${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}:ci-${GITHUB_RUN_ID}-slim" >> "$GITHUB_OUTPUT"
121+
echo "labels=org.opencontainers.image.source=${{ github.repositoryUrl }}" >> "$GITHUB_OUTPUT"
122+
123+
- name: Build and push image
124+
id: build-and-push
125+
uses: docker/build-push-action@v5
126+
with:
127+
context: .
128+
platforms: ${{ steps.build-config.outputs.platforms }}
129+
push: ${{ steps.build-config.outputs.push == 'true' }}
130+
load: ${{ steps.build-config.outputs.load == 'true' }}
131+
tags: ${{ steps.meta.outputs.tags || steps.meta-local.outputs.tags }}
132+
labels: ${{ steps.meta.outputs.labels || steps.meta-local.outputs.labels }}
133+
cache-from: type=gha,scope=slim
134+
cache-to: type=gha,mode=max,scope=slim
135+
build-args: |
136+
VERSION=${{ steps.version.outputs.version }}
137+
VARIANT=slim
138+
139+
- name: Smoke test image
140+
if: steps.build-config.outputs.load == 'true'
141+
run: |
142+
set -euo pipefail
143+
IMAGE="${{ steps.meta-local.outputs.tags }}"
144+
echo "Running smoke test for slim image: $IMAGE"
145+
docker rm -f ttsfm-smoke-slim >/dev/null 2>&1 || true
146+
docker run -d --name ttsfm-smoke-slim -p 127.0.0.1:8001:8000 "$IMAGE"
147+
success=""
148+
for attempt in $(seq 1 10); do
149+
if curl --fail --silent --max-time 5 http://127.0.0.1:8001/api/health > /tmp/ttsfm-health-slim.json; then
150+
success="yes"
151+
cat /tmp/ttsfm-health-slim.json
152+
break
153+
fi
154+
sleep 3
155+
done
156+
docker logs ttsfm-smoke-slim || true
157+
docker rm -f ttsfm-smoke-slim >/dev/null 2>&1 || true
158+
if [ -z "$success" ]; then
159+
echo "Container health check failed" >&2
160+
exit 1
161+
fi
162+
163+
- name: Show image info
164+
run: |
165+
echo "Variant: slim"
166+
echo "Push enabled: ${{ steps.build-config.outputs.push }}"
167+
echo "Image tags: ${{ steps.meta.outputs.tags || steps.meta-local.outputs.tags }}"
168+
echo "Image digest: ${{ steps.build-and-push.outputs.digest }}"
169+

0 commit comments

Comments
 (0)