diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..fb368ba --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,183 @@ +name: CI/CD Pipeline + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main ] + +jobs: + test: + name: 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.24.2' + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Download dependencies + run: go mod download + + - name: Verify dependencies + run: go mod verify + + - name: Run tests + run: go test -v -race -coverprofile=coverage.out ./... + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + file: ./coverage.out + flags: unittests + name: codecov-umbrella + + build: + name: Build + runs-on: ubuntu-latest + needs: test + + strategy: + matrix: + goos: [linux, windows, darwin] + goarch: [amd64, arm64] + exclude: + - goos: windows + goarch: arm64 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24.2' + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Download dependencies + run: go mod download + + - name: Build binaries + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + run: | + mkdir -p bin/${{ matrix.goos }}-${{ matrix.goarch }} + + # Build CLI + go build -ldflags="-s -w" -o bin/${{ matrix.goos }}-${{ matrix.goarch }}/onx${{ matrix.goos == 'windows' && '.exe' || '' }} ./cmd/onx + + # Build daemon + go build -ldflags="-s -w" -o bin/${{ matrix.goos }}-${{ matrix.goarch }}/onxd${{ matrix.goos == 'windows' && '.exe' || '' }} ./cmd/onxd + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: onyx-${{ matrix.goos }}-${{ matrix.goarch }} + path: bin/${{ matrix.goos }}-${{ matrix.goarch }}/ + + security: + name: Security Scan + 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.24.2' + + - name: Run Gosec Security Scanner + uses: securecodewarrior/github-action-gosec@master + with: + args: './...' + + - name: Run SAST with Gosec + run: | + go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest + gosec -fmt sarif -out gosec.sarif ./... + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: gosec.sarif + + 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.24.2' + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: latest + args: --timeout=5m + + release: + name: Release + runs-on: ubuntu-latest + needs: [test, build, security, lint] + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts/ + + - name: Create release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v${{ github.run_number }} + release_name: Release v${{ github.run_number }} + draft: false + prerelease: false + + - name: Upload release assets + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: artifacts/ + asset_name: onyx-binaries.zip + asset_content_type: application/zip \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..c7b3164 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,102 @@ +run: + timeout: 5m + modules-download-mode: readonly + +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0.8 + gocyclo: + min-complexity: 15 + maligned: + suggest-new: true + dupl: + threshold: 100 + goconst: + min-len: 2 + min-occurrences: 2 + misspell: + locale: US + lll: + line-length: 140 + goimports: + local-prefixes: git.dws.rip/DWS/onyx + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + +linters: + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - exportloopref + - exhaustive + - gochecknoinits + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - golint + - gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - interfacer + - lll + - misspell + - nakedret + - noctx + - nolintlint + - rowserrcheck + - scopelint + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + +issues: + exclude-rules: + - path: _test\.go + linters: + - gomnd + - funlen + - goconst + - path: cmd/ + linters: + - gochecknoinits + exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 0 + +severity: + default-severity: error + case-sensitive: false \ No newline at end of file diff --git a/Makefile b/Makefile index 1fdbee2..88cd99f 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,103 @@ # Makefile for Onyx -.PHONY: build test clean install +.PHONY: build test clean install lint security ci + +# Default target +all: clean lint test build build: - go build -o bin/onx ./cmd/onx - go build -o bin/onxd ./cmd/onxd + @echo "Building Onyx CLI and daemon..." + @mkdir -p bin + go build -ldflags="-s -w" -o bin/onx ./cmd/onx + go build -ldflags="-s -w" -o bin/onxd ./cmd/onxd + @echo "Build complete: bin/onx, bin/onxd" test: - go test -v ./... + @echo "Running tests..." + go test -v -race -coverprofile=coverage.out ./... + @echo "Test coverage generated: coverage.out" + +coverage: test + @echo "Coverage report:" + go tool cover -html=coverage.out -o coverage.html + @echo "Coverage report generated: coverage.html" + +lint: + @echo "Running linter..." + golangci-lint run + +security: + @echo "Running security scan..." + @which gosec > /dev/null || (echo "Installing gosec..." && go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest) + gosec ./... + +ci: lint security test build + @echo "CI pipeline completed successfully" install: go install ./cmd/onx go install ./cmd/onxd clean: - rm -rf bin/ + rm -rf bin/ coverage.out coverage.html + +# Development targets +dev-setup: + @echo "Setting up development environment..." + go mod download + go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest + @echo "Development tools installed" + +fmt: + @echo "Formatting code..." + go fmt ./... + goimports -w . + +mod-tidy: + @echo "Tidying modules..." + go mod tidy + +deps-update: + @echo "Updating dependencies..." + go get -u ./... + go mod tidy + +# Cross-platform builds +build-all: + @echo "Building for all platforms..." + @mkdir -p bin + + # Linux + GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/onx-linux-amd64 ./cmd/onx + GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o bin/onxd-linux-amd64 ./cmd/onxd + GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o bin/onx-linux-arm64 ./cmd/onx + GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o bin/onxd-linux-arm64 ./cmd/onxd + + # macOS + GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o bin/onx-darwin-amd64 ./cmd/onx + GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o bin/onxd-darwin-amd64 ./cmd/onxd + GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o bin/onx-darwin-arm64 ./cmd/onx + GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o bin/onxd-darwin-arm64 ./cmd/onxd + + # Windows + GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o bin/onx-windows-amd64.exe ./cmd/onx + GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o bin/onxd-windows-amd64.exe ./cmd/onxd + + @echo "Cross-platform builds completed" + +help: + @echo "Available targets:" + @echo " all - Clean, lint, test, and build" + @echo " build - Build CLI and daemon for current platform" + @echo " build-all - Cross-platform builds" + @echo " test - Run tests with coverage" + @echo " coverage - Generate HTML coverage report" + @echo " lint - Run code linting" + @echo " security - Run security scanning" + @echo " ci - Run full CI pipeline" + @echo " install - Install to PATH" + @echo " clean - Clean build artifacts" + @echo " fmt - Format code" + @echo " mod-tidy - Tidy Go modules" + @echo " dev-setup - Install development tools" + @echo " help - Show this help message" diff --git a/README.md b/README.md new file mode 100644 index 0000000..28a0248 --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# Onyx + +A next-generation version control system designed as a superior user experience layer on top of Git. + +## Overview + +Onyx provides transparent versioning, workstreams for stacked-diff management, and an action log for universal undo functionality. The project is written in Go and uses the go-git library for Git interaction. + +## Features + +- **100% Git Data Model Compatibility**: Uses standard .git directory for shared truth +- **Transparent Versioning**: Background daemon creates continuous snapshots +- **Workstreams**: Stacked-diff workflow management +- **Action Log**: Transactional undo/redo capability +- **Hybrid Storage**: .git for Git objects, .onx for Onyx-specific metadata + +## Quick Start + +### Prerequisites + +- Go 1.24.2 or later +- Git 2.30.0 or later + +### Installation + +```bash +# Clone the repository +git clone https://git.dws.rip/DWS/onyx.git +cd onyx + +# Install dependencies +go mod tidy + +# Build the CLI and daemon +make build + +# Install to PATH +make install +``` + +### Usage + +```bash +# Initialize repository +onx init + +# Create workstream +onx new feature-branch + +# Save work +onx save -m "Add new feature" + +# List workstreams +onx list + +# Switch workstreams +onx switch main + +# Sync with remote +onx sync + +# Push workstream +onx push + +# Undo last operation +onx undo +``` + +## Development + +### Building + +```bash +# Build the CLI and daemon +go build -o bin/onx ./cmd/onx +go build -o bin/onxd ./cmd/onxd + +# Install to PATH +go install ./cmd/onx +go install ./cmd/onxd +``` + +### Testing + +```bash +# Run all tests +go test -v ./... + +# Run tests with coverage +go test -cover ./... + +# Run specific test package +go test -v ./internal/core +``` + +### Linting and Code Quality + +The project uses several tools to maintain code quality: + +```bash +# Run linter +golangci-lint run + +# Run security scanner +gosec ./... + +# Run tests with race detection +go test -race ./... +``` + +## CI/CD + +This project uses Gitea Actions for continuous integration and deployment. The workflow includes: + +### CI Pipeline + +- **Test**: Runs unit tests with race detection and coverage reporting +- **Build**: Cross-compiles binaries for multiple platforms (Linux, Windows, macOS) +- **Security**: Runs security scans using Gosec +- **Lint**: Performs comprehensive code linting with golangci-lint +- **Release**: Creates releases and uploads artifacts for main branch builds + +### Supported Platforms + +- Linux (amd64, arm64) +- Windows (amd64) +- macOS (amd64, arm64) + +### Workflow Triggers + +- Push to `main` or `develop` branches +- Pull requests to `main` branch + +## Architecture + +### Project Structure + +``` +onyx/ +├── cmd/ +│ ├── onx/ # CLI entry point +│ └── onxd/ # Daemon entry point +├── internal/ +│ ├── core/ # Core abstractions +│ ├── git/ # Git interaction layer +│ ├── models/ # Data models +│ ├── storage/ # .onx directory management +│ ├── commands/ # CLI command implementations +│ ├── daemon/ # Daemon implementation +│ └── utils/ # Utilities +├── pkg/ # Public APIs +├── test/ # Integration tests +└── docs/ # Documentation +``` + +### Core Components + +- **Repository**: Central object encapsulating access to both Git repository and Onyx metadata +- **Action Log**: Append-only binary log storing state before/after each operation +- **Workstreams**: Manages stacked-diff workflows through .onx/workstreams.json +- **Daemon**: Background process for continuous snapshot creation + +## Contributing + +1. Fork the repository +2. Create a feature branch (`onx new feature-name`) +3. Make your changes +4. Run tests and linting (`make test lint`) +5. Commit your changes (`onx save -m "Add feature"`) +6. Push to your fork (`onx push`) +7. Create a pull request + +## License + +[License information to be added] + +## Acknowledgments + +- [go-git](https://github.com/go-git/go-git) - Git implementation in pure Go +- [cobra](https://github.com/spf13/cobra) - CLI framework +- [fsnotify](https://github.com/fsnotify/fsnotify) - Filesystem monitoring \ No newline at end of file