Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32759a9fd1 | ||
|
|
9c53334611 |
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
.git
|
||||
node_modules
|
||||
coverage
|
||||
*.md
|
||||
!README.md
|
||||
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
node_modules/
|
||||
coverage/
|
||||
dist/
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
*.log
|
||||
.DS_Store
|
||||
*.swp
|
||||
*~
|
||||
4
.prettierignore
Normal file
4
.prettierignore
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
*.min.js
|
||||
coverage
|
||||
dist
|
||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 4,
|
||||
"proseWrap": "always"
|
||||
}
|
||||
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
# alpine:3.21 (pinned 2026-01-28)
|
||||
FROM alpine:3.21@sha256:22e0ec13c0db6b3e1ba3280e831fc50ba7bffe58e81f31670a64b1afede247bc
|
||||
RUN apk add --no-cache bash shellcheck
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
RUN make check
|
||||
28
Makefile
Normal file
28
Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
.PHONY: check test lint fmt fmt-check secret-scan
|
||||
|
||||
check: lint fmt-check secret-scan test
|
||||
|
||||
test:
|
||||
@echo "Running tests..."
|
||||
@if [ -d tests ] && ls tests/test-*.sh >/dev/null 2>&1; then \
|
||||
for t in tests/test-*.sh; do echo " $$t"; bash "$$t"; done; \
|
||||
else \
|
||||
echo " No tests found"; \
|
||||
fi
|
||||
|
||||
lint:
|
||||
@echo "Linting..."
|
||||
@if command -v shellcheck >/dev/null 2>&1; then \
|
||||
find . -name '*.sh' -not -path './.git/*' -not -path './node_modules/*' -exec shellcheck {} +; \
|
||||
else \
|
||||
echo " shellcheck not installed, skipping"; \
|
||||
fi
|
||||
|
||||
fmt:
|
||||
@echo "No formatter configured for shell scripts"
|
||||
|
||||
fmt-check:
|
||||
@echo "No format check for shell scripts"
|
||||
|
||||
secret-scan:
|
||||
bash tools/secret-scan.sh .
|
||||
27
REPO_POLICIES.md
Normal file
27
REPO_POLICIES.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Repository Policies
|
||||
|
||||
This repository follows the sol/* organization standard policies.
|
||||
|
||||
## Required Files
|
||||
- Makefile with targets: test, lint, fmt, fmt-check, check, docker, hooks, release
|
||||
- .editorconfig
|
||||
- Dockerfile (CI: docker build . runs make check)
|
||||
- REPO_POLICIES.md (this file)
|
||||
- tools/secret-scan.sh
|
||||
|
||||
## Branching
|
||||
- All work on feature branches (feat/*, fix/*, chore/*)
|
||||
- No direct pushes to main (enforced by Gitea branch protection)
|
||||
- PRs required for merging to main
|
||||
|
||||
## Commits
|
||||
- Conventional commit format: feat:, fix:, chore:, docs:
|
||||
- Breaking changes: feat!: or BREAKING CHANGE: in body
|
||||
|
||||
## Releases
|
||||
- SemVer tagging via `make release BUMP=patch|minor|major`
|
||||
- Gitea releases with release notes for each version
|
||||
|
||||
## CI
|
||||
- `docker build .` runs `make check` as part of the build
|
||||
- All checks must pass before merge
|
||||
69
tools/secret-scan.sh
Executable file
69
tools/secret-scan.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# secret-scan.sh — Scans for private keys and high-entropy secrets
|
||||
# Usage: bash tools/secret-scan.sh [directory]
|
||||
# Uses .secret-scan-allowlist for false positives (one file path per line)
|
||||
|
||||
set -e
|
||||
|
||||
SCAN_DIR="${1:-.}"
|
||||
ALLOWLIST=".secret-scan-allowlist"
|
||||
FINDINGS=0
|
||||
|
||||
# Build find exclusions
|
||||
EXCLUDES=(-not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/coverage/*" -not -path "*/dist/*")
|
||||
|
||||
# Load allowlist
|
||||
ALLOWLIST_PATHS=()
|
||||
if [ -f "$ALLOWLIST" ]; then
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
[[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
|
||||
ALLOWLIST_PATHS+=("$line")
|
||||
done < "$ALLOWLIST"
|
||||
fi
|
||||
|
||||
is_allowed() {
|
||||
local file="$1"
|
||||
for allowed in "${ALLOWLIST_PATHS[@]}"; do
|
||||
if [[ "$file" == *"$allowed"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
echo "Scanning $SCAN_DIR for secrets..."
|
||||
|
||||
# Scan for private keys
|
||||
while IFS= read -r file; do
|
||||
[ -f "$file" ] || continue
|
||||
is_allowed "$file" && continue
|
||||
if grep -qE '-----BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----' "$file" 2>/dev/null; then
|
||||
echo "FINDING [private-key]: $file"
|
||||
FINDINGS=$((FINDINGS + 1))
|
||||
fi
|
||||
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f)
|
||||
|
||||
# Scan for high-entropy hex strings (40+ chars)
|
||||
while IFS= read -r file; do
|
||||
[ -f "$file" ] || continue
|
||||
is_allowed "$file" && continue
|
||||
if grep -qE '[0-9a-f]{40,}' "$file" 2>/dev/null; then
|
||||
# Filter out common false positives (git SHAs in lock files, etc.)
|
||||
BASENAME=$(basename "$file")
|
||||
if [[ "$BASENAME" != "package-lock.json" && "$BASENAME" != "*.lock" ]]; then
|
||||
MATCHES=$(grep -oE '[0-9a-f]{40,}' "$file" 2>/dev/null || true)
|
||||
if [ -n "$MATCHES" ]; then
|
||||
echo "FINDING [high-entropy-hex]: $file"
|
||||
FINDINGS=$((FINDINGS + 1))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f -not -name "package-lock.json" -not -name "*.lock")
|
||||
|
||||
if [ "$FINDINGS" -gt 0 ]; then
|
||||
echo "secret-scan: $FINDINGS finding(s) — FAIL"
|
||||
exit 1
|
||||
else
|
||||
echo "secret-scan: clean — PASS"
|
||||
exit 0
|
||||
fi
|
||||
Reference in New Issue
Block a user