chore(deploy): dedupe & regroup Gitea CI variables/secrets
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Successful in 1m4s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m44s

Collapse identical TEST_/PROD_ pairs to single unprefixed Gitea entries, derive
the public URLs from PUBLIC_BASE_URL at deploy time, and share the prod env.sh
renderer between deploy and rollback.

- Collapse to one unprefixed variable: DICT_VERSION, SMTP_RELAY_HOST/PORT/TLS,
  GRAFANA_SMTP_PORT, VITE_VK_APP_LINK, VITE_VK_APP_ID (one Selectel relay + one
  pair of VK apps serve every contour). Secrets collapsed by the owner:
  SMTP_RELAY_USER/PASS, GATEWAY_VK_APP_SECRET, GATEWAY_VK_ID_CLIENT_SECRET.
- Derive at deploy from PUBLIC_BASE_URL (no longer stored): TELEGRAM_MINIAPP_URL,
  GRAFANA_ROOT_URL, VITE_VK_ID_REDIRECT_URL. Removes the prod/test asymmetry and
  fills the missing test VITE_VK_APP_ID (VK web login was half-configured on test).
- Extract deploy/write-prod-env.sh + write-prod-bot-env.sh, shared by prod-deploy
  and prod-rollback so the two cannot drift: a rollback now re-renders the FULL
  runtime env (email / VK login / Grafana alerts previously went dark after a
  rollback) and passes TELEGRAM_SUPPORT_CHAT_ID.
- Single-source DICT_VERSION (CI env + both deploys), fix the v1.3.0/v1.3.1 drift in
  .env.example/README, correct the misleading honeytoken/abuse-ban compose comment,
  and rewrite the deploy/README variable list (+ the previously undocumented
  GATEWAY_VK_APP_SECRET and TELEGRAM_SUPPORT_CHAT_ID).

