Skip to content

Commit 9124c4d

Browse files
authored
chore: production readiness P0/P1 improvements (#199)
* chore: production readiness P0/P1 improvements - Remove committed .env; add .env.example and .gitignore rules - Split router.rs and app.rs into focused submodules - Add audit workflow, LFS gitattributes, README badges, branch prune script * fix: CI lint, docs link, and audit policy for known advisories
1 parent d5b5d55 commit 9124c4d

21 files changed

Lines changed: 2872 additions & 2726 deletions

.cargo/audit.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Track known transitive advisories until upstream fixes land.
2+
# See: https://github.com/Tuntii/RustAPI/issues/200
3+
[advisories]
4+
ignore = [
5+
"RUSTSEC-2026-0185", # quinn-proto – HTTP/3 optional dep; upgrade tracked in #200
6+
"RUSTSEC-2023-0071", # rsa – transitive, no fixed upgrade available
7+
]
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Placeholder environment variables for local documentation/examples
2-
# Replace with real values before running database-backed samples.
1+
# Placeholder environment variables for local documentation/examples.
2+
# Copy to .env and replace with real values before running database-backed samples.
33
DATABASE_URL=postgres://postgres:postgres@localhost:5432/rustapi_dev
44
REDIS_URL=redis://127.0.0.1:6379
55
OAUTH_CLIENT_ID=replace-me
66
OAUTH_CLIENT_SECRET=replace-me
77
OAUTH_REDIRECT_URI=http://127.0.0.1:3000/auth/callback
8-
OIDC_ISSUER_URL=https://accounts.google.com
8+
OIDC_ISSUER_URL=https://accounts.google.com

.gitattributes

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# Auto detect text files and perform LF normalization
2-
* text=auto
3-
api/public/*.txt text eol=lf
4-
.github/scripts/*.sh text eol=lf
1+
# Large binary assets — use Git LFS for PNGs over 500 KB
2+
assets/*.png filter=lfs diff=lfs merge=lfs -text
3+
assets/**/*.png filter=lfs diff=lfs merge=lfs -text
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Prune stale local and remote branches for RustAPI.
2+
# Usage:
3+
# .\.github\scripts\prune_stale_branches.ps1 -DryRun
4+
# .\.github\scripts\prune_stale_branches.ps1
5+
# .\.github\scripts\prune_stale_branches.ps1 -DeleteRemote
6+
7+
param(
8+
[switch]$DryRun,
9+
[switch]$DeleteRemote,
10+
[int]$StaleDays = 30
11+
)
12+
13+
$ErrorActionPreference = "Stop"
14+
$repoRoot = git -C $PSScriptRoot rev-parse --show-toplevel
15+
Set-Location $repoRoot
16+
17+
$protected = @("main", "master", "gh-pages", "Production-baseline")
18+
$stalePatterns = @("^copilot/", "^copilot-", "^sentinel-", "^secure-")
19+
20+
function Test-StaleBranchName([string]$Name) {
21+
foreach ($pattern in $stalePatterns) {
22+
if ($Name -match $pattern) { return $true }
23+
}
24+
return $false
25+
}
26+
27+
Write-Host "Scanning branches older than $StaleDays days..."
28+
$cutoff = (Get-Date).AddDays(-$StaleDays)
29+
30+
$localBranches = git for-each-ref --format="%(refname:short)|%(committerdate:iso8601)" refs/heads/ |
31+
ForEach-Object {
32+
$parts = $_ -split '\|', 2
33+
[PSCustomObject]@{ Name = $parts[0]; Date = [datetime]$parts[1] }
34+
}
35+
36+
$candidates = $localBranches |
37+
Where-Object { $protected -notcontains $_.Name } |
38+
Where-Object { $_.Date -lt $cutoff -or (Test-StaleBranchName $_.Name) }
39+
40+
if (-not $candidates) {
41+
Write-Host "No stale branches found."
42+
exit 0
43+
}
44+
45+
Write-Host ""
46+
Write-Host "Stale branch candidates:"
47+
$candidates | ForEach-Object { Write-Host " $($_.Name) (last commit: $($_.Date.ToString('yyyy-MM-dd')))" }
48+
49+
if ($DryRun) {
50+
Write-Host ""
51+
Write-Host "Dry run - no branches deleted."
52+
exit 0
53+
}
54+
55+
foreach ($branch in $candidates) {
56+
Write-Host "Deleting local branch: $($branch.Name)"
57+
git branch -D $branch.Name
58+
}
59+
60+
if ($DeleteRemote) {
61+
if (-not (Get-Command gh -ErrorAction SilentlyContinue)) {
62+
Write-Error "gh CLI not found. Install GitHub CLI or omit -DeleteRemote."
63+
}
64+
$repo = gh repo view --json nameWithOwner -q .nameWithOwner
65+
$remoteBranches = git for-each-ref --format="%(refname:short)" refs/remotes/origin/ |
66+
ForEach-Object { $_ -replace '^origin/', '' } |
67+
Where-Object { $_ -ne "HEAD" -and $protected -notcontains $_ } |
68+
Where-Object { Test-StaleBranchName $_ }
69+
70+
foreach ($branch in $remoteBranches) {
71+
Write-Host "Deleting remote branch: origin/$branch"
72+
gh api -X DELETE "repos/$repo/git/refs/heads/$branch"
73+
}
74+
}
75+
76+
Write-Host ""
77+
Write-Host "Done. Enable GitHub stale branch archiving:"
78+
Write-Host " Repository Settings - Branches - Add branch ruleset (archive after 30 days)"

.github/workflows/audit.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Security Audit
2+
3+
on:
4+
schedule:
5+
# Weekly on Monday at 06:00 UTC
6+
- cron: "0 6 * * 1"
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
env:
15+
CARGO_TERM_COLOR: always
16+
17+
jobs:
18+
cargo-audit:
19+
name: Cargo Audit
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Install Rust
25+
uses: dtolnay/rust-toolchain@stable
26+
27+
- name: Install cargo-audit
28+
run: cargo install cargo-audit --locked
29+
30+
- name: Run cargo audit
31+
run: cargo audit
32+
# Informational on PRs until transitive advisories are resolved (quinn-proto, rsa).
33+
continue-on-error: ${{ github.event_name == 'pull_request' }}
34+
35+
public-api-label-gate:
36+
name: Public API Label Gate
37+
runs-on: ubuntu-latest
38+
if: github.event_name == 'pull_request'
39+
permissions:
40+
contents: read
41+
pull-requests: read
42+
steps:
43+
- uses: actions/checkout@v4
44+
with:
45+
fetch-depth: 0
46+
47+
- name: Enforce breaking/feature label on snapshot changes
48+
env:
49+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
50+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
51+
PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }}
52+
GITHUB_EVENT_PATH: ${{ github.event_path }}
53+
run: bash .github/scripts/public_api_label_gate.sh

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
/target
22
/memories
3+
4+
# Environment files (never commit secrets)
5+
.env
6+
.env.*
7+
!.env.example
38
/scripts
49
# /benches
510
/.kiro

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
[![Crates.io](https://img.shields.io/crates/v/rustapi-rs.svg)](https://crates.io/crates/rustapi-rs)
99
[![Docs](https://img.shields.io/badge/docs-cookbook-brightgreen)](docs/cookbook/src/SUMMARY.md)
1010
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE)
11+
[![MSRV](https://img.shields.io/badge/MSRV-1.85-orange)](Cargo.toml)
12+
[![Security Audit](https://github.com/Tuntii/RustAPI/actions/workflows/audit.yml/badge.svg)](https://github.com/Tuntii/RustAPI/actions/workflows/audit.yml)
13+
[![Coverage](https://img.shields.io/badge/coverage-tarpaulin-blue)](https://github.com/Tuntii/RustAPI/actions/workflows/ci.yml)
1114
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Tuntii/RustAPI)
1215
</div>
1316

0 commit comments

Comments
 (0)