diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index f2ea3d6..13ee3de 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -79,7 +79,27 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends build-essential libcurl4-openssl-dev libssl-dev - - name: Build elc fresh on the runner + - name: Restore elc binary from GCS cache + id: elc-cache + run: | + set -euo pipefail + # Cache key = SHA256 of both source files that produce elc + ELC_SRC_HASH=$(cat "$EL_HOME/dist/platform/elc.c" "$EL_HOME/el-compiler/runtime/el_runtime.c" | sha256sum | cut -c1-16) + CACHE_OBJ="gs://neuron-ci-cache/elc/linux-amd64/${ELC_SRC_HASH}/elc" + echo "elc_cache_key=${ELC_SRC_HASH}" >> "$GITHUB_OUTPUT" + echo "elc_cache_obj=${CACHE_OBJ}" >> "$GITHUB_OUTPUT" + if gsutil -q stat "$CACHE_OBJ" 2>/dev/null; then + echo "Cache hit: ${CACHE_OBJ}" + gsutil cp "$CACHE_OBJ" "$EL_HOME/dist/platform/elc" + chmod +x "$EL_HOME/dist/platform/elc" + echo "cache_hit=true" >> "$GITHUB_OUTPUT" + else + echo "Cache miss for key ${ELC_SRC_HASH}" + echo "cache_hit=false" >> "$GITHUB_OUTPUT" + fi + + - name: Build elc (cache miss only) + if: steps.elc-cache.outputs.cache_hit != 'true' run: | set -euo pipefail # The committed dist/platform/elc is arm64 from Will's mac. We @@ -93,6 +113,8 @@ jobs: -lcurl -lpthread -ldl -lm -lssl -lcrypto file dist/platform/elc ls -la dist/platform/elc + # Upload to GCS cache for future runs + gsutil cp dist/platform/elc "${{ steps.elc-cache.outputs.elc_cache_obj }}" || true - name: Compute image tag id: tag diff --git a/Dockerfile.stage b/Dockerfile.stage index 3c4dfc5..76682a2 100644 --- a/Dockerfile.stage +++ b/Dockerfile.stage @@ -25,6 +25,11 @@ WORKDIR /build # El runtime (shared by both binaries) COPY runtime/el_runtime.c runtime/el_runtime.h ./ +# Pre-compile el_runtime as a separate cached layer. +# el_runtime.c changes rarely; main.c changes every run. +# Splitting this out means el_runtime.o is cached across builds when only main.c changes. +RUN cc -O2 -c el_runtime.c -I. -o el_runtime.o + # ── Build neuron-web ────────────────────────────────────────────────────────── # # main.c was generated on the host by build-stage.sh from src/*.el via the @@ -35,7 +40,7 @@ COPY dist/main.c ./ RUN cc -O2 -rdynamic \ -o neuron-web \ - main.c web_stubs.c el_runtime.c \ + main.c web_stubs.c el_runtime.o \ -lcurl -lpthread -ldl -lm -lssl -lcrypto # ── Build soul-demo ─────────────────────────────────────────────────────────── @@ -44,7 +49,7 @@ COPY dist/vessel_stubs.c ./ RUN cc -O2 -rdynamic \ -o soul-demo \ - soul-demo.c vessel_stubs.c el_runtime.c \ + soul-demo.c vessel_stubs.c el_runtime.o \ -lcurl -lpthread -ldl -lm -lssl -lcrypto # ── Stage 2: runtime image ──────────────────────────────────────────────────── diff --git a/build-stage.sh b/build-stage.sh index 6bd5530..f78ecc0 100755 --- a/build-stage.sh +++ b/build-stage.sh @@ -89,6 +89,8 @@ sed "${SED_INPLACE[@]}" \ echo "==> Building Docker image marketing:${TAG} for linux/amd64" docker buildx build --platform linux/amd64 --load \ + --cache-from type=registry,ref=us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:cache \ + --cache-to type=registry,ref=us-central1-docker.pkg.dev/neuron-785695/neuron-marketing/marketing:cache,mode=max \ -f Dockerfile.stage \ -t "marketing:${TAG}" \ .