diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..85c38d8 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,148 @@ +# ============================================================================= +# deploy.yml — build every brand in this content repo with Hugo and deploy each +# to .lilsus.fun via rsync over SSH. Runs on every push to main (i.e. +# after each n8n pipeline run that commits repo//...). +# +# INSTALL: copy this file to .gitea/workflows/deploy.yml in the CONTENT repo +# (lilsus/igaming-brands AND/OR lilsus/igaming-brands-i18n). +# +# REQUIRED Gitea secrets (repo → Settings → Actions → Secrets): +# DEPLOY_SSH_KEY - private SSH key (PEM) whose public key is in the server's +# authorized_keys for DEPLOY_USER. No passphrase. +# DEPLOY_HOST - server hostname/IP that Caddy runs on (e.g. lilsus.fun) +# DEPLOY_USER - ssh user with write access to DEPLOY_PATH +# DEPLOY_PATH - base web root, e.g. /srv/www (brand goes to /) +# SSH_KNOWN_HOSTS - output of `ssh-keyscan -H ` (pins the host key) +# OPTIONAL Gitea variables (Settings → Actions → Variables): +# TEMPLATE_REPO - clone URL of the template repo +# (default: https://git.lilsus.fun/lilsus/igaming-template.git) +# HUGO_VERSION - pinned Hugo Extended version (default 0.140.2) +# SITE_TLD - base domain for per-brand hosts (default lilsus.fun) +# +# RUNNER REQUIREMENTS: a registered Gitea act_runner whose image has bash, git, +# curl, tar, rsync, openssh-client and Node.js >= 20 (for Tailwind/PostCSS). +# The default `gitea/runner`/`catthehacker/ubuntu` images include these. +# ============================================================================= +name: Build & Deploy Brands +run-name: deploy ${{ gitea.sha }} + +on: + push: + branches: [main] + paths: + - "repo/**" + - ".gitea/workflows/deploy.yml" + workflow_dispatch: {} + +concurrency: + group: deploy-${{ gitea.ref }} + cancel-in-progress: false + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + env: + TEMPLATE_REPO: ${{ vars.TEMPLATE_REPO || 'https://git.lilsus.fun/lilsus/igaming-template.git' }} + HUGO_VERSION: ${{ vars.HUGO_VERSION || '0.140.2' }} + SITE_TLD: ${{ vars.SITE_TLD || 'lilsus.fun' }} + CONTENT_DIR: ${{ gitea.workspace }}/content-repo + TEMPLATE_DIR: ${{ gitea.workspace }}/template-repo + HUGO_BIN: ${{ gitea.workspace }}/.hugo/hugo + steps: + # --- 1. Clone the content repo (this repo) directly. actions/checkout is + # avoided so we don't depend on the runner reaching github.com. --- + - name: Clone content repo + run: | + set -euo pipefail + rm -rf "$CONTENT_DIR" + git clone --depth 1 \ + "${{ gitea.server_url }}/${{ gitea.repository }}.git" \ + "$CONTENT_DIR" + cd "$CONTENT_DIR" && git checkout -q "${{ gitea.sha }}" || true + echo "Brands:"; ls -1 "$CONTENT_DIR/repo" || (echo "no repo/ dir" && exit 1) + + # --- 2. Clone the template (engine) repo. Public repo → no token needed. --- + - name: Clone template repo + run: | + set -euo pipefail + rm -rf "$TEMPLATE_DIR" + git clone --depth 1 "$TEMPLATE_REPO" "$TEMPLATE_DIR" + test -d "$TEMPLATE_DIR/layouts" || (echo "template has no layouts/" && exit 1) + test -f "$TEMPLATE_DIR/data/locales.yaml" || echo "WARN: template missing data/locales.yaml" + + # --- 3. Install Hugo Extended (pinned) to match local verification. + # Installed to a workspace path and invoked by absolute path + # ($HUGO_BIN) so we don't depend on the runner's PATH-file behaviour. --- + - name: Install Hugo Extended + run: | + set -euo pipefail + HUGO_TARBALL="hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" + URL="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_TARBALL}" + echo "Downloading $URL" + curl -sSL --retry 3 -o /tmp/hugo.tar.gz "$URL" + mkdir -p "$(dirname "$HUGO_BIN")" + tar -xzf /tmp/hugo.tar.gz -C "$(dirname "$HUGO_BIN")" hugo + "$HUGO_BIN" version + + # --- 4. Install Node deps once (Tailwind/PostCSS used by Hugo Pipes). --- + - name: Install template Node deps + run: | + set -euo pipefail + node --version + cd "$TEMPLATE_DIR" + if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi + + # --- 5. Prepare SSH (key + known_hosts) for rsync deploy. --- + - name: Configure SSH + run: | + set -euo pipefail + mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh" + printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > "$HOME/.ssh/deploy_key" + chmod 600 "$HOME/.ssh/deploy_key" + printf '%s\n' "${{ secrets.SSH_KNOWN_HOSTS }}" > "$HOME/.ssh/known_hosts" + chmod 644 "$HOME/.ssh/known_hosts" + + # --- 6. Build every brand and deploy it to .. --- + - name: Build & deploy each brand + run: | + set -euo pipefail + DEPLOY_HOST='${{ secrets.DEPLOY_HOST }}' + DEPLOY_USER='${{ secrets.DEPLOY_USER }}' + DEPLOY_PATH='${{ secrets.DEPLOY_PATH }}' + [ -n "$DEPLOY_HOST" ] && [ -n "$DEPLOY_USER" ] && [ -n "$DEPLOY_PATH" ] \ + || { echo "Missing DEPLOY_HOST/USER/PATH secrets"; exit 1; } + + SSH_OPTS="-i $HOME/.ssh/deploy_key -o UserKnownHostsFile=$HOME/.ssh/known_hosts -o StrictHostKeyChecking=yes" + + for BRAND_PATH in "$CONTENT_DIR"/repo/*/; do + BRAND="$(basename "$BRAND_PATH")" + BASE_URL="https://${BRAND}.${SITE_TLD}/" + BUILD_DIR="${{ gitea.workspace }}/build/${BRAND}" + echo "::group::Build ${BRAND} -> ${BASE_URL}" + + node "$TEMPLATE_DIR/scripts/ci-build-brand.mjs" \ + --template "$TEMPLATE_DIR" \ + --brand-dir "$BRAND_PATH" \ + --out "$BUILD_DIR" + + # node_modules must be reachable from the build dir for Hugo PostCSS. + ln -sfn "$TEMPLATE_DIR/node_modules" "$BUILD_DIR/node_modules" + + "$HUGO_BIN" --source "$BUILD_DIR" --gc --minify --baseURL "$BASE_URL" + test -f "$BUILD_DIR/public/index.html" || { echo "build produced no index.html"; exit 1; } + echo "::endgroup::" + + echo "::group::Deploy ${BRAND}" + # Ensure the target dir exists, then mirror public/ into it. + ssh $SSH_OPTS "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '${DEPLOY_PATH}/${BRAND}'" + rsync -az --delete \ + -e "ssh $SSH_OPTS" \ + "$BUILD_DIR/public/" \ + "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/${BRAND}/" + echo "Deployed ${BRAND} to ${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/${BRAND}/" + echo "::endgroup::" + done + + - name: Cleanup SSH key + if: always() + run: rm -f "$HOME/.ssh/deploy_key"