fix(deploy): preserve host preland config
This commit is contained in:
1 parent
9835bb0ef8
commit
f14ce88cc6
6 files changed
+169
-20
No files matched your search
@@ -6,7 +6,9 @@ name: deploy-preland
|
|||||||
# <prefix>_FTP_USER, <prefix>_FTP_PASS (порт 21). Цели независимы: сбой одного хостинга остальные не останавливает.
|
# <prefix>_FTP_USER, <prefix>_FTP_PASS (порт 21). Цели независимы: сбой одного хостинга остальные не останавливает.
|
||||||
# Заливаются файлы репозитория (git ls-files), кроме служебных (.gitea/, README.md, AGENTS.md, CLAUDE.md, .gitignore) и тех, что живут
|
# Заливаются файлы репозитория (git ls-files), кроме служебных (.gitea/, README.md, AGENTS.md, CLAUDE.md, .gitignore) и тех, что живут
|
||||||
# только на хостинге: requisites.html (реквизиты заполняют на месте — пустой файл из git их бы затёр).
|
# только на хостинге: requisites.html (реквизиты заполняют на месте — пустой файл из git их бы затёр).
|
||||||
# Рабочий config.json единственный и версионируется: он должен попадать в каждую доставку.
|
# Рабочий config.json настраивается владельцем на каждом хостинге и является
|
||||||
|
# источником истины. Обычный deploy его не перезаписывает; задача может менять
|
||||||
|
# только прямо согласованные ключи после чтения текущего host-файла.
|
||||||
# На хостинге ничего не удаляется: удалённое из репозитория убирать вручную.
|
# На хостинге ничего не удаляется: удалённое из репозитория убирать вручную.
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -43,11 +45,35 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install tools (Alpine)
|
- name: Install tools (Alpine)
|
||||||
run: apk add --no-cache git curl
|
run: apk add --no-cache git curl php83-cli
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Preserve host config and add focus if absent
|
||||||
|
env:
|
||||||
|
FTP_HOST: ${{ secrets[format('{0}_FTP_HOST', matrix.prefix)] }}
|
||||||
|
FTP_USER: ${{ secrets[format('{0}_FTP_USER', matrix.prefix)] }}
|
||||||
|
FTP_PASS: ${{ secrets[format('{0}_FTP_PASS', matrix.prefix)] }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
[ -n "$FTP_HOST" ] && [ -n "$FTP_USER" ] && [ -n "$FTP_PASS" ] || { echo "нет секретов ${{ matrix.prefix }}_FTP_*"; exit 1; }
|
||||||
|
dir=$(printf '%s' "$REMOTE_DIR" | sed 's#^/*##; s#/*$##')
|
||||||
|
umask 077
|
||||||
|
netrc=$(mktemp); config=$(mktemp)
|
||||||
|
trap 'rm -f "$netrc" "$config"' EXIT
|
||||||
|
printf 'machine %s login %s password %s\n' "$FTP_HOST" "$FTP_USER" "$FTP_PASS" > "$netrc"
|
||||||
|
curl -sS --ssl-reqd --netrc-file "$netrc" --fail --retry 3 \
|
||||||
|
"ftp://$FTP_HOST/${dir:+$dir/}config.json" -o "$config"
|
||||||
|
changed=0
|
||||||
|
php bin/ensure-focus-config.php "$config" || changed=$?
|
||||||
|
case "$changed" in
|
||||||
|
0) ;;
|
||||||
|
10) curl -sS --ssl-reqd --netrc-file "$netrc" --ftp-create-dirs --retry 3 --fail \
|
||||||
|
-T "$config" "ftp://$FTP_HOST/${dir:+$dir/}config.json" ;;
|
||||||
|
*) exit "$changed" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
- name: Upload over FTP (TLS)
|
- name: Upload over FTP (TLS)
|
||||||
env:
|
env:
|
||||||
FTP_HOST: ${{ secrets[format('{0}_FTP_HOST', matrix.prefix)] }}
|
FTP_HOST: ${{ secrets[format('{0}_FTP_HOST', matrix.prefix)] }}
|
||||||
@@ -62,7 +88,7 @@ jobs:
|
|||||||
netrc=$(mktemp); list=$(mktemp)
|
netrc=$(mktemp); list=$(mktemp)
|
||||||
trap 'rm -f "$netrc" "$list"' EXIT
|
trap 'rm -f "$netrc" "$list"' EXIT
|
||||||
printf 'machine %s login %s password %s\n' "$FTP_HOST" "$FTP_USER" "$FTP_PASS" > "$netrc"
|
printf 'machine %s login %s password %s\n' "$FTP_HOST" "$FTP_USER" "$FTP_PASS" > "$netrc"
|
||||||
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$)' > files.txt
|
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$|config\.json$)' > files.txt
|
||||||
# имя уходит в адрес ftp:// как есть — пробелы и прочее экранирование не поддерживаем
|
# имя уходит в адрес ftp:// как есть — пробелы и прочее экранирование не поддерживаем
|
||||||
if grep -q '[^A-Za-z0-9._/-]' files.txt; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' files.txt; exit 1; fi
|
if grep -q '[^A-Za-z0-9._/-]' files.txt; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' files.txt; exit 1; fi
|
||||||
# один curl на все файлы — одно соединение FTP+TLS вместо соединения на файл
|
# один curl на все файлы — одно соединение FTP+TLS вместо соединения на файл
|
||||||
@@ -99,11 +125,35 @@ jobs:
|
|||||||
REMOTE_DIR: domains/zoomstage.online
|
REMOTE_DIR: domains/zoomstage.online
|
||||||
steps:
|
steps:
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates git curl openssh-client sshpass
|
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
|
- name: Checkout staging branch
|
||||||
run: git clone --depth 1 --branch staging http://git.dira89kv.beget.tech:3000/anton/preland.git .
|
run: git clone --depth 1 --branch staging http://git.dira89kv.beget.tech:3000/anton/preland.git .
|
||||||
|
|
||||||
|
- 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" "$SFTP_USER@$SFTP_HOST" < "$batch"
|
||||||
|
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" "$SFTP_USER@$SFTP_HOST" < "$batch" ;;
|
||||||
|
*) exit "$changed" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
- name: Upload over SFTP
|
- name: Upload over SFTP
|
||||||
env:
|
env:
|
||||||
SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }}
|
SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }}
|
||||||
@@ -119,7 +169,7 @@ jobs:
|
|||||||
files=$(mktemp)
|
files=$(mktemp)
|
||||||
trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT
|
trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT
|
||||||
printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts"
|
printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts"
|
||||||
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$)' > "$files"
|
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$|config\.json$)' > "$files"
|
||||||
if grep -q '[^A-Za-z0-9._/-]' "$files"; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' "$files"; exit 1; fi
|
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"
|
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
|
sed 's#/[^/]*$##' "$files" | grep -v '^$' | sort -u | while read -r dir; do printf '%s\n' "-mkdir $REMOTE_DIR/$dir" >> "$batch"; done
|
||||||
@@ -158,11 +208,35 @@ jobs:
|
|||||||
REMOTE_DIR: ${{ matrix.dir }}
|
REMOTE_DIR: ${{ matrix.dir }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates git curl openssh-client sshpass
|
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 production branch
|
- name: Checkout production branch
|
||||||
run: git clone --depth 1 --branch main http://git.dira89kv.beget.tech:3000/anton/preland.git .
|
run: git clone --depth 1 --branch main http://git.dira89kv.beget.tech:3000/anton/preland.git .
|
||||||
|
|
||||||
|
- 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" "$SFTP_USER@$SFTP_HOST" < "$batch"
|
||||||
|
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" "$SFTP_USER@$SFTP_HOST" < "$batch" ;;
|
||||||
|
*) exit "$changed" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
- name: Upload over SFTP
|
- name: Upload over SFTP
|
||||||
env:
|
env:
|
||||||
SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }}
|
SFTP_HOST: ${{ secrets.ZOOMPIXEL_SFTP_HOST }}
|
||||||
@@ -178,7 +252,7 @@ jobs:
|
|||||||
files=$(mktemp)
|
files=$(mktemp)
|
||||||
trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT
|
trap 'rm -f "$known_hosts" "$batch" "$files"' EXIT
|
||||||
printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts"
|
printf '%s\n' "$SFTP_KNOWN_HOSTS" > "$known_hosts"
|
||||||
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$)' > "$files"
|
git ls-files | grep -vE '^(\.gitea/|README\.md$|AGENTS\.md$|CLAUDE\.md$|\.gitignore$|requisites\.html$|config\.json$)' > "$files"
|
||||||
if grep -q '[^A-Za-z0-9._/-]' "$files"; then echo "имена с недопустимыми символами:"; grep '[^A-Za-z0-9._/-]' "$files"; exit 1; fi
|
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"
|
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
|
sed 's#/[^/]*$##' "$files" | grep -v '^$' | sort -u | while read -r dir; do printf '%s\n' "-mkdir $REMOTE_DIR/$dir" >> "$batch"; done
|
||||||
|
|||||||
@@ -21,10 +21,13 @@
|
|||||||
переход напрямую на `/public/upscale` не заменяет передачу владельца через claim.
|
переход напрямую на `/public/upscale` не заменяет передачу владельца через claim.
|
||||||
- `host` задаёт сайт назначения; HTTPS необходим для `crypto.randomUUID()`.
|
- `host` задаёт сайт назначения; HTTPS необходим для `crypto.randomUUID()`.
|
||||||
Не обходить серверные правила доступа к загрузке и результату обработки.
|
Не обходить серверные правила доступа к загрузке и результату обработки.
|
||||||
- Рабочий `config.json` единственный для всех прилендов: это точная проверенная
|
- Рабочий `config.json` на каждом хостинге настраивает владелец. Деплой не имеет
|
||||||
конфигурация `zoomstage.online`, и каждый FTP/SFTP-deploy обязан доставлять её на
|
права перезаписывать его значений. При появлении новой обязательной UTM workflow
|
||||||
stage и production. `requisites.html` по-прежнему живёт только на хостинге и не
|
получает текущий хостовый конфиг и добавляет только отсутствующий ключ через
|
||||||
перезаписывается. Не создавать target-specific конфиги или `config.json.example`.
|
`bin/ensure-focus-config.php`; имеющиеся значения, включая уже настроенный
|
||||||
|
`focus`, остаются байт-в-байт прежними. `requisites.html` также живёт только на
|
||||||
|
хостинге и не перезаписывается. Не создавать target-specific конфиги или
|
||||||
|
`config.json.example`.
|
||||||
- Коммит в `main` запускает FTP-автодеплой на все цели workflow; откат через `git revert`
|
- Коммит в `main` запускает FTP-автодеплой на все цели workflow; откат через `git revert`
|
||||||
также запускает выкат. Коммит, push и изменения хостинга — только по прямому поручению.
|
также запускает выкат. Коммит, push и изменения хостинга — только по прямому поручению.
|
||||||
- Проверки кода и браузера проводить в Docker без установки ПО на хост.
|
- Проверки кода и браузера проводить в Docker без установки ПО на хост.
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Точечно добавляет новую UTM focus в рабочий конфиг приленда на хостинге.
|
||||||
|
*
|
||||||
|
* Значения уже существующих полей конфигурации намеренно не нормализуются и
|
||||||
|
* не переписываются: владелец настраивает их непосредственно на стенде или
|
||||||
|
* production. Скрипт возвращает 0, когда focus уже существует, и 10, когда
|
||||||
|
* ключ добавлен и config.json требуется загрузить обратно.
|
||||||
|
*
|
||||||
|
* @usage php bin/ensure-focus-config.php /path/to/config.json
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
if ($argc !== 2) {
|
||||||
|
fwrite(STDERR, "Использование: php bin/ensure-focus-config.php /path/to/config.json\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $argv[1];
|
||||||
|
$raw = @file_get_contents($path);
|
||||||
|
if ($raw === false) {
|
||||||
|
fwrite(STDERR, "Не удалось прочитать config.json.\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$config = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
} catch (JsonException $exception) {
|
||||||
|
fwrite(STDERR, "config.json содержит некорректный JSON: {$exception->getMessage()}\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($config) || !isset($config['utm']) || !is_array($config['utm'])) {
|
||||||
|
fwrite(STDERR, "В config.json отсутствует объект utm.\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('focus', $config['utm'])) {
|
||||||
|
fwrite(STDOUT, "focus уже настроен: конфиг не изменён.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$config['utm']['focus'] = [
|
||||||
|
'weights' => [
|
||||||
|
'center' => 0,
|
||||||
|
'face' => 1,
|
||||||
|
],
|
||||||
|
'default' => 'face',
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$encoded = json_encode(
|
||||||
|
$config,
|
||||||
|
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR
|
||||||
|
) . "\n";
|
||||||
|
} catch (JsonException $exception) {
|
||||||
|
fwrite(STDERR, "Не удалось сериализовать config.json: {$exception->getMessage()}\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_put_contents($path, $encoded, LOCK_EX) === false) {
|
||||||
|
fwrite(STDERR, "Не удалось записать обновлённый config.json.\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(STDOUT, "Добавлен только utm.focus (face включён по умолчанию).\n");
|
||||||
|
exit(10);
|
||||||
+3
-3
@@ -60,10 +60,10 @@
|
|||||||
},
|
},
|
||||||
"focus": {
|
"focus": {
|
||||||
"weights": {
|
"weights": {
|
||||||
"center": 1,
|
"center": 0,
|
||||||
"face": 0
|
"face": 1
|
||||||
},
|
},
|
||||||
"default": "center"
|
"default": "face"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ $expected = [
|
|||||||
'bchoice' => 'a',
|
'bchoice' => 'a',
|
||||||
'chb' => 'b',
|
'chb' => 'b',
|
||||||
'tp' => '1',
|
'tp' => '1',
|
||||||
'focus' => 'center',
|
'focus' => 'face',
|
||||||
'utm_source' => 'stage-ad',
|
'utm_source' => 'stage-ad',
|
||||||
'subid' => 'click-42',
|
'subid' => 'click-42',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
/**
|
/**
|
||||||
* Регрессия единственного рабочего конфига приленда.
|
* Регрессия единственного рабочего конфига приленда.
|
||||||
*
|
*
|
||||||
* Stage-конфиг — единственный канонический конфиг каждого приленда. Он должен
|
* Репозиторный config.json задаёт схему и стартовые значения. Рабочий конфиг
|
||||||
* быть в репозитории и попадать во все FTP/SFTP-доставки без исключений.
|
* владельца на хостинге не перезаписывается: delivery добавляет только
|
||||||
|
* отсутствующие обязательные UTM-ключи.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
@@ -25,7 +26,7 @@ if (!is_array($config)) {
|
|||||||
'bchoice' => ['a' => 1, 'b' => 0, 'default' => 'a'],
|
'bchoice' => ['a' => 1, 'b' => 0, 'default' => 'a'],
|
||||||
'chb' => ['a' => 1, 'b' => 0, 'default' => 'b'],
|
'chb' => ['a' => 1, 'b' => 0, 'default' => 'b'],
|
||||||
'tp' => ['1' => 0, '2' => 1, 'default' => '1'],
|
'tp' => ['1' => 0, '2' => 1, 'default' => '1'],
|
||||||
'focus' => ['center' => 1, 'face' => 0, 'default' => 'center'],
|
'focus' => ['center' => 0, 'face' => 1, 'default' => 'face'],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (($config['host'] ?? null) !== $expected['host']) {
|
if (($config['host'] ?? null) !== $expected['host']) {
|
||||||
@@ -58,8 +59,11 @@ foreach ([
|
|||||||
'deploy-zoomstage' => $stageBlock,
|
'deploy-zoomstage' => $stageBlock,
|
||||||
'deploy-zoompixel-production' => $productionBlock,
|
'deploy-zoompixel-production' => $productionBlock,
|
||||||
] as $delivery => $block) {
|
] as $delivery => $block) {
|
||||||
if ($block === '' || str_contains($block, 'config\\.json$')) {
|
if ($block === ''
|
||||||
$failures[] = "{$delivery} обязан доставлять единый версионируемый config.json.";
|
|| !str_contains($block, 'config\\.json$')
|
||||||
|
|| !str_contains($block, 'ensure-focus-config.php')
|
||||||
|
|| !str_contains($block, 'Preserve host config and add focus if absent')) {
|
||||||
|
$failures[] = "{$delivery} обязан сохранять хостовый config.json и добавлять только отсутствующий focus.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user