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
5 changes: 1 addition & 4 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
# Code ownership for openapi
# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

* @zoobzio
* @zoobzio @wintermute-zbz
13 changes: 11 additions & 2 deletions .github/settings.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
repository:
name: openapi
description: OpenAPI 3.1 as native Go types
homepage: https://github.com/zoobzio/openapi
description: OpenAPI 3.1 specification as native Go types
homepage: https://openapi.zoobz.io
has_wiki: true
has_downloads: true
default_branch: main
allow_squash_merge: true
allow_merge_commit: false
allow_rebase_merge: false
delete_branch_on_merge: true
topics:
- go
- golang
- zoobzio
- openapi
- api
- specification
- json-schema
- rest

branches:
- name: main
Expand Down
55 changes: 19 additions & 36 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ jobs:
strategy:
matrix:
go-version: ['1.24', '1.25']

steps:
- uses: actions/checkout@v4

Expand All @@ -22,14 +21,8 @@ jobs:
with:
go-version: ${{ matrix.go-version }}

- name: Test openapi
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...

- name: Upload coverage
if: matrix.go-version == '1.25'
uses: codecov/codecov-action@v4
with:
file: ./coverage.txt
- name: Test
run: make test

lint:
name: Lint
Expand All @@ -43,22 +36,17 @@ jobs:
go-version: '1.25'

- name: golangci-lint
uses: golangci/golangci-lint-action@v8
uses: golangci/golangci-lint-action@v7
with:
version: v2.7.2
args: --config=.golangci.yml --timeout=5m

- name: Security Report
if: always()
run: |
golangci-lint run --config=.golangci.yml --output.formats=json > lint-report.json || true
echo "### Security Scan Summary" >> $GITHUB_STEP_SUMMARY
echo "Linters with findings:" >> $GITHUB_STEP_SUMMARY
jq -r '.Issues[] | .FromLinter' lint-report.json 2>/dev/null | sort | uniq -c | sort -nr >> $GITHUB_STEP_SUMMARY || echo "No issues found ✅" >> $GITHUB_STEP_SUMMARY

benchmark:
name: Benchmark
security:
name: Security
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4

Expand All @@ -67,26 +55,21 @@ jobs:
with:
go-version: '1.25'

- name: Run benchmarks
run: |
echo "### OpenAPI Library Benchmarks" | tee benchmark_results.txt
go test -bench=. -benchmem -benchtime=1s ./... | tee -a benchmark_results.txt
- name: Run Gosec
uses: securego/gosec@master
with:
args: '-fmt sarif -out gosec-results.sarif --no-fail ./...'

- name: Upload benchmark results
uses: actions/upload-artifact@v4
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
continue-on-error: true
with:
name: benchmark-results
path: benchmark_results.txt
sarif_file: gosec-results.sarif

ci-complete:
name: CI Complete
needs: [test, lint, security]
runs-on: ubuntu-latest
if: always()
needs: [test, lint, benchmark]
steps:
- name: Check results
run: |
if [[ "${{ needs.test.result }}" != "success" || "${{ needs.lint.result }}" != "success" || "${{ needs.benchmark.result }}" != "success" ]]; then
echo "One or more CI jobs failed"
exit 1
fi
- run: echo "CI complete"
50 changes: 3 additions & 47 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ on:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
schedule:
# Run at 3:17 AM UTC every Monday
- cron: '17 3 * * 1'

permissions:
actions: read
Expand All @@ -18,63 +15,22 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 360

strategy:
fail-fast: false
matrix:
language: [ 'go' ]

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4

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

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-extended,security-and-quality
languages: go
queries: security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
upload: true
output: codeql-results

- name: Upload CodeQL results
uses: actions/upload-artifact@v4
with:
name: codeql-results-${{ matrix.language }}
path: codeql-results/
retention-days: 7

