Skip to content

Commit a38f50a

Browse files
authored
build: parallelize Docker builds for ~50% speed improvement (#21)
* build: parallelize Docker builds for ~50% speed improvement Split sequential Docker builds into parallel GPU/CPU jobs: - docker-pr → docker-pr-gpu + docker-pr-cpu (parallel) - docker-main → docker-main-gpu + docker-main-cpu (parallel) - docker-prod → docker-prod-gpu + docker-prod-cpu (parallel) Benefits: - GPU and CPU images build simultaneously instead of sequentially - Reduces CI/CD Docker build time by approximately 50% - Better GitHub Actions runner resource utilization - Maintains all existing functionality and outputs * build: fix redundant Docker builds during releases Prevent docker-main jobs from running during releases by: - Adding 'release' to needs dependencies - Excluding when release_created is true Now: - Regular main pushes → docker-main jobs run (:main tags) - Release pushes → only docker-prod jobs run (semantic tags) - Eliminates redundant builds, saves CI/CD resources * chore: update deps, claude, and make smoketest-macos * build: fix Docker release tagging to generate exact version and latest tags - Fix conditional logic: only run docker-prod jobs on actual releases - Simplify tag patterns: generate only {{version}} and latest tags - Results in exactly 4 tags per release: - runpod/tetra-rp:latest, runpod/tetra-rp:v1.2.3 - runpod/tetra-rp-cpu:latest, runpod/tetra-rp-cpu:v1.2.3 * chore: cleanup
1 parent f1826e2 commit a38f50a

File tree

4 files changed

+258
-138
lines changed

4 files changed

+258
-138
lines changed

.github/workflows/ci.yml

Lines changed: 139 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ jobs:
130130
release-type: python
131131
token: ${{ secrets.GITHUB_TOKEN }}
132132

133-
docker-pr:
133+
docker-pr-gpu:
134134
runs-on: ubuntu-latest
135135
needs: [test, lint, local-execution-test]
136136
if: github.event_name == 'pull_request'
@@ -177,6 +177,46 @@ jobs:
177177
cache-to: type=gha,mode=max
178178
load: true
179179

180+
- name: Test GPU Docker image with handler test suite
181+
run: |
182+
echo "Testing GPU image with handler test suite..."
183+
docker run --rm tetra-rp:pr-test ./test-handler.sh
184+
185+
docker-pr-cpu:
186+
runs-on: ubuntu-latest
187+
needs: [test, lint, local-execution-test]
188+
if: github.event_name == 'pull_request'
189+
steps:
190+
- name: Clear Space
191+
run: |
192+
rm -rf /usr/share/dotnet
193+
rm -rf /opt/ghc
194+
rm -rf "/usr/local/share/boost"
195+
rm -rf "$AGENT_TOOLSDIRECTORY"
196+
197+
- name: Checkout repository
198+
uses: actions/checkout@v4
199+
with:
200+
submodules: recursive
201+
fetch-depth: 0
202+
203+
- name: Set up QEMU
204+
uses: docker/setup-qemu-action@v3
205+
206+
- name: Set up Docker Buildx
207+
uses: docker/setup-buildx-action@v3
208+
209+
- name: Set up uv
210+
uses: astral-sh/setup-uv@v4
211+
with:
212+
enable-cache: true
213+
214+
- name: Setup dependencies
215+
run: |
216+
uv sync
217+
git submodule update --remote --merge
218+
cp tetra-rp/src/tetra_rp/protos/remote_execution.py src/
219+
180220
- name: Build and test CPU Docker image (PR)
181221
uses: docker/build-push-action@v6
182222
with:
@@ -189,20 +229,15 @@ jobs:
189229
cache-to: type=gha,mode=max
190230
load: true
191231

192-
- name: Test GPU Docker image with handler test suite
193-
run: |
194-
echo "Testing GPU image with handler test suite..."
195-
docker run --rm tetra-rp:pr-test ./test-handler.sh
196-
197232
- name: Test CPU Docker image with handler test suite
198233
run: |
199234
echo "Testing CPU image with handler test suite..."
200235
docker run --rm tetra-rp-cpu:pr-test ./test-handler.sh
201236
202-
docker-main:
237+
docker-main-gpu:
203238
runs-on: ubuntu-latest
204-
needs: [test, lint, local-execution-test]
205-
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
239+
needs: [test, lint, local-execution-test, release]
240+
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && !needs.release.outputs.release_created
206241
steps:
207242
- name: Clear Space
208243
run: |
@@ -252,6 +287,48 @@ jobs:
252287
cache-from: type=gha
253288
cache-to: type=gha,mode=max
254289

290+
docker-main-cpu:
291+
runs-on: ubuntu-latest
292+
needs: [test, lint, local-execution-test, release]
293+
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && !needs.release.outputs.release_created
294+
steps:
295+
- name: Clear Space
296+
run: |
297+
rm -rf /usr/share/dotnet
298+
rm -rf /opt/ghc
299+
rm -rf "/usr/local/share/boost"
300+
rm -rf "$AGENT_TOOLSDIRECTORY"
301+
302+
- name: Checkout repository
303+
uses: actions/checkout@v4
304+
with:
305+
submodules: recursive
306+
fetch-depth: 0
307+
308+
- name: Set up QEMU
309+
uses: docker/setup-qemu-action@v3
310+
311+
- name: Set up Docker Buildx
312+
uses: docker/setup-buildx-action@v3
313+
314+
- name: Login to Docker Hub
315+
uses: docker/login-action@v3
316+
with:
317+
registry: ${{ env.REGISTRY }}
318+
username: ${{ secrets.DOCKERHUB_USERNAME }}
319+
password: ${{ secrets.DOCKERHUB_TOKEN }}
320+
321+
- name: Set up uv
322+
uses: astral-sh/setup-uv@v4
323+
with:
324+
enable-cache: true
325+
326+
- name: Setup dependencies
327+
run: |
328+
uv sync
329+
git submodule update --remote --merge
330+
cp tetra-rp/src/tetra_rp/protos/remote_execution.py src/
331+
255332
- name: Build and push CPU Docker image (main)
256333
uses: docker/build-push-action@v6
257334
with:
@@ -264,10 +341,10 @@ jobs:
264341
cache-to: type=gha,mode=max
265342

266343

267-
docker-prod:
344+
docker-prod-gpu:
268345
runs-on: ubuntu-latest
269346
needs: [release]
270-
if: needs.release.outputs.release_created || (github.ref == 'refs/heads/main' && needs.release.outputs.tag_name)
347+
if: needs.release.outputs.release_created
271348
steps:
272349
- name: Clear Space
273350
run: |
@@ -301,24 +378,7 @@ jobs:
301378
with:
302379
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
303380
tags: |
304-
type=ref,event=branch
305-
type=ref,event=pr
306-
type=semver,pattern={{version}}
307-
type=semver,pattern={{major}}.{{minor}}
308-
type=semver,pattern={{major}}
309-
type=raw,value=latest,enable={{is_default_branch}}
310-
311-
- name: Extract CPU metadata
312-
id: meta-cpu
313-
uses: docker/metadata-action@v5
314-
with:
315-
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-cpu
316-
tags: |
317-
type=ref,event=branch
318-
type=ref,event=pr
319381
type=semver,pattern={{version}}
320-
type=semver,pattern={{major}}.{{minor}}
321-
type=semver,pattern={{major}}
322382
type=raw,value=latest,enable={{is_default_branch}}
323383
324384
- name: Set up uv
@@ -344,6 +404,57 @@ jobs:
344404
cache-from: type=gha
345405
cache-to: type=gha,mode=max
346406

407+
docker-prod-cpu:
408+
runs-on: ubuntu-latest
409+
needs: [release]
410+
if: needs.release.outputs.release_created
411+
steps:
412+
- name: Clear Space
413+
run: |
414+
rm -rf /usr/share/dotnet
415+
rm -rf /opt/ghc
416+
rm -rf "/usr/local/share/boost"
417+
rm -rf "$AGENT_TOOLSDIRECTORY"
418+
419+
- name: Checkout repository
420+
uses: actions/checkout@v4
421+
with:
422+
submodules: recursive
423+
fetch-depth: 0
424+
425+
- name: Set up QEMU
426+
uses: docker/setup-qemu-action@v3
427+
428+
- name: Set up Docker Buildx
429+
uses: docker/setup-buildx-action@v3
430+
431+
- name: Login to Docker Hub
432+
uses: docker/login-action@v3
433+
with:
434+
registry: ${{ env.REGISTRY }}
435+
username: ${{ secrets.DOCKERHUB_USERNAME }}
436+
password: ${{ secrets.DOCKERHUB_TOKEN }}
437+
438+
- name: Extract CPU metadata
439+
id: meta-cpu
440+
uses: docker/metadata-action@v5
441+
with:
442+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-cpu
443+
tags: |
444+
type=semver,pattern={{version}}
445+
type=raw,value=latest,enable={{is_default_branch}}
446+
447+
- name: Set up uv
448+
uses: astral-sh/setup-uv@v4
449+
with:
450+
enable-cache: true
451+
452+
- name: Setup dependencies
453+
run: |
454+
uv sync
455+
git submodule update --remote --merge
456+
cp tetra-rp/src/tetra_rp/protos/remote_execution.py src/
457+
347458
- name: Build and push CPU Docker image (prod)
348459
uses: docker/build-push-action@v6
349460
with:

CLAUDE.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,9 @@ Configure these in GitHub repository settings:
255255

256256
## Development Best Practices
257257

258-
- Always run `make quality-check` before committing changes
258+
- Always run `make quality-check` before committing changes
259+
260+
## Project Memories
261+
262+
### Docker Guidelines
263+
- Docker container should never refer to src/

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ test-fast: # Run tests with fast-fail mode
7070
test-handler: # Test handler locally with all test_*.json files
7171
./test-handler.sh
7272

73+
# Smoke Tests (local on Mac OS)
74+
75+
smoketest-macos-build: setup # Build CPU-only Mac OS Docker image (macos/arm64)
76+
docker buildx build \
77+
--platform linux/arm64 \
78+
-f Dockerfile-cpu \
79+
-t $(FULL_IMAGE_CPU)-mac \
80+
. --load
81+
82+
smoketest-macos: smoketest-macos-build # Test CPU Docker image locally
83+
docker run --rm $(FULL_IMAGE_CPU)-mac ./test-handler.sh
84+
7385
# Linting commands
7486
lint: # Check code with ruff
7587
uv run ruff check .

0 commit comments

Comments
 (0)