From 77485eee637642ffc222427681778eed50ff20c2 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 18 May 2026 15:06:14 +0800 Subject: [PATCH] Fix CI deploy: default talkpro host, require only SSH secret Gitea workflow no longer needs TALKPRO_HOST secret; defaults match talkpro VPS. Fail fast with a clear message if TALKPRO_SSH_PRIVATE_KEY is missing. Co-authored-by: Cursor --- .env.deploy.example | 5 +++- .gitea/workflows/deploy-talkpro.yml | 40 +++++++++++++++++++++-------- README.md | 9 +++---- scripts/deploy-talkpro.sh | 20 ++++++++------- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/.env.deploy.example b/.env.deploy.example index 8bdf80e..7e008fa 100644 --- a/.env.deploy.example +++ b/.env.deploy.example @@ -1,5 +1,8 @@ # Copy to .env.deploy for local runs: set -a && source .env.deploy && set +a && ./scripts/deploy-talkpro.sh -# In Gitea, use repository secrets instead (see .gitea/workflows/deploy-talkpro.yml). +# +# Gitea Actions: only this secret is required (Settings → Secrets → Actions): +# TALKPRO_SSH_PRIVATE_KEY = full PEM file contents +# Host/user/path defaults are in .gitea/workflows/deploy-talkpro.yml TALKPRO_HOST=13.214.179.69 TALKPRO_USER=ubuntu diff --git a/.gitea/workflows/deploy-talkpro.yml b/.gitea/workflows/deploy-talkpro.yml index 563a8b8..68c8a3d 100644 --- a/.gitea/workflows/deploy-talkpro.yml +++ b/.gitea/workflows/deploy-talkpro.yml @@ -1,15 +1,14 @@ -# Build talk-pro and rsync dist/ to the marketing VPS (SSH host talkpro). +# Build talk-pro and rsync dist/ to the marketing VPS (talkpro.info). # -# Gitea repo secrets (Settings → Secrets): +# Required Gitea repo secret (Settings → Secrets → Actions): # TALKPRO_SSH_PRIVATE_KEY full PEM for ubuntu@talkpro (same as luis-only.pem) -# TALKPRO_HOST e.g. 13.214.179.69 # -# Optional secrets: +# Optional secrets (override defaults below): +# TALKPRO_HOST default 13.214.179.69 # TALKPRO_USER default ubuntu # TALKPRO_REMOTE_ROOT default /home/ubuntu/talkpro # # Requires a runner with: node 22+, npm, rsync, ssh, ssh-keyscan. -# Site-links API (/api/site-links) is deployed separately from the parent talkpro repo. name: Deploy to talkpro @@ -20,6 +19,11 @@ on: - master workflow_dispatch: +env: + TALKPRO_HOST: "13.214.179.69" + TALKPRO_USER: ubuntu + TALKPRO_REMOTE_ROOT: /home/ubuntu/talkpro + jobs: build-and-sync: runs-on: ubuntu-latest @@ -33,9 +37,28 @@ jobs: node-version: "22" cache: npm - - name: Trust host key + - name: Check deploy secrets env: - TALKPRO_HOST: ${{ secrets.TALKPRO_HOST }} + TALKPRO_SSH_PRIVATE_KEY: ${{ secrets.TALKPRO_SSH_PRIVATE_KEY }} + run: | + if [ -z "${TALKPRO_SSH_PRIVATE_KEY}" ]; then + echo "ERROR: Missing Gitea secret TALKPRO_SSH_PRIVATE_KEY" + echo "Add it under Repository → Settings → Secrets (Actions)." + echo "Value: full contents of your ubuntu@talkpro SSH private key (PEM)." + exit 1 + fi + + - name: Apply optional secret overrides + env: + SECRET_HOST: ${{ secrets.TALKPRO_HOST }} + SECRET_USER: ${{ secrets.TALKPRO_USER }} + SECRET_ROOT: ${{ secrets.TALKPRO_REMOTE_ROOT }} + run: | + [ -n "$SECRET_HOST" ] && echo "TALKPRO_HOST=$SECRET_HOST" >> "$GITHUB_ENV" + [ -n "$SECRET_USER" ] && echo "TALKPRO_USER=$SECRET_USER" >> "$GITHUB_ENV" + [ -n "$SECRET_ROOT" ] && echo "TALKPRO_REMOTE_ROOT=$SECRET_ROOT" >> "$GITHUB_ENV" + + - name: Trust host key run: | mkdir -p ~/.ssh chmod 700 ~/.ssh @@ -43,8 +66,5 @@ jobs: - name: Build and rsync to talkpro env: - TALKPRO_HOST: ${{ secrets.TALKPRO_HOST }} - TALKPRO_USER: ${{ secrets.TALKPRO_USER }} - TALKPRO_REMOTE_ROOT: ${{ secrets.TALKPRO_REMOTE_ROOT }} TALKPRO_SSH_PRIVATE_KEY: ${{ secrets.TALKPRO_SSH_PRIVATE_KEY }} run: bash scripts/deploy-talkpro.sh diff --git a/README.md b/README.md index a589a2a..fc66e00 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,13 @@ Open [http://localhost:4321](http://localhost:4321) Pushes to **`main`** or **`master`** run [`.gitea/workflows/deploy-talkpro.yml`](.gitea/workflows/deploy-talkpro.yml): `npm ci` → `npm run build` → `rsync` `dist/` to the marketing server (`/home/ubuntu/talkpro`). -**Repository secrets** (Gitea → Settings → Secrets): +**Repository secret** (Gitea → Settings → Secrets → Actions) — **required**: | Secret | Value | |--------|--------| -| `TALKPRO_SSH_PRIVATE_KEY` | SSH private key (PEM) for `ubuntu@talkpro` | -| `TALKPRO_HOST` | Server IP, e.g. `13.214.179.69` | -| `TALKPRO_USER` | Optional; default `ubuntu` | -| `TALKPRO_REMOTE_ROOT` | Optional; default `/home/ubuntu/talkpro` | +| `TALKPRO_SSH_PRIVATE_KEY` | Full PEM text of the `ubuntu@talkpro` deploy key | + +Host (`13.214.179.69`), user (`ubuntu`), and web root (`/home/ubuntu/talkpro`) are set in the workflow. Optional secrets `TALKPRO_HOST`, `TALKPRO_USER`, `TALKPRO_REMOTE_ROOT` override those defaults. Manual deploy from this repo: diff --git a/scripts/deploy-talkpro.sh b/scripts/deploy-talkpro.sh index 718e83a..dd7f825 100755 --- a/scripts/deploy-talkpro.sh +++ b/scripts/deploy-talkpro.sh @@ -2,21 +2,19 @@ # Build Astro dist/ and rsync to the Talk Pro marketing host (talkpro.info). # Used by Gitea Actions and for manual deploys from this repo. # -# Required env: -# TALKPRO_HOST e.g. 13.214.179.69 -# Optional: -# TALKPRO_USER default ubuntu -# TALKPRO_REMOTE_ROOT default /home/ubuntu/talkpro -# TALKPRO_SSH_PRIVATE_KEY PEM contents (CI / Gitea secret) -# TALKPRO_SSH_KEY_FILE path to PEM (local) +# Required (CI): TALKPRO_SSH_PRIVATE_KEY — PEM contents (Gitea secret) +# Optional: TALKPRO_SSH_KEY_FILE — path to PEM (local) +# Defaults match .env.deploy.example / Gitea workflow job env: +# TALKPRO_HOST=13.214.179.69 TALKPRO_USER=ubuntu TALKPRO_REMOTE_ROOT=/home/ubuntu/talkpro set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$ROOT" -HOST="${TALKPRO_HOST:?Set TALKPRO_HOST (server IP or hostname)}" +HOST="${TALKPRO_HOST:-13.214.179.69}" USER="${TALKPRO_USER:-ubuntu}" REMOTE_ROOT="${TALKPRO_REMOTE_ROOT:-/home/ubuntu/talkpro}" +[[ -n "$HOST" ]] || HOST=13.214.179.69 [[ -n "$USER" ]] || USER=ubuntu [[ -n "$REMOTE_ROOT" ]] || REMOTE_ROOT=/home/ubuntu/talkpro @@ -33,7 +31,11 @@ if [[ -n "${TALKPRO_SSH_PRIVATE_KEY:-}" ]]; then printf '%s\n' "$TALKPRO_SSH_PRIVATE_KEY" > "$TMP_KEY" KEY_FILE="$TMP_KEY" elif [[ -z "$KEY_FILE" || ! -f "$KEY_FILE" ]]; then - echo "Set TALKPRO_SSH_PRIVATE_KEY (PEM) or TALKPRO_SSH_KEY_FILE (path)" >&2 + echo "ERROR: Set TALKPRO_SSH_PRIVATE_KEY (Gitea secret / env) or TALKPRO_SSH_KEY_FILE (local path)" >&2 + exit 1 +fi +if [[ ! -s "$KEY_FILE" ]]; then + echo "ERROR: SSH key file is empty — check TALKPRO_SSH_PRIVATE_KEY secret in Gitea" >&2 exit 1 fi chmod 600 "$KEY_FILE"