CI / changes (push) Successful in 7s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 1m29s
CI / docker-web (push) Failing after 15s
CI / docker-bird (push) Failing after 14s
CI / bird2 (push) Successful in 14s
CI / docker-go (push) Failing after 14s
Enhanced the CI workflow by adding support for docker-bake.hcl to streamline the building and pushing of Go images. Updated Go version to 1.24 and introduced caching for Go module dependencies. Refactored Dockerfiles for evobgp-agent, evobgp-web, and gobinary to utilize build stages more effectively, improving caching and build performance. Adjusted installation commands and entry points for better clarity and maintainability.
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 }}"
|