Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Global code owners - all files require review from @bold-minds
* @bold-minds
36 changes: 36 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
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.

**Code Example**
If applicable, add a minimal code example to help explain your problem.

```go
// Your code here
```

**Environment (please complete the following information):**
- OS: [e.g. Linux, macOS, Windows]
- Go version: [e.g. 1.22.0]
- Library version: [e.g. v1.0.0]

**Additional context**
Add any other context about the problem here.
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Feature request
about: Suggest an idea for this project
title: '[FEATURE] '
labels: 'enhancement'
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Proposed API (if applicable)**
If this feature would involve API changes, please provide a code example of how it would work:

```go
// Your proposed API here
```

**Additional context**
Add any other context or screenshots about the feature request here.

**Backward Compatibility**
- [ ] This feature maintains backward compatibility
- [ ] This feature introduces breaking changes (please explain above)
1 change: 1 addition & 0 deletions .github/badges/coverage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":1,"label":"coverage","message":"pending","color":"lightgrey"}
1 change: 1 addition & 0 deletions .github/badges/dependabot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":1,"label":"security","message":"pending","color":"lightgrey"}
1 change: 1 addition & 0 deletions .github/badges/go-version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":1,"label":"Go","message":"pending","color":"lightgrey"}
1 change: 1 addition & 0 deletions .github/badges/golangci-lint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":1,"label":"golangci-lint","message":"pending","color":"lightgrey"}
1 change: 1 addition & 0 deletions .github/badges/last-updated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"schemaVersion":1,"label":"last updated","message":"pending","color":"lightgrey"}
42 changes: 42 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/Los_Angeles"
open-pull-requests-limit: 5
assignees:
- "bold-minds"
commit-message:
prefix: "deps"
include: "scope"
labels:
- "dependencies"
- "go"
groups:
go-dependencies:
patterns:
- "*"
update-types:
- "minor"
- "patch"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/Los_Angeles"
open-pull-requests-limit: 5
assignees:
- "bold-minds"
commit-message:
prefix: "ci"
include: "scope"
labels:
- "dependencies"
- "github-actions"
173 changes: 173 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
name: test

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

permissions:
contents: write
pull-requests: read
security-events: read
actions: read

jobs:
test:
strategy:
matrix:
include:
# Primary testing: Latest Go on all platforms (time/concurrency testing)
- go-version: '1.24'
os: ubuntu-latest
- go-version: '1.24'
os: windows-latest
- go-version: '1.24'
os: macos-latest
# Compatibility testing: Min supported Go on Linux only
- go-version: '1.22'
os: ubuntu-latest
# Intermediate compatibility: Go 1.23 on Linux only
- go-version: '1.23'
os: ubuntu-latest
runs-on: ${{ matrix.os }}
env:
GOTOOLCHAIN: go1.25.0
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Install dependencies
run: go mod download

# Build validation (cross-platform)
- name: Build validation
run: |
go build ./...
go mod tidy
git diff --exit-code go.mod go.sum

# Unit tests with race detection
- name: Run tests (Unix)
if: runner.os != 'Windows'
run: go test -v -race -coverprofile=coverage.out ./...
- name: Run tests (Windows)
if: runner.os == 'Windows'
run: go test -v -coverprofile="coverage.out" ./...
- name: Run benchmarks
run: go test -bench=. -benchmem ./...

# Generate badge data from CI metrics (only from primary job)
- name: Generate badge data
if: github.ref == 'refs/heads/main' && matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24'
env:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p .github/badges

# Install golangci-lint v2 directly (due to third-party action restrictions)
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest

# Generate coverage badge from existing coverage.out
if [[ -f "coverage.out" ]]; then
COVERAGE=$(go test -coverprofile=temp_coverage.out ./. 2>/dev/null | grep "coverage:" | grep -oE '[0-9]+\.[0-9]+%' | sed 's/%//' | head -1)
rm -f temp_coverage.out 2>/dev/null

if [[ -z "$COVERAGE" ]]; then
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
fi

if (( $(echo "$COVERAGE >= 80" | bc -l) )); then
echo '{"schemaVersion":1,"label":"coverage","message":"'$COVERAGE'%","color":"brightgreen"}' > .github/badges/coverage.json
elif (( $(echo "$COVERAGE >= 60" | bc -l) )); then
echo '{"schemaVersion":1,"label":"coverage","message":"'$COVERAGE'%","color":"yellow"}' > .github/badges/coverage.json
else
echo '{"schemaVersion":1,"label":"coverage","message":"'$COVERAGE'%","color":"red"}' > .github/badges/coverage.json
fi
fi

