14 KiB
Kopia Copilot Instructions
When reviewing code, focus on:
Security Critical Issues
- Check for hardcoded secrets, API keys, or credentials
- Verify proper input validation and sanitization
- Review authentication and authorization logic
Code Quality Essentials
- Functions should be focused and appropriately sized
- Use clear, descriptive naming conventions
- Ensure proper error handling throughout
Performance Issues
- Spot inefficient loops and algorithmic issues
- Check for memory leaks and resource cleanup
- Review caching opportunities for expensive operations
Review Style
- Be specific and actionable in feedback
- Explain the rationale behind recommendations
- Acknowledge good patterns when you see them
- Ask clarifying questions when code intent is unclear
Review Test Coverage
- Ensure there are tests that cover and exercise the new or changed functionality
Always prioritize security vulnerabilities and performance issues that could impact users.
Always suggest changes to improve readability.
Repository Overview
Kopia is a fast and secure open-source backup/restore tool written in Go that creates encrypted snapshots and saves them to remote storage. The repository is approximately 15MB with ~1,000 Go files.
Key Technologies:
- Backend: Go (primary language)
- Build System: GNU Make with cross-platform support (Windows/Linux/macOS/ARM)
- UI: React-based HTML UI (embedded via go:embed, source at github.com/kopia/htmlui)
- Desktop App: Electron-based KopiaUI wrapper
- Website: Hugo static site generator
Build Commands
Setup (Required Before Building)
make -j4 ci-setup
Time: ~30-60 seconds What it does: Downloads Go modules, installs build tools (gotestsum, golangci-lint, hugo, node), and installs npm dependencies for the app. ALWAYS run this after cloning or when build tools are missing.
Linting
Run linter:
make lint
Time: ~3-4 minutes
Linter: golangci-lint with timeout of 1200s
Config: .golangci.yml (extensive configuration with 40+ enabled linters)
Auto-fix linting issues:
make lint-fix
Check code locks:
make check-locks
Note: Not available on linux/arm64 or linux/arm.
Check JavaScript/TypeScript formatting (in app directory):
make check-prettier
Important: Linting is NOT run on linux/arm64 or linux/arm platforms to avoid issues.
Building Kopia CLI
Build without UI (faster for testing):
make install-noui
Output: ~/go/bin/kopia
Time: ~5-10 seconds
Use this for: Testing CLI changes that don't involve the UI.
Race detector build:
make install-race
Use this for: Debugging race conditions.
Full build with embedded HTML UI:
make install
Output: ~/go/bin/kopia
Time: ~10-20 seconds
Note: Embeds HTML UI from github.com/kopia/htmluibuild dependency.
Building KopiaUI Desktop App
Prerequisites: Must build kopia CLI first (creates embedded binary).
make kopia-ui
Output: dist/kopia-ui/ directory with platform-specific installers
Time: ~2-5 minutes
Note: Only works on amd64 architectures. On Linux, may require xvfb for headless testing.
Testing
Unit Tests (Standard)
make test
Time: ~2-4 minutes Runs: All unit tests with gotestsum, excludes TestIndexBlobManagerStress Timeout: 1200s (20 minutes) per test Format: pkgname-and-test-fails
Unit Tests with Coverage
make test-with-coverage
Output: coverage.txt
Time: ~3-5 minutes
Note: Used by Code Coverage workflow. Sets KOPIA_COVERAGE_TEST=1
Index Blob Tests (Separate)
make test-index-blob-v0
Runs: TestIndexBlobManagerStress (excluded from standard tests due to duration)
Integration Tests
make build-integration-test-binary # Build test binary first
make integration-tests
Time: ~5-10 minutes Requires: KOPIA_INTEGRATION_EXE environment variable
CI Test Suites
make ci-tests # Runs: vet + test
make ci-integration-tests # Runs: robustness-tool-tests + socket-activation-tests
Provider Tests (Cloud Storage)
make provider-tests PROVIDER_TEST_TARGET=...
Time: 15 minutes timeout Requires: KOPIA_PROVIDER_TEST=true, credentials for storage backend, rclone binary Note: Tests various cloud storage providers (S3, Azure, GCS, etc.)
Other Test Types
make compat-tests- Compatibility tests with older Kopia versionsmake endurance-tests- Long-running endurance tests (1 hour timeout)make robustness-tests- Robustness testing with FIOmake stress-test- Stress tests (1 hour timeout)make htmlui-e2e-test- HTML UI end-to-end tests (10 minutes timeout)
Race Detector Tests:
make test UNIT_TEST_RACE_FLAGS=-race UNIT_TESTS_TIMEOUT=1200s
Common Issues & Workarounds
Build Issues
-
Missing build tools error: Always run
make -j4 ci-setupfirst after cloning. -
Go version mismatch: Kopia requires the Go toolchain with the version specified in go.mod. The
go-version-fileis used in GitHub Actions. -
Platform-specific builds:
- macOS: Creates universal binaries (AMD64 + ARM64) with
lipo - Windows: Requires chocolatey packages: make, zip, unzip, curl
- Linux ARM: Uses goreleaser for multi-arch builds on AMD64 host
- macOS: Creates universal binaries (AMD64 + ARM64) with
-
KopiaUI build failures on ARM: KopiaUI (Electron app) only builds on amd64. The build is skipped on ARM architectures.
-
Linting on ARM: Linting and check-locks are skipped on linux/arm64 and linux/arm due to tool compatibility.
Test Issues
-
Test timeouts: Default unit test timeout is 1200s (20 minutes). For race detector tests, explicitly set
UNIT_TESTS_TIMEOUT=1200s. -
Parallel execution: Tests use
-parallelflag (8 on amd64, 2 on ARM). Adjust withPARALLELvariable if needed. -
Integration test binary: Must build integration test binary explicitly with
make build-integration-test-binarybefore running integration tests. -
Provider tests require environment: Provider tests need KOPIA_PROVIDER_TEST=true and rclone binary available.
Environment Variables
Important variables for CI/tests:
UNIX_SHELL_ON_WINDOWS=true- Required for Windows buildsKOPIA_COVERAGE_TEST=1- Enable coverage testingKOPIA_INTEGRATION_EXE- Path to integration test binaryTESTING_ACTION_EXE- Path to testing action binaryKOPIA_PROVIDER_TEST=true- Enable provider testsRCLONE_EXE- Path to rclone binary for provider tests
Project Structure
Root Directory Files
main.go- Entry point, uses kingpin for CLI parsingMakefile- Primary build system (GNU Make)go.mod/go.sum- Go module dependencies.golangci.yml- Linter configuration (extensive rules).gitignore- Excludes dist/, .tools/, node_modules/, coverage filesBUILD.md- Detailed build architecture documentationREADME.md- General project information
Source Directories
cli/ - CLI command implementations (~200 command files)
- Each command is in a separate file (e.g.,
command_snapshot_create.go) - Uses kingpin v2 for command-line parsing
- Main entry via
app.go
repo/ - Repository management and storage backends
repo/blob/- Storage provider implementations (s3, azure, gcs, filesystem, etc.)repo/content/- Content-addressable storage layerrepo/format/- Repository format and versioningrepo/manifest/- Manifest managementrepo/object/- Object storage layer
fs/ - Filesystem abstraction layer
fs/localfs/- Local filesystem implementation- Supports snapshots, restore, and filesystem walking
snapshot/ - Snapshot creation and management
snapshot/snapshotmaintenance/- Snapshot GC and maintenancesnapshot/upload/- Upload logic and parallelization
internal/ - Internal packages (74 subdirectories)
- Utilities and shared code not for external use
- Examples: cache, crypto, compression, auth, server, etc.
tests/ - Integration and end-to-end tests
tests/end_to_end_test/- E2E test scenariostests/robustness/- Robustness testing frameworktests/tools/- Test utilities and helpers
tools/ - Build and release tools
tools/gettool/- Tool downloader (downloads versioned binaries)- Various publishing scripts (apt, rpm, docker, homebrew)
tools/.tools/- Downloaded build tools (gitignored)
app/ - Electron-based desktop application (KopiaUI)
- Node.js project with package.json
- Uses Electron Builder for packaging
- Resources in
app/resources/andapp/public/ - Embeds kopia server binary from
dist/kopia_*/kopia
site/ - Hugo-based website (kopia.io)
- Build with
make -C site buildormake website - Auto-generates CLI docs to
site/content/docs/Reference/Command-Line/ - Development server:
make -C site server(http://localhost:1313)
Configuration Files
.golangci.yml- Linter config with 40+ enabled linters, custom rules.codecov.yml- Code coverage reporting config.goreleaser.yml- Release automation config.github/workflows/*.yml- GitHub Actions workflows (19 workflow files)
GitHub Actions Workflows
Pull Request Checks (Always Run)
-
make.yml (Build) - Builds on Windows/Linux/macOS/ARM
- Runs:
make ci-setup→make ci-build - Timeout: 40 minutes
- Creates artifacts: binaries, installers, packages
- Runs:
-
tests.yml - Unit and integration tests on all platforms
- Runs:
make ci-setup→make test-index-blob-v0→make ci-tests→make ci-integration-tests - Uploads logs to artifacts
- Runs:
-
lint.yml - Linting on ubuntu-latest and macos-latest
- Runs:
make lint→make check-locks→make check-prettier - Includes govulncheck for vulnerability scanning
- Runs:
-
code-coverage.yml - Code coverage on ubuntu-latest
- Runs:
make test-with-coverage - Uploads to Codecov
- Runs:
-
race-detector.yml - Race condition detection
- Runs:
make test UNIT_TEST_RACE_FLAGS=-race UNIT_TESTS_TIMEOUT=1200s
- Runs:
Additional Workflows
providers-core.yml/providers-extra.yml- Cloud storage provider testscompat-test.yml- Compatibility with older Kopia versionsstress-test.yml- Stress testingendurance-test.yml- Long-running endurance testslicense-check.yml- License compliance checkingdependency-review.yml- Dependency security reviewcheck-pr-title.yml- PR title format validation
Workflow Tips
- Build artifacts are uploaded and can be downloaded from workflow runs
- Logs are uploaded to
.logs/**/*.logon test failures - Concurrency: All workflows use
cancel-in-progress: truefor the same ref - Scheduling: Some workflows run weekly (Mondays at 8AM)
Development Workflow
Making Code Changes
-
Setup environment:
make -j4 ci-setup -
Make your changes to Go files
-
Build and test iteratively:
make install-noui # Fast build without UI ~/go/bin/kopia --help # Test your changes -
Lint your changes:
make lint -
Run relevant tests:
make test # Unit tests -
For HTML UI changes:
- UI source is in separate repo: github.com/kopia/htmlui
- Pre-built UI imported from: github.com/kopia/htmluibuild
- To test local UI changes:
make install-with-local-htmlui-changes(requires 3 repos checked out side-by-side)
Pre-Commit Checklist
make lintpasses (3-4 minutes)make testpasses (2-4 minutes)- Changes are formatted (gofumpt, gci enabled in linter)
- New packages: License check with
make license-check
Code Style
- Uses golangci-lint with formatters: gci, gofumpt
- Imports organized: standard, default, localmodule
- No
time.Now()outside clock/timetrack packages - useclock.Now() - No
time.Since()- usetimetrack.Timer.Elapsed() - No
filepath.IsAbs()- useospath.IsAbs()for Windows UNC support - Tests use the
stretchr/testifypackages
Key Dependencies
Go modules (from go.mod):
- Cloud providers: Azure SDK, AWS SDK (via minio), Google Cloud Storage
- CLI: alecthomas/kingpin/v2
- Compression: klauspost/compress, klauspost/pgzip
- Testing: stretchr/testify, chromedp (for E2E)
- Observability: Prometheus client, OpenTelemetry
- UI: github.com/kopia/htmluibuild (pre-built React app)
Node.js dependencies (app/package.json):
- electron-builder - Desktop app packaging
- electron-updater - Auto-updates
- React (via htmluibuild) - UI framework
Important Notes
-
Do not modify go.mod/go.sum manually - Use
go getto update dependencies. CI runsgit checkout go.mod go.sumafter ci-setup to revert local changes from tool downloads. -
Build artifacts in dist/ - Gitignored. Contains platform-specific binaries and installers after
make ci-buildormake goreleaser. -
Tools directory -
tools/.tools/is gitignored and populated bymake ci-setup. Contains downloaded versions of gotestsum, linter, node, hugo, etc. -
HTML UI is separate - The HTML UI is maintained in github.com/kopia/htmlui and imported as a pre-built module. Don't try to find UI source in this repo.
-
Platform differences:
- macOS: Creates universal binaries, requires Xcode command line tools
- Windows: Requires chocolatey tools, uses PowerShell for some commands
- Linux ARM: Builds via goreleaser on AMD64 host, creates ARM packages
-
Parallelism: Makefiles use
-j4for parallel execution. Tests use-parallel 8on amd64,-parallel 2on ARM. -
Test binary paths:
- Integration:
dist/testing_$(GOOS)_$(GOARCH)/kopia.exe - UI embedded:
dist/kopia_$(GOOS)_$(GOARCH)/kopia(or universal binary on macOS)
- Integration:
-
Timeout configuration:
- Linter: 1200s (20 minutes)
- Unit tests: 1200s (20 minutes)
- Integration tests: 300s (5 minutes)
- Provider tests: 15 minutes
- Stress/endurance: 3600s (1 hour)
-
Required tools installed by ci-setup:
- gotestsum - Test runner with better output
- golangci-lint - Linter
- node - JavaScript runtime for app builds
- hugo - Static site generator for website
-
Trust these instructions - These instructions have been validated by running all commands. Only search for additional information if something fails or if these instructions are incomplete or incorrect.