feat(ci): последовательный deploy IFT -> E2E -> stage -> E2E (core).
CI / test (push) Successful in 14m42s
CI / test (push) Successful in 14m42s
Stage после API CT remote на IFT; после stage — smoke-core + полный CT на stage. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
name: Deploy stage (core)
|
name: Deploy stage (core)
|
||||||
|
|
||||||
# Auto после успешного CI на master: тот же sha-*, плюс floating :stage.
|
# Auto после успешного E2E IFT на master: promote sha-* → :stage и SSH deploy.
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_run:
|
||||||
workflows: [CI]
|
workflows: ["E2E IFT (core)"]
|
||||||
types: [completed]
|
types: [completed]
|
||||||
branches: [master, main]
|
branches: [master, main]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
name: E2E IFT (core)
|
||||||
|
|
||||||
|
# После успешного Deploy IFT — smoke-core на стенде + полный API CT (remote) против живого IFT.
|
||||||
|
# Учётки — из /opt/eventhub-ift/.env по SSH (ADMIN_*).
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["Deploy IFT (core)"]
|
||||||
|
types: [completed]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: eventhub-back-e2e-ift
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILDKIT_PROGRESS: quiet
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ift-e2e:
|
||||||
|
if: |
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 90
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||||
|
|
||||||
|
- name: Wait for Docker daemon
|
||||||
|
run: bash scripts/ensure-docker-daemon.sh 240
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Load API test credentials from IFT .env
|
||||||
|
env:
|
||||||
|
SSH_HOST: ${{ secrets.IFT_SSH_HOST }}
|
||||||
|
SSH_USER: ${{ secrets.IFT_SSH_USER }}
|
||||||
|
SSH_KEY: ${{ secrets.IFT_SSH_PRIVATE_KEY }}
|
||||||
|
run: bash scripts/load-stand-api-env.sh ift
|
||||||
|
|
||||||
|
- name: E2E IFT (full API suite)
|
||||||
|
env:
|
||||||
|
SSH_HOST: ${{ secrets.IFT_SSH_HOST }}
|
||||||
|
SSH_USER: ${{ secrets.IFT_SSH_USER }}
|
||||||
|
SSH_KEY: ${{ secrets.IFT_SSH_PRIVATE_KEY }}
|
||||||
|
API_HOST: ${{ secrets.E2E_IFT_API_HOST }}
|
||||||
|
ADMIN_API_HOST: ${{ secrets.E2E_IFT_ADMIN_API_HOST }}
|
||||||
|
WS_HOST: ${{ secrets.E2E_IFT_WS_HOST }}
|
||||||
|
ADMIN_WS_HOST: ${{ secrets.E2E_IFT_ADMIN_WS_HOST }}
|
||||||
|
run: bash scripts/run-stand-api-tests.sh ift
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
name: E2E stage (core)
|
||||||
|
|
||||||
|
# После успешного Deploy stage — smoke-core на стенде + полный API CT (remote) против живого stage.
|
||||||
|
# Учётки — из /opt/eventhub-stage/.env по SSH (ADMIN_*).
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["Deploy stage (core)"]
|
||||||
|
types: [completed]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: eventhub-back-e2e-stage
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILDKIT_PROGRESS: quiet
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stage-e2e:
|
||||||
|
if: |
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 90
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||||
|
|
||||||
|
- name: Wait for Docker daemon
|
||||||
|
run: bash scripts/ensure-docker-daemon.sh 240
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Load API test credentials from stage .env
|
||||||
|
env:
|
||||||
|
SSH_HOST: ${{ secrets.STAGE_SSH_HOST }}
|
||||||
|
SSH_USER: ${{ secrets.STAGE_SSH_USER }}
|
||||||
|
SSH_KEY: ${{ secrets.STAGE_SSH_PRIVATE_KEY }}
|
||||||
|
run: bash scripts/load-stand-api-env.sh stage
|
||||||
|
|
||||||
|
- name: E2E stage (full API suite)
|
||||||
|
env:
|
||||||
|
SSH_HOST: ${{ secrets.STAGE_SSH_HOST }}
|
||||||
|
SSH_USER: ${{ secrets.STAGE_SSH_USER }}
|
||||||
|
SSH_KEY: ${{ secrets.STAGE_SSH_PRIVATE_KEY }}
|
||||||
|
API_HOST: ${{ secrets.E2E_STAGE_API_HOST }}
|
||||||
|
ADMIN_API_HOST: ${{ secrets.E2E_STAGE_ADMIN_API_HOST }}
|
||||||
|
WS_HOST: ${{ secrets.E2E_STAGE_WS_HOST }}
|
||||||
|
ADMIN_WS_HOST: ${{ secrets.E2E_STAGE_ADMIN_WS_HOST }}
|
||||||
|
run: bash scripts/run-stand-api-tests.sh stage
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Load admin API test credentials from stand .env via SSH into GITHUB_ENV.
|
||||||
|
# Usage: load-stand-api-env.sh <ift|stage>
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
STAND="${1:?stand: ift|stage}"
|
||||||
|
case "${STAND}" in
|
||||||
|
ift)
|
||||||
|
SSH_HOST="${SSH_HOST:?IFT_SSH_HOST required}"
|
||||||
|
SSH_USER="${SSH_USER:?IFT_SSH_USER required}"
|
||||||
|
SSH_KEY="${SSH_KEY:?IFT_SSH_PRIVATE_KEY required}"
|
||||||
|
ENV_FILE="/opt/eventhub-ift/.env"
|
||||||
|
;;
|
||||||
|
stage)
|
||||||
|
SSH_HOST="${SSH_HOST:?STAGE_SSH_HOST required}"
|
||||||
|
SSH_USER="${SSH_USER:?STAGE_SSH_USER required}"
|
||||||
|
SSH_KEY="${SSH_KEY:?STAGE_SSH_PRIVATE_KEY required}"
|
||||||
|
ENV_FILE="/opt/eventhub-stage/.env"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown stand: ${STAND}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
KEY="$(mktemp)"
|
||||||
|
printf '%s\n' "${SSH_KEY}" > "${KEY}"
|
||||||
|
chmod 600 "${KEY}"
|
||||||
|
|
||||||
|
REMOTE="$(ssh -i "${KEY}" -o BatchMode=yes -o StrictHostKeyChecking=accept-new \
|
||||||
|
"${SSH_USER}@${SSH_HOST}" \
|
||||||
|
"grep -E '^(ADMIN_|SMOKE_ADMIN_)' ${ENV_FILE} || true")"
|
||||||
|
rm -f "${KEY}"
|
||||||
|
|
||||||
|
if [[ -z "${REMOTE}" ]]; then
|
||||||
|
echo "::error::В ${ENV_FILE} нет ADMIN_* / SMOKE_ADMIN_*"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OUT="${GITHUB_ENV:-}"
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ -n "${line}" ]] || continue
|
||||||
|
if [[ -n "${OUT}" ]]; then
|
||||||
|
echo "${line}" >> "${OUT}"
|
||||||
|
else
|
||||||
|
printf '%s\n' "${line}" >> "$(mktemp)"
|
||||||
|
fi
|
||||||
|
done <<< "${REMOTE}"
|
||||||
|
|
||||||
|
echo "Loaded API test credentials from ${ENV_FILE}"
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Full API CT suite against live stand (remote) + smoke-core on stand host.
|
||||||
|
# Usage: run-stand-api-tests.sh <ift|stage>
|
||||||
|
# Requires: ADMIN_* from load-stand-api-env.sh; SSH_* for smoke-core on stand.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
STAND="${1:?stand: ift|stage}"
|
||||||
|
case "${STAND}" in
|
||||||
|
ift)
|
||||||
|
API_HOST="${API_HOST:-https://api.ift.eventhub.local}"
|
||||||
|
ADMIN_API_HOST="${ADMIN_API_HOST:-https://admin-api.ift.eventhub.local}"
|
||||||
|
WS_HOST="${WS_HOST:-wss://api.ift.eventhub.local}"
|
||||||
|
ADMIN_WS_HOST="${ADMIN_WS_HOST:-wss://admin-api.ift.eventhub.local}"
|
||||||
|
DEVOPS_SMOKE="/opt/eventhub-ift/devops/scripts/smoke-core.sh"
|
||||||
|
;;
|
||||||
|
stage)
|
||||||
|
API_HOST="${API_HOST:-https://api.stage.eventhub.local}"
|
||||||
|
ADMIN_API_HOST="${ADMIN_API_HOST:-https://admin-api.stage.eventhub.local}"
|
||||||
|
WS_HOST="${WS_HOST:-wss://api.stage.eventhub.local}"
|
||||||
|
ADMIN_WS_HOST="${ADMIN_WS_HOST:-wss://admin-api.stage.eventhub.local}"
|
||||||
|
DEVOPS_SMOKE="/opt/eventhub-stage/devops/scripts/smoke-core.sh"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown stand: ${STAND}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ -n "${SSH_HOST:-}" && -n "${SSH_USER:-}" && -n "${SSH_KEY:-}" ]]; then
|
||||||
|
KEY="$(mktemp)"
|
||||||
|
printf '%s\n' "${SSH_KEY}" > "${KEY}"
|
||||||
|
chmod 600 "${KEY}"
|
||||||
|
echo "=== smoke-core on ${STAND} (via SSH) ==="
|
||||||
|
ssh -i "${KEY}" -o BatchMode=yes -o StrictHostKeyChecking=accept-new \
|
||||||
|
"${SSH_USER}@${SSH_HOST}" "bash ${DEVOPS_SMOKE} ${STAND}"
|
||||||
|
rm -f "${KEY}"
|
||||||
|
else
|
||||||
|
echo "::warning::SSH_* not set — skip smoke-core on stand host"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== API CT remote (${STAND}) ==="
|
||||||
|
echo " API_HOST=${API_HOST}"
|
||||||
|
echo " ADMIN_API_HOST=${ADMIN_API_HOST}"
|
||||||
|
|
||||||
|
if ! docker image inspect eventhub-api-tests:local >/dev/null 2>&1; then
|
||||||
|
bash scripts/retry-docker-build.sh 5 60 -- \
|
||||||
|
docker buildx build \
|
||||||
|
--network=host \
|
||||||
|
--file docker/ApiTests.Dockerfile \
|
||||||
|
--tag eventhub-api-tests:local \
|
||||||
|
--load \
|
||||||
|
--provenance=false \
|
||||||
|
--sbom=false \
|
||||||
|
.
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker run --rm --network=host \
|
||||||
|
-e CT_MODE=remote \
|
||||||
|
-e "API_HOST=${API_HOST}" \
|
||||||
|
-e "ADMIN_API_HOST=${ADMIN_API_HOST}" \
|
||||||
|
-e "WS_HOST=${WS_HOST}" \
|
||||||
|
-e "ADMIN_WS_HOST=${ADMIN_WS_HOST}" \
|
||||||
|
-e "ADMIN_SUPER_EMAIL=${ADMIN_SUPER_EMAIL:-}" \
|
||||||
|
-e "ADMIN_SUPER_PASSWORD=${ADMIN_SUPER_PASSWORD:-}" \
|
||||||
|
-e "ADMIN_EMAIL=${ADMIN_EMAIL:-}" \
|
||||||
|
-e "ADMIN_PASSWORD=${ADMIN_PASSWORD:-}" \
|
||||||
|
-e "ADMIN_MODER_EMAIL=${ADMIN_MODER_EMAIL:-}" \
|
||||||
|
-e "ADMIN_MODER_PASSWORD=${ADMIN_MODER_PASSWORD:-}" \
|
||||||
|
-e "ADMIN_SUPPORT_EMAIL=${ADMIN_SUPPORT_EMAIL:-}" \
|
||||||
|
-e "ADMIN_SUPPORT_PASSWORD=${ADMIN_SUPPORT_PASSWORD:-}" \
|
||||||
|
eventhub-api-tests:local
|
||||||
|
|
||||||
|
echo "=== API CT passed (${STAND}) ==="
|
||||||
Reference in New Issue
Block a user