From d95b44f8c7ae38c0fbfb42abc380fc21f88ead0a Mon Sep 17 00:00:00 2001 From: Nikolay Bryskin Date: Tue, 23 Jun 2026 09:48:41 +0300 Subject: [PATCH] Add CI workflow that builds the podman image Adds a GitHub Actions workflow that builds the container image with podman on push to master, pull requests, and manual dispatch. On master it also populates a registry-backed layer cache and pushes the image (and tools image) to GHCR via the built-in GITHUB_TOKEN; PR/manual runs build only. podman has no GHA cache backend, so cross-run caching uses --cache-to/ --cache-from against ghcr.io//buildcache, keeping the expensive TDLib/tgcalls/WebRTC layers warm between runs. Also fixes the Containerfile, which never copied video_platform.cpp after 935f6a7 added it to the tgcalls target in CMakeLists.txt, so `make image` was already broken. Copied after the TDLib build so editing it doesn't bust the cached TDLib layer. The Makefile gains an IMAGE_BUILD_ARGS hook so CI injects the cache flags through `make image`/`make push` without diverging from the local build command. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build-image.yml | 58 +++++++++++++++++++++++++++++++ Containerfile | 5 +++ Makefile | 6 +++- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-image.yml diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml new file mode 100644 index 0000000..9c1038f --- /dev/null +++ b/.github/workflows/build-image.yml @@ -0,0 +1,58 @@ +name: build-image + +on: + push: + branches: [master] + pull_request: + workflow_dispatch: + +# This build is heavy (TDLib + tgcalls + WebRTC from source); cancel runs +# superseded by a newer commit on the same ref. +concurrency: + group: build-image-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + packages: write + +env: + # GHCR image, derived from the repo (e.g. ghcr.io/nikicat/tg-echo-service). + # Assumes the repo owner/name are lowercase, as GHCR requires. + IMAGE: ghcr.io/${{ github.repository }} + # Registry-backed layer cache. podman has no GHA cache backend, so it + # pushes/pulls intermediate layers to this repo instead, letting the + # expensive TDLib/tgcalls/WebRTC layers survive across runs. + CACHE_REPO: ghcr.io/${{ github.repository }}/buildcache + +jobs: + build: + runs-on: ubuntu-24.04 # podman 4.9 — supports --layers --cache-to/--cache-from + timeout-minutes: 360 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Free up disk space + run: | + sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/.ghcup \ + /usr/local/lib/android /opt/hostedtoolcache/CodeQL + df -h / + + - name: Log in to GHCR + run: echo "${{ secrets.GITHUB_TOKEN }}" | podman login ghcr.io -u "${{ github.actor }}" --password-stdin + + # Pull request / manual runs: build only, read from cache, never push. + - name: Build image + if: github.event_name != 'push' || github.ref != 'refs/heads/master' + run: | + make image IMAGE="$IMAGE" \ + IMAGE_BUILD_ARGS="--layers --cache-from $CACHE_REPO" + + # master: build, populate the cache, and push the image + tools image. + - name: Build and push image + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + run: | + make push IMAGE="$IMAGE" \ + IMAGE_BUILD_ARGS="--layers --cache-from $CACHE_REPO --cache-to $CACHE_REPO" diff --git a/Containerfile b/Containerfile index 6bab201..5b19d8b 100644 --- a/Containerfile +++ b/Containerfile @@ -16,6 +16,11 @@ RUN cmake -B vendor/td/build -S vendor/td -DCMAKE_BUILD_TYPE=Release && \ cmake --build vendor/td/build -j$(nproc) && \ cmake --install vendor/td/build --prefix /src/td-install +# Custom tgcalls platform source (compiled into the tgcalls lib, so it must +# exist at configure time). Copied after TDLib so editing it doesn't bust the +# cached TDLib layer, but before configure since CMakeLists.txt references it. +COPY video_platform.cpp . + # Configure and build all deps (tgcalls pulls in webrtc, absl, etc.) RUN touch main.cpp && cmake -B build -DCMAKE_BUILD_TYPE=Release RUN cmake --build build -j$(nproc) --target tgcalls diff --git a/Makefile b/Makefile index 74ecd92..5ae2a2f 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,10 @@ export CMAKE_BUILD_PARALLEL_LEVEL IMAGE ?= docker.io/nikicat/tg-echo-service +# Extra flags for the main image build. CI injects layer-cache flags here +# (e.g. --layers --cache-from/--cache-to ); empty for local builds. +IMAGE_BUILD_ARGS ?= + .PHONY: all submodules tdlib configure build clean run run-only prompt glados-prompt image image-tools push push-tools all: build @@ -72,7 +76,7 @@ image-tools: podman build -t $(IMAGE)-tools -f Containerfile.tools . image: image-tools submodules - podman build -t $(IMAGE) . + podman build $(IMAGE_BUILD_ARGS) -t $(IMAGE) . push-tools: image-tools podman push $(IMAGE)-tools