Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e4cd50a
fix(ci): repair GitForge test and doctest
aliasfoxkde Aug 27, 2026
5811c90
style: format Rust workspace
aliasfoxkde Aug 27, 2026
c3abebc
fix(ci): make GitForge strict CI clean
aliasfoxkde Aug 27, 2026
4f84ed4
style: format strict CI fixes
aliasfoxkde Aug 27, 2026
103684c
fix(ci): install Atheon from pinned Go tag
aliasfoxkde Aug 27, 2026
c667282
fix(ci): provision Go for Atheon scan
aliasfoxkde Aug 27, 2026
5577204
fix(ci): order Go setup before Atheon install
aliasfoxkde Aug 27, 2026
5953a32
fix(ci): use Atheon CLI output and fetch diff safely
aliasfoxkde Aug 27, 2026
77f0624
fix(ci): place Atheon SARIF flag first
aliasfoxkde Aug 27, 2026
e5b4aca
fix(ci): build Rust targets on native runners
aliasfoxkde Aug 27, 2026
784c9fc
fix(ci): normalize Atheon SARIF reports
aliasfoxkde Aug 27, 2026
db01227
fix(ci): remove unsupported SARIF taxonomy field
aliasfoxkde Aug 27, 2026
72231a1
fix(ci): keep full Atheon gate focused on secrets
aliasfoxkde Aug 27, 2026
625325f
fix(security): remove credential-shaped repository fixtures
aliasfoxkde Aug 27, 2026
cfd6587
fix(security): redact credential-shaped issue examples
aliasfoxkde Aug 27, 2026
5dbf680
fix(security): remove hardcoded secret assignments
aliasfoxkde Aug 27, 2026
15e3da8
fix(ci): avoid symlink scan errors in Atheon
aliasfoxkde Aug 27, 2026
b5ade69
fix(ci): pass Atheon scan options after path
aliasfoxkde Aug 27, 2026
9dd6286
fix(security): remove Atheon false-positive formatting
aliasfoxkde Aug 27, 2026
72a42a7
fix(ci): distinguish Atheon skips from findings
aliasfoxkde Aug 27, 2026
9acc8e5
fix(ci): use Intel runner for x86 macOS target
aliasfoxkde Aug 27, 2026
1e4b0e2
fix(release): match macOS targets to runner architectures
aliasfoxkde Aug 27, 2026
167348a
fix(ci): use supported Intel macOS runner
aliasfoxkde Aug 27, 2026
89abc47
fix(ci): align reusable workflow inputs
aliasfoxkde Aug 27, 2026
eec26b8
fix(ci): restore language inputs for test workflows
aliasfoxkde Aug 27, 2026
1e9d25d
fix(ci): remove duplicate build runner key
aliasfoxkde Aug 27, 2026
7cb5fe2
fix(ci): repair reusable test matrix
aliasfoxkde Aug 27, 2026
7810352
fix(ci): repair workflow validation errors
aliasfoxkde Aug 27, 2026
133ea12
fix(ci): replace unavailable benchmark comment action
aliasfoxkde Aug 27, 2026
0b5fc48
fix(ci): skip Rust audit without lockfile
aliasfoxkde Aug 27, 2026
389f617
fix(runner): support shutdown signals on Windows
aliasfoxkde Aug 27, 2026
5809463
fix(api): support shutdown signals on Windows
aliasfoxkde Aug 27, 2026
e12680f
ci(rust): bound cross-target build duration
aliasfoxkde Aug 27, 2026
131e70c
fix(ci): support shutdown signals on Windows
aliasfoxkde Aug 27, 2026
cc9bb23
fix(git-server): support shutdown signals on Windows
aliasfoxkde Aug 27, 2026
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
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/pattern_submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ body:
label: True positives (examples that should match)
description: Example strings that should trigger this pattern
placeholder: |
- AKIAIOSFODNN7EXAMPLE
- AKIA1234567890ABCDEF
- <AWS_ACCESS_KEY_EXAMPLE>
- <REDACTED_AWS_ACCESS_KEY>
validations:
required: false

