Init Project
Some checks failed
Go CI Pipeline / build_and_test (push) Failing after 22m0s

This commit is contained in:
enkly
2026-10-30 18:06:55 +01:00
parent da8af794bd
commit 79ce8dc4c0
211 changed files with 44434 additions and 1 deletions

211
.gitea/workflows/ci.yaml Normal file
View File

@@ -0,0 +1,211 @@
name: Go CI Pipeline
on: [push, pull_request]
jobs:
build_and_test:
runs-on: ubuntu-latest
# Start a Docker-in-Docker service container
services:
docker:
image: docker:dind
# --dns pins the dind container to reliable public resolvers instead
# of whatever it inherits from the runner host. Without this, the
# embedded 127.0.0.11 resolver inside dind intermittently fails to
# forward lookups for the registry host ("server misbehaving"),
# which otherwise kills `docker push` nondeterministically.
options: --privileged --dns 1.1.1.1 --dns 8.8.8.8
env:
DOCKER_TLS_CERTDIR: ""
# Point docker CLI to the dind container
env:
DOCKER_HOST: tcp://docker:2375
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.23"
- name: Install dependencies
run: go mod tidy && go mod download
- name: Vet and test
run: |
go vet ./...
go test ./...
- name: Login to private registry
uses: docker/login-action@v3
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push container images
run: |
set -e
REG="${{ secrets.REGISTRY_URL }}/enkly"
SHA="${GITHUB_SHA:-$(git rev-parse HEAD)}"
# Retry helper: docker push against the dind service occasionally
# hits a transient "server misbehaving" DNS failure (127.0.0.11
# couldn't resolve the registry host) rather than a real error.
# Retry a few times with backoff before giving up for real.
push_with_retry() {
local ref="$1"
local attempt=1
local max_attempts=5
until docker push "$ref"; do
if [ "$attempt" -ge "$max_attempts" ]; then
echo "::error::docker push $ref failed after $max_attempts attempts"
return 1
fi
local wait=$((attempt * 5))
echo "push of $ref failed (attempt $attempt/$max_attempts); retrying in ${wait}s..."
sleep "$wait"
attempt=$((attempt + 1))
done
}
for svc in iam billing conversation workspace knowledge agent notification gateway; do
docker build -f services/$svc/Dockerfile -t "$REG/$svc:$SHA" -t "$REG/$svc:latest" .
push_with_retry "$REG/$svc:$SHA"
push_with_retry "$REG/$svc:latest"
done
- name: Build and push vLLM CPU (no AVX512) image
# This is NOT one of the 8 enkly service images above — it's the
# custom vllm/vllm-openai build that k8s/11-vllm.yaml's vllm-chat
# and vllm-embed Deployments require instead of the official
# public.ecr.aws/q9t5s3a7/vllm-cpu-release-repo image, because
# that pre-built image hard-requires avx512f (missing on the
# target cluster's nodes) and crashes with "Illegal instruction"
# without it. Source and build args match k8s/11-vllm.yaml's and
# k8s/README.md's documented command, plus an explicit max_jobs
# cap explained below.
#
# Root cause of the previous failure ("Cannot connect to the
# Docker daemon at tcp://localhost:2375" mid-build): vLLM's
# docker/Dockerfile.cpu defaults to `ARG max_jobs=32`, i.e. 32
# parallel C++ translation units (oneDNN/cutlass kernels etc.)
# compiling at once, each easily using >1GB RES. The dind
# service here — like the target cluster's own nodes (see
# k8s/README.md: ~7949Mi/~7.76Gi per node) — only has a few GB
# of RAM and 2 vCPUs, nowhere near enough for 32-way parallel
# compilation. The build log showed exactly this: individual
# objects going from ~1-10s to 317s (heavy swapping) right
# before the dind container's dockerd was OOM-killed, which
# drops the daemon out from under the still-running `docker
# build` and surfaces as a generic "cannot connect" error rather
# than an explicit OOM message. A plain retry doesn't fix this —
# dockerd itself died, so the service container is gone — only
# bounding parallelism does. We size MAX_JOBS off the runner's
# actual CPU count and memory (~2GB headroom per job) instead of
# trusting the Dockerfile's hardcoded default, floor 1.
#
# Caveat: this clones and compiles vLLM from source on every run
# of this job, on a small runner — expect this step alone to
# take a long time and to be the slowest part of the pipeline.
# If that becomes a problem, the usual fixes are: only run this
# step on a path filter scoped to a pinned vLLM version/tag
# instead of vLLM's default branch, add Docker layer caching
# (e.g. actions/cache or a registry-backed BuildKit cache), or
# move it to its own workflow that isn't triggered on every
# push/PR. We already pin the clone to a tagged vLLM release
# below so a build is reproducible and isn't broken by upstream
# `main` changing under us.
run: |
set -e
REG="${{ secrets.REGISTRY_URL }}/enkly"
SHA="${GITHUB_SHA:-$(git rev-parse HEAD)}"
VLLM_REF="v0.8.5"
push_with_retry() {
local ref="$1"
local attempt=1
local max_attempts=5
until docker push "$ref"; do
if [ "$attempt" -ge "$max_attempts" ]; then
echo "::error::docker push $ref failed after $max_attempts attempts"
return 1
fi
local wait=$((attempt * 5))
echo "push of $ref failed (attempt $attempt/$max_attempts); retrying in ${wait}s..."
sleep "$wait"
attempt=$((attempt + 1))
done
}
# Make sure the dind daemon is actually reachable before we
# kick off a build that can run for tens of minutes.
for i in $(seq 1 30); do
docker info >/dev/null 2>&1 && break
echo "waiting for docker daemon ($i/30)..."
sleep 2
done
docker info >/dev/null 2>&1 || { echo "::error::docker daemon at $DOCKER_HOST is not reachable"; exit 1; }
# Cap compile parallelism to what this runner can actually
# hold in memory, instead of the Dockerfile's hardcoded
# max_jobs=32 (see note above for why that OOM-kills dockerd).
# Budget ~2GB per compile job and never exceed the vCPU count.
CPU_COUNT="$(nproc 2>/dev/null || echo 2)"
MEM_KB="$(awk '/MemTotal/ {print $2}' /proc/meminfo 2>/dev/null || echo 0)"
MEM_JOBS=$((MEM_KB / 1024 / 1024 / 2))
MAX_JOBS="$CPU_COUNT"
if [ "$MEM_JOBS" -gt 0 ] && [ "$MEM_JOBS" -lt "$MAX_JOBS" ]; then
MAX_JOBS="$MEM_JOBS"
fi
[ "$MAX_JOBS" -lt 1 ] && MAX_JOBS=1
echo "Building vLLM with MAX_JOBS=$MAX_JOBS (cpu=$CPU_COUNT, mem_kb=$MEM_KB)"
# `git clone` below runs directly on the runner host (unlike
# `docker build`/push, it never touches $DOCKER_HOST), so the
# --dns 1.1.1.1/8.8.8.8 pin on the dind *service* above does
# nothing for it — that only fixes resolution for things the
# dind daemon itself does (image pulls, registry push). A
# host-level resolver hiccup ("Could not resolve host:
# github.com") is the same class of transient DNS flakiness
# called out in the dind `options` comment, just hitting a
# different resolver. Retry with backoff, and nudge the host
# resolver between attempts where we can (best-effort, never
# fatal if the tool/permission isn't there).
clone_with_retry() {
local attempt=1
local max_attempts=5
until git clone --depth 1 --branch "$VLLM_REF" https://github.com/vllm-project/vllm.git /tmp/vllm-build; do
if [ "$attempt" -ge "$max_attempts" ]; then
echo "::error::git clone of vllm-project/vllm failed after $max_attempts attempts"
return 1
fi
local wait=$((attempt * 5))
echo "git clone failed (attempt $attempt/$max_attempts, likely DNS); retrying in ${wait}s..."
sleep "$wait"
# Best-effort: if the host resolver cache is stuck, poke it.
# Ignore failures - these commands may not exist/be permitted.
(command -v resolvectl >/dev/null 2>&1 && sudo resolvectl flush-caches) || true
(command -v systemd-resolve >/dev/null 2>&1 && sudo systemd-resolve --flush-caches) || true
getent hosts github.com >/dev/null 2>&1 || true
rm -rf /tmp/vllm-build
attempt=$((attempt + 1))
done
}
rm -rf /tmp/vllm-build
clone_with_retry
docker build -f /tmp/vllm-build/docker/Dockerfile.cpu \
--build-arg VLLM_CPU_DISABLE_AVX512=true \
--build-arg max_jobs="$MAX_JOBS" \
--tag "$REG/vllm-cpu:$SHA" \
--tag "$REG/vllm-cpu:latest" \
--target vllm-openai \
/tmp/vllm-build
push_with_retry "$REG/vllm-cpu:$SHA"
push_with_retry "$REG/vllm-cpu:latest"