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
162 changes: 162 additions & 0 deletions .github/workflows/main-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
name: Main Branch Build

on:
push:
branches: [ main ]

env:
GO_VERSION: '1.23'

permissions:
contents: write # Needed to push VERSION file changes
actions: read

jobs:
build-and-version:
name: Build Cross-Platform Binaries
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

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

- name: Install dependencies
run: go mod download

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

- name: Read current version and increment
id: version
run: |
CURRENT_VERSION=$(cat VERSION)
echo "current=$CURRENT_VERSION" >> $GITHUB_OUTPUT

# Increment patch version for main branch builds
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
MAJOR=${VERSION_PARTS[0]}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}

NEW_PATCH=$((PATCH + 1))
NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}"

echo "new=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "$NEW_VERSION" > VERSION

echo "Version incremented from $CURRENT_VERSION to $NEW_VERSION"

- name: Commit version update
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add VERSION
if git diff --staged --quiet; then
echo "No version changes to commit"
else
git commit -m "Bump version to ${{ steps.version.outputs.new }} [skip ci]"
git push
fi
Comment on lines +58 to +68
Copy link

Copilot AI Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow will fail on the first run because it attempts to increment a version before any version bump commits exist. The git diff --staged --quiet check will always be false since VERSION is always modified in the previous step, making the conditional logic ineffective.

Copilot uses AI. Check for mistakes.

- name: Create release directory
run: mkdir -p dist

- name: Build for Linux AMD64
env:
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 1
run: |
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-linux-amd64 ./cmd/lil-rag
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-server-linux-amd64 ./cmd/lil-rag-server

- name: Build for Linux ARM64
env:
GOOS: linux
GOARCH: arm64
CGO_ENABLED: 1
CC: aarch64-linux-gnu-gcc
run: |
sudo apt-get update && sudo apt-get install -y gcc-aarch64-linux-gnu
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-linux-arm64 ./cmd/lil-rag
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-server-linux-arm64 ./cmd/lil-rag-server

- name: Build for macOS AMD64
env:
GOOS: darwin
GOARCH: amd64
CGO_ENABLED: 1
run: |
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-darwin-amd64 ./cmd/lil-rag
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-server-darwin-amd64 ./cmd/lil-rag-server

- name: Build for macOS ARM64
env:
GOOS: darwin
GOARCH: arm64
CGO_ENABLED: 1
run: |
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-darwin-arm64 ./cmd/lil-rag
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-server-darwin-arm64 ./cmd/lil-rag-server

- name: Build for Windows AMD64
env:
GOOS: windows
GOARCH: amd64
CGO_ENABLED: 1
CC: x86_64-w64-mingw32-gcc
run: |
sudo apt-get install -y gcc-mingw-w64
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-windows-amd64.exe ./cmd/lil-rag
go build -ldflags="-s -w -X main.version=${{ steps.version.outputs.new }}" -o dist/lil-rag-server-windows-amd64.exe ./cmd/lil-rag-server

- name: Create archives
run: |
# Linux AMD64
tar -czf dist/lil-rag-${{ steps.version.outputs.new }}-linux-amd64.tar.gz -C dist lil-rag-linux-amd64 lil-rag-server-linux-amd64

# Linux ARM64
tar -czf dist/lil-rag-${{ steps.version.outputs.new }}-linux-arm64.tar.gz -C dist lil-rag-linux-arm64 lil-rag-server-linux-arm64

# macOS AMD64
tar -czf dist/lil-rag-${{ steps.version.outputs.new }}-darwin-amd64.tar.gz -C dist lil-rag-darwin-amd64 lil-rag-server-darwin-amd64

# macOS ARM64
tar -czf dist/lil-rag-${{ steps.version.outputs.new }}-darwin-arm64.tar.gz -C dist lil-rag-darwin-arm64 lil-rag-server-darwin-arm64

# Windows AMD64
zip -j dist/lil-rag-${{ steps.version.outputs.new }}-windows-amd64.zip dist/lil-rag-windows-amd64.exe dist/lil-rag-server-windows-amd64.exe

