docs: add public architecture doc, dev.to link, update performance guide #83
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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!" |