CI / changes (push) Successful in 5s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 21s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 59s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m2s
CI / docker-bird (push) Successful in 1m56s
CI / bird2 (push) Successful in 59s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 2m19s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been cancelled
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been cancelled
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been cancelled
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been cancelled
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been cancelled
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been cancelled
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been cancelled
409 lines
16 KiB
YAML
409 lines
16 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/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.22"
|
|
- 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 BIRD from source (2.14, как в контейнерах)
|
|
run: |
|
|
set -euxo pipefail
|
|
if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=""; fi
|
|
$SUDO apt-get update -qq
|
|
$SUDO cp deploy/docker/bird/bird-from-source.sh /tmp/bird-from-source.sh
|
|
$SUDO chmod +x /tmp/bird-from-source.sh
|
|
$SUDO env BIRD_VERSION=2.14 bash /tmp/bird-from-source.sh
|
|
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-бинарники (api, all, scheduler, ingest, render, deploy, node, agent).
|
|
# Запускается если изменился Go-код или Go-Dockerfile.
|
|
# Если Go-код менялся — требуем успех go-тестов; если только Dockerfile — go skipped, ОК.
|
|
# ---------------------------------------------------------------------------
|
|
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
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- image: evobgp-api
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-api
|
|
birdc: "1"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-all
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-all
|
|
birdc: "1"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-scheduler
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-scheduler
|
|
birdc: "0"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-ingest
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-ingest
|
|
birdc: "0"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-render
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-render
|
|
birdc: "0"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-deploy
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-deploy
|
|
birdc: "0"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-node
|
|
dockerfile: deploy/docker/gobinary/Dockerfile
|
|
bin: evobgp-node
|
|
birdc: "0"
|
|
evobgp_upstream: ""
|
|
- image: evobgp-agent
|
|
dockerfile: deploy/docker/evobgp-agent/Dockerfile
|
|
evobgp_upstream: ""
|
|
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 ${{ matrix.image }}
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
DF: ${{ matrix.dockerfile }}
|
|
IMAGE: ${{ matrix.image }}
|
|
BIN: ${{ matrix.bin }}
|
|
BIRDC: ${{ matrix.birdc }}
|
|
EVOBGP_UPSTREAM: ${{ matrix.evobgp_upstream }}
|
|
run: |
|
|
set -euxo pipefail
|
|
WS="${{ github.workspace }}"
|
|
cd "$WS"
|
|
|
|
IMG="git.shts.su/${OWNER_LC}/${IMAGE}"
|
|
BUILD_ARGS=()
|
|
if [ -n "${BIN:-}" ]; then
|
|
BUILD_ARGS+=(--build-arg "BIN=${BIN}")
|
|
BUILD_ARGS+=(--build-arg "INSTALL_BIRDC=${BIRDC:-0}")
|
|
fi
|
|
if [ -n "${EVOBGP_UPSTREAM:-}" ]; then
|
|
BUILD_ARGS+=(--build-arg "EVOBGP_UPSTREAM=${EVOBGP_UPSTREAM}")
|
|
fi
|
|
|
|
docker buildx build \
|
|
--platform linux/amd64 \
|
|
--file "$DF" \
|
|
"${BUILD_ARGS[@]}" \
|
|
--tag "${IMG}:latest" \
|
|
--tag "${IMG}:${SHORT_SHA}" \
|
|
--tag "${IMG}:sha-${{ github.sha }}" \
|
|
--push \
|
|
"$WS"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Docker: Web-фронтенд (evobgp-web, evobgp-web-all).
|
|
# Не зависит от Go-тестов — SvelteKit собирается отдельно.
|
|
# ---------------------------------------------------------------------------
|
|
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
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- image: evobgp-web
|
|
dockerfile: deploy/docker/evobgp-web/Dockerfile
|
|
evobgp_upstream: ""
|
|
- image: evobgp-web-all
|
|
dockerfile: deploy/docker/evobgp-web/Dockerfile
|
|
evobgp_upstream: evobgp-all
|
|
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 ${{ matrix.image }}
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
DF: ${{ matrix.dockerfile }}
|
|
IMAGE: ${{ matrix.image }}
|
|
EVOBGP_UPSTREAM: ${{ matrix.evobgp_upstream }}
|
|
run: |
|
|
set -euxo pipefail
|
|
WS="${{ github.workspace }}"
|
|
cd "$WS"
|
|
|
|
IMG="git.shts.su/${OWNER_LC}/${IMAGE}"
|
|
BUILD_ARGS=()
|
|
if [ -n "${EVOBGP_UPSTREAM:-}" ]; then
|
|
BUILD_ARGS+=(--build-arg "EVOBGP_UPSTREAM=${EVOBGP_UPSTREAM}")
|
|
fi
|
|
|
|
docker buildx build \
|
|
--platform linux/amd64 \
|
|
--file "$DF" \
|
|
"${BUILD_ARGS[@]}" \
|
|
--tag "${IMG}:latest" \
|
|
--tag "${IMG}:${SHORT_SHA}" \
|
|
--tag "${IMG}:sha-${{ github.sha }}" \
|
|
--push \
|
|
"$WS"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 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
|
|
env:
|
|
OWNER_LC: ${{ steps.meta.outputs.owner_lc }}
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
run: |
|
|
set -euxo pipefail
|
|
WS="${{ github.workspace }}"
|
|
IMG="git.shts.su/${OWNER_LC}/evobgp-bird2"
|
|
|
|
docker buildx build \
|
|
--platform linux/amd64 \
|
|
--file deploy/docker/bird2/Dockerfile \
|
|
--tag "${IMG}:latest" \
|
|
--tag "${IMG}:${SHORT_SHA}" \
|
|
--tag "${IMG}:sha-${{ github.sha }}" \
|
|
--push \
|
|
"$WS"
|