Send the LFS object endpoint one Authorization header, not two
🐳 Android image / Build and push (push) Successful in 2s
Build and test / android-image (push) Successful in 3s
Build and test / Desktop (Linux) (push) Failing after 1h12m2s
Build and test / Layer separation (push) Successful in 36s
Traceability / Requirement traces (push) Failing after 31s
Build and test / Android (aarch64) (push) Failing after 36m17s
🐳 Android image / Build and push (push) Successful in 2s
Build and test / android-image (push) Successful in 3s
Build and test / Desktop (Linux) (push) Failing after 1h12m2s
Build and test / Layer separation (push) Successful in 36s
Traceability / Requirement traces (push) Failing after 31s
Build and test / Android (aarch64) (push) Failing after 36m17s
The model fetch has been failing on every run with LFS: Client error: .../info/lfs/objects/0672d7a7... which reads like a rejected credential and is not one. The object is on the server and downloads fine; what fails is the shape of the request. `git lfs pull` makes two calls. The first, to `/info/lfs/objects/batch`, succeeds -- and Gitea answers it with a short-lived `Bearer` JWT scoped to that one object, for git-lfs to use on the second. git-lfs sends that JWT *and* the `Authorization` header this step had installed in git config, and two `Authorization` headers is a 400 from Gitea. Hence a client error on the object one step after the batch call it just made successfully, which is what made this look like an auth problem rather than a duplication. Confirmed directly against the server: the JWT alone on that URL is a 200, the JWT plus any second `Authorization` is a 400, and a lone token header that is merely wrong is a 401 -- so the scheme was never the issue. `lfs: true` on the checkout fails the same way and for the same reason, because actions/checkout persists a header of its own; the comment here blaming a credential the endpoint would not accept was wrong on both counts. So the headers are stripped -- checkout's included, since nothing later in either job talks to the remote -- and the token is handed to git-lfs as an ordinary credential instead. It authenticates the batch call and leaves the per-object JWT alone. This is what fails the Android job today: the build script sees a 133-byte pointer and panics by design, which is the message it is supposed to give and the one nobody could act on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,24 +39,39 @@ jobs:
|
|||||||
# pointer and failing at inference. That failure reads like a broken build
|
# pointer and failing at inference. That failure reads like a broken build
|
||||||
# instead of a missing fetch, which is how it went unnoticed.
|
# instead of a missing fetch, which is how it went unnoticed.
|
||||||
#
|
#
|
||||||
# Not `lfs: true` on the checkout above: that makes the *checkout* fail on
|
# Not `lfs: true` on the checkout above, and no `Authorization` header
|
||||||
# this server — `git lfs fetch` is rejected at
|
# here either. Both install a blanket header for every request to this
|
||||||
# `/info/lfs/objects/<oid>` with a client error, because the credential
|
# host, and the object download is the one request that already carries
|
||||||
# checkout installs for git is not one the LFS endpoint accepts. Fetching
|
# one: `git lfs pull` asks `/info/lfs/objects/batch` first, and Gitea
|
||||||
# it as its own step with an explicit token keeps a credential problem
|
# answers with a short-lived `Bearer` JWT scoped to that object. git-lfs
|
||||||
# from looking like a checkout problem, and lets the rest of the job say
|
# then sends the JWT *and* the configured header, and two `Authorization`
|
||||||
# what it thinks.
|
# headers is a 400 from Gitea — reported as
|
||||||
|
# LFS: Client error: .../info/lfs/objects/<oid>
|
||||||
|
# one step after the batch call that had just succeeded, which reads like
|
||||||
|
# a rejected credential rather than a duplicated one. A lone token header
|
||||||
|
# is understood fine; it is only the collision that fails.
|
||||||
|
#
|
||||||
|
# So: strip the headers and hand the token to git-lfs as an ordinary
|
||||||
|
# credential instead. It authenticates the batch call and leaves the
|
||||||
|
# per-object JWT untouched. Gitea authenticates on the password, so the
|
||||||
|
# username is a placeholder. Nothing later in this job talks to the
|
||||||
|
# remote, so dropping checkout's header costs us nothing.
|
||||||
#
|
#
|
||||||
# `continue-on-error` deliberately: if this cannot authenticate, the build
|
# `continue-on-error` deliberately: if this cannot authenticate, the build
|
||||||
# below still runs and fails with the build script's own message, which
|
# below still runs and fails with the build script's own message, which
|
||||||
# names the real problem. A checkout that dies here says nothing.
|
# names the real problem. A checkout that dies here says nothing.
|
||||||
- name: Fetch the segmentation model
|
- name: Fetch the segmentation model
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
LFS_TOKEN: ${{ secrets.GITEA_TOKEN || github.token }}
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -e
|
||||||
git lfs install --local
|
git lfs install --local
|
||||||
git config --local lfs.https://gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs.access basic
|
git config --local --get-regexp '^http\..*extraheader$' \
|
||||||
git config --local http.extraheader "Authorization: token ${{ secrets.GITEA_TOKEN || github.token }}"
|
| cut -d' ' -f1 | sort -u \
|
||||||
|
| while read -r key; do git config --local --unset-all "$key"; done || true
|
||||||
|
git config --local lfs.url \
|
||||||
|
"https://x-access-token:${LFS_TOKEN}@gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs"
|
||||||
git lfs pull
|
git lfs pull
|
||||||
ls -l core/dr-segment/models/
|
ls -l core/dr-segment/models/
|
||||||
|
|
||||||
@@ -123,24 +138,39 @@ jobs:
|
|||||||
# pointer and failing at inference. That failure reads like a broken build
|
# pointer and failing at inference. That failure reads like a broken build
|
||||||
# instead of a missing fetch, which is how it went unnoticed.
|
# instead of a missing fetch, which is how it went unnoticed.
|
||||||
#
|
#
|
||||||
# Not `lfs: true` on the checkout above: that makes the *checkout* fail on
|
# Not `lfs: true` on the checkout above, and no `Authorization` header
|
||||||
# this server — `git lfs fetch` is rejected at
|
# here either. Both install a blanket header for every request to this
|
||||||
# `/info/lfs/objects/<oid>` with a client error, because the credential
|
# host, and the object download is the one request that already carries
|
||||||
# checkout installs for git is not one the LFS endpoint accepts. Fetching
|
# one: `git lfs pull` asks `/info/lfs/objects/batch` first, and Gitea
|
||||||
# it as its own step with an explicit token keeps a credential problem
|
# answers with a short-lived `Bearer` JWT scoped to that object. git-lfs
|
||||||
# from looking like a checkout problem, and lets the rest of the job say
|
# then sends the JWT *and* the configured header, and two `Authorization`
|
||||||
# what it thinks.
|
# headers is a 400 from Gitea — reported as
|
||||||
|
# LFS: Client error: .../info/lfs/objects/<oid>
|
||||||
|
# one step after the batch call that had just succeeded, which reads like
|
||||||
|
# a rejected credential rather than a duplicated one. A lone token header
|
||||||
|
# is understood fine; it is only the collision that fails.
|
||||||
|
#
|
||||||
|
# So: strip the headers and hand the token to git-lfs as an ordinary
|
||||||
|
# credential instead. It authenticates the batch call and leaves the
|
||||||
|
# per-object JWT untouched. Gitea authenticates on the password, so the
|
||||||
|
# username is a placeholder. Nothing later in this job talks to the
|
||||||
|
# remote, so dropping checkout's header costs us nothing.
|
||||||
#
|
#
|
||||||
# `continue-on-error` deliberately: if this cannot authenticate, the build
|
# `continue-on-error` deliberately: if this cannot authenticate, the build
|
||||||
# below still runs and fails with the build script's own message, which
|
# below still runs and fails with the build script's own message, which
|
||||||
# names the real problem. A checkout that dies here says nothing.
|
# names the real problem. A checkout that dies here says nothing.
|
||||||
- name: Fetch the segmentation model
|
- name: Fetch the segmentation model
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
LFS_TOKEN: ${{ secrets.GITEA_TOKEN || github.token }}
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -e
|
||||||
git lfs install --local
|
git lfs install --local
|
||||||
git config --local lfs.https://gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs.access basic
|
git config --local --get-regexp '^http\..*extraheader$' \
|
||||||
git config --local http.extraheader "Authorization: token ${{ secrets.GITEA_TOKEN || github.token }}"
|
| cut -d' ' -f1 | sort -u \
|
||||||
|
| while read -r key; do git config --local --unset-all "$key"; done || true
|
||||||
|
git config --local lfs.url \
|
||||||
|
"https://x-access-token:${LFS_TOKEN}@gitea.tourolle.paris/dtourolle/DarkRoom.git/info/lfs"
|
||||||
git lfs pull
|
git lfs pull
|
||||||
ls -l core/dr-segment/models/
|
ls -l core/dr-segment/models/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user