Keep notification-read state personal to user/company, preserve server read-only sections during staff synchronization, and respect separate order-create/edit/delete rights. Add visible mobile header session actions and a sticky logout that survives profile RPC failure; scope asynchronous profile/branding to user and workspace. Targeted browser suites and isolated SQL recovery tests passed in run 35506145405, iPhone screenshots reviewed. Full main QA remains required before production promotion. Workspace branding RPC migration is included but has NOT been applied to production Supabase; older servers retain safe owner-only fallback. No live membership/business-data repair is claimed without identifying the reported employee.
141 lines
5.1 KiB
YAML
141 lines
5.1 KiB
YAML
name: Verify Caterium on Timeweb
|
|
|
|
on:
|
|
workflow_run:
|
|
workflows: ["Caterium QA", "Caterium Direct Production"]
|
|
types: [completed]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: caterium-timeweb-production
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
verify:
|
|
if: >-
|
|
github.event_name == 'workflow_dispatch' ||
|
|
(github.event.workflow_run.conclusion == 'success' &&
|
|
((github.event.workflow_run.name == 'Caterium QA' &&
|
|
github.event.workflow_run.head_branch == 'production') ||
|
|
(github.event.workflow_run.name == 'Caterium Direct Production' &&
|
|
github.event.workflow_run.head_branch == 'main')))
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
env:
|
|
TIMEWEB_BASE_URL: https://app.caterium.ru
|
|
|
|
steps:
|
|
# A GITHUB_TOKEN push to production does not start another push workflow.
|
|
# Observe successful promotion directly and read its published branch.
|
|
- name: Checkout tested production revision
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Caterium QA' && github.event.workflow_run.head_sha || 'production' }}
|
|
|
|
- name: Wait for the exact published assets
|
|
timeout-minutes: 18
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
files=(
|
|
index.html
|
|
app-runtime.js
|
|
core/account-center-v1780.js
|
|
core/company-branding.js
|
|
core/sun-safe.js
|
|
core/login-signature-v1776.js
|
|
core/login-signature-v1776.css
|
|
core/help-center.js
|
|
core/help-center.css
|
|
core/catalog-pricing.js
|
|
core/client-menu.css
|
|
core/ops-ux-v1762.js
|
|
core/mobile-order.js
|
|
core/banquet-menu.js
|
|
core/banquet-client-menu.js
|
|
core/data-layer-v1773.js
|
|
core/trial-demo.js
|
|
core/training-catalog.js
|
|
legacy/bootstrap.js
|
|
caterium-mark-light.svg
|
|
service-worker.js
|
|
)
|
|
temp_dir="$(mktemp -d)"
|
|
trap 'rm -rf "$temp_dir"' EXIT
|
|
revision="$(git rev-parse HEAD)"
|
|
echo "Verifying tested production revision: $revision"
|
|
for file in "${files[@]}"; do test -s "public/$file"; done
|
|
for attempt in $(seq 1 18); do
|
|
stamp="${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}-${attempt}"
|
|
echo "Attempt $attempt/18"
|
|
matched=true
|
|
: > "$temp_dir/hashes.txt"
|
|
for file in "${files[@]}"; do
|
|
expected="$(sha256sum "public/$file" | awk '{print $1}')"
|
|
if ! curl -fsSL --connect-timeout 10 --max-time 20 \
|
|
-H 'Cache-Control: no-cache' \
|
|
"${TIMEWEB_BASE_URL}/${file}?deploy_check=${stamp}" \
|
|
-o "$temp_dir/asset"; then
|
|
echo "Not reachable yet: $file"
|
|
matched=false
|
|
break
|
|
fi
|
|
actual="$(sha256sum "$temp_dir/asset" | awk '{print $1}')"
|
|
echo "$file expected=$expected actual=$actual"
|
|
if [ "$actual" != "$expected" ]; then
|
|
echo "Waiting for updated asset: $file"
|
|
matched=false
|
|
break
|
|
fi
|
|
printf '%s %s\n' "$actual" "$file" >> "$temp_dir/hashes.txt"
|
|
done
|
|
if [ "$matched" = true ]; then
|
|
echo "PASS: all ${#files[@]} production assets match the tested revision."
|
|
{
|
|
echo '## Timeweb publication verified'
|
|
echo "Revision: \`$revision\`"
|
|
echo
|
|
echo 'All checked production assets match byte-for-byte:'
|
|
echo '```text'
|
|
cat "$temp_dir/hashes.txt"
|
|
echo '```'
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
exit 0
|
|
fi
|
|
sleep 30
|
|
done
|
|
echo '::error::Timeweb did not publish the tested assets within the allotted retries.'
|
|
exit 1
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- run: npm ci
|
|
- run: npx playwright install --with-deps chromium
|
|
- name: Check the published loading screen, Help, clients and promotions
|
|
timeout-minutes: 4
|
|
run: node tests/production-ui-smoke.mjs
|
|
- name: Check the published mobile menu form and return arrow
|
|
timeout-minutes: 4
|
|
run: node tests/production-mobile-menu.mjs
|
|
- name: Check the published optional training catalog
|
|
timeout-minutes: 4
|
|
run: node tests/production-training-catalog.mjs
|
|
- name: Check the published single-page banquet menu
|
|
timeout-minutes: 4
|
|
run: node tests/production-banquet-client-menu.mjs
|
|
- name: Check published employee session and mobile logout
|
|
timeout-minutes: 4
|
|
run: node tests/production-employee-session.mjs
|
|
- name: Save production UI verification
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: production-ui-verification
|
|
path: production-ui-results/
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|