# Generate Go version badge
GO_VERSION=$(go version | grep -oE 'go[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1)
echo '{"schemaVersion":1,"label":"Go","message":"'$GO_VERSION'","color":"00ADD8"}' > .github/badges/go-version.json

# Generate last updated badge
LAST_COMMIT_DATE=$(git log -1 --format=%cd --date=short)
echo '{"schemaVersion":1,"label":"last updated","message":"'$LAST_COMMIT_DATE'","color":"teal"}' > .github/badges/last-updated.json

# Generate golangci-lint badge (v2 doesn't support --out-format, use exit code)
if golangci-lint run; then
echo '{"schemaVersion":1,"label":"golangci-lint","message":"0 issues","color":"brightgreen"}' > .github/badges/golangci-lint.json
else
# Count issues by running again and capturing output
ISSUES=$(golangci-lint run 2>&1 | grep -c "^.*\.go:" || echo "0")
if [[ $ISSUES -eq 0 ]]; then
echo '{"schemaVersion":1,"label":"golangci-lint","message":"passing","color":"brightgreen"}' > .github/badges/golangci-lint.json
else
echo '{"schemaVersion":1,"label":"golangci-lint","message":"'$ISSUES' issues","color":"red"}' > .github/badges/golangci-lint.json
fi
fi

# Generate comprehensive security badge (Dependabot + Code Scanning)
echo "🔍 Checking security alerts..."
DEPENDABOT_ALERTS=$(gh api repos/bold-minds/id/dependabot/alerts --jq 'length' 2>/dev/null || echo "0")
echo "Dependabot alerts: $DEPENDABOT_ALERTS"

# Debug code scanning API access
echo "🔍 Checking code scanning alerts..."
gh api repos/bold-minds/id/code-scanning/alerts 2>&1 | head -5 || echo "Code scanning API failed"
CODE_SCANNING_ALERTS=$(gh api repos/bold-minds/id/code-scanning/alerts --jq '[.[] | select(.state == "open")] | length' 2>/dev/null || echo "0")
echo "Code scanning alerts: $CODE_SCANNING_ALERTS"

TOTAL_ALERTS=$((DEPENDABOT_ALERTS + CODE_SCANNING_ALERTS))
OPEN_PRS=$(gh pr list --author "app/dependabot" --state open --json number --jq 'length' 2>/dev/null || echo "0")
echo "Total alerts: $TOTAL_ALERTS, Open PRs: $OPEN_PRS"

if [[ $TOTAL_ALERTS -gt 0 ]]; then
if [[ $DEPENDABOT_ALERTS -gt 0 && $CODE_SCANNING_ALERTS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"security","message":"'$TOTAL_ALERTS' alerts","color":"red"}' > .github/badges/dependabot.json
elif [[ $DEPENDABOT_ALERTS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"security","message":"'$DEPENDABOT_ALERTS' dependency alerts","color":"red"}' > .github/badges/dependabot.json
else
echo '{"schemaVersion":1,"label":"security","message":"'$CODE_SCANNING_ALERTS' code alerts","color":"red"}' > .github/badges/dependabot.json
fi
elif [[ $OPEN_PRS -gt 0 ]]; then
echo '{"schemaVersion":1,"label":"dependabot","message":"'$OPEN_PRS' updates","color":"blue"}' > .github/badges/dependabot.json
else
echo '{"schemaVersion":1,"label":"security","message":"all clear","color":"brightgreen"}' > .github/badges/dependabot.json
fi

- name: Generate GitHub App Token for Badge Commits
if: github.ref == 'refs/heads/main' && matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24'
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.BADGE_BOT_APP_ID }}
private-key: ${{ secrets.BADGE_BOT_PRIVATE_KEY }}

- name: Commit badges to main branch
if: github.ref == 'refs/heads/main' && matrix.os == 'ubuntu-latest' && matrix.go-version == '1.24'
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
# Configure git with GitHub App identity and authentication
git config --global user.name "Badge Automation Bot"
git config --global user.email "action@github.com"

# Configure git to use the GitHub App token for authentication
git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

# Add badge files to git
git add .github/badges/

# Commit if there are changes
if git diff --staged --quiet; then
echo "No badge changes to commit"
else
git commit -m "chore: update badges from CI run ${{ github.run_number }} [skip ci]"
# Push with GitHub App token as GITHUB_TOKEN (standard pattern for repository ruleset bypass)
git push origin HEAD:main
fi
44 changes: 31 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
Expand All @@ -11,22 +8,43 @@
# Test binary, built with `go test -c`
*.test

# Code coverage profiles and other test artifacts
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
coverage.*
*.coverprofile
profile.cov

# Badge files are now committed to main branch for direct access

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
go.work.sum

# env file
.env
# IDE files
.idea/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Coverage reports
coverage.out
coverage.html

# Build artifacts
dist/
build/

# Temporary files
*.tmp
*.temp

# Editor/IDE
# .idea/
# .vscode/
# Log files
*.log
Loading
Loading