Upload kernel deb straight to origin, bypassing Cloudflare's 100MB cap

The Actions runner is overseas, so git.chilldove.com resolves to Cloudflare anycast. Cloudflare free/pro rejects request bodies over 100MB with HTTP 413 at the edge, and the linux-image .deb exceeds 100MB, so every publish failed. The Gitea origin itself accepts the upload (verified to >=110MB); only the CDN edge rejects it.

Pin the publish curl to the registry origin via curl --resolve, sourced from the new PKG_ORIGIN_IP repo variable (no IP baked into git; SNI/Host stay git.chilldove.com so TLS and package routing are unchanged). Document the prerequisite in README and the migration spec.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-06-18 00:56:50 +08:00
parent c85b44c65a
commit 54afeb6762
3 changed files with 30 additions and 2 deletions
+24 -1
View File
@@ -18,6 +18,14 @@ env:
# https://git.chilldove.com/api/packages/icePigeon/debian
PKG_REGISTRY: ${{ github.server_url }}/api/packages/${{ github.repository_owner }}/debian
PKG_USER: ${{ github.repository_owner }}
# Optional origin pin for uploads. The kernel image .deb is >100 MB, which trips
# the request-body cap of a CDN/proxy fronting the registry (Cloudflare free/pro
# caps at 100 MB and returns 413 at the edge, before the body reaches Gitea — the
# origin itself accepts it). Set the Gitea repo/org variable PKG_ORIGIN_IP to the
# registry origin's address (the host behind the CDN) and the publish step pins the
# upload straight there via curl --resolve, bypassing the CDN. vars (unlike secrets)
# ARE available to workflow-level env. Leave empty if no CDN fronts uploads.
PKG_ORIGIN_IP: ${{ vars.PKG_ORIGIN_IP }}
# NOTE: PKG_TOKEN (the write:package secret) is declared at JOB level below. The
# secrets context is not available to workflow-level env, so a value set here
# would silently be empty.
@@ -283,10 +291,25 @@ jobs:
exit 1
fi
# The kernel image .deb is >100 MB, which trips the request-body cap of a
# CDN/proxy in front of the registry (Cloudflare free/pro = 100 MB) and 413s
# at the edge before the body reaches Gitea — the origin itself accepts it.
# If PKG_ORIGIN_IP is set, pin the upload straight to that origin so the
# oversized PUT never touches the CDN. SNI/Host stay $reg_host, so TLS and
# package routing are unchanged; only the TCP connect target moves.
reg_host=${PKG_REGISTRY#*://}; reg_host=${reg_host%%/*}
resolve=()
if [ -n "${PKG_ORIGIN_IP:-}" ]; then
resolve=(--resolve "${reg_host}:443:${PKG_ORIGIN_IP}")
echo "Uploading direct to origin ${PKG_ORIGIN_IP}, bypassing any CDN in front of ${reg_host}."
else
echo "PKG_ORIGIN_IP unset: uploading via DNS for ${reg_host}; if a CDN fronts it (e.g. Cloudflare, 100 MB cap) the kernel image will 413. Set the PKG_ORIGIN_IP variable to fix." >&2
fi
# Gitea returns 201/202 on upload, 409 when the file already exists.
upload() {
local f="$1" code
code=$(curl -sS -o /dev/null -w '%{http_code}' \
code=$(curl -sS -o /dev/null -w '%{http_code}' "${resolve[@]}" \
--user "$PKG_USER:$PKG_TOKEN" --upload-file "$f" \
"$PKG_REGISTRY/pool/stable/main/upload" || echo 000)
case "$code" in