Give bench a credential for the forge clones

The previous commit moved both Hanzo clones to the forge on the strength
of an anonymous ls-remote that only succeeded because the machine running
it had forge credentials cached. It does not serve anonymously:

  git ls-remote --heads --tags https://git.hanzo.ai/hanzoai/frappe develop
  fatal: could not read Username for 'https://git.hanzo.ai'

So supply one. A credential helper reads the token from the BuildKit
mount, and the two RUNs that clone from the forge mount it; the secret
never lands in a layer. Public remotes never reach the helper, because
git only asks when the server challenges it.

The token is the run's own GITHUB_TOKEN. If that turns out to be scoped
too narrowly to read hanzoai/frappe from hanzoai/helpdesk, the fix is to
point `forge=` at an org-level forge token — the Dockerfile side does not
change.
This commit is contained in:
2026-08-12 20:32:41 -07:00
parent 4b0a0eb003
commit 6827018615
2 changed files with 16 additions and 4 deletions
+4
View File
@@ -60,6 +60,10 @@ jobs:
push: true
provenance: false
tags: ghcr.io/hanzoai/helpdesk:${{ steps.meta.outputs.tag }}
# bench clones the Frappe core and this app from the forge, which
# serves nothing anonymously. The run's own token is the credential.
secrets: |
forge=${{ secrets.GITHUB_TOKEN }}
# build-push-action can exit 0 before the manifest resolves, so a green run
# could still mean a future ImagePullBackOff. Prove it pulls.
+12 -4
View File
@@ -51,12 +51,19 @@ WORKDIR /home/frappe
# frappe-bench CLI
RUN pip install --user frappe-bench
# Both Hanzo repos are read from the forge — it is where they live, and it does
# not move out from under the build the way the GitHub org did. The forge serves
# nothing anonymously, so git answers its credential prompt from the token the
# build mounts. Public remotes never reach the helper: git only asks when the
# server challenges it.
RUN git config --global credential.helper \
'!f(){ test "$1" = get && printf "username=oauth2\npassword=%s\n" "$(cat /run/secrets/forge)"; :; };f'
# Initialise a bench against the Hanzo Frappe core (carries the SQLite driver).
# Both Hanzo repos are read from the forge: it is where they live, it serves
# them anonymously, and it does not move out from under the build.
ARG FRAPPE_REPO=https://git.hanzo.ai/hanzoai/frappe
ARG FRAPPE_BRANCH=develop
RUN bench init --skip-redis-config-generation --verbose \
RUN --mount=type=secret,id=forge,uid=1000,required=true \
bench init --skip-redis-config-generation --verbose \
--frappe-path ${FRAPPE_REPO} --frappe-branch ${FRAPPE_BRANCH} \
frappe-bench
@@ -70,7 +77,8 @@ RUN bench get-app --skip-assets https://github.com/frappe/telephony
# branch being built.
ARG HELPDESK_REPO=https://git.hanzo.ai/hanzoai/helpdesk
ARG HELPDESK_BRANCH=develop
RUN bench get-app helpdesk ${HELPDESK_REPO} --branch ${HELPDESK_BRANCH}
RUN --mount=type=secret,id=forge,uid=1000,required=true \
bench get-app helpdesk ${HELPDESK_REPO} --branch ${HELPDESK_BRANCH}
# Build all frontend assets (frappe desk + helpdesk SPA).
RUN bench build --production