From df5d872021cead93bd38e9879b95bc31606d44b2 Mon Sep 17 00:00:00 2001 From: Jeremie Fraeys Date: Thu, 12 Feb 2026 12:05:00 -0500 Subject: [PATCH] ci: migrate from GitHub to Forgejo/Gitea - Add Forgejo workflow files (.forgejo/workflows/) - Add Gitea templates (.gitea/ISSUE_TEMPLATE/, .gitea/PULL_REQUEST_TEMPLATE.md) - Remove legacy .github/ workflows and templates --- .forgejo/workflows/benchmark-metrics.yml | 81 +++++++ .forgejo/workflows/ci.yml | 271 +++++++++++++++++++++++ .forgejo/workflows/docs.yml | 113 ++++++++++ .forgejo/workflows/label.yml | 22 ++ .forgejo/workflows/release-mirror.yml | 190 ++++++++++++++++ .forgejo/workflows/stale.yml | 33 +++ .gitea/ISSUE_TEMPLATE/bug_report.md | 49 ++++ .gitea/ISSUE_TEMPLATE/feature_request.md | 34 +++ .gitea/PULL_REQUEST_TEMPLATE.md | 35 +++ .gitea/labeler.yml | 82 +++++++ .gitea/rsync_manifest.json | 21 ++ 11 files changed, 931 insertions(+) create mode 100644 .forgejo/workflows/benchmark-metrics.yml create mode 100644 .forgejo/workflows/ci.yml create mode 100644 .forgejo/workflows/docs.yml create mode 100644 .forgejo/workflows/label.yml create mode 100644 .forgejo/workflows/release-mirror.yml create mode 100644 .forgejo/workflows/stale.yml create mode 100644 .gitea/ISSUE_TEMPLATE/bug_report.md create mode 100644 .gitea/ISSUE_TEMPLATE/feature_request.md create mode 100644 .gitea/PULL_REQUEST_TEMPLATE.md create mode 100644 .gitea/labeler.yml create mode 100644 .gitea/rsync_manifest.json diff --git a/.forgejo/workflows/benchmark-metrics.yml b/.forgejo/workflows/benchmark-metrics.yml new file mode 100644 index 0000000..e088d42 --- /dev/null +++ b/.forgejo/workflows/benchmark-metrics.yml @@ -0,0 +1,81 @@ +name: Benchmark Metrics + +on: + workflow_dispatch: + +jobs: + benchmark: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + + - name: Run benchmarks + run: | + echo "Running performance benchmarks..." + go test -bench=. -benchmem ./tests/benchmarks/... > benchmark_results.txt 2>&1 + + grep "Benchmark.*-[0-9].*" benchmark_results.txt > clean_benchmarks.txt || true + + - name: Convert to Prometheus metrics + run: | + echo "# HELP benchmark_time_per_op Time per operation in nanoseconds" > prometheus_metrics.txt + echo "# TYPE benchmark_time_per_op gauge" >> prometheus_metrics.txt + echo "# HELP benchmark_memory_per_op Memory per operation in bytes" >> prometheus_metrics.txt + echo "# TYPE benchmark_memory_per_op gauge" >> prometheus_metrics.txt + echo "# HELP benchmark_allocs_per_op Allocations per operation" >> prometheus_metrics.txt + echo "# TYPE benchmark_allocs_per_op gauge" >> prometheus_metrics.txt + + while IFS= read -r line; do + if [[ -n "$line" ]]; then + BENCHMARK_NAME=$(echo "$line" | awk '{print $1}' | sed 's/-[0-9]*$//') + TIME_PER_OP=$(echo "$line" | awk '{print $3}') + MEMORY_PER_OP=$(echo "$line" | awk '{print $4}') + ALLOCS_PER_OP=$(echo "$line" | awk '{print $5}') + + CLEAN_NAME=$(echo "$BENCHMARK_NAME" | sed 's/[^a-zA-Z0-9_]/_/g') + + echo "benchmark_time_per_op{benchmark=\"$CLEAN_NAME\"} ${TIME_PER_OP/ns/}" >> prometheus_metrics.txt + echo "benchmark_memory_per_op{benchmark=\"$CLEAN_NAME\"} ${MEMORY_PER_OP/B\/op/}" >> prometheus_metrics.txt + echo "benchmark_allocs_per_op{benchmark=\"$CLEAN_NAME\"} ${ALLOCS_PER_OP/allocs\/op/}" >> prometheus_metrics.txt + fi + done < clean_benchmarks.txt + + - name: Push to Prometheus Pushgateway + env: + PROMETHEUS_PUSHGATEWAY_URL: ${{ secrets['PROMETHEUS_PUSHGATEWAY_URL'] }} + run: | + if [ -n "$PROMETHEUS_PUSHGATEWAY_URL" ]; then + echo "Pushing metrics to Prometheus..." + curl --data-binary @prometheus_metrics.txt \ + "$PROMETHEUS_PUSHGATEWAY_URL/metrics/job/benchmark/instance/${{ github.run_id }}" + else + echo "PROMETHEUS_PUSHGATEWAY_URL not configured, skipping push" + fi + + - name: Upload benchmark results + uses: actions/upload-artifact@v4 + with: + name: benchmark-results + path: | + benchmark_results.txt + clean_benchmarks.txt + prometheus_metrics.txt + retention-days: 30 + + - name: Display results summary + run: | + echo "=== Benchmark Results Summary ===" + cat prometheus_metrics.txt | grep "benchmark_time_per_op" | head -10 diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..2e6b1b1 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,271 @@ +name: CI/CD Pipeline + +on: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + security-events: write + actions: read + packages: write + +env: + GO_VERSION: '1.25.0' + ZIG_VERSION: '0.15.2' + RSYNC_VERSION: '3.3.0' + +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 build-essential autoconf automake libtool pkg-config musl-tools + + - name: Build pinned rsync from official source (for CLI tests) + run: | + make -C cli build-rsync RSYNC_VERSION=${{ env.RSYNC_VERSION }} + + - name: Verify dependencies + run: go mod verify + + - name: Run tests + run: make test + + - name: Test internal/queue package + run: go test -v -race -coverprofile=queue-coverage.out ./internal/queue/... + + - name: Run comprehensive tests + run: make test-full + + - name: Run linters + run: make lint + + - name: Generate coverage report + run: make test-coverage + + - name: Upload coverage to Codecov + if: secrets.CODECOV_TOKEN != '' + uses: codecov/codecov-action@v4 + with: + file: ./coverage/coverage.out + flags: unittests + name: codecov-umbrella + token: ${{ secrets.CODECOV_TOKEN }} + + dev-smoke: + name: Dev Compose Smoke Test + runs-on: ubuntu-latest + needs: test + timeout-minutes: 20 + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Run dev smoke test + run: make dev-smoke + + 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 build-essential autoconf automake libtool pkg-config musl-tools + + - name: Build pinned rsync from official source + run: | + make -C cli build-rsync RSYNC_VERSION=${{ env.RSYNC_VERSION }} + + - name: Build binaries + run: | + make build + + - name: Test binaries + run: | + ./bin/user_manager --help + ./bin/worker --help + ./bin/tui --help + ./bin/data_manager --help + ./cli/zig-out/bin/ml --help + ls -lh ./cli/zig-out/bin/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: | + chmod +x scripts/*.sh || true + chmod +x scripts/maintenance/*.sh || true + + ./scripts/verify_release.sh --help + ./scripts/manage-artifacts.sh help + ./scripts/track_performance.sh --help + ./scripts/smoke-test.sh --help + + 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 + uses: actions/upload-artifact@v4 + if: always() + with: + name: trivy-results + path: trivy-results.sarif + retention-days: 30 + + - 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' && secrets.GHCR_TOKEN != '' + 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: ${{ secrets.GHCR_USERNAME }} + password: ${{ secrets.GHCR_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 diff --git a/.forgejo/workflows/docs.yml b/.forgejo/workflows/docs.yml new file mode 100644 index 0000000..d6d817b --- /dev/null +++ b/.forgejo/workflows/docs.yml @@ -0,0 +1,113 @@ +name: Documentation + +on: + workflow_dispatch: + push: + branches: [ main ] + pull_request: + +concurrency: + group: "docs" + cancel-in-progress: false + +env: + GO_VERSION: '1.21' + HUGO_VERSION: ${{ vars.HUGO_VERSION || '0.125.7' }} + FORGEJO_PAGES_BRANCH: ${{ vars.FORGEJO_PAGES_BRANCH || 'pages' }} + FORGEJO_DOCS_BASE_URL: ${{ vars.FORGEJO_DOCS_BASE_URL || '/' }} + GH_PAGES_REPO: ${{ vars.GH_PAGES_REPO || '' }} + GH_PAGES_BRANCH: ${{ vars.GH_PAGES_BRANCH || 'gh-pages' }} + GH_DOCS_BASE_URL: ${{ vars.GH_DOCS_BASE_URL || '' }} + +jobs: + build-and-publish: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y wget rsync git + + - name: Set up Go (for Hugo Modules) + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Hugo + run: | + wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb + sudo dpkg -i ${{ runner.temp }}/hugo.deb + + - name: Build docs (Forgejo) + run: | + hugo --source docs --gc --minify --baseURL "${FORGEJO_DOCS_BASE_URL}" --destination "${{ runner.temp }}/site-forgejo" + + - name: Build docs (GitHub) + if: env.GH_PAGES_REPO != '' + run: | + BASE_URL="${GH_DOCS_BASE_URL}" + if [ -z "${BASE_URL}" ]; then + BASE_URL="https://${GH_PAGES_REPO%%/*}.github.io/${GH_PAGES_REPO#*/}/" + fi + hugo --source docs --gc --minify --baseURL "${BASE_URL}" --destination "${{ runner.temp }}/site-github" + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: docs-site + path: ${{ runner.temp }}/site-forgejo + retention-days: 30 + + - name: Publish docs to Forgejo + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_PAGES_TOKEN || secrets.GITEA_TOKEN || secrets.GITHUB_TOKEN }} + run: | + if [ -z "${FORGEJO_TOKEN}" ]; then + echo "Missing FORGEJO_PAGES_TOKEN (or GITEA_TOKEN/GITHUB_TOKEN fallback)" >&2 + exit 1 + fi + + SERVER_URL="${{ github.server_url }}" + HOST="${SERVER_URL#https://}" + HOST="${HOST#http://}" + REMOTE="https://oauth2:${FORGEJO_TOKEN}@${HOST}/${{ github.repository }}.git" + + mkdir -p "${{ runner.temp }}/publish-forgejo" + cd "${{ runner.temp }}/publish-forgejo" + git init + git checkout --orphan "${FORGEJO_PAGES_BRANCH}" + rsync -a --delete "${{ runner.temp }}/site-forgejo/" ./ + git add -A + git config user.name "forgejo-actions" + git config user.email "actions@${HOST}" + git commit -m "docs: publish" || true + git remote add origin "${REMOTE}" + git push --force origin "${FORGEJO_PAGES_BRANCH}" + + - name: Publish docs to GitHub Pages + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && env.GH_PAGES_REPO != '' + env: + GH_TOKEN: ${{ secrets.GH_PAGES_TOKEN || secrets.GH_MIRROR_TOKEN }} + run: | + if [ -z "${GH_TOKEN}" ]; then + echo "Missing GH_PAGES_TOKEN (or GH_MIRROR_TOKEN fallback)" >&2 + exit 1 + fi + + REMOTE="https://x-access-token:${GH_TOKEN}@github.com/${GH_PAGES_REPO}.git" + + mkdir -p "${{ runner.temp }}/publish-github" + cd "${{ runner.temp }}/publish-github" + git init + git checkout --orphan "${GH_PAGES_BRANCH}" + rsync -a --delete "${{ runner.temp }}/site-github/" ./ + git add -A + git config user.name "github-actions" + git config user.email "actions@github.com" + git commit -m "docs: publish" || true + git remote add origin "${REMOTE}" + git push --force origin "${GH_PAGES_BRANCH}" diff --git a/.forgejo/workflows/label.yml b/.forgejo/workflows/label.yml new file mode 100644 index 0000000..8222bf1 --- /dev/null +++ b/.forgejo/workflows/label.yml @@ -0,0 +1,22 @@ +name: Label Pull Request + +on: + workflow_dispatch: + +jobs: + label: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Label PR + uses: actions/labeler@v4 + with: + repo-token: ${{ secrets.GITEA_TOKEN }} + configuration-path: .gitea/labeler.yml + sync-labels: true diff --git a/.forgejo/workflows/release-mirror.yml b/.forgejo/workflows/release-mirror.yml new file mode 100644 index 0000000..21d1e71 --- /dev/null +++ b/.forgejo/workflows/release-mirror.yml @@ -0,0 +1,190 @@ +name: Mirror Release to GitHub + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +env: + GO_VERSION: '1.25.0' + ZIG_VERSION: '0.15.2' + GH_MIRROR_REPO: ${{ vars.GH_MIRROR_REPO }} + +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: Install jq + run: | + sudo apt-get update + sudo apt-get install -y jq + + - name: Load rsync manifest + id: manifest + run: | + MANIFEST=.gitea/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 + TARGET="${{ matrix.target }}" + OS="" + ARCH="" + case "$TARGET" in + x86_64-linux-*) OS="linux"; ARCH="x86_64" ;; + aarch64-linux-*) OS="linux"; ARCH="arm64" ;; + x86_64-macos*) OS="darwin"; ARCH="x86_64" ;; + aarch64-macos*) OS="darwin"; ARCH="arm64" ;; + x86_64-windows*) OS="windows"; ARCH="x86_64" ;; + aarch64-windows*) OS="windows"; ARCH="arm64" ;; + *) echo "Unsupported Zig target: $TARGET"; exit 1 ;; + esac + + RSYNC_OUT="cli/src/assets/rsync_release_${OS}_${ARCH}.bin" + + wget -O "$RSYNC_OUT" ${{ matrix.rsync-url }} || \ + curl -L -o "$RSYNC_OUT" ${{ matrix.rsync-url }} + + echo "${{ matrix.rsync-sha256 }} $RSYNC_OUT" | sha256sum -c + chmod +x "$RSYNC_OUT" + ls -lh "$RSYNC_OUT" + + - name: Build CLI + working-directory: cli + run: | + zig build --release=small -Dtarget=${{ matrix.target }} + 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 fetch_ml_*; do + if [[ -f "${binary}" ]]; then + tar -czf "${binary}.tar.gz" "${binary}" + sha256sum "${binary}.tar.gz" > "${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 + + mirror-github-release: + name: Mirror release to GitHub + needs: [build-cli, build-go-backends] + runs-on: ubuntu-latest + steps: + - name: Validate mirror configuration + env: + GH_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }} + run: | + if [ -z "${GH_MIRROR_REPO}" ]; then + echo "Missing required variable GH_MIRROR_REPO (expected like 'jfraeysd/fetch_ml')" + exit 1 + fi + if [ -z "${GH_TOKEN}" ]; then + echo "Missing required secret GH_MIRROR_TOKEN" + exit 1 + fi + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Prepare release assets + run: | + mkdir -p release + cp artifacts/ml-*/ml-*.tar.gz* release/ + cp artifacts/go-backends/*.tar.gz* release/ + + cd release + sha256sum *.tar.gz > checksums.txt + ls -lh + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + repository: ${{ env.GH_MIRROR_REPO }} + files: release/* + generate_release_notes: true + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }} diff --git a/.forgejo/workflows/stale.yml b/.forgejo/workflows/stale.yml new file mode 100644 index 0000000..4434f65 --- /dev/null +++ b/.forgejo/workflows/stale.yml @@ -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 || secrets.GITEA_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" diff --git a/.gitea/ISSUE_TEMPLATE/bug_report.md b/.gitea/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..00fa04a --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/bug_report.md @@ -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. diff --git a/.gitea/ISSUE_TEMPLATE/feature_request.md b/.gitea/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..e17975b --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/feature_request.md @@ -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? diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6bb2ed9 --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -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. diff --git a/.gitea/labeler.yml b/.gitea/labeler.yml new file mode 100644 index 0000000..0a3e465 --- /dev/null +++ b/.gitea/labeler.yml @@ -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" diff --git a/.gitea/rsync_manifest.json b/.gitea/rsync_manifest.json new file mode 100644 index 0000000..c79fdc8 --- /dev/null +++ b/.gitea/rsync_manifest.json @@ -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" + } + } +}