CI / changes (push) Successful in 6s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 21s
CI / docker-web (push) Failing after 13s
CI / docker-bird (push) Failing after 14s
CI / bird2 (push) Successful in 13s
CI / docker-go (push) Failing after 13s
Refactored the Docker build commands in the CI workflow to remove the wildcard prefix from variable settings, ensuring proper variable assignment. Updated the README documentation to reflect these changes and provide clearer instructions for building images with the correct variable syntax.
320 lines
13 KiB
YAML
320 lines
13 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main, master]
|
|
pull_request:
|
|
branches: [main, master]
|
|
|
|
jobs:
|
|
# ---------------------------------------------------------------------------
|
|
# Гранулярная детекция изменений по модулям.
|
|
# Каждый флаг соответствует группе файлов; downstream-джобы запускаются
|
|
# только когда их группа затронута. Изменение CI-конфигурации (.gitea/workflows/*)
|
|
# поднимает все флаги, чтобы гарантировать полный прогон.
|
|
# ---------------------------------------------------------------------------
|
|
changes:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
openapi: ${{ steps.detect.outputs.openapi }}
|
|
go: ${{ steps.detect.outputs.go }}
|
|
web: ${{ steps.detect.outputs.web }}
|
|
bird_conf: ${{ steps.detect.outputs.bird_conf }}
|
|
docker_go: ${{ steps.detect.outputs.docker_go }}
|
|
docker_web: ${{ steps.detect.outputs.docker_web }}
|
|
docker_bird: ${{ steps.detect.outputs.docker_bird }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
- id: detect
|
|
name: Detect changed paths per module
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
openapi=false
|
|
go=false
|
|
web=false
|
|
bird_conf=false
|
|
docker_go=false
|
|
docker_web=false
|
|
docker_bird=false
|
|
|
|
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
base="${{ github.event.pull_request.base.sha }}"
|
|
head="${{ github.event.pull_request.head.sha }}"
|
|
FILES="$(git diff --name-only "$base" "$head")"
|
|
else
|
|
before="${{ github.event.before }}"
|
|
after="${{ github.sha }}"
|
|
if [ -n "$before" ] && [ "$before" != "0000000000000000000000000000000000000000" ]; then
|
|
FILES="$(git diff --name-only "$before" "$after")"
|
|
elif git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
|
|
FILES="$(git diff --name-only HEAD~1 HEAD)"
|
|
else
|
|
openapi=true; go=true; web=true; bird_conf=true
|
|
docker_go=true; docker_web=true; docker_bird=true
|
|
for v in openapi go web bird_conf docker_go docker_web docker_bird; do
|
|
echo "$v=true" >> "$GITHUB_OUTPUT"
|
|
done
|
|
echo "No parent commit — full pipeline"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$(printf '%s' "$FILES" | tr -d '[:space:]')" ]; then
|
|
go=true; web=true
|
|
for v in openapi go web bird_conf docker_go docker_web docker_bird; do
|
|
eval "echo \"\$v=\$$v\"" >> "$GITHUB_OUTPUT"
|
|
done
|
|
echo "Empty diff — safe fallback: go=true web=true"
|
|
exit 0
|
|
fi
|
|
|
|
ci_changed=false
|
|
|
|
while IFS= read -r f || [ -n "${f:-}" ]; do
|
|
[ -z "${f:-}" ] && continue
|
|
case "$f" in
|
|
.gitea/workflows/*) ci_changed=true ;;
|
|
docs/openapi.yaml|redocly.yaml) openapi=true ;;
|
|
web/README.md) ;; # doc-only
|
|
web/*) web=true ;;
|
|
deploy/bird/*) bird_conf=true ;;
|
|
deploy/docker/bird/*) docker_bird=true; docker_go=true ;;
|
|
deploy/docker/gobinary/*) docker_go=true ;;
|
|
deploy/docker/docker-bake.hcl) docker_go=true; docker_web=true ;;
|
|
deploy/docker/evobgp-agent/*) docker_go=true ;;
|
|
deploy/docker/evobgp-web/*) docker_web=true ;;
|
|
deploy/docker/bird2/*) docker_bird=true ;;
|
|
go.mod|go.sum|go.work) go=true ;;
|
|
*.go) go=true ;;
|
|
cmd/*|internal/*) go=true ;;
|
|
esac
|
|
done <<< "$FILES"
|
|
|
|
if $ci_changed; then
|
|
go=true; web=true; bird_conf=true
|
|
docker_go=true; docker_web=true; docker_bird=true
|
|
fi
|
|
|
|
for v in openapi go web bird_conf docker_go docker_web docker_bird; do
|
|
eval "echo \"\$v=\$$v\"" >> "$GITHUB_OUTPUT"
|
|
done
|
|
|
|
echo "Changed files (first 30):"
|
|
printf '%s\n' "$FILES" | head -n 30
|
|
echo "--- flags ---"
|
|
echo "openapi=$openapi go=$go web=$web bird_conf=$bird_conf"
|
|
echo "docker_go=$docker_go docker_web=$docker_web docker_bird=$docker_bird ci=$ci_changed"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
openapi:
|
|
needs: [changes]
|
|
if: needs.changes.outputs.openapi == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "20"
|
|
- name: Lint OpenAPI (Redocly)
|
|
run: npx --yes @redocly/cli@1 lint docs/openapi.yaml
|
|
|
|
# ---------------------------------------------------------------------------
|
|
go:
|
|
needs: [changes]
|
|
if: needs.changes.outputs.go == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version: "1.24"
|
|
cache: true
|
|
cache-dependency-path: go.sum
|
|
- name: Vet
|
|
run: go vet ./...
|
|
- name: Test
|
|
run: go test ./... -race -count=1
|
|
- name: Build all commands
|
|
run: |
|
|
set -euxo pipefail
|
|
out="${RUNNER_TEMP}/evobgp-bin"
|
|
mkdir -p "$out"
|
|
for d in cmd/*/; do
|
|
name="$(basename "$d")"
|
|
go build -o "$out/$name" "./$d"
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
bird2:
|
|
runs-on: ubuntu-latest
|
|
needs: [changes, go]
|
|
if: >-
|
|
always() &&
|
|
needs.changes.result == 'success' &&
|
|
needs.go.result != 'failure' &&
|
|
(needs.changes.outputs.go == 'true' ||
|
|
needs.changes.outputs.bird_conf == 'true' ||
|
|
needs.changes.outputs.docker_bird == 'true' ||
|
|
needs.changes.outputs.docker_go == 'true')
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install bird2 (репозиторий Ubuntu runner, как в образе evobgp-bird2)
|
|
run: |
|
|
set -euxo pipefail
|
|
if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=""; fi
|
|
$SUDO apt-get update -qq
|
|
DEBIAN_FRONTEND=noninteractive $SUDO apt-get install -y -qq bird2
|
|
bird --version
|
|
- name: bird -p on all scenario bird.conf files
|
|
env:
|
|
WORKSPACE: ${{ github.workspace }}
|
|
run: |
|
|
set -euxo pipefail
|
|
WS="${WORKSPACE:-$PWD}"
|
|
cd "$WS"
|
|
if [ ! -f internal/birdfmt/testdata/scenarios/minimal/bird.conf ]; then
|
|
echo "Нет сценариев BIRD в checkout. Проверьте, что internal/birdfmt/testdata/scenarios закоммичен и push в remote."
|
|
ls -la internal/birdfmt/testdata/ 2>/dev/null || ls -la
|
|
exit 1
|
|
fi
|
|
for conf in internal/birdfmt/testdata/scenarios/*/bird.conf; do
|
|
echo "==> $conf"
|
|
bird -c "$WS/$conf" -p
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Docker: все Go-образы одним buildx bake (один go mod download, одна компиляция cmd/*,
|
|
# birdc собирается один раз для api/all). Registry cache: evobgp-buildcache:go-buildcache.
|
|
# ---------------------------------------------------------------------------
|
|
docker-go:
|
|
needs: [changes, go]
|
|
if: >-
|
|
always() &&
|
|
needs.changes.result == 'success' &&
|
|
needs.go.result != 'failure' &&
|
|
github.event_name == 'push' &&
|
|
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') &&
|
|
(needs.changes.outputs.go == 'true' || needs.changes.outputs.docker_go == 'true')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
- name: Prepare image metadata
|
|
id: meta
|
|
run: |
|
|
set -euo pipefail
|
|
owner_lc="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
|
echo "owner_lc=$owner_lc" >> "$GITHUB_OUTPUT"
|
|
short_sha="$(echo '${{ github.sha }}' | cut -c1-7)"
|
|
echo "short_sha=$short_sha" >> "$GITHUB_OUTPUT"
|
|
- name: Log in to Gitea Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: git.shts.su
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.ACTIONS_PAT || gitea.token }}
|
|
- name: Build and push Go images (bake)
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
docker buildx bake -f docker-bake.hcl go-images \
|
|
--push \
|
|
--set "REGISTRY=git.shts.su/${OWNER_LC}" \
|
|
--set "IMAGE_TAG=latest" \
|
|
--set "SHORT_SHA=${SHORT_SHA}" \
|
|
--set "SHA_FULL=${{ github.sha }}" \
|
|
--set "CACHE_REF_GO=git.shts.su/${OWNER_LC}/evobgp-buildcache:go-buildcache"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Docker: Web (evobgp-web, evobgp-web-all) — один npm ci (кэш) + два nginx-тега.
|
|
# ---------------------------------------------------------------------------
|
|
docker-web:
|
|
needs: [changes]
|
|
if: >-
|
|
github.event_name == 'push' &&
|
|
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') &&
|
|
(needs.changes.outputs.web == 'true' || needs.changes.outputs.docker_web == 'true')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
- name: Prepare image metadata
|
|
id: meta
|
|
run: |
|
|
set -euo pipefail
|
|
owner_lc="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
|
echo "owner_lc=$owner_lc" >> "$GITHUB_OUTPUT"
|
|
short_sha="$(echo '${{ github.sha }}' | cut -c1-7)"
|
|
echo "short_sha=$short_sha" >> "$GITHUB_OUTPUT"
|
|
- name: Log in to Gitea Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: git.shts.su
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.ACTIONS_PAT || gitea.token }}
|
|
- name: Build and push Web images (bake)
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
docker buildx bake -f docker-bake.hcl web-images \
|
|
--push \
|
|
--set "REGISTRY=git.shts.su/${OWNER_LC}" \
|
|
--set "IMAGE_TAG=latest" \
|
|
--set "SHORT_SHA=${SHORT_SHA}" \
|
|
--set "SHA_FULL=${{ github.sha }}" \
|
|
--set "CACHE_REF_WEB=git.shts.su/${OWNER_LC}/evobgp-buildcache:web-buildcache"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Docker: BIRD2 (evobgp-bird2).
|
|
# Собирается только при изменении deploy/bird/ или Dockerfile bird2.
|
|
# ---------------------------------------------------------------------------
|
|
docker-bird:
|
|
needs: [changes]
|
|
if: >-
|
|
github.event_name == 'push' &&
|
|
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') &&
|
|
(needs.changes.outputs.bird_conf == 'true' || needs.changes.outputs.docker_bird == 'true')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
- name: Prepare image metadata
|
|
id: meta
|
|
run: |
|
|
set -euo pipefail
|
|
owner_lc="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
|
echo "owner_lc=$owner_lc" >> "$GITHUB_OUTPUT"
|
|
short_sha="$(echo '${{ github.sha }}' | cut -c1-7)"
|
|
echo "short_sha=$short_sha" >> "$GITHUB_OUTPUT"
|
|
- name: Log in to Gitea Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: git.shts.su
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.ACTIONS_PAT || gitea.token }}
|
|
- name: Build and push evobgp-bird2 (bake)
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
docker buildx bake -f docker-bake.hcl evobgp-bird2 \
|
|
--push \
|
|
--set "REGISTRY=git.shts.su/${OWNER_LC}" \
|
|
--set "IMAGE_TAG=latest" \
|
|
--set "SHORT_SHA=${SHORT_SHA}" \
|
|
--set "SHA_FULL=${{ github.sha }}"
|