8092bdb024
ремонт: deploy.yml fail на F1 миграции — schema public требует postgres superuser, у crm_migrator нет прав на CREATE OR REPLACE FUNCTION Applies F1 audit-chain advisory-lock migration via sudo -u postgres psql, then INSERTs migration row so subsequent php artisan migrate skips it. Workaround for prod deploy where crm_migrator can't modify public schema.
114 lines
3.9 KiB
YAML
114 lines
3.9 KiB
YAML
name: Apply F1 audit-chain advisory-lock migration via postgres superuser
|
|
|
|
# Incident response: redeploy.yml fails on F1 migration because crm_migrator role
|
|
# lacks privilege to CREATE OR REPLACE FUNCTION в schema public.
|
|
# This workflow applies F1 migration SQL directly via sudo -u postgres psql,
|
|
# then INSERTs the migration row so subsequent `php artisan migrate` skips it.
|
|
#
|
|
# Ref: docs/superpowers/plans/2026-05-29-audit-chain-race-fix.md Task 2
|
|
# Migration file: app/database/migrations/2026_05_30_000001_add_advisory_lock_to_audit_chain_hash.php
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
confirm_apply:
|
|
description: 'Подтверждаю применение F1 миграции на проде'
|
|
required: true
|
|
default: 'false'
|
|
type: boolean
|
|
|
|
jobs:
|
|
apply:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
env:
|
|
LIDERRA_HOST: 111.88.246.137
|
|
LIDERRA_USER: ubuntu
|
|
CONFIRM: ${{ github.event.inputs.confirm_apply }}
|
|
|
|
steps:
|
|
- name: Guard
|
|
run: |
|
|
if [[ "$CONFIRM" != "true" ]]; then
|
|
echo "::error::confirm_apply=true required"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Setup SSH key
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.LIDERRA_SSH_KEY }}" > ~/.ssh/liderra_deploy
|
|
chmod 600 ~/.ssh/liderra_deploy
|
|
ssh-keyscan -H ${{ env.LIDERRA_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
|
|
|
- name: Apply F1 SQL + register migration
|
|
run: |
|
|
ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} \
|
|
"bash -s" <<'REMOTE' | tee /tmp/f1-apply.log
|
|
set +e
|
|
|
|
echo "=== 1. BEFORE: current audit_chain_hash function source ==="
|
|
sudo -u postgres psql -d liderra -c "\df+ public.audit_chain_hash" 2>&1 | head -20
|
|
|
|
echo
|
|
echo "=== 2. Apply F1 advisory-lock migration via sudo -u postgres ==="
|
|
sudo -u postgres psql -d liderra <<'SQL'
|
|
CREATE OR REPLACE FUNCTION public.audit_chain_hash() RETURNS trigger AS $$
|
|
DECLARE
|
|
prev_hash BYTEA;
|
|
lock_key BIGINT;
|
|
BEGIN
|
|
lock_key := ('x' || lpad(to_hex(TG_RELID::int), 16, '0'))::bit(64)::bigint;
|
|
PERFORM pg_advisory_xact_lock(lock_key);
|
|
|
|
EXECUTE format(
|
|
'SELECT log_hash FROM %I ORDER BY id DESC LIMIT 1',
|
|
TG_TABLE_NAME
|
|
) INTO prev_hash;
|
|
|
|
NEW.log_hash := digest(
|
|
COALESCE(prev_hash, ''::bytea) || NEW::text::bytea,
|
|
'sha256'
|
|
);
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
SQL
|
|
APPLY_RC=$?
|
|
echo "Apply RC: $APPLY_RC"
|
|
|
|
echo
|
|
echo "=== 3. Verify function now contains pg_advisory_xact_lock ==="
|
|
sudo -u postgres psql -d liderra -c "SELECT pg_get_functiondef('public.audit_chain_hash'::regproc) LIKE '%pg_advisory_xact_lock%' AS has_lock"
|
|
|
|
echo
|
|
echo "=== 4. Register migration row (skip if already exists) ==="
|
|
sudo -u postgres psql -d liderra <<'SQL'
|
|
INSERT INTO migrations (migration, batch)
|
|
SELECT '2026_05_30_000001_add_advisory_lock_to_audit_chain_hash', COALESCE(MAX(batch),0)+1 FROM migrations
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM migrations WHERE migration = '2026_05_30_000001_add_advisory_lock_to_audit_chain_hash'
|
|
);
|
|
SELECT migration, batch FROM migrations WHERE migration LIKE '%advisory_lock%';
|
|
SQL
|
|
|
|
echo
|
|
echo "=== DONE ==="
|
|
REMOTE
|
|
|
|
- name: Print summary
|
|
if: always()
|
|
run: |
|
|
{
|
|
echo "## F1 migration apply"
|
|
echo
|
|
echo '```'
|
|
cat /tmp/f1-apply.log 2>/dev/null || echo "(no log)"
|
|
echo '```'
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Cleanup SSH key
|
|
if: always()
|
|
run: rm -f ~/.ssh/liderra_deploy
|