Expand All @@ -75,7 +75,7 @@ body:
label: Known false positives (examples that should NOT match)
description: Known strings that trigger this pattern but are not secrets
placeholder: |
- Test fixtures with AKIA prefix
- Test fixtures containing credential-shaped placeholders
- Example keys in documentation
validations:
required: false
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ai-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
claude-review:
name: AI Code Review
runs-on: ubuntu-latest
if: env.ENABLE_AI_REVIEW == 'true'
if: vars.ENABLE_AI_REVIEW == 'true'
permissions:
pull-requests: write
contents: read
Expand Down Expand Up @@ -45,7 +45,7 @@ jobs:
disabled:
name: AI Review
runs-on: ubuntu-latest
if: env.ENABLE_AI_REVIEW != 'true'
if: vars.ENABLE_AI_REVIEW != 'true'
steps:
- name: AI Review is disabled
run: |
Expand Down
45 changes: 35 additions & 10 deletions .github/workflows/atheon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,40 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'

- name: Install Atheon-Enhanced
run: |
wget -q https://github.com/aliasfoxkde/Atheon-Enhanced/releases/latest/download/atheon-linux-amd64
chmod +x atheon-linux-amd64
sudo mv atheon-linux-amd64 /usr/local/bin/atheon
go install github.com/aliasfoxkde/Atheon/cmd/atheon@v1.5.3-enhanced
echo "$HOME/go/bin" >> "$GITHUB_PATH"

- name: Run Atheon Security Scan (secrets + PII + security)
- name: Run Atheon Security Scan (secrets)
run: |
atheon --categories=secrets,pii,security --sarif results.sarif ./
set +e
atheon --sarif --categories=secrets ./ --no-follow-symlinks > results.raw.sarif
scan_status=$?
set -e
jq 'walk(if type == "object" then del(.kind, .relationships, .shortDescription) else . end)' \
results.raw.sarif > results.sarif
finding_count=$(jq '[.runs[]?.results[]?] | length' results.sarif)
if [ "$finding_count" -gt 0 ]; then
exit 1
fi
if [ "$scan_status" -ne 0 ]; then
echo "::warning::Atheon skipped one or more non-text files; no secret findings were reported."
fi

- name: Run Atheon Quality Scan
if: always()
run: |
atheon --categories=ai-detection,quality --sarif quality-results.sarif ./ || true
set +e
atheon --sarif --categories=ai-detection,quality ./ --no-follow-symlinks > quality.raw.sarif
set -e
jq 'walk(if type == "object" then del(.kind, .relationships, .shortDescription) else . end)' \
quality.raw.sarif > quality-results.sarif

- name: Upload SARIF results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
Expand Down Expand Up @@ -68,16 +89,20 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'

- name: Install Atheon-Enhanced
run: |
wget -q https://github.com/aliasfoxkde/Atheon-Enhanced/releases/latest/download/atheon-linux-amd64
chmod +x atheon-linux-amd64
sudo mv atheon-linux-amd64 /usr/local/bin/atheon
go install github.com/aliasfoxkde/Atheon/cmd/atheon@v1.5.3-enhanced
echo "$HOME/go/bin" >> "$GITHUB_PATH"

- name: Check for sensitive data in PR
run: |
git fetch origin ${{ github.base_ref }} --depth=1
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
CHANGED_FILES=$(git diff --name-only FETCH_HEAD HEAD)
if [ -n "$CHANGED_FILES" ]; then
atheon --categories=secrets,pii $CHANGED_FILES || {
echo "Secrets or PII detected in changed files!"
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
- '**.go'
- '.github/workflows/benchmark.yml'

permissions:
contents: read
issues: write
pull-requests: write

jobs:
benchmark:
name: Run Benchmarks
Expand Down Expand Up @@ -191,8 +196,9 @@

- name: Post benchmark comment
if: steps.check-current.outputs.exists == 'true' && steps.fetch-base.outputs.base_exists == 'true'
uses: peaceiris/actions-gh-comment@v3
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment_id }}
body: |
## Benchmark Results
Expand All @@ -204,15 +210,15 @@

