2 Commits

Author SHA1 Message Date
octoturge 850337530f Add a git credential helper for Gitea, backed by tea's own login
Provision Coder Templates / build-images (push) Successful in 7s
Provision Coder Templates / provision (push) Successful in 2m7s
Coder's GIT_ASKPASS only knows about github.com; for git.octoturge.com
it falls through to a broken interactive prompt, so `git push`/`pull`
over HTTPS hangs or fails even after `tea login add` succeeds. A
credential helper answering `git credential fill` runs before
GIT_ASKPASS is consulted, so wire one up (gated on the wizard's
existing DID_GITEA check) that reads the live OAuth token straight out
of tea's own credentials.json - verified end-to-end against a running
workspace (git ls-remote over HTTPS authenticated successfully).

Bump every template's VERSION to publish it.
2026-08-31 09:17:55 +02:00
octoturge ecf927aef9 Bump every template's VERSION to publish the git.octoturge.com fix
Provision Coder Templates / build-images (push) Successful in 5s
Provision Coder Templates / provision (push) Successful in 2m13s
The host-gateway change in the previous commit only takes effect on a new
template version - bump every template's VERSION file from 1 to 2 so
coder-templates.yml actually pushes it instead of skipping as "already
pushed". Existing workspaces need a stop/start against the new version to
pick up the updated docker_container host mapping.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRq8ts9zwge8Rttbuku9FQ
2026-08-28 18:04:51 +02:00
12 changed files with 342 additions and 6 deletions
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).
+1 -1
View File
@@ -1 +1 @@
1
3
+56
View File
@@ -149,6 +149,62 @@ fi
# for an OAuth login) vary by auth method.
command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
# --- Git credential helper for Gitea, backed by tea's own login ---
# Coder injects GIT_ASKPASS to answer git's own credential prompts, but it
# only recognizes external auth providers it knows about (github.com is
# configured on the Coder deployment itself) - for any other host it falls
# through to a broken interactive prompt that just hangs a non-interactive
# git subprocess. A credential helper that successfully answers
# `git credential fill` runs *before* GIT_ASKPASS is ever consulted, so
# registering one for git.octoturge.com sidesteps that broken path
# entirely, without touching how Coder handles github.com.
#
# The token itself lives in tea's own store
# (~/.config/tea/credentials.json), which tea keeps fresh (via its
# refresh_token) as a side effect of any authenticated call - this helper
# never keeps its own copy, just re-reads tea's live value every time git
# asks.
if [ "$DID_GITEA" -eq 1 ]; then
GITEA_LOGIN_NAME="$(awk '
/^[[:space:]]*- name:/ { name = $NF }
/url: https:\/\/git\.octoturge\.com/ { print name; exit }
' "$HOME/.config/tea/config.yml" 2>/dev/null)"
if [ -n "$GITEA_LOGIN_NAME" ]; then
mkdir -p "$HOME/.local/bin"
HELPER="$HOME/.local/bin/git-credential-gitea-tea"
cat > "$HELPER" <<'HELPER_EOT'
#!/bin/sh
# Auto-generated by cli-setup-wizard.sh - re-run the wizard with --force to
# regenerate this after logging into a different Gitea account.
LOGIN_NAME="__GITEA_LOGIN_NAME__"
CRED_FILE="$HOME/.config/tea/credentials.json"
case "$1" in
get)
# Authenticated no-op call: gives tea a chance to refresh and persist
# an expired access_token before we read it below.
tea whoami >/dev/null 2>&1
token="$(grep -oP "(?<=\"$LOGIN_NAME\":).*" "$CRED_FILE" 2>/dev/null \
| grep -oP '(?<=access_token\\":\\")[^\\"]*' | head -n1)"
if [ -n "$token" ]; then
echo "username=oauth2"
echo "password=$token"
fi
;;
store|erase)
# No-op: credentials.json (managed by tea) is the single source of
# truth, nothing for git to persist or clear on this end.
;;
esac
HELPER_EOT
sed -i "s/__GITEA_LOGIN_NAME__/$GITEA_LOGIN_NAME/" "$HELPER"
chmod +x "$HELPER"
git config --global credential."https://git.octoturge.com".helper "$HELPER"
echo "Configured git to push/pull https://git.octoturge.com using your tea login."
fi
fi
# --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now -
# stays silent for "local git only" (neither was set up).