diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 3a020db..104c563 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -1,6 +1,7 @@ name: deploy-preland -# После коммита в main — заливка преленда на хостинги всех целей (FTP с TLS) и проверка страницы каждой цели. +# После коммита в main сохраняется legacy-выпуск на Beget. Новые домены ZoomPixel +# доставляются отдельными SFTP job: staging — только на stage, main — только на production. # Цель — домен со своим хостингом (список — matrix ниже): реквизиты — секреты репозитория _FTP_HOST, # _FTP_USER, _FTP_PASS (порт 21). Цели независимы: сбой одного хостинга остальные не останавливает. # Заливаются файлы репозитория (git ls-files), кроме служебных (.gitea/, README.md, AGENTS.md, CLAUDE.md, .gitignore) и тех, что живут @@ -11,10 +12,12 @@ on: push: branches: - main + - staging jobs: deploy: name: deploy ${{ matrix.name }} + if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest strategy: @@ -82,3 +85,113 @@ jobs: esac printf '%s' "$page" | grep -q 'claim?key=' || { echo "переход не на claim — залит старый код?"; exit 1; } echo "страница в порядке" + + deploy-zoomstage: + name: deploy zoomstage.online + if: github.ref == 'refs/heads/staging' + runs-on: zoomzilla-production + defaults: + run: + shell: sh + env: + PRELAND_URL: https://zoomstage.online + REMOTE_DIR: domains/zoomstage.online + steps: + - name: Install tools + run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git curl openssh-client sshpass + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Upload over SFTP + env: + SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }} + SFTP_USER: ${{ secrets.ZOOMPIXEL_SFTP_USER }} + SFTP_PASS: ${{ secrets.ZOOMPIXEL_SFTP_PASS }} + SFTP_KNOWN_HOSTS: ${{ secrets.ZOOMPIXEL_SFTP_KNOWN_HOSTS }} + run: | + set -eu + [ -n "$SFTP_HOST" ] && [ -n "$SFTP_USER" ] && [ -n "$SFTP_PASS" ] && [ -n "$SFTP_KNOWN_HOSTS" ] || { echo "не заданы секреты ZOOMPIXEL_SFTP_*"; exit 1; } + umask 077 + known_hosts=$(mktemp) + batch=$(mktemp) + files=$(mktemp) + trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT + printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" + git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|config\.json$|requisites\.html$)' > "$files" + if grep -q '[^A-Za-z0-9._/-]' "$files"; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' "$files"; exit 1; fi + printf '%s\n' "-mkdir $REMOTE_DIR" > "$batch" + sed 's#/[^/]*$##' "$files" | grep -v '^$' | sort -u | while read -r dir; do printf '%s\n' "-mkdir $REMOTE_DIR/$dir" >> "$batch"; done + while read -r file; do printf '%s\n' "put -p $file $REMOTE_DIR/$file" >> "$batch"; done < "$files" + SSHPASS="$SFTP_PASS" sshpass -e sftp -b "$batch" -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" "$SFTP_USER@$SFTP_HOST" + echo "залито файлов: $(wc -l < "$files")" + + - name: Check the page + run: | + set -eu + page=$(curl -fsS --max-time 30 "$PRELAND_URL/?nc=$(date +%s)") + api=$(printf '%s' "$page" | grep -o 'const createApiUrl = "[^"]*"' || true) + echo "$api" + case "$api" in *'zoomzilla.ru\/api\/images\/public\/create'*) ;; *) echo "на странице нет адреса загрузки Zoomzilla"; exit 1 ;; esac + esac + printf '%s' "$page" | grep -q 'claim?key=' || { echo "переход не на claim"; exit 1; } + + deploy-zoompixel-production: + name: deploy ${{ matrix.name }} + if: github.ref == 'refs/heads/main' + runs-on: zoomzilla-production + strategy: + fail-fast: false + matrix: + include: + - name: zoompixel.ru + url: https://zoompixel.ru + dir: domains/zoompixel.ru + - name: zoompixel.online + url: https://zoompixel.online + dir: domains/zoompixel.online + defaults: + run: + shell: sh + env: + PRELAND_URL: ${{ matrix.url }} + REMOTE_DIR: ${{ matrix.dir }} + steps: + - name: Install tools + run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git curl openssh-client sshpass + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Upload over SFTP + env: + SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }} + SFTP_USER: ${{ secrets.ZOOMPIXEL_SFTP_USER }} + SFTP_PASS: ${{ secrets.ZOOMPIXEL_SFTP_PASS }} + SFTP_KNOWN_HOSTS: ${{ secrets.ZOOMPIXEL_SFTP_KNOWN_HOSTS }} + run: | + set -eu + [ -n "$SFTP_HOST" ] && [ -n "$SFTP_USER" ] && [ -n "$SFTP_PASS" ] && [ -n "$SFTP_KNOWN_HOSTS" ] || { echo "не заданы секреты ZOOMPIXEL_SFTP_*"; exit 1; } + umask 077 + known_hosts=$(mktemp) + batch=$(mktemp) + files=$(mktemp) + trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT + printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" + git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|config\.json$|requisites\.html$)' > "$files" + if grep -q '[^A-Za-z0-9._/-]' "$files"; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' "$files"; exit 1; fi + printf '%s\n' "-mkdir $REMOTE_DIR" > "$batch" + sed 's#/[^/]*$##' "$files" | grep -v '^$' | sort -u | while read -r dir; do printf '%s\n' "-mkdir $REMOTE_DIR/$dir" >> "$batch"; done + while read -r file; do printf '%s\n' "put -p $file $REMOTE_DIR/$file" >> "$batch"; done < "$files" + SSHPASS="$SFTP_PASS" sshpass -e sftp -b "$batch" -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" "$SFTP_USER@$SFTP_HOST" + echo "залито файлов: $(wc -l < "$files")" + + - name: Check the page + run: | + set -eu + page=$(curl -fsS --max-time 30 "$PRELAND_URL/?nc=$(date +%s)") + api=$(printf '%s' "$page" | grep -o 'const createApiUrl = "[^"]*"' || true) + echo "$api" + case "$api" in *'zoomzilla.ru\/api\/images\/public\/create'*) ;; *) echo "на странице нет адреса загрузки Zoomzilla"; exit 1 ;; esac + esac + printf '%s' "$page" | grep -q 'claim?key=' || { echo "переход не на claim"; exit 1; }