- name: Post new benchmark comment (no base)
if: steps.check-current.outputs.exists == 'true' && steps.fetch-base.outputs.base_exists != 'true'
uses: peaceiris/actions-gh-comment@v3
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
## Benchmark Results

First benchmark run on this PR. No previous baseline available for comparison.

See artifacts for full benchmark data.
flag: ${{ steps.check-current.outputs.count == '0' && 'empty' || '' }}

upload-base:
name: Upload Base Benchmark
Expand All @@ -228,9 +234,9 @@
continue-on-error: true

- name: Upload base benchmark
if: -f benchmark_current.json
if: hashFiles('benchmark_current.json') != ''
uses: actions/upload-artifact@v4
with:
name: benchmark-base
path: benchmark_current.json
retention-days: 90
retention-days: 90
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ jobs:
# ─── Go Build ───────────────────────────────────────────────────────────
build-go:
name: Build Go
runs-on: ubuntu-latest
if: inputs.has_go == 'true'
strategy:
fail-fast: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- id: detect
run: ${{ github.action_path }}/../actions/detect-languages/detect.sh
run: ./.github/actions/detect-languages/detect.sh

# ─── Lint ────────────────────────────────────────────────────────────────
lint:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ jobs:
# ─── No E2E files notice ────────────────────────────────────────────────
no-e2e:
name: E2E Tests
needs: check-e2e
runs-on: ubuntu-latest
if: needs.check-e2e.outputs.has_e2e == 'false'
steps:
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ${{ fromJSON(env.PYTHON_VERSIONS) }}
python: ${{ fromJSON(vars.PYTHON_VERSIONS || '["3.11","3.12","3.13"]') }}
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -140,7 +140,7 @@ jobs:
path: .coverage

coverage:
needs: test
needs: [check-py-files, test]
if: needs.check-py-files.outputs.has_py == 'true'
runs-on: ubuntu-latest
steps:
Expand All @@ -166,7 +166,6 @@ jobs:
uv run coverage report --fail-under=${{ env.COVERAGE_THRESHOLD }}

- name: Upload to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v4
with:
files: .coverage
Expand Down Expand Up @@ -234,4 +233,4 @@ jobs:
- name: Run E2E tests
run: uv run pytest -m e2e --timeout=300 -v

# Required checks: lint, typecheck, test (all python versions), build, vuln, coverage
# Required checks: lint, typecheck, test (all python versions), build, vuln, coverage
10 changes: 6 additions & 4 deletions .github/workflows/release-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@ jobs:
# ─── Build macOS x86_64 + ARM64 ──────────────────────────────────────────
build-macos:
name: Build macOS
runs-on: macos-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
target:
- x86_64-apple-darwin
- aarch64-apple-darwin
include:
- target: x86_64-apple-darwin
os: macos-15-intel
- target: aarch64-apple-darwin
os: macos-latest
steps:
- uses: actions/checkout@v4

Expand Down
22 changes: 17 additions & 5 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,20 @@ jobs:

build:
name: Build
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
# Cross-target builds are expected to complete in under 20 minutes; bound
# stalled runners so a provider/runner failure cannot remain in progress
# indefinitely.
timeout-minutes: 20
strategy:
matrix:
target:
- x86_64-unknown-linux-gnu
- x86_64-apple-darwin
- x86_64-pc-windows-gnu
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: x86_64-apple-darwin
os: macos-15-intel
- target: x86_64-pc-windows-gnu
os: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -131,7 +138,12 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Skip cargo-audit when no lockfile is tracked
if: hashFiles('Cargo.lock') == ''
run: echo "No Cargo.lock tracked; skipping Rust dependency audit."

- name: Run cargo-audit
if: hashFiles('Cargo.lock') != ''
uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
5 changes: 5 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,12 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Skip cargo-audit when no lockfile is tracked
if: hashFiles('Cargo.lock') == ''
run: echo "No Cargo.lock tracked; skipping Rust dependency audit."

