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
30 changes: 15 additions & 15 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ jobs:
contents: read

steps:
- name: Check out code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check out code
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'

- name: Run tests
run: make test
- name: Run tests
run: make test

- name: Upload coverage
uses: codecov/codecov-action@v4
if: success()
with:
fail_ci_if_error: false
- name: Upload coverage
uses: codecov/codecov-action@v4

Choose a reason for hiding this comment

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

Issue: Pin the codecov action to a specific commit hash instead of using the v4 tag. This prevents potential supply chain attacks by ensuring the exact version of the action is used consistently.

Recommended Code Changes:

uses: codecov/codecov-action@[specific-commit-hash]

if: success()
with:
fail_ci_if_error: false
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/codeGROOVE-dev/prcost
go 1.25.3

require (
github.com/codeGROOVE-dev/ds9 v0.0.0-20251028153329-0fbc86f835ed
github.com/codeGROOVE-dev/ds9 v0.5.0
github.com/codeGROOVE-dev/gsm v0.0.0-20251019065141-833fe2363d22
github.com/codeGROOVE-dev/prx v0.0.0-20251027204543-4e6165f046e5
github.com/codeGROOVE-dev/prx v0.0.0-20251028202628-9f237ee71356
github.com/codeGROOVE-dev/turnclient v0.0.0-20251028130307-1f85c9aa43c4
golang.org/x/time v0.14.0
)
Expand Down
14 changes: 4 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
github.com/codeGROOVE-dev/ds9 v0.0.0-20251028153329-0fbc86f835ed h1:PNvhCROSwAybWrJwYkTBUAaydQKJ8dWD8ml7gde5nkA=
github.com/codeGROOVE-dev/ds9 v0.0.0-20251028153329-0fbc86f835ed/go.mod h1:/hZt40fp5FfuzVwiw9fgoOMBAa260rKPiWNJt8RU10Y=
github.com/codeGROOVE-dev/ds9 v0.5.0 h1:J5IX1S1HtuJjGvj/gaMCXMY0HQb5Gzqz5c1a2uz14VM=
github.com/codeGROOVE-dev/ds9 v0.5.0/go.mod h1:/hZt40fp5FfuzVwiw9fgoOMBAa260rKPiWNJt8RU10Y=
github.com/codeGROOVE-dev/gsm v0.0.0-20251019065141-833fe2363d22 h1:gtN3rOc6YspO646BkcOxBhPjEqKUz+jl175jIqglfDg=
github.com/codeGROOVE-dev/gsm v0.0.0-20251019065141-833fe2363d22/go.mod h1:KV+w19ubP32PxZPE1hOtlCpTaNpF0Bpb32w5djO8UTg=
github.com/codeGROOVE-dev/prx v0.0.0-20251027012315-7b273aabfc7d h1:kUaCKFRxWFrWEyl4fVHi+eY/D5tKhBU29a8YbQyihEk=
github.com/codeGROOVE-dev/prx v0.0.0-20251027012315-7b273aabfc7d/go.mod h1:7qLbi18baOyS8yO/6/64SBIqtyzSzLFdsDST15NPH3w=
github.com/codeGROOVE-dev/prx v0.0.0-20251027204543-4e6165f046e5 h1:tjxTLJ5NXx1xhReL4M+J4LTl/JGNSZjPrznAoci06OA=
github.com/codeGROOVE-dev/prx v0.0.0-20251027204543-4e6165f046e5/go.mod h1:FEy3gz9IYDXWnKWkoDSL+pWu6rujxbBSrF4w5A8QSK0=
github.com/codeGROOVE-dev/retry v1.2.0 h1:xYpYPX2PQZmdHwuiQAGGzsBm392xIMl4nfMEFApQnu8=
github.com/codeGROOVE-dev/retry v1.2.0/go.mod h1:8OgefgV1XP7lzX2PdKlCXILsYKuz6b4ZpHa/20iLi8E=
github.com/codeGROOVE-dev/prx v0.0.0-20251028202628-9f237ee71356 h1:lHoHnylLAp7/7BMhdiTh9Z2+p4ATcQ7aFcgqxOFGzE4=
github.com/codeGROOVE-dev/prx v0.0.0-20251028202628-9f237ee71356/go.mod h1:FEy3gz9IYDXWnKWkoDSL+pWu6rujxbBSrF4w5A8QSK0=
github.com/codeGROOVE-dev/retry v1.3.0 h1:/+ipAWRJLL6y1R1vprYo0FSjSBvH6fE5j9LKXjpD54g=
github.com/codeGROOVE-dev/retry v1.3.0/go.mod h1:8OgefgV1XP7lzX2PdKlCXILsYKuz6b4ZpHa/20iLi8E=
github.com/codeGROOVE-dev/turnclient v0.0.0-20251022064427-5a712e1e10e6 h1:7FCmaftkl362oTZHVJyUg+xhxqfQFx+JisBf7RgklL8=
github.com/codeGROOVE-dev/turnclient v0.0.0-20251022064427-5a712e1e10e6/go.mod h1:fYwtN9Ql6lY8t2WvCfENx+mP5FUwjlqwXCLx9CVLY20=
github.com/codeGROOVE-dev/turnclient v0.0.0-20251028130307-1f85c9aa43c4 h1:si9tMEo5SXpDuDXGkJ1zNnnpP8TbmakrkNujAbpKlqA=
github.com/codeGROOVE-dev/turnclient v0.0.0-20251028130307-1f85c9aa43c4/go.mod h1:bFWMd0JeaJY0kSIO5AcRQdJLXF3Fo3eKclE49vmIZes=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
Expand Down
24 changes: 12 additions & 12 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"sync"
"time"

