The release dry run builds and inspects the packages and proves signing and verification with a throwaway key; the release workflow signs SHA256SUMS when RELEASE_SIGNING_KEY is set and checks the signature with the installer's public key. The shell job runs the brand check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
220 lines
7.7 KiB
YAML
220 lines
7.7 KiB
YAML
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Continuous integration (ADR 0003). Runs on Gitea Actions with
|
|
# GitHub-Actions-compatible syntax. External actions are pinned by commit SHA.
|
|
name: ci
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
go:
|
|
name: Go (lint, test, vuln)
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:17.11-alpine
|
|
env:
|
|
POSTGRES_USER: ddi
|
|
POSTGRES_PASSWORD: ddi-ci-only
|
|
POSTGRES_DB: ddi_test
|
|
options: >-
|
|
--health-cmd "pg_isready -U ddi -d ddi_test"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 20
|
|
env:
|
|
# Database tests must run in CI instead of being skipped.
|
|
DDI_TEST_DATABASE_URL: postgres://ddi:ddi-ci-only@postgres:5432/ddi_test?sslmode=disable
|
|
DDI_REQUIRE_DB_TESTS: "1"
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
- name: Install tools
|
|
run: scripts/ci/install-tools.sh
|
|
- name: Ensure C toolchain for the race detector
|
|
run: |
|
|
if ! command -v gcc >/dev/null; then
|
|
apt-get update -qq && apt-get install -y -qq --no-install-recommends gcc libc6-dev
|
|
fi
|
|
- name: Lint
|
|
run: make lint-go
|
|
- name: Test
|
|
run: make test-go
|
|
- name: Coverage summary
|
|
run: go tool cover -func=coverage.txt | tail -n 1
|
|
- name: Vulnerability scan
|
|
run: go tool govulncheck ./...
|
|
|
|
proto:
|
|
name: Protobuf
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- name: Install tools
|
|
run: scripts/ci/install-tools.sh
|
|
- name: Lint and format
|
|
run: make lint-proto
|
|
- name: Generated code is up to date
|
|
run: buf generate && git diff --exit-code -- proto/gen
|
|
|
|
web:
|
|
name: Web (lint, test, audit, build)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: "24"
|
|
- name: Install dependencies
|
|
run: make web-deps
|
|
- name: API types are up to date with the OpenAPI spec
|
|
run: cd web && npm run gen:api && git diff --exit-code -- src/api/schema.d.ts
|
|
- name: Lint, format, typecheck
|
|
run: make lint-web
|
|
- name: Test
|
|
run: make test-web
|
|
- name: Audit
|
|
run: cd web && npm audit --audit-level=high
|
|
- name: Build
|
|
run: cd web && npm run build
|
|
|
|
shell:
|
|
name: Shell and licence headers
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- name: Install tools
|
|
run: scripts/ci/install-tools.sh
|
|
- name: shellcheck
|
|
run: make lint-shell
|
|
- name: SPDX headers
|
|
run: make lint-spdx
|
|
- name: No hard-coded product names (ADR 0018)
|
|
run: make lint-brand
|
|
|
|
release-dry-run:
|
|
name: Release build (dry run)
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:17.11-alpine
|
|
env:
|
|
POSTGRES_USER: ddi
|
|
POSTGRES_PASSWORD: ddi-ci-only
|
|
POSTGRES_DB: ddi
|
|
options: >-
|
|
--health-cmd "pg_isready -U ddi -d ddi"
|
|
--health-interval 5s
|
|
--health-timeout 3s
|
|
--health-retries 20
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
fetch-depth: 0
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: "24"
|
|
- name: Install nfpm
|
|
run: scripts/ci/install-tools.sh "$HOME/.local/bin" nfpm
|
|
- name: Build release artefacts and packages
|
|
run: make release PACKAGES=1
|
|
- name: Verify checksums
|
|
run: cd dist && sha256sum -c SHA256SUMS
|
|
- name: Inspect packages
|
|
run: |
|
|
ls -l dist/*.deb dist/*.rpm
|
|
# 3 binaries x 2 architectures x (deb, rpm)
|
|
test "$(ls dist/*.deb dist/*.rpm | wc -l)" -eq 12
|
|
for deb in dist/*_amd64.deb; do
|
|
dpkg-deb --info "$deb" >/dev/null
|
|
dpkg-deb --contents "$deb" >contents.txt
|
|
grep -q ' ./usr/bin/' contents.txt
|
|
grep -q ' ./usr/lib/systemd/system/.*\.service$' contents.txt
|
|
grep -q ' ./usr/share/doc/.*/LICENSE$' contents.txt
|
|
done
|
|
- name: Release signature (throwaway key)
|
|
run: |
|
|
command -v openssl >/dev/null || (apt-get update -qq && apt-get install -y -qq openssl)
|
|
scripts/sign-release.sh selftest
|
|
umask 077
|
|
key="$(mktemp)"
|
|
openssl genpkey -algorithm ed25519 -out "$key"
|
|
RELEASE_SIGNING_KEY="$(cat "$key")" scripts/sign-release.sh sign dist/SHA256SUMS
|
|
scripts/sign-release.sh public-key "$key" >"$key.pub"
|
|
scripts/sign-release.sh verify dist/SHA256SUMS dist/SHA256SUMS.sig "$key.pub"
|
|
rm -f "$key" "$key.pub" dist/SHA256SUMS.sig
|
|
- name: Smoke test of the released server binary
|
|
env:
|
|
DDI_DATABASE_URL: postgres://ddi:ddi-ci-only@postgres:5432/ddi?sslmode=disable
|
|
run: scripts/ci/smoke-server.sh dist
|
|
|
|
# Needs a runner with access to a Docker daemon (see docs/adr/0003).
|
|
e2e:
|
|
name: End-to-end (server, agents, BIND, Kea)
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
# The Docker daemon may be shared: unique compose project.
|
|
COMPOSE_PROJECT_NAME: ddi-e2e-${{ github.run_id }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: "24"
|
|
- name: API change reaches BIND and Kea through the agents
|
|
run: make test-e2e
|
|
|
|
# Needs a runner with access to a Docker daemon (see docs/adr/0003).
|
|
integration:
|
|
name: Integration (real BIND and Kea)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: false
|
|
- name: Generated configuration and agent roles against real BIND and Kea
|
|
run: make test-integration
|
|
|
|
# Needs a runner with access to a Docker daemon (see docs/adr/0003).
|
|
dev-environment:
|
|
name: Development environment (compose)
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
# The Docker daemon may be shared: unique project, random host ports.
|
|
COMPOSE_PROJECT_NAME: ddi-ci-${{ github.run_id }}
|
|
DDI_DEV_PG_PORT: ""
|
|
DDI_DEV_DNS_PORT: ""
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- name: Validate compose file
|
|
run: docker compose -f deploy/compose/compose.dev.yaml config -q
|
|
- name: Start
|
|
run: make dev-up
|
|
- name: Smoke test
|
|
run: make dev-smoke
|
|
- name: Logs
|
|
if: always()
|
|
run: docker compose -f deploy/compose/compose.dev.yaml logs --no-color
|
|
- name: Stop
|
|
if: always()
|
|
run: docker compose -f deploy/compose/compose.dev.yaml down -v
|