Files
rednote-tool-studio/.gitea/workflows/ci.yml
T
hexin-codex-bot 276a8ae473
Verify and deploy production / verify-and-deploy (push) Successful in 2m34s
feat: add image project dashboard and canvas editor
2026-10-05 15:20:43 +08:00

119 lines
4.0 KiB
YAML

name: Verify and deploy production
concurrency:
group: rednote-tool-studio-production
cancel-in-progress: false
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
verify-and-deploy:
runs-on: ces-control
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Type check
run: npm run typecheck
- name: Unit tests
run: npm test
- name: Production build
run: npm run build
- name: Deploy persistent production service
if: gitea.event_name == 'workflow_dispatch' || (gitea.event_name == 'push' && gitea.ref == 'refs/heads/main')
env:
RELEASE_SHA: ${{ gitea.sha }}
run: |
set -eu
if [ "$(id -u)" -eq 0 ]; then
SUDO=""
elif sudo -n true 2>/dev/null; then
SUDO="sudo -n"
else
echo "The ces-control runner needs root or passwordless sudo for persistent systemd deployment"
exit 1
fi
PORT=18080
APP_ROOT=/opt/rednote-tool-studio
RELEASE_DIR="$APP_ROOT/releases/$RELEASE_SHA"
DATA_ROOT=/var/lib/rednote-tool-studio
SERVICE_USER=rednote-studio
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
$SUDO useradd --system --home "$DATA_ROOT" --shell /usr/sbin/nologin "$SERVICE_USER"
fi
$SUDO mkdir -p "$APP_ROOT/releases" "$APP_ROOT/bin" "$DATA_ROOT/projects" "$DATA_ROOT/image-projects"
$SUDO install -m 0755 "$(command -v node)" "$APP_ROOT/bin/node"
$SUDO mkdir -p "$RELEASE_DIR/.next" "$RELEASE_DIR/data"
$SUDO cp -a .next/standalone/. "$RELEASE_DIR/"
$SUDO cp -a .next/static "$RELEASE_DIR/.next/static"
$SUDO cp -a templates vendor "$RELEASE_DIR/"
$SUDO ln -sfn "$DATA_ROOT/projects" "$RELEASE_DIR/data/projects"
$SUDO ln -sfn "$DATA_ROOT/image-projects" "$RELEASE_DIR/data/image-projects"
$SUDO chown -R root:root "$APP_ROOT"
$SUDO chown -R "$SERVICE_USER:$SERVICE_USER" "$DATA_ROOT"
$SUDO ln -sfn "$RELEASE_DIR" "$APP_ROOT/current"
$SUDO rm -f /etc/rednote-tool-studio.password
cat > rednote-tool-studio.service <<EOF
[Unit]
Description=Rednote Content Studio
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$SERVICE_USER
Group=$SERVICE_USER
WorkingDirectory=$APP_ROOT/current
Environment=NODE_ENV=production
Environment=HOSTNAME=0.0.0.0
Environment=PORT=$PORT
ExecStart=$APP_ROOT/bin/node server.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
$SUDO install -m 0644 rednote-tool-studio.service /etc/systemd/system/rednote-tool-studio.service
$SUDO systemctl daemon-reload
$SUDO systemctl enable --now rednote-tool-studio.service
$SUDO systemctl restart rednote-tool-studio.service
for attempt in $(seq 1 30); do
if "$APP_ROOT/bin/node" -e "fetch('http://127.0.0.1:$PORT/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"; then
break
fi
if [ "$attempt" -eq 30 ]; then
$SUDO systemctl status rednote-tool-studio.service --no-pager || true
$SUDO journalctl -u rednote-tool-studio.service -n 100 --no-pager || true
exit 1
fi
sleep 2
done
$SUDO systemctl is-enabled rednote-tool-studio.service
$SUDO systemctl is-active rednote-tool-studio.service
echo "Persistent deployment verified: service=rednote-tool-studio port=$PORT data=$DATA_ROOT/projects release=$RELEASE_SHA"