Files
stellaamor.com/.gitea/workflows/deploy.yml
eddie c9aa00d80f
Some checks failed
Deploy (stellaamor) / deploy (push) Has been cancelled
add build YML
2025-10-07 17:55:18 -04:00

135 lines
4.9 KiB
YAML

name: Deploy (stellaamor)
on:
push:
branches: [ "main" ] # change if you use main
jobs:
deploy:
runs-on: [ self-hosted, mainhost, docker ]
concurrency:
group: deploy-stellaamor
cancel-in-progress: false
env:
# ---- required (set these as repo/org SECRETS) ----
SSH_HOST: ${{ secrets.SSH_HOST }} # e.g. 192.168.122.50 (the stellaamor VM)
SSH_USER: ${{ secrets.SSH_USER }} # e.g. deploy
SSH_KEY: ${{ secrets.SSH_KEY }} # private key (ed25519), one line
# optional but recommended: known_hosts entry for your VM
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
# ---- repo-scoped settings (safe to commit) ----
APP_ROOT: /var/www/stellaamor # base dir on the VM
UPLOADS_DIR: uploads # relative to shared/
KEEP_N: "5" # how many releases to keep
HEALTH_URL: https://stellaamor.com/ # simple GET should return 200
SERVICE_RELOAD: "systemctl reload apache2 || true"
steps:
- name: Checkout
uses: actions/checkout@v4
# only build assets if you actually have a package.json with build script
- name: Maybe build frontend (Vue/etc)
if: hashFiles('package.json') != ''
uses: actions/setup-node@v4
with:
node-version: "20"
- name: npm ci
if: hashFiles('package.json') != ''
run: npm ci
- name: npm build
if: hashFiles('package.json') != ''
run: npm run build
- name: Prepare release tarball
run: |
set -euo pipefail
REL="$(date -u +%Y%m%d-%H%M%SZ)-${{ github.sha }}"
echo "REL=$REL" >> $GITHUB_ENV
mkdir -p release
# include everything except VCS, node dev dirs, and your uploads (they live in shared/)
tar \
--exclude-vcs \
--exclude='./node_modules' \
--exclude='./${{ env.UPLOADS_DIR }}' \
-czf "release/${REL}.tar.gz" \
.
- name: Write SSH key
run: |
umask 077
printf "%s" "${SSH_KEY}" > ~/.ssh/id_ed25519
if [ -n "${SSH_KNOWN_HOSTS}" ]; then
printf "%s\n" "${SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
else
# fall back only if you must (less secure)
echo "StrictHostKeyChecking no" >> ~/.ssh/config
fi
- name: Upload & activate atomically
run: |
set -euo pipefail
REL="${{ env.REL }}"
TAR="release/${REL}.tar.gz"
APP="${{ env.APP_ROOT }}"
SHARED="${APP}/shared"
RELEASES="${APP}/releases"
CUR="${APP}/current"
# ensure layout exists
ssh -i ~/.ssh/id_ed25519 ${SSH_USER}@${SSH_HOST} "
set -e
sudo install -d -o ${SSH_USER} -g ${SSH_USER} -m 755 ${RELEASES} ${SHARED}
sudo install -d -o ${SSH_USER} -g ${SSH_USER} -m 755 ${SHARED}/${{ env.UPLOADS_DIR }}
"
# upload tar
scp -i ~/.ssh/id_ed25519 ${TAR} ${SSH_USER}@${SSH_HOST}:/tmp/${REL}.tar.gz
# unpack to new release, link shared, write metadata, flip symlink, reload, health check
ssh -i ~/.ssh/id_ed25519 ${SSH_USER}@${SSH_HOST} '
set -euo pipefail
REL="'${REL}'"; APP="'${APP}'"; SHARED="'${SHARED}'"; RELEASES="'${RELEASES}'"; CUR="'${CUR}'";
NEW="${RELEASES}/${REL}"
mkdir -p "${NEW}"
tar -xzf "/tmp/${REL}.tar.gz" -C "${NEW}"
rm -f "/tmp/${REL}.tar.gz"
# link shared paths (uploads, env/config if you keep one there)
rm -rf "${NEW}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}"
ln -s "${SHARED}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}" "${NEW}/${UPLOADS_DIR:-'${{ env.UPLOADS_DIR }}'}"
# optional: link a shared .env if you use one
if [ -f "${SHARED}/.env" ]; then
ln -sf "${SHARED}/.env" "${NEW}/.env"
fi
# metadata
printf "sha=%s\nbuilt_at=%s\n" "'${{ github.sha }}'" "$(date -u +%FT%TZ)" > "${NEW}/RELEASE"
# keep previous target for rollback
PREV="$(readlink -f "${CUR}" || true)"
ln -sfn "${NEW}" "${CUR}"
# reload services
'"${{ env.SERVICE_RELOAD }}"' >/dev/null 2>&1 || true
# health check (simple GET)
if command -v curl >/dev/null 2>&1; then
curl -fsS --max-time 5 "'"${{ env.HEALTH_URL }}"'" >/dev/null || {
echo "Health check failed, rolling back..."
[ -n "${PREV}" ] && ln -sfn "${PREV}" "${CUR}" && '"${{ env.SERVICE_RELOAD }}"' >/dev/null 2>&1 || true
exit 1
}
fi
# prune old releases
cd "${RELEASES}"
ls -1tr | head -n -'${{ env.KEEP_N }}' | xargs -r -I{} rm -rf "{}"
'