feat: add GitHub workflows and development tooling
- Add comprehensive CI/CD workflows for testing and releases - Include issue and pull request templates - Add GitHub labeler configuration for automated triage - Include license check and stale issue management - Add Windsurf rules for development workflow - Include database directory structure with gitkeep Provides complete GitHub automation and development tooling for streamlined contribution and project management.
This commit is contained in:
parent
c980167041
commit
e5dcb347d8
13 changed files with 855 additions and 0 deletions
49
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
49
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
name: Bug Report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
## Describe the Bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
## To Reproduce
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
## Expected Behavior
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
## Actual Behavior
|
||||
A clear and concise description of what actually happened.
|
||||
|
||||
## Environment
|
||||
- OS: [e.g. macOS 13.0, Ubuntu 22.04]
|
||||
- Go version: [e.g. 1.21.0]
|
||||
- Fetch ML version: [e.g. v1.0.0]
|
||||
- Configuration: [e.g. file-based auth, database auth]
|
||||
|
||||
## Configuration
|
||||
```yaml
|
||||
# Paste relevant configuration here
|
||||
auth:
|
||||
enabled: true
|
||||
# ...
|
||||
```
|
||||
|
||||
## Logs
|
||||
```
|
||||
# Paste relevant logs here
|
||||
2024-01-01 12:00:00 ERROR: ...
|
||||
```
|
||||
|
||||
## Additional Context
|
||||
Add any other context about the problem here.
|
||||
|
||||
## Possible Solution
|
||||
If you have ideas on how to fix this, please describe them here.
|
||||
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project
|
||||
title: "[FEATURE] "
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
## Feature Description
|
||||
A clear and concise description of what the feature is.
|
||||
|
||||
## Problem Statement
|
||||
What problem does this feature solve? What pain point does it address?
|
||||
|
||||
## Proposed Solution
|
||||
Describe the solution you'd like to see implemented.
|
||||
|
||||
## Alternative Solutions
|
||||
Describe any alternative solutions or features you've considered.
|
||||
|
||||
## Use Cases
|
||||
Describe specific use cases where this feature would be valuable.
|
||||
|
||||
## Implementation Details
|
||||
If you have technical ideas on how this should be implemented, describe them here.
|
||||
|
||||
## Mockups/UI (if applicable)
|
||||
If this involves UI changes, include mockups or screenshots.
|
||||
|
||||
## Additional Context
|
||||
Add any other context, screenshots, or examples about the feature request here.
|
||||
|
||||
## Questions
|
||||
Do you have any questions about how this feature might work?
|
||||
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
## Description
|
||||
Brief description of what this PR changes.
|
||||
|
||||
## Type of Change
|
||||
- [ ] Bug fix (non-breaking change that fixes an issue)
|
||||
- [ ] New feature (non-breaking change that adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Documentation update
|
||||
|
||||
## Testing
|
||||
- [ ] Unit tests pass
|
||||
- [ ] Integration tests pass (if applicable)
|
||||
- [ ] Manual testing completed
|
||||
- [ ] Security audit passed
|
||||
|
||||
## Checklist
|
||||
- [ ] Code follows the project's style guidelines
|
||||
- [ ] Self-review of the code completed
|
||||
- [ ] Documentation updated if necessary
|
||||
- [ ] Tests added for new functionality
|
||||
- [ ] No hardcoded secrets or credentials
|
||||
- [ ] Error handling implemented appropriately
|
||||
|
||||
## Security Considerations
|
||||
- [ ] No sensitive data in logs
|
||||
- [ ] Proper input validation
|
||||
- [ ] Authentication/authorization properly implemented
|
||||
- [ ] No SQL injection vulnerabilities
|
||||
- [ ] No XSS vulnerabilities (if applicable)
|
||||
|
||||
## Screenshots (if applicable)
|
||||
Add screenshots to help explain your changes.
|
||||
|
||||
## Additional Context
|
||||
Add any other context about the pull request here.
|
||||
82
.github/labeler.yml
vendored
Normal file
82
.github/labeler.yml
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Labeler configuration for automatic PR labeling
|
||||
|
||||
# Bug reports
|
||||
bug:
|
||||
- "[BUG]"
|
||||
- "bug:"
|
||||
- "fixes #"
|
||||
- "closes #"
|
||||
|
||||
# Feature requests
|
||||
enhancement:
|
||||
- "[FEATURE]"
|
||||
- "feat:"
|
||||
- "feature:"
|
||||
- "add "
|
||||
|
||||
# Documentation
|
||||
documentation:
|
||||
- "[DOCS]"
|
||||
- "docs:"
|
||||
- "README"
|
||||
- "documentation"
|
||||
|
||||
# Security
|
||||
security:
|
||||
- "[SECURITY]"
|
||||
- "security:"
|
||||
- "auth"
|
||||
- "authentication"
|
||||
- "RBAC"
|
||||
- "permissions"
|
||||
|
||||
# Testing
|
||||
testing:
|
||||
- "[TEST]"
|
||||
- "test:"
|
||||
- "tests"
|
||||
- "unit test"
|
||||
- "integration test"
|
||||
|
||||
# CI/CD
|
||||
ci:
|
||||
- "[CI]"
|
||||
- "workflow"
|
||||
- "github actions"
|
||||
- "build"
|
||||
- "deploy"
|
||||
|
||||
# Configuration
|
||||
configuration:
|
||||
- "[CONFIG]"
|
||||
- "config"
|
||||
- "yaml"
|
||||
- "settings"
|
||||
|
||||
# Dependencies
|
||||
dependencies:
|
||||
- "[DEPS]"
|
||||
- "go.mod"
|
||||
- "dependency"
|
||||
- "update"
|
||||
|
||||
# Performance
|
||||
performance:
|
||||
- "[PERF]"
|
||||
- "performance"
|
||||
- "optimize"
|
||||
- "speed"
|
||||
|
||||
# Breaking changes
|
||||
breaking-change:
|
||||
- "[BREAKING]"
|
||||
- "breaking"
|
||||
- "deprecated"
|
||||
- "remove"
|
||||
|
||||
# TUI
|
||||
tui:
|
||||
- "[TUI]"
|
||||
- "cmd/tui"
|
||||
- "terminal ui"
|
||||
- "interface"
|
||||
21
.github/rsync_manifest.json
vendored
Normal file
21
.github/rsync_manifest.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"version": "v3.2.7",
|
||||
"base_url": "https://github.com/JMarvi3/rsync-static/releases/download",
|
||||
"platforms": {
|
||||
"linux-x86_64": {
|
||||
"target": "x86_64-linux-musl",
|
||||
"asset": "rsync-linux-x86_64",
|
||||
"sha256": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5"
|
||||
},
|
||||
"macos-x86_64": {
|
||||
"target": "x86_64-macos",
|
||||
"asset": "rsync-macos-x86_64",
|
||||
"sha256": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5"
|
||||
},
|
||||
"macos-arm64": {
|
||||
"target": "aarch64-macos",
|
||||
"asset": "rsync-macos-arm64",
|
||||
"sha256": "0019dfc4b32d63c1392aa264aed2253c1e0c2fb09216f8e2cc269bbfb8bb49b5"
|
||||
}
|
||||
}
|
||||
}
|
||||
272
.github/workflows/ci.yml
vendored
Normal file
272
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
name: CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
# Concurrency control to prevent multiple runs of the same workflow
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# Workflow permissions
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
actions: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.25.0'
|
||||
ZIG_VERSION: '0.15.2'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:7
|
||||
ports:
|
||||
- 6379:6379
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.mod') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Set up Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
with:
|
||||
version: ${{ env.ZIG_VERSION }}
|
||||
|
||||
- name: Cache Zig build
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/zig
|
||||
cli/zig-cache
|
||||
cli/zig-out
|
||||
key: ${{ runner.os }}-zig-${{ hashFiles('cli/**') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-zig-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
go mod download
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y podman redis-tools
|
||||
|
||||
- name: Verify dependencies
|
||||
run: go mod verify
|
||||
|
||||
- name: Run tests
|
||||
run: make test
|
||||
env:
|
||||
REDIS_URL: redis://localhost:6379
|
||||
|
||||
- name: Test internal/queue package
|
||||
run: go test -v -race -coverprofile=queue-coverage.out ./internal/queue/...
|
||||
env:
|
||||
REDIS_URL: redis://localhost:6379
|
||||
|
||||
- name: Run comprehensive tests
|
||||
run: make test-all
|
||||
env:
|
||||
REDIS_URL: redis://localhost:6379
|
||||
|
||||
- name: Run linters
|
||||
run: make lint
|
||||
|
||||
- name: Generate coverage report
|
||||
run: make coverage
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
file: ./coverage.out
|
||||
flags: unittests
|
||||
name: codecov-umbrella
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Set up Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
with:
|
||||
version: ${{ env.ZIG_VERSION }}
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum', '**/go.mod') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y podman
|
||||
|
||||
- name: Build binaries
|
||||
run: |
|
||||
make build
|
||||
make cli-build
|
||||
# Build Zig CLI (dev and prod)
|
||||
cd cli && zig build dev && zig build prod && cd ..
|
||||
# Note: prod builds use rsync_placeholder wrapper
|
||||
# For true embedded rsync, add static binary to cli/src/assets/rsync_release.bin
|
||||
|
||||
- name: Test binaries
|
||||
run: |
|
||||
./bin/user_manager --help
|
||||
./bin/worker --help
|
||||
./bin/tui --help
|
||||
./bin/data_manager --help
|
||||
# Test Zig CLI
|
||||
./cli/zig-out/prod/ml --help
|
||||
# Verify binary size (should be small with placeholder rsync)
|
||||
ls -lh ./cli/zig-out/prod/ml
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fetch_ml_binaries
|
||||
path: |
|
||||
bin/
|
||||
cli/zig-out/
|
||||
dist/
|
||||
retention-days: 30
|
||||
|
||||
test-scripts:
|
||||
name: Test Scripts
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y podman redis-tools bats
|
||||
|
||||
- name: Test scripts
|
||||
run: |
|
||||
# Test script functionality
|
||||
chmod +x scripts/*.sh
|
||||
|
||||
# Test quick start script (dry run)
|
||||
./scripts/quick_start.sh --help || true
|
||||
|
||||
# Test security monitor
|
||||
./scripts/security-monitor.sh help
|
||||
|
||||
# Test auto setup
|
||||
./scripts/auto_setup.sh help
|
||||
|
||||
# Test deployment scripts
|
||||
./scripts/deploy-secure.sh --help || true
|
||||
./scripts/deploy-production.sh --help || true
|
||||
|
||||
security-scan:
|
||||
name: Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
with:
|
||||
scan-type: 'fs'
|
||||
scan-ref: '.'
|
||||
format: 'sarif'
|
||||
output: 'trivy-results.sarif'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
if: always()
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
|
||||
- name: Gosec Security Scanner
|
||||
run: |
|
||||
go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest
|
||||
gosec ./...
|
||||
|
||||
docker-build:
|
||||
name: Docker Build
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test, build, test-scripts]
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ github.repository }}:latest
|
||||
ghcr.io/${{ github.repository }}:${{ github.sha }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
50
.github/workflows/docs.yml
vendored
Normal file
50
.github/workflows/docs.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
name: Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths: [ 'docs/**', 'README.md' ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths: [ 'docs/**', 'README.md' ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v3
|
||||
|
||||
- name: Build with Jekyll
|
||||
uses: actions/jekyll-build-pages@v1
|
||||
with:
|
||||
source: ./docs
|
||||
destination: ./_site
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
22
.github/workflows/label.yml
vendored
Normal file
22
.github/workflows/label.yml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: Label Pull Request
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Label PR
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
configuration-path: .github/labeler.yml
|
||||
sync-labels: true
|
||||
51
.github/workflows/license-check.yml
vendored
Normal file
51
.github/workflows/license-check.yml
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
name: License Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
license-check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check license headers
|
||||
run: |
|
||||
# Check if LICENSE file exists
|
||||
if [ ! -f "LICENSE" ]; then
|
||||
echo "LICENSE file is missing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if it's MIT license
|
||||
if ! grep -q "MIT License" LICENSE; then
|
||||
echo "License file should be MIT License"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "License file OK"
|
||||
|
||||
- name: Check Go files for license headers
|
||||
run: |
|
||||
# Check for license headers in Go files (optional but good practice)
|
||||
missing_headers=0
|
||||
|
||||
for file in $(find . -name "*.go" -not -path "./vendor/*" -not -path "./.git/*"); do
|
||||
if ! head -10 "$file" | grep -q "Copyright" && ! head -10 "$file" | grep -q "MIT"; then
|
||||
echo "Missing license header in: $file"
|
||||
missing_headers=$((missing_headers + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $missing_headers -gt 0 ]; then
|
||||
echo "Found $missing_headers Go files without license headers"
|
||||
echo "Consider adding license headers to Go files"
|
||||
# Don't fail the build, just warn
|
||||
else
|
||||
echo "All Go files have license headers"
|
||||
fi
|
||||
197
.github/workflows/release.yml
vendored
Normal file
197
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Trigger on version tags like v1.0.0
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.25.0'
|
||||
ZIG_VERSION: '0.15.2'
|
||||
|
||||
jobs:
|
||||
prepare_rsync:
|
||||
name: Prepare rsync metadata
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.manifest.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Load rsync manifest
|
||||
id: manifest
|
||||
run: |
|
||||
MANIFEST=.github/rsync_manifest.json
|
||||
MATRIX=$(jq -c '
|
||||
. as $cfg
|
||||
| $cfg.platforms
|
||||
| to_entries
|
||||
| map({
|
||||
platform: .key,
|
||||
target: .value.target,
|
||||
"rsync-url": ($cfg.base_url + "/" + $cfg.version + "/" + .value.asset),
|
||||
"rsync-sha256": .value.sha256
|
||||
})
|
||||
' "$MANIFEST")
|
||||
printf 'matrix={"include":%s}\n' "$MATRIX" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-cli:
|
||||
name: Build CLI - ${{ matrix.platform }}
|
||||
needs: prepare_rsync
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.prepare_rsync.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
with:
|
||||
version: ${{ env.ZIG_VERSION }}
|
||||
|
||||
- name: Download static rsync
|
||||
run: |
|
||||
mkdir -p cli/src/assets
|
||||
wget -O cli/src/assets/rsync_release.bin ${{ matrix.rsync-url }} || \
|
||||
curl -L -o cli/src/assets/rsync_release.bin ${{ matrix.rsync-url }}
|
||||
echo "${{ matrix.rsync-sha256 }} cli/src/assets/rsync_release.bin" | sha256sum -c
|
||||
chmod +x cli/src/assets/rsync_release.bin
|
||||
ls -lh cli/src/assets/rsync_release.bin
|
||||
|
||||
- name: Build CLI
|
||||
working-directory: cli
|
||||
run: |
|
||||
zig build -Dtarget=${{ matrix.target }} -Doptimize=ReleaseSmall
|
||||
ls -lh zig-out/bin/ml
|
||||
|
||||
- name: Strip binary (Linux only)
|
||||
if: matrix.platform == 'linux-x86_64'
|
||||
working-directory: cli
|
||||
run: strip zig-out/bin/ml
|
||||
|
||||
- name: Package binary
|
||||
run: |
|
||||
mkdir -p dist
|
||||
cp cli/zig-out/bin/ml dist/ml-${{ matrix.platform }}
|
||||
cd dist
|
||||
tar -czf ml-${{ matrix.platform }}.tar.gz ml-${{ matrix.platform }}
|
||||
sha256sum ml-${{ matrix.platform }}.tar.gz > ml-${{ matrix.platform }}.tar.gz.sha256
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ml-${{ matrix.platform }}
|
||||
path: |
|
||||
dist/ml-${{ matrix.platform }}.tar.gz
|
||||
dist/ml-${{ matrix.platform }}.tar.gz.sha256
|
||||
|
||||
build-go-backends:
|
||||
name: Build Go Backends
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Build binaries
|
||||
run: |
|
||||
make cross-platform
|
||||
ls -lh dist/
|
||||
|
||||
- name: Package binaries
|
||||
run: |
|
||||
cd dist
|
||||
for binary in api-server worker tui data_manager user_manager; do
|
||||
if [[ -f "${binary}" ]]; then
|
||||
tar -czf "fetch_ml_${binary}.tar.gz" "${binary}"
|
||||
sha256sum "fetch_ml_${binary}.tar.gz" > "fetch_ml_${binary}.tar.gz.sha256"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: go-backends
|
||||
path: |
|
||||
dist/*.tar.gz
|
||||
dist/*.sha256
|
||||
|
||||
create-release:
|
||||
name: Create GitHub Release
|
||||
needs: [build-cli, build-go-backends]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
- name: Prepare release assets
|
||||
run: |
|
||||
mkdir -p release
|
||||
# Copy CLI binaries
|
||||
cp artifacts/ml-*/ml-*.tar.gz* release/
|
||||
# Copy Go binaries
|
||||
cp artifacts/go-backends/*.tar.gz* release/
|
||||
|
||||
# Generate combined checksums
|
||||
cd release
|
||||
sha256sum *.tar.gz > checksums.txt
|
||||
ls -lh
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: release/*
|
||||
body: |
|
||||
## 🚀 Release ${{ github.ref_name }}
|
||||
|
||||
### CLI Binaries (Zero Dependencies)
|
||||
All CLI binaries include embedded static rsync for complete independence.
|
||||
|
||||
- **`ml-linux-x86_64.tar.gz`** - Linux x86_64 (fully static, musl)
|
||||
- **`ml-macos-x86_64.tar.gz`** - macOS Intel
|
||||
- **`ml-macos-arm64.tar.gz`** - macOS Apple Silicon
|
||||
|
||||
### Go Backend Binaries
|
||||
- **`fetch_ml_api-server.tar.gz`** - API Server
|
||||
- **`fetch_ml_worker.tar.gz`** - Worker
|
||||
- **`fetch_ml_tui.tar.gz`** - Terminal UI
|
||||
- **`fetch_ml_data_manager.tar.gz`** - Data Manager
|
||||
- **`fetch_ml_user_manager.tar.gz`** - User Manager
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
# Download and extract
|
||||
tar -xzf ml-<platform>.tar.gz
|
||||
|
||||
# Make executable and move to PATH
|
||||
chmod +x ml-<platform>
|
||||
sudo mv ml-<platform> /usr/local/bin/ml
|
||||
|
||||
# Verify installation
|
||||
ml --help
|
||||
```
|
||||
|
||||
### Checksums
|
||||
SHA256 checksums are provided in `checksums.txt` and individual `.sha256` files.
|
||||
generate_release_notes: true
|
||||
draft: false
|
||||
prerelease: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
33
.github/workflows/stale.yml
vendored
Normal file
33
.github/workflows/stale.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Mark Stale Issues and PRs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * 1" # Every Monday at midnight
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Mark stale issues and PRs
|
||||
uses: actions/stale@v8
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
days-before-close: 14
|
||||
stale-issue-label: "stale"
|
||||
stale-pr-label: "stale"
|
||||
stale-issue-message: |
|
||||
This issue has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs within 14 days.
|
||||
Thank you for your contributions!
|
||||
stale-pr-message: |
|
||||
This pull request has been automatically marked as stale because it has not had recent activity.
|
||||
It will be closed if no further activity occurs within 14 days.
|
||||
Thank you for your contributions!
|
||||
exempt-issue-labels: "pinned,security,help wanted,good first issue"
|
||||
exempt-pr-labels: "pinned,security,help wanted,good first issue"
|
||||
6
.windsurf/rules/test-new-features.md
Normal file
6
.windsurf/rules/test-new-features.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
trigger: model_decision
|
||||
description: When a new feature is added, this prompt needs to be run
|
||||
---
|
||||
|
||||
When a significant feature is added make sure that the tests are added as well, change the docs to add details and make sure that the scripts, if needed, are changed. Don't forget to cleanup, you tend to leave a lot of unncessary files and code arround. Do not write loose .md to track task and todo, either add to the code or tell me.
|
||||
3
db/.gitkeep
Normal file
3
db/.gitkeep
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# This directory stores SQLite database files
|
||||
# Database files are automatically created by the application
|
||||
# Example: fetch_ml.db
|
||||
Loading…
Reference in a new issue