- name: Security Summary
if: always()
run: |
echo "### CodeQL Security Analysis Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Language:** ${{ matrix.language }}" >> $GITHUB_STEP_SUMMARY
echo "**Status:** Analysis completed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Results will be available in the Security tab of your repository." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "#### What CodeQL Checks:" >> $GITHUB_STEP_SUMMARY
echo "- SQL injection vulnerabilities" >> $GITHUB_STEP_SUMMARY
echo "- Path traversal vulnerabilities" >> $GITHUB_STEP_SUMMARY
echo "- Cross-site scripting (XSS)" >> $GITHUB_STEP_SUMMARY
echo "- Insecure randomness" >> $GITHUB_STEP_SUMMARY
echo "- Hard-coded credentials" >> $GITHUB_STEP_SUMMARY
echo "- Command injection" >> $GITHUB_STEP_SUMMARY
echo "- And many more security patterns..." >> $GITHUB_STEP_SUMMARY
139 changes: 11 additions & 128 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,152 +6,35 @@ on:
pull_request:
branches: [ main, master ]

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

jobs:
coverage:
name: Test Coverage Analysis
name: Coverage
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4

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

- name: Install dependencies
run: |
go mod download
go install github.com/boumenot/gocover-cobertura@latest

- name: Run tests with coverage
run: |
echo "=== Testing openapi library ==="
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...

# Generate coverage report
go tool cover -func=coverage.out > coverage-summary.txt
echo "Coverage Summary:"
tail -1 coverage-summary.txt
run: go test -tags testing -coverprofile=coverage.out -covermode=atomic ./...

# Generate HTML report
go tool cover -html=coverage.out -o coverage.html

# Convert to Cobertura format for better PR integration
gocover-cobertura < coverage.out > coverage.xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
- name: Upload to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.out
flags: unit
name: openapi-coverage
flags: unittests
name: codecov-openapi
fail_ci_if_error: false
verbose: true

- name: Generate coverage badge
run: |
# Extract coverage percentage
COVERAGE=$(go tool cover -func=coverage.out | tail -1 | grep -oE '[0-9]+\.[0-9]+' | tail -1)
echo "Coverage: $COVERAGE%"
echo "COVERAGE=$COVERAGE" >> $GITHUB_ENV

# Determine badge color
if awk "BEGIN {exit !($COVERAGE >= 80)}"; then
COLOR="green"
elif awk "BEGIN {exit !($COVERAGE >= 60)}"; then
COLOR="yellow"
else
COLOR="red"
fi
echo "COVERAGE_COLOR=$COLOR" >> $GITHUB_ENV

- name: Create coverage comment (PR only)
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');

// Read coverage summary
const summary = fs.readFileSync('coverage-summary.txt', 'utf8');
const lines = summary.split('\n').filter(line => line.trim());

// Extract key metrics
const totalLine = lines[lines.length - 1];
const coverage = totalLine.match(/(\d+\.\d+)%/)?.[1] || 'N/A';

// Create comment body
const body = `## 📊 Coverage Report

**Total Coverage:** ${coverage}%

### Coverage by Package
\`\`\`
${lines.slice(0, -1).join('\n')}
\`\`\`

---
*Coverage report generated by [Codecov](https://codecov.io)*`;

// Post or update comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});

const botComment = comments.find(comment =>
comment.user.type === 'Bot' && comment.body.includes('📊 Coverage Report')
);

if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
continue-on-error: true

- name: Upload coverage artifacts
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: |
coverage.*
coverage-summary.txt
retention-days: 30

- name: Coverage summary
- name: Coverage Summary
run: |
echo "### 📊 Test Coverage Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Coverage:** ${{ env.COVERAGE }}%" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "#### Coverage by Package" >> $GITHUB_STEP_SUMMARY
go tool cover -func=coverage.out | tail -1
echo "## Coverage Report" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
head -n -1 coverage-summary.txt >> $GITHUB_STEP_SUMMARY
go tool cover -func=coverage.out >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "#### Coverage Reports" >> $GITHUB_STEP_SUMMARY
echo "- 📄 [HTML Report](coverage.html) - Download from artifacts" >> $GITHUB_STEP_SUMMARY
echo "- 📊 [Codecov Dashboard](https://codecov.io/gh/zoobzio/openapi) - View online" >> $GITHUB_STEP_SUMMARY
Loading
Loading