Skip to content

shadowfork: dbfork mutation engine + LevelDB/RocksDB e2e #87

shadowfork: dbfork mutation engine + LevelDB/RocksDB e2e

shadowfork: dbfork mutation engine + LevelDB/RocksDB e2e #87

Workflow file for this run

name: CI
# CI is split from e2e-test.yml so the fast feedback (lint / unit test /
# coverage / vuln scan) runs on every PR and push, while the heavier e2e
# stays on the existing schedule. Each job is independent so a slow scan
# doesn't block a quick lint failure.
on:
push:
branches: [master, develop, "00*-*"]
pull_request:
branches: [master, develop]
permissions:
contents: read
jobs:
lint:
name: golangci-lint
runs-on: ubuntu-latest
# Lint blocks the PR. .golangci.yml excludes patterns we've decided
# are noise (errcheck on fmt.Fprint*, defer Close on cleanup paths,
# gocritic style nags). Real issues — unused vars, ineffective
# assignments, real errcheck on actionable returns — still fail.
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
# We compile golangci-lint with the project's own Go toolchain via
# GOTOOLCHAIN. Released v1 binaries are pinned to go1.22 in their
# module so a pre-built install errors out with "Go language
# version used to build golangci-lint is lower than the targeted
# Go version" against any project on a newer Go.
- name: Install golangci-lint
env:
GOTOOLCHAIN: go1.25.9
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.8
- name: Run golangci-lint
run: golangci-lint run --timeout=5m ./...
test:
name: Test + coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: go vet
run: go vet ./...
- name: Unit tests with coverage
run: |
go test -race -count=1 -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -func=coverage.out | tail -1
# Codecov upload is optional; only runs when CODECOV_TOKEN secret
# is present so forks don't fail the job.
- name: Upload coverage
if: ${{ env.CODECOV_TOKEN != '' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@v5
with:
files: coverage.out
token: ${{ secrets.CODECOV_TOKEN }}
govulncheck:
name: Vulnerability scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: Run govulncheck
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
proto-drift:
name: Proto-binding drift
runs-on: ubuntu-latest
# Regenerates internal/dbfork/proto/pb/ via the project's gen
# script and fails if the result differs from what's committed.
# Catches two failure modes:
# 1. Upstream .proto edit (via the git subtree pull workflow)
# without running the gen script — committed bindings would
# silently lag the proto definitions.
# 2. Hand-edit of a *.pb.go file (they look like normal Go and
# tempt operators to "just tweak" — they're machine-
# generated and will be clobbered by the next regen).
#
# protoc-gen-go version is pinned via go.mod's `tool` directive
# (Go 1.24+ pattern). `go install tool` here installs ALL tools
# declared in go.mod — currently just protoc-gen-go @ the
# matching google.golang.org/protobuf runtime version. Single
# source of truth; mismatched generator vs runtime can't happen.
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: Install protoc
uses: arduino/setup-protoc@v3
with:
# Pinned to the EXACT 35.0 that generated the committed
# internal/dbfork/proto/pb/*.pb.go files (their header reads
# `protoc v7.35.0`). The drift job regenerates and diffs the
# committed bytes, including that header line — so a wildcard
# `35.x` would resolve to the latest 35.minor and false-report
# drift the day 35.1 ships, despite no .proto change. Bump
# this deliberately alongside a regenerate-and-commit.
version: "35.0"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install pinned tools (protoc-gen-go via go.mod)
run: go install tool
- name: Regenerate proto bindings
run: bash scripts/gen-dbfork-protos.sh
- name: Fail on drift
# `git diff --exit-code` returns 1 if any file differs. We dump
# the diff first so the failure log shows what changed without
# the developer needing to re-run locally.
run: |
if ! git diff --exit-code internal/dbfork/proto/pb/; then
echo "::error::Committed .pb.go files drifted from regeneration."
echo "::error::Run 'bash scripts/gen-dbfork-protos.sh' locally + commit the result."
exit 1
fi
build-matrix:
name: Cross-compile
runs-on: ubuntu-latest
strategy:
matrix:
target:
- { os: linux, arch: amd64 }
- { os: linux, arch: arm64 }
- { os: darwin, arch: amd64 }
- { os: darwin, arch: arm64 }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.25"
cache: true
- name: Build ${{ matrix.target.os }}/${{ matrix.target.arch }}
env:
GOOS: ${{ matrix.target.os }}
GOARCH: ${{ matrix.target.arch }}
CGO_ENABLED: "0"
run: go build -o /tmp/trond-${{ matrix.target.os }}-${{ matrix.target.arch }} .