- name: Generate checksums
run: |
cd dist
sha256sum *.tar.gz *.zip > checksums.txt

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: lil-rag-${{ steps.version.outputs.new }}-binaries
path: |
dist/*.tar.gz
dist/*.zip
dist/checksums.txt
retention-days: 30

- name: Display build summary
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "**Version:** ${{ steps.version.outputs.new }}" >> $GITHUB_STEP_SUMMARY
echo "**Platforms:** Linux (AMD64, ARM64), macOS (AMD64, ARM64), Windows (AMD64)" >> $GITHUB_STEP_SUMMARY
echo "**Artifacts:** $(ls -1 dist/*.tar.gz dist/*.zip | wc -l) archives created" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Files Generated:" >> $GITHUB_STEP_SUMMARY
ls -la dist/ >> $GITHUB_STEP_SUMMARY
26 changes: 21 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,27 @@ Mini-RAG follows [Semantic Versioning](https://semver.org/):

### Creating Releases

1. **Update version numbers** in relevant files
2. **Update CHANGELOG.md** with release notes
3. **Create git tag** with version number
4. **Create GitHub release** with binaries
5. **Update documentation** if needed
The project uses an automated build system for releases:

#### Automatic Builds (Main Branch)
When code is merged to the `main` branch, the CI/CD system automatically:
1. **Increments the patch version** in the `VERSION` file
2. **Builds cross-platform binaries** (Linux, macOS, Windows)
3. **Creates versioned archives** with checksums
4. **Uploads build artifacts** to GitHub Actions

#### Manual Releases (Tags)
For official releases, create a Git tag:
1. **Update CHANGELOG.md** with release notes
2. **Create git tag** with version number (e.g., `v1.0.0`)
3. **Push the tag** to trigger the release workflow
4. **Create GitHub release** with binaries from the tag workflow

#### Version Management
- Version is stored in the `VERSION` file at the repository root
- All binaries include embedded version information
- Use `--version` flag to check binary version
- Follow [Semantic Versioning](https://semver.org/) conventions

## 💡 Feature Development

Expand Down
47 changes: 39 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Lil-RAG - A simple RAG system with SQLite and Ollama

.PHONY: build test clean install fmt vet lint help dev examples deps coverage
.PHONY: build test clean install fmt vet lint help dev examples deps coverage build-cross clean-dist version

# Build binary names
BINARY_CLI=lil-rag
Expand All @@ -19,6 +19,10 @@ GOVET=$(GOCMD) vet
LDFLAGS=-ldflags="-s -w"
BUILDFLAGS=-trimpath

# Get version from VERSION file if it exists, otherwise use "dev"
VERSION=$(shell if [ -f VERSION ]; then cat VERSION; else echo "dev"; fi)
LDFLAGS_WITH_VERSION=-ldflags="-s -w -X main.version=$(VERSION)"

# Default target
help: ## Show this help message
@echo 'Lil-RAG Build System'
Expand All @@ -30,21 +34,21 @@ help: ## Show this help message
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " %-15s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

build: ## Build CLI and server binaries
@echo "Building $(BINARY_CLI) and $(BINARY_SERVER)..."
@echo "Building $(BINARY_CLI) and $(BINARY_SERVER) version $(VERSION)..."
@mkdir -p bin
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS) -o bin/$(BINARY_CLI) ./cmd/lil-rag
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS) -o bin/$(BINARY_SERVER) ./cmd/lil-rag-server
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o bin/$(BINARY_CLI) ./cmd/lil-rag
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o bin/$(BINARY_SERVER) ./cmd/lil-rag-server
@echo "Build complete!"

build-cli: ## Build only the CLI binary
@echo "Building $(BINARY_CLI)..."
@echo "Building $(BINARY_CLI) version $(VERSION)..."
@mkdir -p bin
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS) -o bin/$(BINARY_CLI) ./cmd/lil-rag
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o bin/$(BINARY_CLI) ./cmd/lil-rag

build-server: ## Build only the server binary
@echo "Building $(BINARY_SERVER)..."
@echo "Building $(BINARY_SERVER) version $(VERSION)..."
@mkdir -p bin
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS) -o bin/$(BINARY_SERVER) ./cmd/lil-rag-server
$(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o bin/$(BINARY_SERVER) ./cmd/lil-rag-server

test: ## Run tests
$(GOTEST) -v ./pkg/... ./internal/... ./cmd/...
Expand All @@ -58,6 +62,7 @@ clean: ## Clean build artifacts
$(GOCLEAN)
rm -f bin/$(BINARY_CLI) bin/$(BINARY_SERVER)
rm -f coverage.out coverage.html
rm -rf dist/

install: build ## Install binaries to $GOPATH/bin
@echo "Installing binaries to $(GOPATH)/bin..."
Expand Down Expand Up @@ -91,4 +96,30 @@ examples: build ## Build and validate example programs
all: clean deps lint test build examples ## Run all checks and build everything
@echo "All tasks completed successfully!"

build-cross: ## Build binaries for all platforms
@echo "Building cross-platform binaries version $(VERSION)..."
Copy link

Copilot AI Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cross-compilation targets assume availability of cross-compilers (aarch64-linux-gnu-gcc, x86_64-w64-mingw32-gcc) without installation steps. This will fail on systems without these cross-compilers installed, making the build-cross target unreliable for local development.

Copilot uses AI. Check for mistakes.
@mkdir -p dist
@echo "Building for Linux AMD64..."
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_CLI)-linux-amd64 ./cmd/lil-rag
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_SERVER)-linux-amd64 ./cmd/lil-rag-server
@echo "Building for Linux ARM64..."
GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_CLI)-linux-arm64 ./cmd/lil-rag
GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_SERVER)-linux-arm64 ./cmd/lil-rag-server
@echo "Building for macOS AMD64..."
GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_CLI)-darwin-amd64 ./cmd/lil-rag
GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_SERVER)-darwin-amd64 ./cmd/lil-rag-server
@echo "Building for macOS ARM64..."
GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_CLI)-darwin-arm64 ./cmd/lil-rag
GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_SERVER)-darwin-arm64 ./cmd/lil-rag-server
@echo "Building for Windows AMD64..."
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_CLI)-windows-amd64.exe ./cmd/lil-rag
GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc $(GOBUILD) $(BUILDFLAGS) $(LDFLAGS_WITH_VERSION) -o dist/$(BINARY_SERVER)-windows-amd64.exe ./cmd/lil-rag-server
@echo "Cross-platform build complete!"

clean-dist: ## Clean distribution artifacts
rm -rf dist/

version: ## Show current version
@echo "$(VERSION)"

.DEFAULT_GOAL := help
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,12 @@ func main() {
# Run tests
make test

# Build for current platform
make build

# Build for all platforms (Linux, macOS, Windows)
make build-cross

# Format code
make fmt

Expand All @@ -419,6 +425,32 @@ make clean

# Install binaries to $GOPATH/bin
make install

# Show current version
make version
```

### Version Management

The project uses semantic versioning stored in the `VERSION` file. When code is merged to the main branch, the build system automatically:

1. **Increments the patch version** (e.g., 1.0.0 → 1.0.1)
2. **Builds cross-platform binaries** for Linux, macOS, and Windows
3. **Embeds the version** into the binaries at build time
4. **Creates release archives** with checksums
5. **Updates the VERSION file** in the repository

### Cross-Platform Builds

The CI/CD system builds binaries for:
- **Linux**: AMD64, ARM64
- **macOS**: AMD64 (Intel), ARM64 (Apple Silicon)
- **Windows**: AMD64

All binaries include the version information and can be checked with:
```bash
./lil-rag --version
./lil-rag-server --version
```

## 🏗️ Architecture
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
27 changes: 18 additions & 9 deletions cmd/lil-rag-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
"lil-rag/pkg/minirag"
)

// version is set during build time via ldflags
var version = "dev"

func main() {
if err := run(); err != nil {
log.Fatal(err)
Expand All @@ -24,16 +27,22 @@ func main() {

func run() error {
var (
dbPath = flag.String("db", "", "Database path (overrides profile config)")
dataDir = flag.String("data-dir", "", "Data directory (overrides profile config)")
ollamaURL = flag.String("ollama", "", "Ollama URL (overrides profile config)")
model = flag.String("model", "", "Embedding model (overrides profile config)")
vectorSize = flag.Int("vector-size", 0, "Vector size (overrides profile config)")
host = flag.String("host", "", "Server host (overrides profile config)")
port = flag.Int("port", 0, "Server port (overrides profile config)")
dbPath = flag.String("db", "", "Database path (overrides profile config)")
dataDir = flag.String("data-dir", "", "Data directory (overrides profile config)")
ollamaURL = flag.String("ollama", "", "Ollama URL (overrides profile config)")
model = flag.String("model", "", "Embedding model (overrides profile config)")
vectorSize = flag.Int("vector-size", 0, "Vector size (overrides profile config)")
host = flag.String("host", "", "Server host (overrides profile config)")
port = flag.Int("port", 0, "Server port (overrides profile config)")
showVersion = flag.Bool("version", false, "Show version")
)
flag.Parse()

if *showVersion {
fmt.Printf("lil-rag-server version %s\n", version)
return nil
}

profileConfig, err := config.LoadProfile()
if err != nil {
return fmt.Errorf("failed to load profile config: %w", err)
Expand Down Expand Up @@ -82,7 +91,7 @@ func run() error {
}
defer rag.Close()

handler := handlers.New(rag)
handler := handlers.NewWithVersion(rag, version)
mux := http.NewServeMux()

mux.Handle("/api/index", handler.Index())
Expand All @@ -101,7 +110,7 @@ func run() error {
}

go func() {
log.Printf("Starting server on %s", addr)
log.Printf("Starting lil-rag-server version %s on %s", version, addr)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Printf("Server error: %v", err)
}
Expand Down
Loading
Loading