Merge pull request 'fix: fix: Forgejo API tokens rejected for git HTTP push — agents must use password auth (#361)' (#362) from fix/issue-361 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
commit
863925cb1c
4 changed files with 67 additions and 7 deletions
|
|
@ -24,7 +24,8 @@ if [ ! -d "${PROJECT_REPO_ROOT}/.git" ]; then
|
|||
log "Cloning repo..."
|
||||
mkdir -p "$(dirname "$PROJECT_REPO_ROOT")"
|
||||
chown -R agent:agent /home/agent/repos 2>/dev/null || true
|
||||
su -s /bin/bash agent -c "git clone http://dev-bot:${FORGE_TOKEN}@forgejo:3000/${FORGE_REPO:-disinto-admin/disinto}.git ${PROJECT_REPO_ROOT}"
|
||||
# Use password auth for git HTTP — Forgejo 11.x rejects API tokens for push (#361)
|
||||
su -s /bin/bash agent -c "git clone http://dev-bot:${FORGE_PASS:-${FORGE_TOKEN}}@forgejo:3000/${FORGE_REPO:-disinto-admin/disinto}.git ${PROJECT_REPO_ROOT}"
|
||||
log "Repo cloned"
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,38 @@ fi
|
|||
|
||||
install_project_crons
|
||||
|
||||
# Configure git credential helper for password-based HTTP auth.
|
||||
# Forgejo 11.x rejects API tokens for git push (#361); password auth works.
|
||||
# This ensures all git operations (clone, fetch, push) from worktrees use
|
||||
# password auth without needing tokens embedded in remote URLs.
|
||||
if [ -n "${FORGE_PASS:-}" ] && [ -n "${FORGE_URL:-}" ]; then
|
||||
_forge_host=$(printf '%s' "$FORGE_URL" | sed 's|https\?://||; s|/.*||')
|
||||
_forge_proto=$(printf '%s' "$FORGE_URL" | sed 's|://.*||')
|
||||
# Determine the bot username from FORGE_TOKEN identity (or default to dev-bot)
|
||||
_bot_user=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_URL}/api/v1/user" 2>/dev/null | jq -r '.login // empty') || _bot_user=""
|
||||
_bot_user="${_bot_user:-dev-bot}"
|
||||
|
||||
# Write a static credential helper script (git credential protocol)
|
||||
cat > /home/agent/.git-credentials-helper <<CREDEOF
|
||||
#!/bin/sh
|
||||
# Auto-generated git credential helper for Forgejo password auth (#361)
|
||||
# Only respond to "get" action; ignore "store" and "erase".
|
||||
[ "\$1" = "get" ] || exit 0
|
||||
# Read and discard stdin (git sends protocol/host info)
|
||||
cat >/dev/null
|
||||
echo "protocol=${_forge_proto}"
|
||||
echo "host=${_forge_host}"
|
||||
echo "username=${_bot_user}"
|
||||
echo "password=${FORGE_PASS}"
|
||||
CREDEOF
|
||||
chmod 755 /home/agent/.git-credentials-helper
|
||||
chown agent:agent /home/agent/.git-credentials-helper
|
||||
|
||||
su -s /bin/bash agent -c "git config --global credential.helper '/home/agent/.git-credentials-helper'"
|
||||
log "Git credential helper configured for ${_bot_user}@${_forge_host} (password auth)"
|
||||
fi
|
||||
|
||||
# Configure tea CLI login for forge operations (runs as agent user).
|
||||
# tea stores config in ~/.config/tea/ — persistent across container restarts
|
||||
# only if that directory is on a mounted volume.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
#
|
||||
# Globals expected:
|
||||
# FORGE_URL - Forge instance URL (e.g. http://localhost:3000)
|
||||
# FORGE_TOKEN - API token for Forge operations
|
||||
# FORGE_TOKEN - API token for Forge operations (used for API verification)
|
||||
# FORGE_PASS - Bot password for git HTTP push (#361: tokens rejected by Forgejo 11.x)
|
||||
# FACTORY_ROOT - Root of the disinto factory
|
||||
# PRIMARY_BRANCH - Primary branch name (e.g. main)
|
||||
#
|
||||
|
|
@ -20,6 +21,7 @@ set -euo pipefail
|
|||
_assert_forge_push_globals() {
|
||||
local missing=()
|
||||
[ -z "${FORGE_URL:-}" ] && missing+=("FORGE_URL")
|
||||
[ -z "${FORGE_PASS:-}" ] && missing+=("FORGE_PASS")
|
||||
[ -z "${FORGE_TOKEN:-}" ] && missing+=("FORGE_TOKEN")
|
||||
[ -z "${FACTORY_ROOT:-}" ] && missing+=("FACTORY_ROOT")
|
||||
[ -z "${PRIMARY_BRANCH:-}" ] && missing+=("PRIMARY_BRANCH")
|
||||
|
|
@ -33,13 +35,14 @@ _assert_forge_push_globals() {
|
|||
push_to_forge() {
|
||||
local repo_root="$1" forge_url="$2" repo_slug="$3"
|
||||
|
||||
# Build authenticated remote URL: http://dev-bot:<token>@host:port/org/repo.git
|
||||
if [ -z "${FORGE_TOKEN:-}" ]; then
|
||||
echo "Error: FORGE_TOKEN not set — cannot push to Forgejo" >&2
|
||||
# Build authenticated remote URL: http://dev-bot:<password>@host:port/org/repo.git
|
||||
# Forgejo 11.x rejects API tokens for git HTTP push (#361); password auth works.
|
||||
if [ -z "${FORGE_PASS:-}" ]; then
|
||||
echo "Error: FORGE_PASS not set — cannot push to Forgejo (see #361)" >&2
|
||||
return 1
|
||||
fi
|
||||
local auth_url
|
||||
auth_url=$(printf '%s' "$forge_url" | sed "s|://|://dev-bot:${FORGE_TOKEN}@|")
|
||||
auth_url=$(printf '%s' "$forge_url" | sed "s|://|://dev-bot:${FORGE_PASS}@|")
|
||||
local remote_url="${auth_url}/${repo_slug}.git"
|
||||
# Display URL without token
|
||||
local display_url="${forge_url}/${repo_slug}.git"
|
||||
|
|
|
|||
|
|
@ -294,8 +294,21 @@ setup_forge() {
|
|||
[predictor-bot]="FORGE_PREDICTOR_TOKEN"
|
||||
[architect-bot]="FORGE_ARCHITECT_TOKEN"
|
||||
)
|
||||
# Map: bot-username -> env-var-name for the password
|
||||
# Forgejo 11.x API tokens don't work for git HTTP push (#361).
|
||||
# Store passwords so agents can use password auth for git operations.
|
||||
local -A bot_pass_vars=(
|
||||
[dev-bot]="FORGE_PASS"
|
||||
[review-bot]="FORGE_REVIEW_PASS"
|
||||
[planner-bot]="FORGE_PLANNER_PASS"
|
||||
[gardener-bot]="FORGE_GARDENER_PASS"
|
||||
[vault-bot]="FORGE_VAULT_PASS"
|
||||
[supervisor-bot]="FORGE_SUPERVISOR_PASS"
|
||||
[predictor-bot]="FORGE_PREDICTOR_PASS"
|
||||
[architect-bot]="FORGE_ARCHITECT_PASS"
|
||||
)
|
||||
|
||||
local bot_user bot_pass token token_var
|
||||
local bot_user bot_pass token token_var pass_var
|
||||
|
||||
for bot_user in dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot architect-bot; do
|
||||
bot_pass="bot-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)"
|
||||
|
|
@ -389,6 +402,17 @@ setup_forge() {
|
|||
export "${token_var}=${token}"
|
||||
echo " ${bot_user} token generated and saved (${token_var})"
|
||||
|
||||
# Store password in .env for git HTTP push (#361)
|
||||
# Forgejo 11.x API tokens don't work for git push; password auth does.
|
||||
pass_var="${bot_pass_vars[$bot_user]}"
|
||||
if grep -q "^${pass_var}=" "$env_file" 2>/dev/null; then
|
||||
sed -i "s|^${pass_var}=.*|${pass_var}=${bot_pass}|" "$env_file"
|
||||
else
|
||||
printf '%s=%s\n' "$pass_var" "$bot_pass" >> "$env_file"
|
||||
fi
|
||||
export "${pass_var}=${bot_pass}"
|
||||
echo " ${bot_user} password saved (${pass_var})"
|
||||
|
||||
# Backwards-compat aliases for dev-bot and review-bot
|
||||
if [ "$bot_user" = "dev-bot" ]; then
|
||||
export CODEBERG_TOKEN="$token"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue