Skip to content

feat!: introduce comprehensive OpenAPI 3.0.x/3.1.x parser with validation, walking, and upgrading #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Ensure consistent line endings across platforms
# All text files should use LF (Unix) line endings

# Default behavior: normalize line endings to LF on checkin,
# but allow platform-specific line endings on checkout
* text=auto

# Force LF line endings for specific file types that should always be consistent
*.go text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.json text eol=lf
*.md text eol=lf
*.txt text eol=lf
*.sh text eol=lf

# Test data files should always use LF to match Go's YAML output
testdata/**/*.yaml text eol=lf
testdata/**/*.yml text eol=lf
testdata/**/*.json text eol=lf

# Binary files should not be normalized
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.zip binary
*.tar.gz binary
58 changes: 58 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
version: 2
updates:
# Enable version updates for Go modules
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
open-pull-requests-limit: 10
reviewers:
- "speakeasy-api/maintainers"
assignees:
- "speakeasy-api/maintainers"
commit-message:
prefix: "deps"
prefix-development: "deps"
include: "scope"
labels:
- "dependencies"
- "go"
groups:
# Group patch and minor updates together
go-minor-patch:
patterns:
- "*"
update-types:
- "minor"
- "patch"
# Keep major updates separate for careful review
go-major:
patterns:
- "*"
update-types:
- "major"

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
open-pull-requests-limit: 5
reviewers:
- "speakeasy-api/maintainers"
assignees:
- "speakeasy-api/maintainers"
commit-message:
prefix: "ci"
include: "scope"
labels:
- "dependencies"
- "github-actions"
groups:
github-actions:
patterns:
- "*"
20 changes: 20 additions & 0 deletions .github/workflows/commits.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Validate Conventional Commits

on:
pull_request:
types:
- opened
- reopened
- edited
- synchronize
- ready_for_review
jobs:
build:
name: Conventional Commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 # v1.3.0
- uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
145 changes: 118 additions & 27 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,125 @@ on:
branches: [main]

jobs:
test-and-build:
lint:
name: Lint and Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install mise
uses: jdx/mise-action@v2

- name: Get Go cache paths
id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT

- name: Cache Go Build Cache
uses: actions/cache@v4
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}

- name: Cache Go Mod Cache
uses: actions/cache@v4
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}

- name: Check code formatting
run: mise run fmt-check

- name: Check module dependencies
run: mise run mod-check

- name: Run lint task
run: mise run lint

- name: Check examples are up to date
run: mise run examples-check

test-and-build:
name: Test and Build
needs: lint
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: write

steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
- name: Install mise
uses: jdx/mise-action@v2

- name: Get Go cache paths
id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT

- name: Cache Go Build Cache
uses: actions/cache@v4
with:
go-version: "1.23"
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}

- name: Install dependencies
run: go mod download
- name: Cache Go Mod Cache
uses: actions/cache@v4
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v6
- name: Cache downloaded test files
uses: actions/cache@v4
with:
version: latest
path: |
~/tmp/speakeasy-api_arazzo
${{ runner.temp }}/speakeasy-api_arazzo
key: arazzo-test-files-${{ hashFiles('arazzo/arazzo_test.go') }}
restore-keys: |
arazzo-test-files-

- name: Run tests with coverage
run: |
go test -v -race -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -html=coverage.out -o coverage.html
if: matrix.os == 'ubuntu-latest'
run: mise run test-coverage

- name: Run tests (Windows)
if: matrix.os == 'windows-latest'
run: gotestsum --format testname -- -race ./...

- name: Calculate coverage
if: matrix.os == 'ubuntu-latest'
id: coverage
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}')
echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT
echo "Coverage: $COVERAGE"

- name: Get main branch coverage
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
id: main-coverage
run: |
# Store current working directory
CURRENT_DIR=$(pwd)

# Fetch main branch
git fetch origin main:main

# Checkout main branch in a temporary directory
git worktree add /tmp/main-branch main

# Run tests on main branch to get coverage
cd /tmp/main-branch
go test -coverprofile=main-coverage.out -covermode=atomic ./... > /dev/null 2>&1 || echo "Main branch tests failed"

if [ -f main-coverage.out ]; then
MAIN_COVERAGE=$(go tool cover -func=main-coverage.out | grep total | awk '{print $3}' || echo "0.0%")
echo "main-coverage=$MAIN_COVERAGE" >> $GITHUB_OUTPUT
Expand All @@ -69,23 +137,24 @@ jobs:
echo "main-coverage=0.0%" >> $GITHUB_OUTPUT
echo "Could not get main branch coverage"
fi

# Return to original directory
cd "$CURRENT_DIR"

# Clean up worktree (force removal to handle modified files)
git worktree remove --force /tmp/main-branch || rm -rf /tmp/main-branch

- name: Generate coverage summary
if: matrix.os == 'ubuntu-latest'
id: coverage-summary
run: |
echo "## πŸ“Š Test Coverage Report" > coverage-summary.md
echo "" >> coverage-summary.md

# Current coverage
CURRENT_COV="${{ steps.coverage.outputs.coverage }}"
echo "**Current Coverage:** \`$CURRENT_COV\`" >> coverage-summary.md

# Compare with main if this is a PR
if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ steps.main-coverage.outputs.main-coverage }}" != "" ]; then
MAIN_COV="${{ steps.main-coverage.outputs.main-coverage }}"
Expand All @@ -109,7 +178,7 @@ jobs:
fi
fi
fi

echo "" >> coverage-summary.md
echo "### Coverage by Package" >> coverage-summary.md
echo "\`\`\`" >> coverage-summary.md
Expand All @@ -122,25 +191,25 @@ jobs:
echo "_Generated by GitHub Actions_" >> coverage-summary.md

- name: Comment PR with coverage
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const coverageSummary = fs.readFileSync('coverage-summary.md', 'utf8');

// Look for existing coverage comment
const comments = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});

const botComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('πŸ“Š Test Coverage Report')
);

if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
Expand All @@ -160,12 +229,34 @@ jobs:
}

- name: Upload coverage artifact
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: |
coverage.out
coverage.html

- name: Build
- name: Build (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: mise run build

- name: Build (Windows)
if: matrix.os == 'windows-latest'
run: go build -v ./...

# Summary job that depends on all matrix jobs
# This provides a single status check for branch protection
test-summary:
name: Test Summary
needs: [lint, test-and-build]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
if [ "${{ needs.test-and-build.result }}" != "success" ]; then
echo "Tests failed or were cancelled"
exit 1
fi
echo "All tests passed successfully"
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Coverage files generated by test-coverage task
coverage.out
coverage.html

# VSCode settings (user-specific)
.vscode/*
!.vscode/settings.example.json
Loading
Loading