Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @kolkov
207 changes: 207 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
name: CI

# CI Strategy:
# - Tests run on Linux, macOS, and Windows (cross-platform IPC library)
# - Go 1.25+ required (matches go.mod requirement)
# - CGO_ENABLED=0: Pure Go library, no C compiler required
#
# Branch Strategy (GitHub Flow):
# - main branch: Production-ready code
# - Feature branches: Tested via pull_request trigger
# - Pull requests: Must pass all checks before merge

env:
CGO_ENABLED: "0"

on:
push:
branches:
- main
pull_request:
branches:
- main

permissions:
contents: read
id-token: write # Required for Codecov OIDC token

jobs:
# Build verification - Cross-platform
build:
name: Build - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.25']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Download dependencies
run: go mod download

- name: Verify dependencies
run: go mod verify

- name: Build all packages
run: go build ./...

# Unit tests - Cross-platform
test:
name: Test - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.25']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Download dependencies
run: go mod download

- name: Run go vet
if: matrix.os == 'ubuntu-latest'
run: go vet ./...

- name: Run tests
run: go test -v ./...

- name: Run tests with coverage
if: matrix.os == 'ubuntu-latest'
run: go test -coverprofile=coverage.out -covermode=atomic ./...

- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v5
with:
files: coverage.out
use_oidc: true

# Linting
lint:
name: Lint
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'
cache: true

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: latest
args: --timeout=5m

# Code formatting check
formatting:
name: Formatting
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'
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"

# Dependency freshness check
# Uses go-mod-outdated (https://github.com/psampaz/go-mod-outdated)
# Non-blocking: reports outdated deps as warnings, does not fail CI
deps:
name: Dependencies
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'
cache: true

- name: Install go-mod-outdated
run: go install github.com/psampaz/go-mod-outdated@latest

- name: Check all dependencies
run: |
echo "## All Dependencies Status"
go list -u -m -json all 2>/dev/null | go-mod-outdated -style markdown || true

- name: Check direct dependencies for updates
run: |
echo "## Direct Dependencies with Available Updates"
OUTDATED=$(go list -u -m -json all 2>/dev/null | go-mod-outdated -update -direct || true)
if [ -n "$OUTDATED" ]; then
echo "$OUTDATED"
echo ""
echo "::warning::Some direct dependencies have updates available"
else
echo "All direct dependencies are up to date!"
fi

- name: Check ecosystem dependencies
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "## Ecosystem Dependencies"
WARNINGS=0

check_ecosystem_dep() {
local DEP=$1 REPO=$2
LOCAL=$(grep "$DEP" go.mod 2>/dev/null | grep -v "^module" | awk '{print $2}')
[ -z "$LOCAL" ] && return 0

LATEST=$(gh release view --repo "$REPO" --json tagName -q '.tagName' 2>/dev/null || echo "")
[ -z "$LATEST" ] && { echo " $DEP: $LOCAL (cannot verify)"; return 0; }

if [ "$LOCAL" = "$LATEST" ]; then
echo " $DEP: $LOCAL"
else
echo " $DEP: $LOCAL -> $LATEST available"
WARNINGS=$((WARNINGS + 1))
fi
}

check_ecosystem_dep "github.com/pierrec/lz4/v4" "pierrec/lz4"

[ $WARNINGS -gt 0 ] && echo "::warning::$WARNINGS ecosystem dep(s) outdated. Run: go get <dep>@latest"
exit 0 # Non-blocking
165 changes: 165 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# GolangCI-Lint v2 Configuration for gogpu/compose
# Documentation: https://golangci-lint.run/docs/configuration/

version: "2"

run:
timeout: 5m
tests: true

linters:
enable:
# Code quality and complexity
- gocyclo
- gocognit
- funlen
- maintidx
- cyclop
- nestif

# Bug detection
- govet
- staticcheck
- errcheck
- errorlint
- gosec
- nilnil
- nilerr
- ineffassign

# Code style and consistency
- misspell
- whitespace
- unconvert
- unparam

# Naming conventions
- errname
- revive

# Performance
- prealloc
- makezero

# Code practices
- goconst
- gocritic
- goprintffuncname
- nolintlint
- nakedret

# Additional quality checkers
- dupl
- dogsled
- durationcheck

settings:
govet:
enable:
- copylocks
disable:
- fieldalignment

gocyclo:
min-complexity: 20

cyclop:
max-complexity: 20

funlen:
lines: 120
statements: 60

gocognit:
min-complexity: 30

misspell:
locale: US

nestif:
min-complexity: 4

revive:
rules:
- name: var-naming
- name: error-return
- name: error-naming
- name: if-return
- name: increment-decrement
- name: var-declaration
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unreachable-code
- name: redefines-builtin-id

gocritic:
enabled-tags:
- diagnostic
- style
- performance

disabled-checks:
- commentFormatting
- whyNoLint
- unnamedResult
- commentedOutCode
- octalLiteral
- paramTypeCombine

settings:
hugeParam:
sizeThreshold: 256

exclusions:
rules:
# Enum String() methods: the string literal IS the constant name, not a
# candidate for extraction. Standard Go stringer pattern (false positive).
- linters: [goconst]
source: 'return "'

# Test files - allow more flexibility
- path: _test\.go
linters:
- gocyclo
- cyclop
- funlen
- maintidx
- errcheck
- gosec
- goconst
- dogsled
- dupl
- gocognit

# Example code
- path: examples?/.*\.go
linters:
- errcheck
- errorlint
- funlen
- gocyclo
- cyclop
- gocognit
- revive
- gosec
- gocritic

formatters:
enable:
- gofmt
- goimports

issues:
max-issues-per-linter: 0
max-same-issues: 0
new: false

output:
sort-order:
- file
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0] — 2026-05-17

### Added

- **Wire protocol v1** (`internal/protocol/`) — 64-byte fixed header, 128-byte handshake messages, message types, encode/decode with zero allocations (100% coverage)
- **Codec package** (`internal/codec/`) — Raw pass-through + LZ4 block compression via `pierrec/lz4/v4` (97% coverage, 2.9 GB/s encode, 99.6% compression on GUI pixels)
- **Connection manager** (`internal/conn/`) — module registry with monotonic ID allocation, lifecycle state machine, hot-plug callbacks (98.9% coverage)
- **Flow controller** (`internal/flow/`) — pull-based frame pacing (Wayland frame callback pattern), adaptive rate reduction after missed frames (100% coverage)
- **Unix socket transport** (`internal/transport/socket/`) — framed Conn, Listener, Dialer for Unix domain sockets (95.1% coverage, 4.3 GB/s, 45μs latency)
- **Public API** — `compose.Listen()`, `compose.Dial()`, `Frame` type, functional options (`WithMaxModules`, `WithCompression`, `WithName`, `WithFrameSize`, `WithFPS`)
- **CI/CD** — GitHub Actions (build/test/lint on Ubuntu/macOS/Windows), Codecov, golangci-lint v2
Loading
Loading