deploy: use reliable HTTPS transport for Gitea sync

This commit is contained in:
syntaxbullet
2026-09-07 13:01:32 +02:00
parent b20af6d95c
commit 2598a5b350
3 changed files with 21 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
# Automatic production deployment # Automatic production deployment
The server checks `git@git.ayau.me:syntaxbullet/minabot.git`, branch `main`, every The server checks `https://git.ayau.me/syntaxbullet/minabot.git`, branch `main`, every
minute after the last check finishes. A local commit is deployed after it is minute after the last check finishes. A local commit is deployed after it is
pushed to Gitea. Other branches are not deployed. If several commits arrive pushed to Gitea. Other branches are not deployed. If several commits arrive
between checks, the latest fetched main commit is built. between checks, the latest fetched main commit is built.
@@ -9,9 +9,12 @@ between checks, the latest fetched main commit is built.
git push origin main git push origin main
``` ```
The server uses a repository-only read key under `/opt/minabot/git-auth`, registered The repository is public, so the server fetches over HTTPS without credentials.
as `minabot-production-read-only` in Gitea. The personal Mac SSH key is not copied Gitea's SSH transport disconnected during transfer, so this checkout also pushes
to the server. Host verification uses the existing trusted Gitea host keys. over HTTPS. Its repository-local credential helper reads the existing `ayau` Tea
login only for this exact HTTPS host/repository; it stores no additional token copy.
The personal Mac SSH key and Tea token are not copied to the server. If the repository
becomes private, provision repository-scoped read credentials before the change.
The pipeline fetches into a bare repository and archives an exact commit into The pipeline fetches into a bare repository and archives an exact commit into
`/opt/minabot/releases/<sha>`. It builds a test image, runs typecheck and the full `/opt/minabot/releases/<sha>`. It builds a test image, runs typecheck and the full

View File

@@ -6,7 +6,7 @@ root=${MINABOT_DEPLOY_ROOT:-/opt/minabot}
cd "$root" cd "$root"
exec 9>deploy.lock exec 9>deploy.lock
flock -n 9 || exit 0 flock -n 9 || exit 0
export GIT_SSH_COMMAND="ssh -i $root/git-auth/id_ed25519 -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$root/git-auth/known_hosts -o ConnectTimeout=10 -o ServerAliveInterval=15 -o ServerAliveCountMax=2" export GIT_TERMINAL_PROMPT=0
repo="$root/git-sync.git" repo="$root/git-sync.git"
target='' target=''
switching=false switching=false
@@ -53,7 +53,7 @@ trap failed ERR
if [[ ! -d "$repo" ]]; then if [[ ! -d "$repo" ]]; then
git init --bare "$repo" git init --bare "$repo"
git --git-dir="$repo" remote add origin git@git.ayau.me:syntaxbullet/minabot.git git --git-dir="$repo" remote add origin https://git.ayau.me/syntaxbullet/minabot.git
fi fi
timeout 90 git --git-dir="$repo" fetch --quiet origin +refs/heads/main:refs/remotes/origin/main timeout 90 git --git-dir="$repo" fetch --quiet origin +refs/heads/main:refs/remotes/origin/main
target=$(git --git-dir="$repo" rev-parse refs/remotes/origin/main) target=$(git --git-dir="$repo" rev-parse refs/remotes/origin/main)

View File

@@ -0,0 +1,12 @@
// Repository-local HTTPS credential helper. Git consumes stdout; never log it.
import { join } from 'node:path';
if (process.argv[2] !== 'get') process.exit(0);
const fields = Object.fromEntries((await Bun.stdin.text()).trim().split('\n').map(line => {
const index = line.indexOf('='); return [line.slice(0, index), line.slice(index + 1)];
}));
if (fields.protocol !== 'https' || fields.host !== 'git.ayau.me' || fields.path !== 'syntaxbullet/minabot.git') process.exit(0);
const base = process.env.XDG_CONFIG_HOME || join(process.env.HOME!, 'Library', 'Application Support');
const config = Bun.YAML.parse(await Bun.file(join(base, 'tea', 'config.yml')).text()) as { logins?: { name: string; url: string; user: string; token: string }[] };
const login = config.logins?.find(login => login.name === 'ayau' && login.url.replace(/\/$/, '') === 'https://git.ayau.me');
if (!login?.token || !login.user || /[\r\n]/.test(login.token + login.user)) process.exit(1);
process.stdout.write(`username=${login.user}\npassword=${login.token}\n\n`);