From c0920026776e5b269ae2fa360396ee32538b9041 Mon Sep 17 00:00:00 2001 From: Dan Crosby Date: Tue, 28 Jul 2026 11:44:41 -0700 Subject: [PATCH] Route CI LFS through Gitea (#8812) * Route CI LFS through Gitea * Add fresh Gitea LFS verification mode * Expose fresh LFS verification failures * Avoid duplicate Gitea LFS auth headers --- .github/workflows/docker_build.yml | 8 ++ .github/workflows/ios_testflight.yml | 2 + .github/workflows/mac_build.yml | 2 + .github/workflows/unity_build.yml | 4 + .lfsconfig | 3 + ci/github_actions/fetch_lfs.sh | 121 ++++++++++++++++++++++----- 6 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 .lfsconfig diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 22ba20a003..1499793036 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -59,6 +59,11 @@ on: required: true default: 'false' type: boolean + verify_gitea_lfs: + description: 'Force LFS download from an empty temporary cache' + required: true + default: 'false' + type: boolean # Only allow one deployment at a time; queue new ones (never cancel a running deploy). # The build-all job checks if it's still the latest commit on main and skips if not, @@ -134,6 +139,9 @@ jobs: - name: Fetch LFS files needed for admin server if: steps.check-latest.outputs.skip != 'true' env: + GITEA_LFS_TOKEN: ${{ secrets.GITEA_LFS_TOKEN }} + GITEA_LFS_USERNAME: ${{ secrets.GITEA_LFS_USERNAME }} + GITEA_LFS_VERIFY_FRESH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.verify_gitea_lfs == 'true' }} GITHUB_TOKEN: ${{ github.token }} run: ./ci/github_actions/fetch_lfs.sh --include="src/main/go/net/eagle0/admin_server/static/tiles/*" diff --git a/.github/workflows/ios_testflight.yml b/.github/workflows/ios_testflight.yml index f0b86a8efd..b49ff9cd79 100644 --- a/.github/workflows/ios_testflight.yml +++ b/.github/workflows/ios_testflight.yml @@ -154,6 +154,8 @@ jobs: - name: Fetch LFS files env: + GITEA_LFS_TOKEN: ${{ secrets.GITEA_LFS_TOKEN }} + GITEA_LFS_USERNAME: ${{ secrets.GITEA_LFS_USERNAME }} GITHUB_TOKEN: ${{ github.token }} run: ./ci/github_actions/fetch_lfs.sh diff --git a/.github/workflows/mac_build.yml b/.github/workflows/mac_build.yml index dfb9182bd3..cc58424565 100644 --- a/.github/workflows/mac_build.yml +++ b/.github/workflows/mac_build.yml @@ -159,6 +159,8 @@ jobs: - name: Fetch LFS files env: + GITEA_LFS_TOKEN: ${{ secrets.GITEA_LFS_TOKEN }} + GITEA_LFS_USERNAME: ${{ secrets.GITEA_LFS_USERNAME }} GITHUB_TOKEN: ${{ github.token }} run: ./ci/github_actions/fetch_lfs.sh diff --git a/.github/workflows/unity_build.yml b/.github/workflows/unity_build.yml index d985469ff4..0d9a45d987 100644 --- a/.github/workflows/unity_build.yml +++ b/.github/workflows/unity_build.yml @@ -148,6 +148,8 @@ jobs: - name: Fetch LFS files env: + GITEA_LFS_TOKEN: ${{ secrets.GITEA_LFS_TOKEN }} + GITEA_LFS_USERNAME: ${{ secrets.GITEA_LFS_USERNAME }} GITHUB_TOKEN: ${{ github.token }} run: ./ci/github_actions/fetch_lfs.sh - name: Ensure Unity version installed @@ -265,6 +267,8 @@ jobs: - name: Fetch LFS files env: + GITEA_LFS_TOKEN: ${{ secrets.GITEA_LFS_TOKEN }} + GITEA_LFS_USERNAME: ${{ secrets.GITEA_LFS_USERNAME }} GITHUB_TOKEN: ${{ github.token }} run: ./ci/github_actions/fetch_lfs.sh - name: Ensure Unity version installed diff --git a/.lfsconfig b/.lfsconfig new file mode 100644 index 0000000000..64043d5c2b --- /dev/null +++ b/.lfsconfig @@ -0,0 +1,3 @@ +[lfs] + url = https://gitea.eagle0.net/admin/eagle0-lfs.git/info/lfs + pushurl = https://gitea.eagle0.net/admin/eagle0-lfs.git/info/lfs diff --git a/ci/github_actions/fetch_lfs.sh b/ci/github_actions/fetch_lfs.sh index e6e734cd19..9b9bb3a7a7 100755 --- a/ci/github_actions/fetch_lfs.sh +++ b/ci/github_actions/fetch_lfs.sh @@ -1,9 +1,9 @@ #!/bin/bash -# Fetch LFS files from Gitea mirror with retry. +# Fetch LFS files from the private Gitea LFS repository with retry. # -# Gitea's mirror-sync API is async — the webhook fires on push but the -# actual sync may still be in progress when CI starts. Retry with backoff -# to bridge the gap. +# The primary endpoint is committed in .lfsconfig. CI supplies Gitea +# credentials through GITEA_LFS_USERNAME and GITEA_LFS_TOKEN. GitHub LFS +# remains a temporary fallback while the Gitea migration is verified. # # Usage: # ./ci/github_actions/fetch_lfs.sh # full pull @@ -16,6 +16,15 @@ export PATH="${COMMON_PATHS}:${PATH}" MAX_ATTEMPTS=5 RETRY_DELAY=15 +GITEA_LFS_URL="https://gitea.eagle0.net/admin/eagle0-lfs.git/info/lfs" +GITEA_CREDENTIAL_FILE="" + +cleanup() { + if [ -n "$GITEA_CREDENTIAL_FILE" ]; then + rm -f -- "$GITEA_CREDENTIAL_FILE" + fi +} +trap cleanup EXIT if [ -n "${GITHUB_PATH:-}" ]; then for path in /opt/homebrew/bin /usr/local/bin; do @@ -43,34 +52,106 @@ git lfs install --local --force echo "LFS objects before pull:" git lfs ls-files | wc -l -GIT_LFS_PULL=(git lfs pull) +GITEA_LFS_PULL=() FALLBACK_GITHUB_LFS_PULL=() +GITEA_CREDENTIAL_CONFIG=() +GITEA_LFS_STORAGE_CONFIG=() + +if [ "${GITEA_LFS_VERIFY_FRESH:-}" = "true" ]; then + if [ -z "${RUNNER_TEMP:-}" ]; then + echo "ERROR: RUNNER_TEMP must be set for fresh Gitea LFS verification" + exit 1 + fi + + MAX_ATTEMPTS=1 + GITEA_LFS_STORAGE=$(mktemp -d "$RUNNER_TEMP/gitea-lfs-verification.XXXXXX") + GITEA_LFS_STORAGE_CONFIG=(-c "lfs.storage=$GITEA_LFS_STORAGE") + echo "Using empty temporary Git LFS storage for verification" +fi + +if [ -n "${GITEA_LFS_USERNAME:-}" ]; then + if [ -z "${GITEA_LFS_TOKEN:-}" ]; then + echo "ERROR: GITEA_LFS_TOKEN must be set when GITEA_LFS_USERNAME is set" + exit 1 + fi +elif [ -n "${GITEA_LFS_TOKEN:-}" ]; then + echo "ERROR: GITEA_LFS_USERNAME must be set when GITEA_LFS_TOKEN is set" + exit 1 +fi + +if [ -n "${GITEA_LFS_USERNAME:-}" ]; then + GITEA_CREDENTIAL_FILE=$(mktemp "${RUNNER_TEMP:-/tmp}/gitea-lfs-credentials.XXXXXX") + chmod 600 "$GITEA_CREDENTIAL_FILE" + git credential-store --file="$GITEA_CREDENTIAL_FILE" store <