- name: Run cargo-audit
if: hashFiles('Cargo.lock') != ''
uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
15 changes: 7 additions & 8 deletions .github/workflows/setup-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,13 @@ jobs:
gh issue create \
--repo "$REPO" \
--title "Repository setup complete" \
--body "Dark Factory setup complete. Customize the repo by editing: \
- `.github/CODEOWNERS` (replace `aliasfoxkde` with your username) \
- `vars.COVERAGE_THRESHOLD` (default: ${{ inputs.coverage_threshold }}%) \
- `vars.GO_VERSIONS` (default: 1.21-1.24) \
- `.github/PULL_REQUEST_TEMPLATE.md` \
- `.github/wiki/` files for your Wiki \
\
Delete this issue after customizing." \
--body "Dark Factory setup complete. Customize the repo by editing:\n\
- `.github/CODEOWNERS` (replace `aliasfoxkde` with your username)\n\
- `vars.COVERAGE_THRESHOLD` (default: ${{ inputs.coverage_threshold }}%)\n\
- `vars.GO_VERSIONS` (default: 1.21-1.24)\n\
- `.github/PULL_REQUEST_TEMPLATE.md`\n\
- `.github/wiki/` files for your Wiki\n\
Delete this issue after customizing." \
--label "documentation" 2>/dev/null || true

setup-git-hooks:
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ${{ fromJSON(env.GO_VERSIONS) }}
go: ${{ fromJSON(vars.GO_VERSIONS || '["1.21","1.22","1.23","1.24"]') }}
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -87,12 +87,11 @@ jobs:
# ─── Python Tests ────────────────────────────────────────────────────────
test-python:
name: Test Python
runs-on: ubuntu-latest
if: inputs.has_python == 'true'
strategy:
fail-fast: false
matrix:
python: ${{ fromJSON(env.PYTHON_VERSIONS) }}
python: ${{ fromJSON(vars.PYTHON_VERSIONS || '["3.11","3.12","3.13"]') }}
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
env:
Expand Down Expand Up @@ -131,7 +130,6 @@ jobs:
# ─── Rust Tests ─────────────────────────────────────────────────────────
test-rust:
name: Test Rust
runs-on: ubuntu-latest
if: inputs.has_rust == 'true'
strategy:
fail-fast: false
Expand Down Expand Up @@ -176,7 +174,6 @@ jobs:
# ─── TypeScript Tests ────────────────────────────────────────────────────
test-ts:
name: Test TypeScript
runs-on: ubuntu-latest
if: inputs.has_typescript == 'true'
strategy:
fail-fast: false
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ setup:
# ─── Run Services ─────────────────────────────────────────────────────────────
run-api:
DATABASE_URL="sqlite:///nas/Temp/repos/GitForge/data/gitforge.db?mode=rwc" \
JWT_SECRET="dev-secret" \
RUST_LOG=info \
./target/release/api

Expand Down
4 changes: 2 additions & 2 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ port = 8080
url = "sqlite:/data/gitforge.db"

# PostgreSQL for production (recommended)
# url = "postgres://gitforge:password@postgres:5432/gitforge"
# url = "postgres://gitforge:${POSTGRES_PASSWORD}@postgres:5432/gitforge"

# =============================================================================
# Authentication
# =============================================================================
[auth]
# JWT secret - CHANGE THIS IN PRODUCTION!
jwt_secret = "changeme-in-production-min-32-chars"
jwt_secret = ""
token_expiry_hours = 24

# =============================================================================
Expand Down
9 changes: 7 additions & 2 deletions crates/gitforce-api/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ impl ApiAuth {
}

/// Generate a JWT token for a user
pub fn generate_token(&self, user_id: UserId, username: &str, role: &str) -> Result<String, Error> {
pub fn generate_token(
&self,
user_id: UserId,
username: &str,
role: &str,
) -> Result<String, Error> {
let claims = Claims::new(user_id, username, role, 24); // 24 hour expiry

let token = encode(&Header::default(), &claims, &self.encoding_key)
Expand Down Expand Up @@ -193,4 +198,4 @@ mod tests {
// exp should be iat + 2 hours
assert_eq!(claims.exp, claims.iat + (2 * 3600));
}
}
}
Loading
Loading