name: deploy-preland # Решение владельца 19.10.2026, preland#4: только stage. # Production выкаты временно отключены; Барбариска больше не используется. on: push: branches: - staging jobs: 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 ca-certificates git curl openssh-client sshpass php-cli - name: Checkout staging branch env: RELEASE_SHA: ${{ github.sha }} run: | set -eu git clone --depth 1 --branch staging http://git.dira89kv.beget.tech:3000/anton/preland.git . git fetch --depth 1 origin "$RELEASE_SHA" git checkout --detach "$RELEASE_SHA" [ "$(git rev-parse HEAD)" = "$RELEASE_SHA" ] - name: Validate release and current stage sets before upload run: | set -eu php bin/release-assets.php --check for test in tests/check-*.php; do php "$test"; done php bin/release-assets.php --primary # /N/ по-прежнему принадлежит stage. Любое расхождение требует # сначала перенести актуальный снимок в Git по задаче. php bin/release-assets.php --stage-sets "$PRELAND_URL" - name: Preserve host config and add focus if absent 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); config=$(mktemp) trap 'rm -f "$known_hosts" "$batch" "$config"' EXIT printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" printf '%s\n' "get -p $REMOTE_DIR/config.json $config" > "$batch" SSHPASS="$SFTP_PASS" sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$SFTP_USER@$SFTP_HOST" changed=0 php bin/ensure-focus-config.php "$config" || changed=$? case "$changed" in 0) ;; 10) printf '%s\n' "put -p $config $REMOTE_DIR/config.json" > "$batch" SSHPASS="$SFTP_PASS" sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$SFTP_USER@$SFTP_HOST" ;; *) exit "$changed" ;; esac # preland#11: отдельное прямое разрешение21.10 на актуальные реквизиты. changed=0 php bin/ensure-requisites-config.php "$config" || changed=$? case "$changed" in 0) ;; 10) printf '%s\n' "put -p $config $REMOTE_DIR/config.json" > "$batch" SSHPASS="$SFTP_PASS" sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$SFTP_USER@$SFTP_HOST" ;; *) exit "$changed" ;; esac - 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) dirs=$(mktemp) trap 'rm -f "$known_hosts" "$batch" "$files" "$dirs"' EXIT printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" # Наборы `/N/` на stage — редактируемый контент. Кодовая доставка их # намеренно не перезаписывает: актуальное содержимое stage фиксируют в Git # отдельной синхронизацией по задаче. # Положительный список: tests/bin/планы не публикуются. php bin/release-assets.php --files | grep -vE '^(config\.json$|[0-9]+/)' > "$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" while read -r file; do case "$file" in */*) dir=${file%/*} ;; *) continue ;; esac while [ -n "$dir" ]; do printf '%s\n' "$dir" >> "$dirs" case "$dir" in */*) dir=${dir%/*} ;; *) break ;; esac done done < "$files" sort -u "$dirs" | 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 -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$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 printf '%s' "$page" | grep -q 'claim?key=' || { echo "переход не на claim"; exit 1; } curl -fsS --max-time 30 "$PRELAND_URL/1/01_desk_1-source.avif" -o /dev/null || { echo "не опубликован первый набор примеров"; exit 1; } curl -fsS --max-time 30 "$PRELAND_URL/2/01_desk_1-source.avif" -o /dev/null || { echo "не опубликован второй набор примеров"; exit 1; } page2=$(curl -fsS --max-time 30 "$PRELAND_URL/?indpic=2&nc=$(date +%s)") printf '%s' "$page2" | grep -q '2/01_mob_1-source.avif' || { echo "indpic=2 не использует второй набор примеров"; exit 1; } php bin/release-assets.php --remote "$PRELAND_URL" php bin/release-assets.php --stage-requisites "$PRELAND_URL" - name: Remove previously published internal files 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 umask 077 known_hosts=$(mktemp); batch=$(mktemp) trap 'rm -f "$known_hosts" "$batch"' EXIT printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" # Только точно известные служебные файлы прежнего deploy, без рекурсии. git ls-files tests bin docs/superpowers | while read -r file; do printf '%s\n' "-rm $REMOTE_DIR/$file" >> "$batch" done SSHPASS="$SFTP_PASS" sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$SFTP_USER@$SFTP_HOST" - name: Remove obsolete demo directories 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 umask 077 known_hosts=$(mktemp) batch=$(mktemp) trap 'rm -f "$known_hosts" "$batch"' EXIT printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts" for set in demo demo-2; do for example in 1 2 3 4 5; do for file in source.avif source.jpg source.webp result.avif result.jpg result.webp thumb.avif thumb.jpg thumb.webp source_mob.avif result_mob.avif thumb_mob.avif; do printf '%s\n' "-rm $REMOTE_DIR/images/$set/$example/$file" >> "$batch" done printf '%s\n' "-rmdir $REMOTE_DIR/images/$set/$example" >> "$batch" done printf '%s\n' "-rmdir $REMOTE_DIR/images/$set" >> "$batch" done SSHPASS="$SFTP_PASS" sshpass -e sftp -oBatchMode=no -oStrictHostKeyChecking=yes -oUserKnownHostsFile="$known_hosts" -b "$batch" "$SFTP_USER@$SFTP_HOST"