Building from Source
Prerequisites
System Requirements
| Component | Version | Purpose |
|---|---|---|
| Go | 1.24.2+ | Build and run source |
| Git | 2.30+ | Clone repository |
| Make | 3.81+ | Build automation (optional) |
| MongoDB | 4.4+ | Database |
System Packages
flow8 requires document processing libraries for full functionality:
macOS (Homebrew):
brew install imagemagick ghostscript tesseract libreofficeUbuntu/Debian:
sudo apt-get updatesudo apt-get install -y \ imagemagick \ ghostscript \ tesseract-ocr \ libreoffice \ liboffice-java-common \ openssl \ pkg-configCentOS/RHEL:
sudo yum install -y \ ImageMagick \ ghostscript \ tesseract \ libreoffice \ libreoffice-headless \ openssl-devel \ pkgconfigmacOS Silicon (M1/M2):
Ensure Tesseract is installed for ARM64:
# Using Rosetta for x86_64 dependenciesarch -x86_64 brew install tesseractGo Setup
Install Go 1.24.2
macOS:
brew install go@1.24brew link go@1.24go version # Should print go version go1.24.2Linux (Ubuntu):
wget https://go.dev/dl/go1.24.2.linux-amd64.tar.gzsudo rm -rf /usr/local/gosudo tar -C /usr/local -xzf go1.24.2.linux-amd64.tar.gzexport PATH=$PATH:/usr/local/go/bingo versionDocker (if using container):
FROM golang:1.24.2-alpineRUN apk add --no-cache git makeWORKDIR /appGo Environment Variables
# Workspace mode (Go 1.18+)export GOWORK=off # If using workspaces
# For private Go modulesexport GOPRIVATE=github.com/osbits/*export GONOSUMDB=github.com/osbits/*
# Build optimizationexport CGO_ENABLED=1 # Required for SQLite/cryptoexport GOOS=linux # Target OSexport GOARCH=amd64 # Target architecture (or arm64 for Apple Silicon)Private Module Access
flow8 uses private Go modules from github.com/osbits/. You must configure Git authentication:
Using SSH Keys
# Generate SSH key (if needed)ssh-keygen -t ed25519 -f ~/.ssh/github_flow8 -C "your_email@example.com"
# Add to SSH agentssh-add ~/.ssh/github_flow8
# Configure Gitgit config --global user.email "you@example.com"git config --global user.name "Your Name"
# Test SSH accessssh -T git@github.comUsing Personal Access Tokens
# Create PAT in GitHub settings (Settings β Developer settings β Personal access tokens)# Scopes: repo, read:packages
# Configure Git credentialsgit config --global credential.helper storegit config --global credential.useHttpPath true
# For go get, configure .netrccat >> ~/.netrc << EOFmachine github.comlogin your-github-usernamepassword ghp_your_personal_access_tokenEOFchmod 600 ~/.netrcSSH Config
Host github.com HostName github.com User git IdentityFile ~/.ssh/github_flow8 AddKeysToAgent yes IdentitiesOnly yesBuilding from Source
Clone Repository
git clone git@github.com:osbits/flow8.gitcd flow8git checkout develop # Main development branchDownload Dependencies
go mod downloadgo mod verify # Ensure checksums matchRun Server
Development (with hot reload):
# Simple rungo run server.go
# With Delve debuggerdlv debug -l localhost:2345 -- server.go
# With live reload (requires entr or similar)find . -name '*.go' | entr go run server.goCheck health:
curl http://localhost:4454/healthBuild Binary
Development build:
go build -o flow8 server.go
# Run binary./flow8Production build (optimized):
go build \ -ldflags="-s -w -X main.Version=1.0.0 -X main.BuildTime=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \ -tags=netgo \ -o flow8-release \ server.go
# Strip binarystrip flow8-release
# Check sizels -lh flow8-releaseCross-compile for Linux (from macOS):
GOOS=linux GOARCH=amd64 go build -o flow8-linux server.goConfiguration
Environment Setup
# Copy environment templatecp .env.example .env
# Edit with your valuesexport MONGODB_URI=mongodb://localhost:27017/flow8export ENCRYPTION_KEY=$(openssl rand -hex 128)export ENCRYPTION_KEY_SALT=$(openssl rand -hex 32)export SERVER_PORT=4454
# Load into shellset -asource .envset +aConfiguration File
# Create config directorymkdir -p config
# Create config.ymlcat > config/config.yml << 'EOF'server: port: 4454 max_request_size_mb: 100
mongodb: uri: ${MONGODB_URI} database: flow8 max_pool_size: 100
encryption: key_algorithm: argon2id
session: ttl_hours: 1 cookie_secure: false # OK for development cookie_http_only: trueEOFTesting
Run All Tests
go test ./...
# With verbose outputgo test -v ./...
# With coveragego test -cover ./...
# Generate coverage HTMLgo test -coverprofile=coverage.out ./...go tool cover -html=coverage.out -o coverage.htmlRun Specific Package Tests
# Test service packagego test ./pkg/service/...
# Test with regex filtergo test -run TestFlow ./...
# Test with benchmarkgo test -bench=. -benchmem ./pkg/plugins/layers/v2/...Run Single Test
go test -run TestIteratorModule -v ./pkg/plugins/layers/v2/
# With timeoutgo test -timeout 30s -run TestLayerService ./pkg/service/...Test with Integration Test Fixtures
# Tests use recorded fixtures (no external API calls)go test -v ./pkg/service/flow_test_service.go
# Regenerate fixtures (requires credentials)UPDATE_FIXTURES=true go test ./pkg/service/...Development Workflow
Project Structure
flow8/βββ server.go # Entry pointβββ go.mod # Module definitionβββ go.sum # Dependency checksumsβββ .env.example # Environment templateβββ config/β βββ config.yml # YAML configurationβββ pkg/β βββ auth/ # Authenticationβ βββ cache/ # In-memory cachingβ βββ service/ # Business logicβ βββ http/ # HTTP controllersβ βββ model/ # MongoDB modelsβ βββ plugin/ # Plugin systemβ βββ plugins/layers/v2/ # 135+ modulesβ βββ ... (other packages)βββ storage/ # Runtime data (gitignored)β βββ db/β βββ data/β βββ logs/β βββ tmp/βββ docs/ # API documentationAdding a New Module
Create file pkg/plugins/layers/v2/module_mymodule.go:
package v2
import ( "github.com/osbits/gorgany")
type MyModule struct { *PluginModule}
func NewModuleMymodule(pm *PluginModule) *MyModule { return &MyModule{PluginModule: pm}}
func (m *MyModule) Execute(params Params) Response { // Implementation return Response{ State: "DONE", Output: map[string]interface{}{ "result": "success", }, }}Register automatically via reflection discovery.
Code Style
Follow Go conventions:
# Format codego fmt ./...
# Lint with golangci-lintgolangci-lint run ./...
# Vet for common mistakesgo vet ./...
# Run tests before commitgo test ./...Install golangci-lint:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/binGit Workflow
# Create feature branchgit checkout -b feature/my-feature
# Make changes# ... edit code, run tests ...go test ./...
# Commitgit add .git commit -m "feat: describe the feature"
# Pushgit push origin feature/my-feature
# Create pull request on GitHubModule Catalog Generation
Generate CSV catalog of all 135+ modules:
go run cmd/modulescsv/main.go > modules.csv
# Output CSV with columns:# - Name# - Description# - Category# - Inputs# - Outputs# - RequiredDependency Management
Update Dependencies
# Check for available updatesgo list -u -m all
# Update specific modulego get -u github.com/osbits/gorgany@latest
# Update all indirect dependenciesgo get -u ./...
# Tidy unused dependenciesgo mod tidy
# Verify integritygo mod verifyPrivate Module Issues
If you get βno go-import meta tagβ error:
go get github.com/osbits/gorganygo: github.com/osbits/gorgany@v0.0.0: reading github.com/osbits/gorgany/go.mod at master: no go-import meta tags (404)Solution:
# Ensure SSH key is added to SSH agentssh-add ~/.ssh/github_flow8
# Test SSH accessssh -T git@github.com
# Re-run go getgo get github.com/osbits/gorganyDebugging
Delve Debugger
# Installgo install github.com/go-delve/delve/cmd/dlv@latest
# Debug from sourcedlv debug -l localhost:2345 -- server.go
# Connect from IDE (VS Code, GoLand, etc.)# Port: 2345IDE Setup
VS Code (.vscode/launch.json):
{ "version": "0.2.0", "configurations": [ { "name": "Connect to Delve", "type": "go", "mode": "remote", "remotePath": "/app", "port": 2345, "host": "127.0.0.1", "showLog": true } ]}GoLand: Run β Edit Configurations β Go Remote
Logging & Debugging
Enable debug logging:
LOG_LEVEL=debug go run server.go
# Output includes:# - HTTP request/response details# - MongoDB query traces# - Module execution stepsProduction Build
Build Checklist
# Run all testsgo test ./...
# Check for vet issuesgo vet ./...
# Run lintergolangci-lint run ./pkg/...
# Check test coveragego test -cover ./... | grep coverage
# Update versionexport VERSION=1.0.0
# Build binarygo build \ -ldflags="-s -w -X main.Version=$VERSION" \ -o flow8-$VERSION \ server.go
# Create checksumssha256sum flow8-$VERSION > flow8-$VERSION.sha256
# Sign binary (optional)gpg --detach-sign flow8-$VERSIONDocker Build
# Build imagedocker build -t flow8core:latest .
# Test imagedocker run --rm -p 4454:4454 flow8core:latest
# Tag for registrydocker tag flow8core:latest ghcr.io/osbits/flow8core:latest
# Push to registrydocker push ghcr.io/osbits/flow8core:latestTroubleshooting
Module Not Found
no required module providing package github.com/osbits/gorganySolution:
# Update go.sumgo mod tidygo mod downloadCGO Compilation Error
gcc: command not foundSolution:
# Disable CGO (not recommended, may break SQLite)CGO_ENABLED=0 go build server.go
# Or install build tools# Ubuntu: sudo apt-get install build-essential# macOS: xcode-select --installMongoDB Connection Refused
connect: connection refusedSolution:
# Start MongoDBmongod --dbpath /data/db &
# Or use Dockerdocker run -d -p 27017:27017 mongo:6.0Out of Memory During Build
# Limit parallel buildsgo build -p 1 server.go
# Or increase swap