"github.com/codeGROOVE-dev/ds9"
"github.com/codeGROOVE-dev/ds9/pkg/datastore"
"github.com/codeGROOVE-dev/gsm"
"github.com/codeGROOVE-dev/prcost/pkg/cost"
"github.com/codeGROOVE-dev/prcost/pkg/github"
Expand Down Expand Up @@ -117,7 +117,7 @@ type Server struct {
prDataCacheMu sync.RWMutex
calcResultCacheMu sync.RWMutex
// DataStore client for persistent caching (nil if not enabled).
dsClient *ds9.Client
dsClient *datastore.Client
}

// CalculateRequest represents a request to calculate PR costs.
Expand Down Expand Up @@ -236,7 +236,7 @@ func New() *Server {

// Initialize DataStore client if DATASTORE_DB is set (persistent caching across restarts).
if dbID := os.Getenv("DATASTORE_DB"); dbID != "" {
dsClient, err := ds9.NewClientWithDatabase(ctx, "", dbID)
dsClient, err := datastore.NewClientWithDatabase(ctx, "", dbID)
if err != nil {
logger.WarnContext(ctx, "Failed to initialize DataStore client - persistent caching disabled",
"database_id", dbID, "error", err)
Expand Down Expand Up @@ -374,11 +374,11 @@ func (s *Server) cachedPRQuery(ctx context.Context, key string) ([]github.PRSumm
return nil, false
}

dsKey := ds9.NameKey("PRQueryCache", key, nil)
dsKey := datastore.NameKey("PRQueryCache", key, nil)
var entity prQueryCacheEntity
err := s.dsClient.Get(ctx, dsKey, &entity)
if err != nil {
if !errors.Is(err, ds9.ErrNoSuchEntity) {
if !errors.Is(err, datastore.ErrNoSuchEntity) {
s.logger.WarnContext(ctx, "DataStore cache read failed", "key", key, "error", err)
}
return nil, false
Expand Down Expand Up @@ -452,7 +452,7 @@ func (s *Server) cachePRQuery(ctx context.Context, key string, prs []github.PRSu
QueryKey: key,
}

dsKey := ds9.NameKey("PRQueryCache", key, nil)
dsKey := datastore.NameKey("PRQueryCache", key, nil)
if _, err := s.dsClient.Put(ctx, dsKey, &entity); err != nil {
s.logger.WarnContext(ctx, "Failed to write PR query to DataStore", "key", key, "error", err)
return
Expand Down Expand Up @@ -482,11 +482,11 @@ func (s *Server) cachedPRData(ctx context.Context, key string) (cost.PRData, boo
return cost.PRData{}, false
}

dsKey := ds9.NameKey("PRDataCache", key, nil)
dsKey := datastore.NameKey("PRDataCache", key, nil)
var entity prDataCacheEntity
err := s.dsClient.Get(ctx, dsKey, &entity)
if err != nil {
if !errors.Is(err, ds9.ErrNoSuchEntity) {
if !errors.Is(err, datastore.ErrNoSuchEntity) {
s.logger.WarnContext(ctx, "DataStore cache read failed", "key", key, "error", err)
}
return cost.PRData{}, false
Expand Down Expand Up @@ -542,7 +542,7 @@ func (s *Server) cachePRData(ctx context.Context, key string, prData cost.PRData
URL: key,
}

dsKey := ds9.NameKey("PRDataCache", key, nil)
dsKey := datastore.NameKey("PRDataCache", key, nil)
if _, err := s.dsClient.Put(ctx, dsKey, &entity); err != nil {
s.logger.WarnContext(ctx, "Failed to write PR data to DataStore", "key", key, "error", err)
return
Expand Down Expand Up @@ -586,11 +586,11 @@ func (s *Server) cachedCalcResult(ctx context.Context, prURL string, cfg cost.Co
return cost.Breakdown{}, false
}

dsKey := ds9.NameKey("CalcResultCache", key, nil)
dsKey := datastore.NameKey("CalcResultCache", key, nil)
var entity calcResultCacheEntity
err := s.dsClient.Get(ctx, dsKey, &entity)
if err != nil {
if !errors.Is(err, ds9.ErrNoSuchEntity) {
if !errors.Is(err, datastore.ErrNoSuchEntity) {
s.logger.WarnContext(ctx, "DataStore calc cache read failed", "key", key, "error", err)
}
return cost.Breakdown{}, false
Expand Down Expand Up @@ -646,7 +646,7 @@ func (s *Server) cacheCalcResult(ctx context.Context, prURL string, cfg cost.Con
ConfigKey: configHash(cfg),
}

dsKey := ds9.NameKey("CalcResultCache", key, nil)
dsKey := datastore.NameKey("CalcResultCache", key, nil)
if _, err := s.dsClient.Put(ctx, dsKey, &entity); err != nil {
s.logger.WarnContext(ctx, "Failed to write calc result to DataStore", "key", key, "error", err)
return
Expand Down
8 changes: 7 additions & 1 deletion pkg/cost/cost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log/slog"
"os"
"strings"
"sync"
"testing"
"time"
)
Expand Down Expand Up @@ -702,6 +703,7 @@ func TestCalculateFastTurnaroundNoDelay(t *testing.T) {

// Mock PRFetcher for testing AnalyzePRs
type mockPRFetcher struct {
mu sync.Mutex
data map[string]PRData
failURLs map[string]error
callCount int
Expand All @@ -710,10 +712,14 @@ type mockPRFetcher struct {
}

func (m *mockPRFetcher) FetchPRData(ctx context.Context, prURL string, updatedAt time.Time) (PRData, error) {
m.mu.Lock()
m.callCount++
callCount := m.callCount
maxCalls := m.maxCalls
m.mu.Unlock()

// Fail after max calls if set
if m.maxCalls > 0 && m.callCount > m.maxCalls {
if maxCalls > 0 && callCount > maxCalls {
return PRData{}, errors.New("max calls exceeded")
}

Expand Down
Loading