Add Forgejo Actions CI, remove GitHub Actions #1
2 changed files with 32 additions and 140 deletions
32
.forgejo/workflows/ci.yml
Normal file
32
.forgejo/workflows/ci.yml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
|
- name: Install + type-check + build frontend
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npx tsc --noEmit
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
- name: Install + type-check + build backend
|
||||||
|
working-directory: backend
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npx tsc --noEmit
|
||||||
|
npm run build
|
||||||
140
.github/workflows/deploy.yml
vendored
140
.github/workflows/deploy.yml
vendored
|
|
@ -1,140 +0,0 @@
|
||||||
name: Deploy to racknerd1
|
|
||||||
|
|
||||||
# Deploys ArchNest (frontend + backend + guacd) to racknerd1 via Docker Compose.
|
|
||||||
#
|
|
||||||
# Triggers:
|
|
||||||
# - push to main (automatic)
|
|
||||||
# - manual run from the Actions tab (workflow_dispatch)
|
|
||||||
#
|
|
||||||
# Required GitHub Actions repo secrets (Settings -> Secrets and variables -> Actions):
|
|
||||||
# RACKNERD_HOST - racknerd1 hostname or IP the runner can SSH to
|
|
||||||
# RACKNERD_USER - deploy SSH user (must be in the docker group)
|
|
||||||
# RACKNERD_SSH_KEY - private SSH key (PEM) for that user
|
|
||||||
# RACKNERD_PORT - SSH port (optional, defaults to 22)
|
|
||||||
#
|
|
||||||
# One-time host setup (NOT done by this workflow, see README Deployment section):
|
|
||||||
# - Docker + Docker Compose installed, deploy user in the docker group
|
|
||||||
# - mkdir -p /opt/archnest
|
|
||||||
# - Create /opt/archnest/.env from .env.example with real generated secrets
|
|
||||||
# (ARCHNEST_JWT_SECRET, ARCHNEST_SECRET_KEY, ARCHNEST_GUAC_CRYPT_KEY, ...).
|
|
||||||
# This workflow refuses to deploy if that file is missing, and never
|
|
||||||
# overwrites it, so live secrets/data are safe across deploys.
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
workflow_dispatch: {}
|
|
||||||
|
|
||||||
# Prevent overlapping deploys clobbering each other.
|
|
||||||
concurrency:
|
|
||||||
group: deploy-racknerd1
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
env:
|
|
||||||
DEPLOY_PATH: /opt/archnest
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Fail fast on build/type errors before touching the server.
|
|
||||||
validate:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 22
|
|
||||||
|
|
||||||
- name: Install + type-check + build frontend
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npx tsc --noEmit
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: Install + type-check + build backend
|
|
||||||
working-directory: backend
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npx tsc --noEmit
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
needs: validate
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Pre-flight - confirm host .env exists (don't deploy without secrets)
|
|
||||||
uses: appleboy/ssh-action@v1.2.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.RACKNERD_HOST }}
|
|
||||||
username: ${{ secrets.RACKNERD_USER }}
|
|
||||||
key: ${{ secrets.RACKNERD_SSH_KEY }}
|
|
||||||
port: ${{ secrets.RACKNERD_PORT || 22 }}
|
|
||||||
script: |
|
|
||||||
set -e
|
|
||||||
mkdir -p ${{ env.DEPLOY_PATH }}
|
|
||||||
if [ ! -f ${{ env.DEPLOY_PATH }}/.env ]; then
|
|
||||||
echo "::error::Missing ${{ env.DEPLOY_PATH }}/.env on the host."
|
|
||||||
echo "Create it from .env.example with real secrets before deploying."
|
|
||||||
echo "It is intentionally never created/overwritten by this workflow."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo ".env present - proceeding."
|
|
||||||
|
|
||||||
- name: Copy repo to racknerd1
|
|
||||||
uses: appleboy/scp-action@v0.1.7
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.RACKNERD_HOST }}
|
|
||||||
username: ${{ secrets.RACKNERD_USER }}
|
|
||||||
key: ${{ secrets.RACKNERD_SSH_KEY }}
|
|
||||||
port: ${{ secrets.RACKNERD_PORT || 22 }}
|
|
||||||
source: "."
|
|
||||||
target: ${{ env.DEPLOY_PATH }}
|
|
||||||
# Keep the host-only .env (and any other untracked host state) intact.
|
|
||||||
rm: false
|
|
||||||
overwrite: true
|
|
||||||
|
|
||||||
- name: Build, restart, and clean up
|
|
||||||
uses: appleboy/ssh-action@v1.2.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.RACKNERD_HOST }}
|
|
||||||
username: ${{ secrets.RACKNERD_USER }}
|
|
||||||
key: ${{ secrets.RACKNERD_SSH_KEY }}
|
|
||||||
port: ${{ secrets.RACKNERD_PORT || 22 }}
|
|
||||||
command_timeout: 20m
|
|
||||||
script: |
|
|
||||||
set -e
|
|
||||||
cd ${{ env.DEPLOY_PATH }}
|
|
||||||
docker compose up -d --build --remove-orphans
|
|
||||||
docker image prune -f
|
|
||||||
|
|
||||||
- name: Health check (backend /api/health)
|
|
||||||
uses: appleboy/ssh-action@v1.2.0
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.RACKNERD_HOST }}
|
|
||||||
username: ${{ secrets.RACKNERD_USER }}
|
|
||||||
key: ${{ secrets.RACKNERD_SSH_KEY }}
|
|
||||||
port: ${{ secrets.RACKNERD_PORT || 22 }}
|
|
||||||
script: |
|
|
||||||
set -e
|
|
||||||
echo "Waiting for backend to become healthy..."
|
|
||||||
for i in $(seq 1 30); do
|
|
||||||
if curl -fsS http://127.0.0.1:4000/api/health >/dev/null 2>&1; then
|
|
||||||
echo "Backend healthy."
|
|
||||||
# Confirm the frontend container is serving too.
|
|
||||||
if curl -fsS http://127.0.0.1:8080/ >/dev/null 2>&1; then
|
|
||||||
echo "Frontend healthy. Deploy succeeded."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "Frontend not ready yet..."
|
|
||||||
fi
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
echo "::error::Health check failed after ~150s. Dumping container status + logs."
|
|
||||||
cd ${{ env.DEPLOY_PATH }}
|
|
||||||
docker compose ps || true
|
|
||||||
docker compose logs --tail=80 || true
|
|
||||||
exit 1
|
|
||||||
Loading…
Add table
Reference in a new issue