Skip to content

docs: add public architecture doc, dev.to link, update performance guide #83

docs: add public architecture doc, dev.to link, update performance guide

docs: add public architecture doc, dev.to link, update performance guide #83

Workflow file for this run

name: CI
# Testing Strategy:
# - Tests run on Linux and Windows (AMD64 only - macOS planned for v0.5.0)
# - goffi uses platform-specific assembly (System V vs Win64 ABI)
# - Go 1.25+ required (matches go.mod requirement)
# - Race detector critical for low-level FFI code
#
# Branch Strategy (Git Flow):
# - feature/** branches: Development work
# - release/** branches: Pre-release testing (test here BEFORE merging to main)
# - develop branch: Integration branch
# - main branch: Production-ready code only (protected)
# - Pull requests: Must pass all tests before merge
on:
push:
branches:
- main
- develop
- 'experiment/**' # goffi uses experiment/** for prototypes
- 'feature/**'
- 'release/**'
- 'hotfix/**'
pull_request:
branches:
- main
- develop
jobs:
# Linting - Fast fail on code quality issues
lint:
name: Lint
runs-on: ubuntu-latest
env:
CGO_ENABLED: 0 # goffi uses fakecgo with build tag !cgo
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
- name: Download dependencies
run: go mod download
- name: Verify dependencies
run: go mod verify
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: latest
args: --config=.golangci.yml --timeout=5m
# Code formatting check
formatting:
name: Code Formatting
runs-on: ubuntu-latest
env:
CGO_ENABLED: 0 # goffi is zero-CGO library
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
- name: Check formatting
run: |
if [ -n "$(gofmt -l .)" ]; then
echo "ERROR: The following files are not formatted:"
gofmt -l .
echo ""
echo "Run 'go fmt ./...' to fix formatting issues."
exit 1
fi
echo "All files are properly formatted ✓"
# Unit tests - Platform-specific (Linux + Windows + macOS AMD64)
test:
name: Test - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [lint, formatting]
permissions:
contents: read
id-token: write # Required for Codecov OIDC tokenless upload
env:
CGO_ENABLED: 0 # goffi is zero-CGO library
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
# macos-latest: Apple Silicon ARM64 (M-series)
# Note: macOS Intel (x86_64) deprecated Dec 2025, no free tier Intel runners
# Intel tested via Linux/Windows AMD64 (same System V / similar ABI)
# Build tags in source files (//go:build) select correct implementation
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
cache-dependency-path: go.sum
- name: Download dependencies
run: go mod download
- name: Verify dependencies
run: go mod verify
# Note: go vet is included in golangci-lint job (with proper exclusions)
# Running it separately would fail on assembly code and unsafe.Pointer usage
- name: Run unit tests
shell: bash
run: |
# Note: Race detector requires CGO_ENABLED=1, so we run it separately
# Go automatically selects platform-specific files via build tags
# Test only main packages to avoid coverage dilution from platform-specific files
go test -v -coverprofile=coverage.txt -covermode=atomic ./ffi ./types
- name: Display coverage summary
shell: bash
run: |
echo "Coverage summary for ${{ matrix.os }}:"
go tool cover -func=coverage.txt | tail -1
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.os }}
path: coverage.txt
retention-days: 7
- name: Upload coverage to Codecov (Linux only)
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v5
with:
use_oidc: true
slug: go-webgpu/goffi
files: ./coverage.txt
flags: unittests
name: codecov-goffi
fail_ci_if_error: false
verbose: true
# NOTE: Race detection is NOT supported for zero-CGO libraries
# - Race detector requires CGO_ENABLED=1
# - Our fakecgo has build tag !cgo
# - With CGO_ENABLED=1, fakecgo doesn't compile
# - This is a known limitation of zero-CGO approach
# - Manual race testing can be done with CGO enabled and real C runtime
# Benchmarks - Performance validation (Linux only - reference platform)
benchmarks:
name: Benchmarks
runs-on: ubuntu-latest
needs: [lint, formatting]
env:
CGO_ENABLED: 0 # goffi is zero-CGO library
GOOS: linux
GOARCH: amd64
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache: true
- name: Download dependencies
run: go mod download
- name: Run benchmarks
run: |
echo "Running FFI overhead benchmarks..."
go test -bench=BenchmarkGoffi -benchmem -run=^$ ./ffi | tee bench.txt
- name: Validate performance regression
run: |
# Check FFI overhead is < 200ns (acceptable threshold)
overhead=$(grep "BenchmarkGoffiOverhead" bench.txt | awk '{print $3}' | sed 's/ns\/op//')
echo "FFI Overhead: ${overhead}ns/op"
if (( $(echo "$overhead > 200" | bc -l) )); then
echo "::warning::FFI overhead ($overhead ns/op) exceeds 200ns threshold"
else
echo "✅ FFI overhead within acceptable range"
fi
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmarks
path: bench.txt
retention-days: 30
# Quality gate - Coverage threshold enforcement
quality-gate:
name: Quality Gate
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Download coverage reports
uses: actions/download-artifact@v4
with:
path: coverage-reports
- name: Check coverage thresholds
shell: bash
run: |
MIN_COVERAGE=70 # goffi maintains 89.1%, threshold set lower for safety
FAILED=0
echo "Checking coverage thresholds (minimum: ${MIN_COVERAGE}%)..."
echo "Note: ARM64 platforms are cross-compile verified, coverage informational only"
echo ""
for report in coverage-reports/coverage-*/coverage.txt; do
if [ ! -f "$report" ]; then
continue
fi
# Extract OS name from path
os=$(echo "$report" | sed -E 's/.*coverage-([^/]+).*/\1/')
# Calculate coverage percentage
total_line=$(go tool cover -func "$report" | grep total)
cov=$(echo "$total_line" | awk '{print $3}' | sed 's/%//')
# ARM64 (macos-latest) is cross-compile verified, not production
# Only enforce coverage on production AMD64 platforms
if [[ "$os" == "macos-latest" ]]; then
echo "📊 $os (ARM64) coverage: ${cov}% (informational, cross-compile verified)"
continue
fi
echo "📊 $os coverage: ${cov}%"
# Check threshold (use awk for float comparison)
if awk -v cov="$cov" -v min="$MIN_COVERAGE" 'BEGIN {exit !(cov < min)}'; then
echo "::error::Coverage for $os (${cov}%) is below ${MIN_COVERAGE}%"
FAILED=1
fi
done
echo ""
if [ $FAILED -eq 1 ]; then
echo "❌ Coverage check FAILED"
exit 1
fi
echo "✅ All coverage thresholds met"
echo "🎯 Production platforms (AMD64): 85%+ coverage"
# Final status - All checks passed
ci-success:
name: CI Success
needs: [lint, formatting, test, benchmarks, quality-gate]
runs-on: ubuntu-latest
if: success()
steps:
- name: Success
run: |
echo "✅ All CI checks passed!"
echo "✅ Lint: PASSED"
echo "✅ Formatting: PASSED"
echo "✅ Tests: PASSED"
echo " - Linux AMD64 (ubuntu-latest)"
echo " - Windows AMD64 (windows-latest)"
echo " - macOS ARM64 (macos-latest)"
echo "✅ Benchmarks: PASSED"
echo "✅ Quality Gate: PASSED"
echo ""
echo "Note: macOS Intel uses same ABI as Linux AMD64"
echo "🚀 Ready for merge!"