From 6d3e7a9315617cd5318d0e8ed83ccbb9198b3795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=A1=D0=B0?= =?UTF-8?q?=D0=B1=D0=B8=D0=BB=D0=B8=D0=BD?= Date: Fri, 10 Jul 2026 23:04:11 +0300 Subject: [PATCH] CI: build and push admin-ui image in CI; deploy-ift SSH-only. Move docker build/push from deploy-ift to CI (EventHubBack pattern). Deploy no longer needs docker.sock on the WSL runner. Add ensure-docker-daemon.sh for Docker Desktop on host runner. --- .gitea/workflows/ci.yml | 48 +++++++++++++++++++++++- .gitea/workflows/deploy-ift.yml | 65 +-------------------------------- scripts/ensure-docker-daemon.sh | 65 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 65 deletions(-) create mode 100644 scripts/ensure-docker-daemon.sh diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 3779ac6..4a5dfe6 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -6,14 +6,20 @@ on: pull_request: workflow_dispatch: +# Один runner (DESKTOP-SIR8B3R): параллельные workflow ломают кэш act/actions. concurrency: group: eventhub-frontadmin-ci-${{ github.ref }} cancel-in-progress: false +env: + BUILDKIT_PROGRESS: quiet + DOCKER_BUILDKIT: 1 + REGISTRY: git.sabilin.com/eventhub + jobs: test: runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 45 steps: - uses: actions/checkout@v4 @@ -25,3 +31,43 @@ jobs: - run: npm ci - run: npm run lint - run: npm run build + + - name: Wait for Docker daemon + if: github.event_name == 'push' + run: bash scripts/ensure-docker-daemon.sh 240 + + - name: Set up Docker Buildx + if: github.event_name == 'push' + uses: docker/setup-buildx-action@v3 + + - name: Build admin-ui image + if: github.event_name == 'push' + run: | + set -euo pipefail + bash scripts/retry-docker-build.sh 5 60 -- \ + docker buildx build \ + --network=host \ + --file Dockerfile \ + --tag eventhub-admin-ui:local \ + --load \ + --provenance=false \ + --sbom=false \ + . + + - name: Login to registry + if: github.event_name == 'push' + uses: docker/login-action@v2 + with: + registry: git.sabilin.com + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Push admin-ui image + if: github.event_name == 'push' + run: | + set -euo pipefail + TAG="sha-${GITHUB_SHA:0:12}" + docker tag eventhub-admin-ui:local "${REGISTRY}/eventhub-admin-ui:${TAG}" + docker tag eventhub-admin-ui:local "${REGISTRY}/eventhub-admin-ui:ift" + bash scripts/retry-docker-build.sh 5 30 -- docker push "${REGISTRY}/eventhub-admin-ui:${TAG}" + bash scripts/retry-docker-build.sh 5 30 -- docker push "${REGISTRY}/eventhub-admin-ui:ift" diff --git a/.gitea/workflows/deploy-ift.yml b/.gitea/workflows/deploy-ift.yml index 0e47c32..81fa0ce 100644 --- a/.gitea/workflows/deploy-ift.yml +++ b/.gitea/workflows/deploy-ift.yml @@ -11,23 +11,14 @@ concurrency: group: eventhub-frontadmin-deploy-ift cancel-in-progress: false -env: - REGISTRY: git.sabilin.com/eventhub - BUILDKIT_PROGRESS: quiet - DOCKER_BUILDKIT: 1 - jobs: deploy-ift-admin: if: | github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') runs-on: ubuntu-latest - timeout-minutes: 90 + timeout-minutes: 30 steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }} - - name: Compute image tag id: meta run: | @@ -39,60 +30,6 @@ jobs: fi echo "tag=sha-${SHA:0:12}" >> "$GITHUB_OUTPUT" - - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - - - run: npm ci - - run: npm run build - - - name: Wait for Docker daemon - run: | - set -euo pipefail - for i in $(seq 1 36); do - if docker info >/dev/null 2>&1; then - echo "Docker ready" - exit 0 - fi - echo "waiting for docker (${i}/36)..." - sleep 5 - done - echo "Docker daemon not available" - exit 1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to registry - uses: docker/login-action@v2 - with: - registry: git.sabilin.com - username: ${{ secrets.REGISTRY_USER }} - password: ${{ secrets.REGISTRY_PASSWORD }} - - - name: Build admin-ui image - run: | - set -euo pipefail - bash scripts/retry-docker-build.sh 5 60 -- \ - docker buildx build \ - --network=host \ - --file Dockerfile \ - --tag eventhub-admin-ui:local \ - --load \ - --provenance=false \ - --sbom=false \ - . - - - name: Push admin-ui image - run: | - set -euo pipefail - TAG="${{ steps.meta.outputs.tag }}" - docker tag eventhub-admin-ui:local "${REGISTRY}/eventhub-admin-ui:${TAG}" - docker tag eventhub-admin-ui:local "${REGISTRY}/eventhub-admin-ui:ift" - bash scripts/retry-docker-build.sh 5 30 -- docker push "${REGISTRY}/eventhub-admin-ui:${TAG}" - bash scripts/retry-docker-build.sh 5 30 -- docker push "${REGISTRY}/eventhub-admin-ui:ift" - - name: Deploy admin on IFT via SSH uses: appleboy/ssh-action@v0.1.5 with: diff --git a/scripts/ensure-docker-daemon.sh b/scripts/ensure-docker-daemon.sh new file mode 100644 index 0000000..51eb02c --- /dev/null +++ b/scripts/ensure-docker-daemon.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Ensure Docker daemon is reachable on WSL host runner (Docker Desktop integration). +# Usage: ensure-docker-daemon.sh [max_wait_seconds] +set -euo pipefail + +MAX_WAIT="${1:-240}" +INTERVAL=5 +DEADLINE=$((SECONDS + MAX_WAIT)) + +docker_ok() { + timeout 8 docker info >/dev/null 2>&1 +} + +find_docker_host() { + local candidates=( + "${DOCKER_HOST:-}" + "unix:///var/run/docker.sock" + "unix:///mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.sock" + "unix:///mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.proxy.sock" + "unix:///mnt/wsl/docker-desktop/shared-sockets/guest-services/docker.container-proxy.sock" + ) + local host path + for host in "${candidates[@]}"; do + [[ -n "${host}" ]] || continue + path="${host#unix://}" + if [[ -S "${path}" ]] && DOCKER_HOST="${host}" docker_ok; then + export DOCKER_HOST="${host}" + echo "Docker ready (${host})" + return 0 + fi + done + if docker_ok; then + echo "Docker ready (default socket)" + return 0 + fi + return 1 +} + +start_docker_desktop() { + local exe="/mnt/c/Program Files/Docker/Docker/Docker Desktop.exe" + if [[ -f "${exe}" ]]; then + echo "Starting Docker Desktop..." + powershell.exe -NoProfile -Command "Start-Process 'C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe'" >/dev/null 2>&1 || true + return 0 + fi + echo "Docker Desktop executable not found" + return 1 +} + +attempt=0 +while (( SECONDS < DEADLINE )); do + attempt=$((attempt + 1)) + if find_docker_host; then + exit 0 + fi + if (( attempt == 1 || attempt == 7 )); then + start_docker_desktop || true + fi + echo "waiting for docker (${attempt}, $((DEADLINE - SECONDS))s left)..." + sleep "${INTERVAL}" +done + +echo "Docker daemon not available after ${MAX_WAIT}s" +echo "Hint: start Docker Desktop on Windows and enable WSL integration." +exit 1