CI / changes (push) Successful in 7s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 25s
CI / docker-web (push) Failing after 16s
CI / docker-bird (push) Failing after 16s
CI / bird2 (push) Successful in 16s
CI / docker-go (push) Failing after 14s
Added the BUILDX_BAKE_ENTITLEMENTS_FS environment variable set to "0" in the CI workflow to allow Docker builds to read the repository context. Updated the README to clarify this change and provide guidance on local usage for similar issues.
322 lines
13 KiB
YAML
322 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:
|
|
REGISTRY: git.shts.su/${{ steps.meta.outputs.owner_lc }}
|
|
IMAGE_TAG: latest
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
SHA_FULL: ${{ github.sha }}
|
|
CACHE_REF_GO: git.shts.su/${{ steps.meta.outputs.owner_lc }}/evobgp-buildcache:go-buildcache
|
|
CACHE_REF_WEB: ""
|
|
# buildx bake: context ../.. (корень репо) — на доверенном CI отключаем fs entitlement gate
|
|
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
sh write-bake-override.sh
|
|
docker buildx bake -f docker-bake.hcl -f docker-bake.override.hcl go-images --push
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 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:
|
|
REGISTRY: git.shts.su/${{ steps.meta.outputs.owner_lc }}
|
|
IMAGE_TAG: latest
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
SHA_FULL: ${{ github.sha }}
|
|
CACHE_REF_GO: ""
|
|
CACHE_REF_WEB: git.shts.su/${{ steps.meta.outputs.owner_lc }}/evobgp-buildcache:web-buildcache
|
|
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
sh write-bake-override.sh
|
|
docker buildx bake -f docker-bake.hcl -f docker-bake.override.hcl web-images --push
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 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:
|
|
REGISTRY: git.shts.su/${{ steps.meta.outputs.owner_lc }}
|
|
IMAGE_TAG: latest
|
|
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
|
SHA_FULL: ${{ github.sha }}
|
|
CACHE_REF_GO: ""
|
|
CACHE_REF_WEB: ""
|
|
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
|
run: |
|
|
set -euxo pipefail
|
|
cd "${{ github.workspace }}/deploy/docker"
|
|
sh write-bake-override.sh
|
|
docker buildx bake -f docker-bake.hcl -f docker-bake.override.hcl evobgp-bird2 --push
|