CI / changes (push) Successful in 4s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 20s
CI / bird2 (push) Successful in 15s
CI / docker-images (deploy/docker/bird2/Dockerfile, evobgp-bird2) (push) Successful in 45s
CI / docker-images (deploy/docker/evobgp-agent/Dockerfile, evobgp-agent) (push) Successful in 1m6s
CI / docker-images (deploy/docker/evobgp-web/Dockerfile, evobgp-web) (push) Successful in 51s
CI / docker-images (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, evobgp-all) (push) Successful in 1m27s
CI / docker-images (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, evobgp-api) (push) Successful in 1m32s
CI / docker-images (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, evobgp-deploy) (push) Successful in 1m27s
CI / docker-images (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, evobgp-ingest) (push) Successful in 1m23s
CI / docker-images (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, evobgp-node) (push) Successful in 1m21s
CI / docker-images (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, evobgp-render) (push) Successful in 1m31s
CI / docker-images (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, evobgp-scheduler) (push) Successful in 1m24s
260 lines
8.9 KiB
YAML
260 lines
8.9 KiB
YAML
name: CI
|
||
|
||
on:
|
||
push:
|
||
branches: [main, master]
|
||
pull_request:
|
||
branches: [main, master]
|
||
|
||
jobs:
|
||
changes:
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
openapi: ${{ steps.detect.outputs.openapi }}
|
||
code: ${{ steps.detect.outputs.code }}
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
- id: detect
|
||
name: Detect changed paths (OpenAPI vs doc-only vs code)
|
||
run: |
|
||
set -euo pipefail
|
||
|
||
openapi=false
|
||
code=true
|
||
|
||
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
|
||
# Нет родителя (первый коммит / тонкий clone) — полный пайплайн + OpenAPI
|
||
openapi=true
|
||
code=true
|
||
echo "openapi=$openapi" >> "$GITHUB_OUTPUT"
|
||
echo "code=$code" >> "$GITHUB_OUTPUT"
|
||
echo "No parent commit: openapi=true code=true"
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
# Пустой diff (редко) — не отключаем сборку из осторожности
|
||
if [ -z "$(printf '%s' "$FILES" | tr -d '[:space:]')" ]; then
|
||
openapi=false
|
||
code=true
|
||
echo "openapi=$openapi" >> "$GITHUB_OUTPUT"
|
||
echo "code=$code" >> "$GITHUB_OUTPUT"
|
||
echo "Empty diff: openapi=false code=true"
|
||
exit 0
|
||
fi
|
||
|
||
if printf '%s\n' "$FILES" | grep -qE '^docs/openapi\.yaml$|^redocly\.yaml$'; then
|
||
openapi=true
|
||
fi
|
||
|
||
doc_only_all=true
|
||
while IFS= read -r f || [ -n "${f:-}" ]; do
|
||
[ -z "${f:-}" ] && continue
|
||
if [[ "$f" == "README.md" || "$f" == ".gitea/README.md" || "$f" == "web/README.md" || "$f" == "redocly.yaml" || "$f" == docs/* ]]; then
|
||
continue
|
||
fi
|
||
doc_only_all=false
|
||
break
|
||
done <<< "$FILES"
|
||
|
||
if $doc_only_all; then
|
||
code=false
|
||
else
|
||
code=true
|
||
fi
|
||
|
||
echo "openapi=$openapi" >> "$GITHUB_OUTPUT"
|
||
echo "code=$code" >> "$GITHUB_OUTPUT"
|
||
echo "Changed files (first 20):"
|
||
printf '%s\n' "$FILES" | head -n 20
|
||
echo "openapi=$openapi code=$code"
|
||
|
||
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.code == '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: [go]
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
# Вложенный docker + bind-mount ломается, если демон Docker на хосте не видит путь
|
||
# workspace runner'а (/workspace/...). bird -p на самом job-раннере надёжнее.
|
||
- name: Install 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
|
||
|
||
# Сборка образов и push в Container Registry Gitea (только push в main/master; см. .gitea/README.md).
|
||
docker-images:
|
||
needs: [go]
|
||
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|
||
runs-on: ubuntu-latest
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
include:
|
||
- image: evobgp-api
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-api
|
||
birdc: "1"
|
||
- image: evobgp-all
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-all
|
||
birdc: "1"
|
||
- image: evobgp-scheduler
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-scheduler
|
||
birdc: "0"
|
||
- image: evobgp-ingest
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-ingest
|
||
birdc: "0"
|
||
- image: evobgp-render
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-render
|
||
birdc: "0"
|
||
- image: evobgp-deploy
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-deploy
|
||
birdc: "0"
|
||
- image: evobgp-node
|
||
dockerfile: deploy/docker/gobinary/Dockerfile
|
||
bin: evobgp-node
|
||
birdc: "0"
|
||
- image: evobgp-web
|
||
dockerfile: deploy/docker/evobgp-web/Dockerfile
|
||
- image: evobgp-agent
|
||
dockerfile: deploy/docker/evobgp-agent/Dockerfile
|
||
- image: evobgp-bird2
|
||
dockerfile: deploy/docker/bird2/Dockerfile
|
||
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"
|
||
echo "docker_push=true" >> "$GITHUB_OUTPUT"
|
||
|
||
- name: Log in to Gitea Registry
|
||
if: steps.meta.outputs.docker_push == 'true'
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: git.shts.su
|
||
username: ${{ gitea.actor }}
|
||
# PAT репозитория или встроенный токен job (нужны права на пакеты в настройках Actions).
|
||
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 }}
|
||
DO_PUSH: ${{ steps.meta.outputs.docker_push }}
|
||
DF: ${{ matrix.dockerfile }}
|
||
IMAGE: ${{ matrix.image }}
|
||
BIN: ${{ matrix.bin }}
|
||
BIRDC: ${{ matrix.birdc }}
|
||
run: |
|
||
set -euxo pipefail
|
||
WS="${{ github.workspace }}"
|
||
cd "$WS"
|
||
|
||
TAG_LOCAL="evobgp:${IMAGE}-${SHORT_SHA}"
|
||
BUILD_ARGS=()
|
||
if [ -n "${BIN:-}" ]; then
|
||
BUILD_ARGS+=(--build-arg "BIN=${BIN}")
|
||
BUILD_ARGS+=(--build-arg "INSTALL_BIRDC=${BIRDC:-0}")
|
||
fi
|
||
|
||
if [ "$DO_PUSH" = "true" ]; then
|
||
IMG="git.shts.su/${OWNER_LC}/${IMAGE}"
|
||
docker buildx build \
|
||
--platform linux/amd64 \
|
||
--file "$DF" \
|
||
"${BUILD_ARGS[@]}" \
|
||
--tag "${IMG}:latest" \
|
||
--tag "${IMG}:${SHORT_SHA}" \
|
||
--tag "${IMG}:sha-${{ github.sha }}" \
|
||
--push \
|
||
"$WS"
|
||
else
|
||
docker buildx build \
|
||
--platform linux/amd64 \
|
||
--file "$DF" \
|
||
"${BUILD_ARGS[@]}" \
|
||
--tag "$TAG_LOCAL" \
|
||
--load \
|
||
"$WS"
|
||
fi
|