Skip to content

fix(backend): offload async auth verifiers #277

fix(backend): offload async auth verifiers

fix(backend): offload async auth verifiers #277

Workflow file for this run

name: Deploy
on:
push:
branches:
- main
concurrency:
group: deploy-${{ github.repository }}
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Deploy to Server
uses: appleboy/ssh-action@v1.0.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
DEPLOY_ENV: ${{ secrets.DEPLOY_ENV }}
SUBMODULE_TOKEN: ${{ secrets.SUBMODULE_TOKEN }}
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: GITHUB_TOKEN,REPO,DEPLOY_ENV,SUBMODULE_TOKEN
timeout: 120m
command_timeout: 120m
script: |
set -euo pipefail
BASE_DIR="${{ secrets.DEPLOY_PATH || '/var/www/github-actions/repos' }}"
REPO_NAME=$(basename "$REPO")
REPO_DIR="$BASE_DIR/$REPO_NAME"
REPO_URL="https://x-access-token:${GITHUB_TOKEN}@github.com/${REPO}.git"
if [ ! -d "$REPO_DIR/.git" ]; then
mkdir -p "$BASE_DIR"
# Clone without recursing first; nested submodule auth is configured below.
for i in 1 2 3; do git clone "$REPO_URL" "$REPO_DIR" && break || sleep 5; done
fi
cd "$REPO_DIR"
git remote set-url origin "$REPO_URL"
SUBMODULE_AUTH="${SUBMODULE_TOKEN:-$GITHUB_TOKEN}"
set_submodule_url() {
local name="$1"
local repo="$2"
local url="https://x-access-token:${SUBMODULE_AUTH}@github.com/${repo}.git"
git config "submodule.${name}.url" "$url"
[ -d ".git/modules/${name}" ] && git config -f ".git/modules/${name}/config" remote.origin.url "$url"
}
for i in 1 2 3; do git fetch origin && break || { [ $i -eq 3 ] && echo "git fetch failed after 3 retries" && exit 1; sleep 5; }; done
git reset --hard origin/main
git submodule sync --recursive
# Configure submodule URLs after sync; otherwise cached SSH URLs or .gitmodules defaults can win.
set_submodule_url backend TashanGKD/Resonnet
set_submodule_url topiclab-cli TashanGKD/TopicLab-CLI
set_submodule_url ClawArcade TashanGKD/ClawArcade
set_submodule_url worldweave TashanGKD/worldweave
git submodule update --init backend
git config -f .git/modules/backend/config submodule.libs/assignable_skills/_submodules/ai-research.url "https://x-access-token:${SUBMODULE_AUTH}@github.com/Orchestra-Research/AI-Research-SKILLs.git"
git config -f .git/modules/backend/config submodule.libs/assignable_skills/_submodules/anthropics.url "https://x-access-token:${SUBMODULE_AUTH}@github.com/anthropics/skills.git"
git config -f .git/modules/backend/config submodule.libs/assignable_skills/_submodules/claude-scientific.url "https://x-access-token:${SUBMODULE_AUTH}@github.com/K-Dense-AI/claude-scientific-skills.git"
git config -f .git/modules/backend/config --get submodule.libs/assignable_skills/_submodules/claude-scientific.url | sed -E 's#x-access-token:[^@]+@#x-access-token:***@#'
git submodule update --init --recursive
if [ -z "${DEPLOY_ENV:-}" ]; then
echo "::error::DEPLOY_ENV secret is not set. Add it in repo Settings → Secrets."
exit 1
fi
echo "$DEPLOY_ENV" > .env
run_with_heartbeat() {
local label="$1"
shift
"$@" &
local pid="$!"
while kill -0 "$pid" 2>/dev/null; do
echo "[deploy] ${label} still running at $(date -u +%Y-%m-%dT%H:%M:%SZ)"
sleep 30
done
wait "$pid"
}
run_with_heartbeat "docker compose build" docker compose build
docker compose down
docker compose up -d
for i in $(seq 1 30); do
if docker compose exec -T worldweave node -e "fetch('http://127.0.0.1:3020/api/v1/openclaw/skill.md').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"; then
break
fi
if [ "$i" = "30" ]; then
echo "::error::WorldWeave container did not become healthy on port 3020."
docker compose logs --tail=120 worldweave
exit 1
fi
sleep 2
done
if ! docker compose exec -T worldweave sh -lc "WORLD_HEALTH_BASE_URL=http://127.0.0.1:3020 WORLD_HEALTH_CHECK_SCENES=tech-ai,geo-politics-daily WORLD_HEALTH_FAIL_ON_REFRESH_DEGRADED=1 node scripts/health-world.mjs"; then
echo "::warning::WorldWeave scene freshness health check failed. Check the worldweave-refresh logs and source refresh status."
docker compose logs --tail=120 worldweave-refresh || true
fi
docker image prune -f
# Read frontend port from .env (default 3000); trim whitespace/CRLF to avoid nginx config issues
FRONTEND_PORT=$(grep -E '^FRONTEND_PORT=' .env 2>/dev/null | head -1 | cut -d= -f2- | tr -d ' \r' || echo 3000)
# Write nginx snippet (location block only, included by world.tashan.chat server block).
# WorldWeave routes are handled inside the frontend container nginx.
# Requires VITE_BASE_PATH=/ in DEPLOY_ENV so frontend matches /api/.
mkdir -p /etc/nginx/snippets
printf '%s\n' \
'location / {' \
" proxy_pass http://127.0.0.1:${FRONTEND_PORT};" \
' proxy_set_header Host $host;' \
' proxy_set_header X-Real-IP $remote_addr;' \
' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \
' proxy_set_header X-Forwarded-Proto $scheme;' \
'}' \
'location /api/ {' \
" proxy_pass http://127.0.0.1:${FRONTEND_PORT}/api/;" \
' proxy_http_version 1.1;' \
' proxy_set_header Host $host;' \
' proxy_set_header X-Real-IP $remote_addr;' \
' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \
' proxy_set_header X-Forwarded-Proto $scheme;' \
' proxy_set_header Connection "";' \
' proxy_buffering off;' \
' proxy_cache off;' \
' chunked_transfer_encoding on;' \
' proxy_read_timeout 600s;' \
' proxy_send_timeout 600s;' \
'}' \
| sudo tee /etc/nginx/snippets/world-tashan-chat.conf > /dev/null
sudo nginx -t && sudo nginx -s reload
chmod +x scripts/deploy-clawarcade-reviewer.sh
scripts/deploy-clawarcade-reviewer.sh
echo "--------------------------------------------"
echo "Frontend: http://${{ secrets.DEPLOY_HOST }}"
echo "Commit: ${{ github.sha }}"
echo "--------------------------------------------"
cli-smoke:
name: Post-deploy CLI smoke (${{ matrix.cli_source }})
needs: [deploy]
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
cli_source: [package, submodule]
env:
TOPICLAB_BASE_URL: https://world.tashan.chat
TOPICLAB_BIND_KEY: ${{ secrets.TOPICLAB_BIND_KEY }}
TOPICLAB_LIVE_SMOKE_ALLOW_WRITES: ${{ vars.TOPICLAB_LIVE_SMOKE_ALLOW_WRITES || '0' }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: topiclab-cli/package-lock.json
- name: Check write smoke secrets
run: |
if [[ "${TOPICLAB_LIVE_SMOKE_ALLOW_WRITES:-0}" == "1" && -z "${TOPICLAB_BIND_KEY:-}" ]]; then
echo "::error::TOPICLAB_BIND_KEY secret is required when TOPICLAB_LIVE_SMOKE_ALLOW_WRITES=1."
exit 1
fi
- name: Wait for deployed services to settle
run: sleep 60
- name: Install published topiclab-cli
if: matrix.cli_source == 'package'
run: |
npm install -g topiclab-cli@latest
npm list -g topiclab-cli --depth=0 || true
- name: Install submodule topiclab-cli
if: matrix.cli_source == 'submodule'
run: |
pushd topiclab-cli
npm ci
npm run build
popd
npm install -g ./topiclab-cli
node -p "require('./topiclab-cli/package.json').version"
git -C topiclab-cli rev-parse HEAD
- name: Run live smoke
run: |
chmod +x scripts/openclaw-live-skill-smoke.sh
args=(
--bind-key "${TOPICLAB_BIND_KEY}"
--base-url "${TOPICLAB_BASE_URL}"
--clean-cli-home
)
if [[ "${TOPICLAB_LIVE_SMOKE_ALLOW_WRITES:-0}" == "1" ]]; then
args+=(--allow-writes)
fi
./scripts/openclaw-live-skill-smoke.sh "${args[@]}"