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
100 changes: 100 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: CI

Comment on lines +1 to +2
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR metadata says this change is only adding CI, but this PR also includes non-CI changes (provider name constants, factory switch updates, e2e test change, and go.mod edit). Please confirm these are intended to be in this PR (or split them) so reviewers can track non-CI behavior changes separately.

Copilot uses AI. Check for mistakes.
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
verify:
name: Verify
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
cache: true
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.

- name: Download dependencies
run: make deps

Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.
- name: Verify dependencies are tidy
run: git diff --exit-code -- go.mod go.sum

- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.10
args: --help
verify: false
Comment on lines +36 to +41
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step is configured to run golangci-lint --help and sets verify: false, so it doesn't actually perform any linting/config validation and its intent is unclear. If the goal is to lint, let the action run with the repo config; if the goal is only to install the binary for make fmt/make lint, use an explicit install step (or an install-only mode) instead of invoking --help.

Suggested change
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.10
args: --help
verify: false
- name: Install golangci-lint
run: |
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

Copilot uses AI. Check for mistakes.

- name: Format check
run: make fmt
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.

Comment thread
spencercjh marked this conversation as resolved.
- name: Verify formatting
run: git diff --exit-code

- name: Run linter
run: make lint

- name: Run tests
run: make test

build:
name: Build
runs-on: ubuntu-latest
needs: verify
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.26
cache: true
Comment thread
spencercjh marked this conversation as resolved.
Comment thread
spencercjh marked this conversation as resolved.

- name: Build binary
run: make build
Comment thread
spencercjh marked this conversation as resolved.

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: spec-forge-linux
path: build/spec-forge
retention-days: 7

test-e2e:
name: E2E Tests
runs-on: ubuntu-latest
needs: build
Comment thread
spencercjh marked this conversation as resolved.
steps:
- name: Checkout code
uses: actions/checkout@v4
Comment thread
spencercjh marked this conversation as resolved.

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: stable
Comment thread
spencercjh marked this conversation as resolved.
cache: true
Comment thread
spencercjh marked this conversation as resolved.

- name: Set up JDK 25
uses: actions/setup-java@v4
Comment thread
spencercjh marked this conversation as resolved.
Comment on lines +90 to +94
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E2E job also uses go-version: stable, which can make runs non-reproducible (especially for go test and module resolution) compared to the pinned Go version in go.mod/build job. Prefer go-version-file: go.mod or the same pinned Go version across jobs.

Copilot uses AI. Check for mistakes.
with:
java-version: "25"
distribution: "temurin"

- name: Run E2E tests (${{ matrix.test-type }})
run: make test-e2e
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/spencercjh/spec-forge

go 1.26.0
go 1.26

require (
github.com/getkin/kin-openapi v0.133.0
Expand Down
7 changes: 6 additions & 1 deletion integration-tests/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ func TestE2E_MavenSpringBoot_Generate(t *testing.T) {
t.Errorf("Expected Maven build tool, got %s", info.BuildTool)
}

if !info.HasSpringdocDeps {
springInfo, ok := info.FrameworkData.(*spring.Info)
if !ok {
t.Fatal("Expected FrameworkData to be *spring.Info")
}

if !springInfo.HasSpringdocDeps {
t.Error("Expected springdoc dependencies to be present")
}

Expand Down
4 changes: 2 additions & 2 deletions internal/enricher/provider/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ func NewUnsupportedProviderError(provider string) *UnsupportedProviderError {
// NewProvider creates a provider based on the provider type
func NewProvider(cfg Config) (Provider, error) { //nolint:gocritic // copying config is acceptable
switch cfg.Provider {
case "openai":
case OpenAIProviderName:
return newOpenAIProvider(cfg.APIKey, cfg.Model)
case "anthropic":
return newAnthropicProvider(cfg.APIKey, cfg.Model)
case "ollama":
case OllamaProviderName:
baseURL := cfg.BaseURL
if baseURL == "" {
baseURL = "http://localhost:11434"
Expand Down
7 changes: 5 additions & 2 deletions internal/enricher/provider/ollama.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/tmc/langchaingo/llms/ollama"
)

// OllamaProviderName is the name of the Ollama provider.
const OllamaProviderName = "ollama"

// OllamaProvider implements Provider for Ollama local LLM using langchaingo
type OllamaProvider struct {
llm llms.Model
Expand Down Expand Up @@ -39,12 +42,12 @@ func newOllamaProvider(baseURL, model string) (*OllamaProvider, error) {
func (p *OllamaProvider) Generate(ctx context.Context, prompt string) (string, error) {
response, err := llms.GenerateFromSinglePrompt(ctx, p.llm, prompt)
if err != nil {
return "", fmt.Errorf("ollama generation failed: %w", err)
return "", fmt.Errorf("%s generation failed: %w", OllamaProviderName, err)
}
return response, nil
}

// Name returns the provider name
func (p *OllamaProvider) Name() string {
return "ollama"
return OllamaProviderName
}
5 changes: 4 additions & 1 deletion internal/enricher/provider/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/tmc/langchaingo/llms/openai"
)

// OpenAIProviderName is the name of the OpenAI provider.
const OpenAIProviderName = "openai"

Comment thread
spencercjh marked this conversation as resolved.
// OpenAIProvider implements Provider for OpenAI using langchaingo
type OpenAIProvider struct {
llm llms.Model
Expand Down Expand Up @@ -41,5 +44,5 @@ func (p *OpenAIProvider) Generate(ctx context.Context, prompt string) (string, e

// Name returns the provider name
func (p *OpenAIProvider) Name() string {
return "openai"
return OpenAIProviderName
}