The Gitea variables are reworked via the API; the stale TEST_/PROD_ entries are
deleted after the test contour goes green.
This commit is contained in:
Ilia Denisov
2026-07-03 21:07:07 +02:00
parent 72e9b600b0
commit 7f85362288
8 changed files with 271 additions and 189 deletions
+35 -26
View File
@@ -26,12 +26,12 @@ on:
push:
branches: [development]
# The dictionary release the test suite validates against — the current
# scrabble-dictionary release. Centralised here so a release bump is one edit; the
# unit/integration jobs inherit it. The deploy job overrides it per contour with
# vars.TEST_DICT_VERSION (the seed for a fresh volume), see deploy/README.md.
# The dictionary release. One Gitea variable is the single source of truth: the
# test suite validates against it here (inherited by the unit/integration jobs) and
# both contours' deploy jobs seed a fresh volume with the same value. A release bump
# is one edit (the variable). See deploy/README.md.
env:
DICT_VERSION: v1.3.1
DICT_VERSION: ${{ vars.DICT_VERSION }}
jobs:
# changes detects which areas a PR/push touched, so the test jobs can skip when
@@ -329,20 +329,22 @@ jobs:
TELEGRAM_PROMO_BOT_TOKEN: ${{ secrets.TEST_TELEGRAM_PROMO_BOT_TOKEN }}
# VK Mini App protected key (offline HMAC for the launch-param signature); empty
# leaves the VK auth path (auth.vk) disabled until the operator sets the secret.
GATEWAY_VK_APP_SECRET: ${{ secrets.TEST_GATEWAY_VK_APP_SECRET }}
# One VK Mini App serves every contour -> unprefixed secret.
GATEWAY_VK_APP_SECRET: ${{ secrets.GATEWAY_VK_APP_SECRET }}
# VK ID web login (browser VK-identity linking): the VK ID "Web" app's protected key
# for the server-side confidential code exchange — a SEPARATE VK app from the Mini
# App above. Empty leaves the link.vk.* ops disabled.
GATEWAY_VK_ID_CLIENT_SECRET: ${{ secrets.TEST_GATEWAY_VK_ID_CLIENT_SECRET }}
# App above. One VK ID "Web" app serves every contour -> unprefixed secret.
GATEWAY_VK_ID_CLIENT_SECRET: ${{ secrets.GATEWAY_VK_ID_CLIENT_SECRET }}
# Signs the finished-game export download URLs (backend + compose interpolation).
EXPORT_SIGN_KEY: ${{ secrets.TEST_EXPORT_SIGN_KEY }}
# Transactional email via the shared Selectel relay. Empty host leaves the
# backend on the log mailer (email disabled) but the contour still boots.
SMTP_RELAY_USER: ${{ secrets.TEST_SMTP_RELAY_USER }}
SMTP_RELAY_PASS: ${{ secrets.TEST_SMTP_RELAY_PASS }}
SMTP_RELAY_HOST: ${{ vars.TEST_SMTP_RELAY_HOST }}
SMTP_RELAY_PORT: ${{ vars.TEST_SMTP_RELAY_PORT }}
SMTP_RELAY_TLS: ${{ vars.TEST_SMTP_RELAY_TLS }}
# Transactional email via the shared Selectel relay: one account for every
# contour -> unprefixed host/port/tls/user/pass. Empty host leaves the backend
# on the log mailer (email disabled) but the contour still boots.
SMTP_RELAY_USER: ${{ secrets.SMTP_RELAY_USER }}
SMTP_RELAY_PASS: ${{ secrets.SMTP_RELAY_PASS }}
SMTP_RELAY_HOST: ${{ vars.SMTP_RELAY_HOST }}
SMTP_RELAY_PORT: ${{ vars.SMTP_RELAY_PORT }}
SMTP_RELAY_TLS: ${{ vars.SMTP_RELAY_TLS }}
SMTP_RELAY_FROM: ${{ vars.TEST_SMTP_RELAY_FROM }}
# Operator alerts: backend admin emails (new feedback / complaints) + Grafana
# infra alerts. Distinct senders + recipients; Grafana uses the relay's STARTTLS
@@ -351,15 +353,15 @@ jobs:
ADMIN_EMAIL: ${{ vars.TEST_ADMIN_EMAIL }}
SMTP_RELAY_SERVICE_FROM: ${{ vars.TEST_SMTP_RELAY_SERVICE_FROM }}
SERVICE_EMAIL: ${{ vars.TEST_SERVICE_EMAIL }}
GRAFANA_SMTP_PORT: ${{ vars.TEST_GRAFANA_SMTP_PORT }}
GRAFANA_SMTP_PORT: ${{ vars.GRAFANA_SMTP_PORT }}
GF_SMTP_ENABLED: ${{ vars.TEST_GF_SMTP_ENABLED }}
# Canonical public origin for links in the email (this contour's URL);
# required by the backend whenever SMTP_RELAY_HOST is set.
PUBLIC_BASE_URL: ${{ vars.TEST_PUBLIC_BASE_URL }}
GM_BASICAUTH_USER: ${{ vars.TEST_GM_BASICAUTH_USER }}
GRAFANA_ROOT_URL: ${{ vars.TEST_GRAFANA_ROOT_URL }}
CADDY_SITE_ADDRESS: ${{ vars.TEST_CADDY_SITE_ADDRESS }}
TELEGRAM_MINIAPP_URL: ${{ vars.TEST_TELEGRAM_MINIAPP_URL }}
# TELEGRAM_MINIAPP_URL, GRAFANA_ROOT_URL and VITE_VK_ID_REDIRECT_URL are derived
# from PUBLIC_BASE_URL in the run step below, not stored as their own variables.
TELEGRAM_GAME_CHANNEL_ID: ${{ vars.TEST_TELEGRAM_GAME_CHANNEL_ID }}
TELEGRAM_CHAT_ID: ${{ vars.TEST_TELEGRAM_CHAT_ID }}
TELEGRAM_SUPPORT_CHAT_ID: ${{ vars.TEST_TELEGRAM_SUPPORT_CHAT_ID }}
@@ -372,16 +374,16 @@ jobs:
VITE_TELEGRAM_BOT_ID: ${{ vars.TEST_VITE_TELEGRAM_BOT_ID }}
VITE_TELEGRAM_LINK: ${{ vars.TEST_VITE_TELEGRAM_LINK }}
VITE_TELEGRAM_GAME_CHANNEL_NAME: ${{ vars.TEST_VITE_TELEGRAM_GAME_CHANNEL_NAME }}
VITE_VK_APP_LINK: ${{ vars.TEST_VITE_VK_APP_LINK }}
# VK ID web login: the "Web" app id + its trusted redirect URL. One value each feeds
# both the SPA (the authorize URL) and the gateway (client_id / exchange redirect_uri).
VITE_VK_APP_ID: ${{ vars.TEST_VITE_VK_APP_ID }}
VITE_VK_ID_REDIRECT_URL: ${{ vars.TEST_VK_ID_REDIRECT_URL }}
VITE_GATEWAY_URL: ${{ vars.TEST_VITE_GATEWAY_URL }}
# Unset vars render empty -> the compose ":-" defaults apply.
# VK Mini App landing link + VK ID "Web" app id: one value each serves every
# contour -> unprefixed. VITE_VK_APP_ID also feeds the gateway (GATEWAY_VK_ID_APP_ID);
# the VK ID redirect URL is derived from PUBLIC_BASE_URL in the run step below.
VITE_VK_APP_LINK: ${{ vars.VITE_VK_APP_LINK }}
VITE_VK_APP_ID: ${{ vars.VITE_VK_APP_ID }}
# VITE_GATEWAY_URL omitted: the SPA is served same-origin, so it stays the
# compose ":-" empty default. Other unset vars likewise fall to their defaults.
POSTGRES_DB: ${{ vars.TEST_POSTGRES_DB }}
POSTGRES_USER: ${{ vars.TEST_POSTGRES_USER }}
DICT_VERSION: ${{ vars.TEST_DICT_VERSION }}
DICT_VERSION: ${{ vars.DICT_VERSION }}
LOG_LEVEL: ${{ vars.TEST_LOG_LEVEL }}
run: |
# Seed the config files to a stable host path. The runner checks out into
@@ -394,6 +396,13 @@ jobs:
mkdir -p "$conf"
cp -r caddy otelcol prometheus tempo grafana blackbox "$conf"/
export SCRABBLE_CONFIG_DIR="$conf"
# Derive the public URLs from the one canonical origin instead of storing each as
# its own variable (paths are structural SPA routes / the Caddy /_gm sub-path).
# Exported before build so the VK ID redirect is baked into the SPA.
base="${PUBLIC_BASE_URL%/}"
export TELEGRAM_MINIAPP_URL="$base/telegram/"
export GRAFANA_ROOT_URL="$base/_gm/grafana/"
export VITE_VK_ID_REDIRECT_URL="$base/app/"
# Grafana's SMTP from_address must be a BARE address (it rejects the "Name" <addr>
# form the backend go-mail accepts) and validates it even when SMTP is disabled — a
# bad value crash-loops Grafana. Split the display-format SERVICE From into a bare
+36 -88
View File
@@ -40,15 +40,16 @@ jobs:
VITE_TELEGRAM_BOT_ID: ${{ vars.PROD_VITE_TELEGRAM_BOT_ID }}
VITE_TELEGRAM_LINK: ${{ vars.PROD_VITE_TELEGRAM_LINK }}
VITE_TELEGRAM_GAME_CHANNEL_NAME: ${{ vars.PROD_VITE_TELEGRAM_GAME_CHANNEL_NAME }}
VITE_VK_APP_LINK: ${{ vars.PROD_VITE_VK_APP_LINK }}
# VK ID web login: the "Web" app id + trusted redirect URL, baked into the SPA authorize URL.
VITE_VK_APP_ID: ${{ vars.PROD_VITE_VK_APP_ID }}
VITE_VK_ID_REDIRECT_URL: ${{ vars.PROD_VK_ID_REDIRECT_URL }}
VITE_GATEWAY_URL: ${{ vars.PROD_VITE_GATEWAY_URL }}
# VK Mini App link + VK ID "Web" app id: one value each serves every contour.
VITE_VK_APP_LINK: ${{ vars.VITE_VK_APP_LINK }}
VITE_VK_APP_ID: ${{ vars.VITE_VK_APP_ID }}
# VITE_GATEWAY_URL omitted: the SPA is served same-origin (compose ":-" default).
POSTGRES_PASSWORD: ${{ secrets.PROD_POSTGRES_PASSWORD }}
GM_BASICAUTH_HASH: ${{ secrets.PROD_GM_BASICAUTH_HASH }}
TELEGRAM_MINIAPP_URL: ${{ vars.PROD_TELEGRAM_MINIAPP_URL }}
DICT_VERSION: ${{ vars.PROD_DICT_VERSION }}
# PUBLIC_BASE_URL drives the derived VK ID redirect (baked into the SPA) and the
# Mini App URL; both are computed in the build step, not stored variables.
PUBLIC_BASE_URL: ${{ vars.PROD_PUBLIC_BASE_URL }}
DICT_VERSION: ${{ vars.DICT_VERSION }}
steps:
- uses: actions/checkout@v4
with:
@@ -62,6 +63,11 @@ jobs:
working-directory: deploy
run: |
export TAG="${{ steps.ver.outputs.tag }}" APP_VERSION="${{ steps.ver.outputs.tag }}" SCRABBLE_CONFIG_DIR=.
# Derive the public URLs from the one canonical origin: the VK ID redirect is a
# build-arg baked into the SPA, and the Mini App URL satisfies the (profiled-out)
# bot service's compose ":?" guard during parse. See deploy/write-prod-env.sh.
base="${PUBLIC_BASE_URL%/}"
export VITE_VK_ID_REDIRECT_URL="$base/app/" TELEGRAM_MINIAPP_URL="$base/telegram/"
# The main-stack images via compose (reuses the build args, incl. VERSION);
# the bot separately, since it is profiled out of the prod compose.
docker compose -f docker-compose.yml -f docker-compose.prod.yml build
@@ -86,20 +92,21 @@ jobs:
GM_BASICAUTH_HASH: ${{ secrets.PROD_GM_BASICAUTH_HASH }}
GRAFANA_ADMIN_PASSWORD: ${{ secrets.PROD_GRAFANA_ADMIN_PASSWORD }}
TELEGRAM_BOT_TOKEN: ${{ secrets.PROD_TELEGRAM_BOT_TOKEN }}
GATEWAY_VK_APP_SECRET: ${{ secrets.PROD_GATEWAY_VK_APP_SECRET }}
# VK ID web login: the SPA app id + redirect URL (the gateway reuses them as its
# client_id / exchange redirect_uri at runtime) and the "Web" app's protected key.
VITE_VK_APP_ID: ${{ vars.PROD_VITE_VK_APP_ID }}
VITE_VK_ID_REDIRECT_URL: ${{ vars.PROD_VK_ID_REDIRECT_URL }}
GATEWAY_VK_ID_CLIENT_SECRET: ${{ secrets.PROD_GATEWAY_VK_ID_CLIENT_SECRET }}
GATEWAY_VK_APP_SECRET: ${{ secrets.GATEWAY_VK_APP_SECRET }}
# VK ID web login: the "Web" app id (the gateway reuses it as GATEWAY_VK_ID_APP_ID at
# runtime) + the app's protected key. Both shared across contours. The redirect URL is
# derived from PUBLIC_BASE_URL in deploy/write-prod-env.sh.
VITE_VK_APP_ID: ${{ vars.VITE_VK_APP_ID }}
GATEWAY_VK_ID_CLIENT_SECRET: ${{ secrets.GATEWAY_VK_ID_CLIENT_SECRET }}
# Signs the finished-game export download URLs (backend BACKEND_EXPORT_SIGN_KEY).
EXPORT_SIGN_KEY: ${{ secrets.PROD_EXPORT_SIGN_KEY }}
# Transactional email via the shared Selectel relay (confirm-codes).
SMTP_RELAY_USER: ${{ secrets.PROD_SMTP_RELAY_USER }}
SMTP_RELAY_PASS: ${{ secrets.PROD_SMTP_RELAY_PASS }}
SMTP_RELAY_HOST: ${{ vars.PROD_SMTP_RELAY_HOST }}
SMTP_RELAY_PORT: ${{ vars.PROD_SMTP_RELAY_PORT }}
SMTP_RELAY_TLS: ${{ vars.PROD_SMTP_RELAY_TLS }}
# Transactional email via the shared Selectel relay (confirm-codes): one account for
# every contour -> unprefixed host/port/tls/user/pass.
SMTP_RELAY_USER: ${{ secrets.SMTP_RELAY_USER }}
SMTP_RELAY_PASS: ${{ secrets.SMTP_RELAY_PASS }}
SMTP_RELAY_HOST: ${{ vars.SMTP_RELAY_HOST }}
SMTP_RELAY_PORT: ${{ vars.SMTP_RELAY_PORT }}
SMTP_RELAY_TLS: ${{ vars.SMTP_RELAY_TLS }}
SMTP_RELAY_FROM: ${{ vars.PROD_SMTP_RELAY_FROM }}
# Operator alerts: backend admin emails + Grafana infra alerts (distinct senders +
# recipients; Grafana uses the relay's STARTTLS host:port).
@@ -107,20 +114,20 @@ jobs:
ADMIN_EMAIL: ${{ vars.PROD_ADMIN_EMAIL }}
SMTP_RELAY_SERVICE_FROM: ${{ vars.PROD_SMTP_RELAY_SERVICE_FROM }}
SERVICE_EMAIL: ${{ vars.PROD_SERVICE_EMAIL }}
GRAFANA_SMTP_PORT: ${{ vars.PROD_GRAFANA_SMTP_PORT }}
GRAFANA_SMTP_PORT: ${{ vars.GRAFANA_SMTP_PORT }}
GF_SMTP_ENABLED: ${{ vars.PROD_GF_SMTP_ENABLED }}
PUBLIC_BASE_URL: ${{ vars.PROD_PUBLIC_BASE_URL }}
PROD_BOTLINK_CA: ${{ secrets.PROD_BOTLINK_CA }}
PROD_BOTLINK_GATEWAY_CERT: ${{ secrets.PROD_BOTLINK_GATEWAY_CERT }}
PROD_BOTLINK_GATEWAY_KEY: ${{ secrets.PROD_BOTLINK_GATEWAY_KEY }}
GM_BASICAUTH_USER: ${{ vars.PROD_GM_BASICAUTH_USER }}
GRAFANA_ROOT_URL: ${{ vars.PROD_GRAFANA_ROOT_URL }}
CADDY_SITE_ADDRESS: ${{ vars.PROD_CADDY_SITE_ADDRESS }}
LOG_LEVEL: ${{ vars.PROD_LOG_LEVEL }}
DICT_VERSION: ${{ vars.PROD_DICT_VERSION }}
DICT_VERSION: ${{ vars.DICT_VERSION }}
POSTGRES_DB: ${{ vars.PROD_POSTGRES_DB }}
POSTGRES_USER: ${{ vars.PROD_POSTGRES_USER }}
TELEGRAM_MINIAPP_URL: ${{ vars.PROD_TELEGRAM_MINIAPP_URL }}
# TELEGRAM_MINIAPP_URL and GRAFANA_ROOT_URL are derived from PUBLIC_BASE_URL in
# deploy/write-prod-env.sh, not stored variables.
steps:
- uses: actions/checkout@v4
with:
@@ -148,56 +155,8 @@ jobs:
run: |
umask 077
mkdir -p stage/certs-main
# Grafana needs a BARE from-address (it rejects the "Name" <addr> form the backend
# accepts, and validates it even when disabled); split the display-format here.
svc_from="${SMTP_RELAY_SERVICE_FROM:-}"
GRAFANA_SMTP_FROM_NAME=''
case "$svc_from" in
*"<"*">"*)
GRAFANA_SMTP_FROM_ADDRESS="$(printf '%s' "$svc_from" | sed -E 's/.*<([^>]+)>.*/\1/')"
GRAFANA_SMTP_FROM_NAME="$(printf '%s' "$svc_from" | sed -E 's/[[:space:]]*<[^>]*>.*$//; s/^"//; s/"$//')" ;;
*) GRAFANA_SMTP_FROM_ADDRESS="$svc_from" ;;
esac
cat > stage/env.sh <<EOF
export REGISTRY='$REGISTRY'
export SCRABBLE_CONFIG_DIR='/opt/scrabble'
export POSTGRES_DB='${POSTGRES_DB:-scrabble}'
export POSTGRES_USER='${POSTGRES_USER:-scrabble}'
export POSTGRES_PASSWORD='$POSTGRES_PASSWORD'
export GM_BASICAUTH_USER='${GM_BASICAUTH_USER:-gm}'
export GM_BASICAUTH_HASH='$GM_BASICAUTH_HASH'
export GRAFANA_ADMIN_PASSWORD='$GRAFANA_ADMIN_PASSWORD'
export GRAFANA_ROOT_URL='$GRAFANA_ROOT_URL'
export CADDY_SITE_ADDRESS='$CADDY_SITE_ADDRESS'
export LOG_LEVEL='${LOG_LEVEL:-info}'
export DICT_VERSION='$DICT_VERSION'
export APP_VERSION='$TAG'
export TELEGRAM_BOT_TOKEN='$TELEGRAM_BOT_TOKEN'
export TELEGRAM_MINIAPP_URL='$TELEGRAM_MINIAPP_URL'
export GATEWAY_VK_APP_SECRET='$GATEWAY_VK_APP_SECRET'
# VK ID web login: needed at runtime — the gateway's GATEWAY_VK_ID_* env resolves
# its app id / redirect URL from these VITE_ values (one source, shared with the SPA).
export VITE_VK_APP_ID='$VITE_VK_APP_ID'
export VITE_VK_ID_REDIRECT_URL='$VITE_VK_ID_REDIRECT_URL'
export GATEWAY_VK_ID_CLIENT_SECRET='$GATEWAY_VK_ID_CLIENT_SECRET'
export EXPORT_SIGN_KEY='$EXPORT_SIGN_KEY'
export SMTP_RELAY_HOST='$SMTP_RELAY_HOST'
export SMTP_RELAY_PORT='$SMTP_RELAY_PORT'
export SMTP_RELAY_TLS='$SMTP_RELAY_TLS'
export SMTP_RELAY_USER='$SMTP_RELAY_USER'
export SMTP_RELAY_PASS='$SMTP_RELAY_PASS'
export SMTP_RELAY_FROM='$SMTP_RELAY_FROM'
export SMTP_RELAY_ADMIN_FROM='$SMTP_RELAY_ADMIN_FROM'
export ADMIN_EMAIL='$ADMIN_EMAIL'
export SMTP_RELAY_SERVICE_FROM='$SMTP_RELAY_SERVICE_FROM'
export GRAFANA_SMTP_FROM_ADDRESS='$GRAFANA_SMTP_FROM_ADDRESS'
export GRAFANA_SMTP_FROM_NAME='$GRAFANA_SMTP_FROM_NAME'
export SERVICE_EMAIL='$SERVICE_EMAIL'
export GRAFANA_SMTP_PORT='$GRAFANA_SMTP_PORT'
export GF_SMTP_ENABLED='$GF_SMTP_ENABLED'
export PUBLIC_BASE_URL='$PUBLIC_BASE_URL'
export GATEWAY_ABUSE_BAN_ENABLED='true'
EOF
# Shared with prod-rollback so the two paths render an identical runtime env.
APP_VERSION="$TAG" bash deploy/write-prod-env.sh stage/env.sh
printf '%s\n' "$PROD_BOTLINK_CA" > stage/certs-main/ca.crt
printf '%s\n' "$PROD_BOTLINK_GATEWAY_CERT" > stage/certs-main/gateway.crt
printf '%s\n' "$PROD_BOTLINK_GATEWAY_KEY" > stage/certs-main/gateway.key
@@ -236,7 +195,8 @@ jobs:
PROD_BOTLINK_BOT_CERT: ${{ secrets.PROD_BOTLINK_BOT_CERT }}
PROD_BOTLINK_BOT_KEY: ${{ secrets.PROD_BOTLINK_BOT_KEY }}
LOG_LEVEL: ${{ vars.PROD_LOG_LEVEL }}
TELEGRAM_MINIAPP_URL: ${{ vars.PROD_TELEGRAM_MINIAPP_URL }}
# PUBLIC_BASE_URL drives the derived Mini App URL in deploy/write-prod-bot-env.sh.
PUBLIC_BASE_URL: ${{ vars.PROD_PUBLIC_BASE_URL }}
TELEGRAM_GAME_CHANNEL_ID: ${{ vars.PROD_TELEGRAM_GAME_CHANNEL_ID }}
TELEGRAM_CHAT_ID: ${{ vars.PROD_TELEGRAM_CHAT_ID }}
TELEGRAM_SUPPORT_CHAT_ID: ${{ vars.PROD_TELEGRAM_SUPPORT_CHAT_ID }}
@@ -253,20 +213,8 @@ jobs:
run: |
umask 077
mkdir -p stage/certs-bot
cat > stage/env.bot.sh <<EOF
export SCRABBLE_CONFIG_DIR='/opt/scrabble'
export BOT_IMAGE='$REGISTRY/scrabble-telegram-bot:$TAG'
export BOTLINK_GATEWAY_ADDR='$MAIN_HOST:9443'
export TELEGRAM_BOT_TOKEN='$TELEGRAM_BOT_TOKEN'
export TELEGRAM_MINIAPP_URL='$TELEGRAM_MINIAPP_URL'
export TELEGRAM_GAME_CHANNEL_ID='$TELEGRAM_GAME_CHANNEL_ID'
export TELEGRAM_CHAT_ID='$TELEGRAM_CHAT_ID'
export TELEGRAM_SUPPORT_CHAT_ID='$TELEGRAM_SUPPORT_CHAT_ID'
export TELEGRAM_PROMO_BOT_TOKEN='$TELEGRAM_PROMO_BOT_TOKEN'
export TELEGRAM_BOT_USERNAME='$TELEGRAM_BOT_USERNAME'
export TELEGRAM_BOT_LINK='$TELEGRAM_BOT_LINK'
export LOG_LEVEL='${LOG_LEVEL:-info}'
EOF
# Shared with prod-rollback so the two paths render an identical bot env.
BOT_IMAGE="$REGISTRY/scrabble-telegram-bot:$TAG" bash deploy/write-prod-bot-env.sh stage/env.bot.sh
printf '%s\n' "$PROD_BOTLINK_CA" > stage/certs-bot/ca.crt
printf '%s\n' "$PROD_BOTLINK_BOT_CERT" > stage/certs-bot/bot.crt
printf '%s\n' "$PROD_BOTLINK_BOT_KEY" > stage/certs-bot/bot.key
+29 -35
View File
@@ -51,13 +51,31 @@ jobs:
PROD_BOTLINK_GATEWAY_CERT: ${{ secrets.PROD_BOTLINK_GATEWAY_CERT }}
PROD_BOTLINK_GATEWAY_KEY: ${{ secrets.PROD_BOTLINK_GATEWAY_KEY }}
GM_BASICAUTH_USER: ${{ vars.PROD_GM_BASICAUTH_USER }}
GRAFANA_ROOT_URL: ${{ vars.PROD_GRAFANA_ROOT_URL }}
CADDY_SITE_ADDRESS: ${{ vars.PROD_CADDY_SITE_ADDRESS }}
LOG_LEVEL: ${{ vars.PROD_LOG_LEVEL }}
DICT_VERSION: ${{ vars.PROD_DICT_VERSION }}
DICT_VERSION: ${{ vars.DICT_VERSION }}
POSTGRES_DB: ${{ vars.PROD_POSTGRES_DB }}
POSTGRES_USER: ${{ vars.PROD_POSTGRES_USER }}
TELEGRAM_MINIAPP_URL: ${{ vars.PROD_TELEGRAM_MINIAPP_URL }}
PUBLIC_BASE_URL: ${{ vars.PROD_PUBLIC_BASE_URL }}
# Full runtime env — parity with prod-deploy's deploy-main so a rollback re-renders
# the SAME env.sh (email / VK login / Grafana alerts survive a rollback). TELEGRAM_MINIAPP_URL
# and GRAFANA_ROOT_URL are derived from PUBLIC_BASE_URL in deploy/write-prod-env.sh.
GATEWAY_VK_APP_SECRET: ${{ secrets.GATEWAY_VK_APP_SECRET }}
VITE_VK_APP_ID: ${{ vars.VITE_VK_APP_ID }}
GATEWAY_VK_ID_CLIENT_SECRET: ${{ secrets.GATEWAY_VK_ID_CLIENT_SECRET }}
EXPORT_SIGN_KEY: ${{ secrets.PROD_EXPORT_SIGN_KEY }}
SMTP_RELAY_USER: ${{ secrets.SMTP_RELAY_USER }}
SMTP_RELAY_PASS: ${{ secrets.SMTP_RELAY_PASS }}
SMTP_RELAY_HOST: ${{ vars.SMTP_RELAY_HOST }}
SMTP_RELAY_PORT: ${{ vars.SMTP_RELAY_PORT }}
SMTP_RELAY_TLS: ${{ vars.SMTP_RELAY_TLS }}
SMTP_RELAY_FROM: ${{ vars.PROD_SMTP_RELAY_FROM }}
SMTP_RELAY_ADMIN_FROM: ${{ vars.PROD_SMTP_RELAY_ADMIN_FROM }}
ADMIN_EMAIL: ${{ vars.PROD_ADMIN_EMAIL }}
SMTP_RELAY_SERVICE_FROM: ${{ vars.PROD_SMTP_RELAY_SERVICE_FROM }}
SERVICE_EMAIL: ${{ vars.PROD_SERVICE_EMAIL }}
GRAFANA_SMTP_PORT: ${{ vars.GRAFANA_SMTP_PORT }}
GF_SMTP_ENABLED: ${{ vars.PROD_GF_SMTP_ENABLED }}
INPUT_TARGET: ${{ inputs.target_version }}
steps:
- uses: actions/checkout@v4
@@ -89,24 +107,9 @@ jobs:
run: |
umask 077
mkdir -p stage/certs-main
cat > stage/env.sh <<EOF
export REGISTRY='$REGISTRY'
export SCRABBLE_CONFIG_DIR='/opt/scrabble'
export POSTGRES_DB='${POSTGRES_DB:-scrabble}'
export POSTGRES_USER='${POSTGRES_USER:-scrabble}'
export POSTGRES_PASSWORD='$POSTGRES_PASSWORD'
export GM_BASICAUTH_USER='${GM_BASICAUTH_USER:-gm}'
export GM_BASICAUTH_HASH='$GM_BASICAUTH_HASH'
export GRAFANA_ADMIN_PASSWORD='$GRAFANA_ADMIN_PASSWORD'
export GRAFANA_ROOT_URL='$GRAFANA_ROOT_URL'
export CADDY_SITE_ADDRESS='$CADDY_SITE_ADDRESS'
export LOG_LEVEL='${LOG_LEVEL:-info}'
export DICT_VERSION='$DICT_VERSION'
export APP_VERSION='$TARGET'
export TELEGRAM_BOT_TOKEN='$TELEGRAM_BOT_TOKEN'
export TELEGRAM_MINIAPP_URL='$TELEGRAM_MINIAPP_URL'
export GATEWAY_ABUSE_BAN_ENABLED='true'
EOF
# Same writer as prod-deploy's deploy-main -> the rollback re-renders the FULL
# runtime env (not a subset), so email / VK login / Grafana alerts survive it.
APP_VERSION="$TARGET" bash deploy/write-prod-env.sh stage/env.sh
printf '%s\n' "$PROD_BOTLINK_CA" > stage/certs-main/ca.crt
printf '%s\n' "$PROD_BOTLINK_GATEWAY_CERT" > stage/certs-main/gateway.crt
printf '%s\n' "$PROD_BOTLINK_GATEWAY_KEY" > stage/certs-main/gateway.key
@@ -147,9 +150,11 @@ jobs:
PROD_BOTLINK_BOT_CERT: ${{ secrets.PROD_BOTLINK_BOT_CERT }}
PROD_BOTLINK_BOT_KEY: ${{ secrets.PROD_BOTLINK_BOT_KEY }}
LOG_LEVEL: ${{ vars.PROD_LOG_LEVEL }}
TELEGRAM_MINIAPP_URL: ${{ vars.PROD_TELEGRAM_MINIAPP_URL }}
# PUBLIC_BASE_URL drives the derived Mini App URL; SUPPORT_CHAT_ID for parity with deploy.
PUBLIC_BASE_URL: ${{ vars.PROD_PUBLIC_BASE_URL }}
TELEGRAM_GAME_CHANNEL_ID: ${{ vars.PROD_TELEGRAM_GAME_CHANNEL_ID }}
TELEGRAM_CHAT_ID: ${{ vars.PROD_TELEGRAM_CHAT_ID }}
TELEGRAM_SUPPORT_CHAT_ID: ${{ vars.PROD_TELEGRAM_SUPPORT_CHAT_ID }}
TELEGRAM_BOT_USERNAME: ${{ vars.PROD_TELEGRAM_BOT_USERNAME }}
TELEGRAM_BOT_LINK: ${{ vars.PROD_VITE_TELEGRAM_LINK }}
steps:
@@ -163,19 +168,8 @@ jobs:
run: |
umask 077
mkdir -p stage/certs-bot
cat > stage/env.bot.sh <<EOF
export SCRABBLE_CONFIG_DIR='/opt/scrabble'
export BOT_IMAGE='$REGISTRY/scrabble-telegram-bot:$TARGET'
export BOTLINK_GATEWAY_ADDR='$MAIN_HOST:9443'
export TELEGRAM_BOT_TOKEN='$TELEGRAM_BOT_TOKEN'
export TELEGRAM_MINIAPP_URL='$TELEGRAM_MINIAPP_URL'
export TELEGRAM_GAME_CHANNEL_ID='$TELEGRAM_GAME_CHANNEL_ID'
export TELEGRAM_CHAT_ID='$TELEGRAM_CHAT_ID'
export TELEGRAM_PROMO_BOT_TOKEN='$TELEGRAM_PROMO_BOT_TOKEN'
export TELEGRAM_BOT_USERNAME='$TELEGRAM_BOT_USERNAME'
export TELEGRAM_BOT_LINK='$TELEGRAM_BOT_LINK'
export LOG_LEVEL='${LOG_LEVEL:-info}'
EOF
# Same writer as prod-deploy's deploy-bot (parity; includes TELEGRAM_SUPPORT_CHAT_ID).
BOT_IMAGE="$REGISTRY/scrabble-telegram-bot:$TARGET" bash deploy/write-prod-bot-env.sh stage/env.bot.sh
printf '%s\n' "$PROD_BOTLINK_CA" > stage/certs-bot/ca.crt
printf '%s\n' "$PROD_BOTLINK_BOT_CERT" > stage/certs-bot/bot.crt
printf '%s\n' "$PROD_BOTLINK_BOT_KEY" > stage/certs-bot/bot.key