Skip to content

Commit afe29a0

Browse files
mstaebleclaude
andcommitted
Switch release consumers from BigQuery to PostgreSQL
Switch all release data consumers to read from the release_definitions table in PostgreSQL, populated by the release-definitions loader from the prior commit. Key changes: - getReleases() in server.go reads exclusively from PG - Remove QueryReleases and QueryReleaseDates from the DataProvider interface and both implementations (BQ and PG providers) - GetComponentReport, RefreshMetricsDB, and syncRegressions call GetReleasesFromDB directly instead of going through the provider - Add GetReleaseDatesFromDB to derive CR time ranges from PG - Update releasefallback and test_details to use GetReleaseDatesFromDB - Delete BQ releasedates.go - Switch automatejira, MCP releases tool, and job_runs to use PG - Remove hardcoded releaseMetadata map from PG provider - Fix stale "from big query" error messages in server.go Ref: TRT-2734 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 801c5d3 commit afe29a0

20 files changed

Lines changed: 312 additions & 352 deletions

File tree

cmd/sippy/automatejira.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ func NewAutomateJiraCommand() *cobra.Command {
152152
if err != nil {
153153
log.WithError(err).Fatal("unable to load views")
154154
}
155-
releases, err := api.GetReleases(context.Background(), bigQueryClient, false)
155+
dbc, err := f.PostgresFlags.GetDBClient()
156+
if err != nil {
157+
log.WithError(err).Fatal("unable to connect to postgres")
158+
}
159+
releases, err := api.GetReleasesFromDB(ctx, dbc)
156160
if err != nil {
157161
log.WithError(err).Fatal("error querying releases")
158162
}
@@ -178,10 +182,6 @@ func NewAutomateJiraCommand() *cobra.Command {
178182
return errors.WithMessage(err, "error validating options")
179183
}
180184

181-
dbc, err := f.PostgresFlags.GetDBClient()
182-
if err != nil {
183-
log.WithError(err).Fatal("unable to connect to postgres")
184-
}
185185
j, err := jiraautomator.NewJiraAutomator(
186186
jiraClient, bigQueryClient, provider, dbc, cacheOpts,
187187
views.ComponentReadiness, releases, f.SippyURL, f.JiraAccount,

cmd/sippy/load.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import (
3737
"github.com/openshift/sippy/pkg/dataloader/prowloader"
3838
"github.com/openshift/sippy/pkg/dataloader/prowloader/gcs"
3939
"github.com/openshift/sippy/pkg/dataloader/prowloader/github"
40-
releasedefloader "github.com/openshift/sippy/pkg/dataloader/releasedefloader"
40+
"github.com/openshift/sippy/pkg/dataloader/releasedefloader"
4141
"github.com/openshift/sippy/pkg/dataloader/releaseloader"
4242
"github.com/openshift/sippy/pkg/dataloader/testownershiploader"
4343
"github.com/openshift/sippy/pkg/db"
@@ -176,9 +176,12 @@ func NewLoadCommand() *cobra.Command {
176176
}
177177
}
178178
if len(releaseConfigs) == 0 && bigqueryErr == nil {
179-
releaseConfigs, err = api.GetReleasesFromBigQuery(context.Background(), bqc)
180-
if err != nil {
181-
return errors.Wrapf(err, "error querying releases from bigquery")
179+
rows, bqErr := api.GetReleaseRowsFromBigQuery(context.Background(), bqc)
180+
if bqErr != nil {
181+
return errors.Wrapf(bqErr, "error querying releases from bigquery")
182+
}
183+
for _, row := range rows {
184+
releaseConfigs = append(releaseConfigs, api.DefinitionToRelease(releasedefloader.ReleaseRowToDefinition(row)))
182185
}
183186
}
184187

cmd/sippy/seed_data.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/spf13/pflag"
1717
"gopkg.in/yaml.v3"
1818

19+
"github.com/openshift/sippy/pkg/api"
1920
componentreadiness "github.com/openshift/sippy/pkg/api/componentreadiness"
2021
pgprovider "github.com/openshift/sippy/pkg/api/componentreadiness/dataprovider/postgres"
2122
"github.com/openshift/sippy/pkg/api/componentreadiness/utils"
@@ -746,7 +747,7 @@ func syncRegressions(dbc *db.DB) error {
746747
provider := pgprovider.NewPostgresProvider(dbc, nil)
747748
ctx := context.Background()
748749

749-
releases, err := provider.QueryReleases(ctx)
750+
releases, err := api.GetReleasesFromDB(ctx, dbc)
750751
if err != nil {
751752
return fmt.Errorf("querying releases: %w", err)
752753
}

pkg/api/componentreadiness/component_report.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func GetComponentReport(
8282
reqOptions reqopts.RequestOptions,
8383
baseURL string,
8484
) (report crtype.ComponentReport, errs []error) {
85-
releaseConfigs, err := provider.QueryReleases(ctx)
85+
releaseConfigs, err := api.GetReleasesFromDB(ctx, dbc)
8686
if err != nil {
8787
return report, []error{err}
8888
}
@@ -278,7 +278,7 @@ func (c *ComponentReportGenerator) initializeMiddleware() {
278278
c.middlewares = middleware.List{}
279279
// Initialize all our middleware applicable to this request.
280280
if c.ReqOptions.AdvancedOption.IncludeMultiReleaseAnalysis && c.ReqOptions.SampleRelease.PullRequestOptions == nil {
281-
c.middlewares = append(c.middlewares, releasefallback.NewReleaseFallbackMiddleware(c.dataProvider, c.ReqOptions, c.releaseConfigs))
281+
c.middlewares = append(c.middlewares, releasefallback.NewReleaseFallbackMiddleware(c.dataProvider, c.ReqOptions, c.releaseConfigs, c.dbc))
282282
}
283283
if c.dbc != nil {
284284
c.middlewares = append(c.middlewares, regressiontracker.NewRegressionTrackerMiddleware(c.dbc, c.ReqOptions))

pkg/api/componentreadiness/dataprovider/bigquery/provider.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/openshift/sippy/pkg/apis/api/componentreport/crtest"
2020
"github.com/openshift/sippy/pkg/apis/api/componentreport/reqopts"
2121
apiCache "github.com/openshift/sippy/pkg/apis/cache"
22-
v1 "github.com/openshift/sippy/pkg/apis/sippy/v1"
2322
bqcachedclient "github.com/openshift/sippy/pkg/bigquery"
2423
"github.com/openshift/sippy/pkg/bigquery/bqlabel"
2524
"github.com/openshift/sippy/pkg/util/param"
@@ -170,14 +169,6 @@ func (p *BigQueryProvider) QueryJobVariants(ctx context.Context) (crtest.JobVari
170169
return variants, nil
171170
}
172171

173-
func (p *BigQueryProvider) QueryReleaseDates(ctx context.Context, reqOptions reqopts.RequestOptions) ([]crtest.ReleaseTimeRange, []error) {
174-
return GetReleaseDatesFromBigQuery(ctx, p.client, reqOptions)
175-
}
176-
177-
func (p *BigQueryProvider) QueryReleases(ctx context.Context) ([]v1.Release, error) {
178-
return apiPkg.GetReleasesFromBigQuery(ctx, p.client)
179-
}
180-
181172
func (p *BigQueryProvider) QueryUniqueVariantValues(ctx context.Context, field string, nested bool) ([]string, error) {
182173
unnest := ""
183174
if nested {

pkg/api/componentreadiness/dataprovider/bigquery/releasedates.go

Lines changed: 0 additions & 44 deletions
This file was deleted.

pkg/api/componentreadiness/dataprovider/interface.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"github.com/openshift/sippy/pkg/apis/api/componentreport/crtest"
99
"github.com/openshift/sippy/pkg/apis/api/componentreport/reqopts"
1010
"github.com/openshift/sippy/pkg/apis/cache"
11-
v1 "github.com/openshift/sippy/pkg/apis/sippy/v1"
1211
)
1312

1413
// TestStatusQuerier fetches aggregated test pass/fail counts.
@@ -40,12 +39,6 @@ type MetadataQuerier interface {
4039
// QueryJobVariants returns all variant names and their possible values.
4140
QueryJobVariants(ctx context.Context) (crtest.JobVariants, []error)
4241

43-
// QueryReleaseDates returns the time ranges for each known release.
44-
QueryReleaseDates(ctx context.Context, reqOptions reqopts.RequestOptions) ([]crtest.ReleaseTimeRange, []error)
45-
46-
// QueryReleases returns known release configurations.
47-
QueryReleases(ctx context.Context) ([]v1.Release, error)
48-
4942
// QueryUniqueVariantValues returns distinct values for a variant column
5043
// from the past 60 days.
5144
QueryUniqueVariantValues(ctx context.Context, field string, nested bool) ([]string, error)

pkg/api/componentreadiness/dataprovider/postgres/provider.go

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"github.com/openshift/sippy/pkg/apis/api/componentreport/crtest"
1919
"github.com/openshift/sippy/pkg/apis/api/componentreport/reqopts"
2020
"github.com/openshift/sippy/pkg/apis/cache"
21-
v1 "github.com/openshift/sippy/pkg/apis/sippy/v1"
2221
"github.com/openshift/sippy/pkg/db"
2322
)
2423

@@ -133,98 +132,6 @@ func (p *PostgresProvider) QueryJobVariants(ctx context.Context) (crtest.JobVari
133132
return variants, nil
134133
}
135134

136-
// releaseMetadata holds hardcoded release info for known releases.
137-
// This avoids needing a releases table — we derive release names from prow_jobs
138-
// and fill in metadata from this map.
139-
var releaseMetadata = map[string]struct {
140-
previousRelease string
141-
gaOffsetDays int // 0 = no GA date (in development)
142-
product string // empty = defaults to "OCP"
143-
}{
144-
"4.17": {previousRelease: "4.16", gaOffsetDays: -540},
145-
"4.18": {previousRelease: "4.17", gaOffsetDays: -395},
146-
"4.19": {previousRelease: "4.18", gaOffsetDays: -289},
147-
"4.20": {previousRelease: "4.19", gaOffsetDays: -163},
148-
"4.21": {previousRelease: "4.20", gaOffsetDays: -58},
149-
"4.22": {previousRelease: "4.21"},
150-
"5.0": {previousRelease: "4.22"},
151-
}
152-
153-
func (p *PostgresProvider) QueryReleases(ctx context.Context) ([]v1.Release, error) {
154-
var releaseNames []string
155-
err := p.dbc.DB.WithContext(ctx).Raw(`SELECT DISTINCT release FROM prow_jobs WHERE deleted_at IS NULL ORDER BY release DESC`).
156-
Pluck("release", &releaseNames).Error
157-
if err != nil {
158-
return nil, fmt.Errorf("querying releases: %w", err)
159-
}
160-
161-
caps := map[v1.ReleaseCapability]bool{
162-
v1.ComponentReadinessCap: true,
163-
v1.FeatureGatesCap: true,
164-
v1.MetricsCap: true,
165-
v1.PayloadTagsCap: true,
166-
v1.SippyClassicCap: true,
167-
}
168-
169-
now := time.Now().UTC()
170-
var releases []v1.Release
171-
for _, name := range releaseNames {
172-
rel := v1.Release{
173-
Release: name,
174-
Capabilities: caps,
175-
Product: "OCP",
176-
}
177-
if meta, ok := releaseMetadata[name]; ok {
178-
rel.PreviousRelease = meta.previousRelease
179-
if meta.gaOffsetDays != 0 {
180-
ga := now.AddDate(0, 0, meta.gaOffsetDays)
181-
rel.GADate = &ga
182-
}
183-
if meta.product != "" {
184-
rel.Product = meta.product
185-
}
186-
}
187-
releases = append(releases, rel)
188-
}
189-
return releases, nil
190-
}
191-
192-
func (p *PostgresProvider) QueryReleaseDates(ctx context.Context, _ reqopts.RequestOptions) ([]crtest.ReleaseTimeRange, []error) {
193-
// Derive time ranges from actual data in the DB rather than hardcoded GA dates.
194-
// This ensures fallback queries find data where it actually exists.
195-
type releaseRange struct {
196-
Release string
197-
Start time.Time
198-
End time.Time
199-
}
200-
var ranges []releaseRange
201-
err := p.dbc.DB.WithContext(ctx).Raw(`
202-
SELECT pj.release,
203-
MIN(pjr.timestamp) AS start,
204-
MAX(pjr.timestamp) AS end
205-
FROM prow_job_runs pjr
206-
JOIN prow_jobs pj ON pj.id = pjr.prow_job_id
207-
WHERE pj.deleted_at IS NULL AND pjr.deleted_at IS NULL
208-
GROUP BY pj.release
209-
ORDER BY pj.release DESC
210-
`).Scan(&ranges).Error
211-
if err != nil {
212-
return nil, []error{fmt.Errorf("querying release dates: %w", err)}
213-
}
214-
215-
var dates []crtest.ReleaseTimeRange
216-
for _, r := range ranges {
217-
start := r.Start
218-
end := r.End
219-
dates = append(dates, crtest.ReleaseTimeRange{
220-
Release: r.Release,
221-
Start: &start,
222-
End: &end,
223-
})
224-
}
225-
return dates, nil
226-
}
227-
228135
func (p *PostgresProvider) QueryUniqueVariantValues(ctx context.Context, field string, nested bool) ([]string, error) {
229136
if nested {
230137
// Return all variant key names

pkg/api/componentreadiness/middleware/releasefallback/releasefallback.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/openshift/sippy/pkg/apis/api/componentreport/testdetails"
1717
apiCache "github.com/openshift/sippy/pkg/apis/cache"
1818
v1 "github.com/openshift/sippy/pkg/apis/sippy/v1"
19+
"github.com/openshift/sippy/pkg/db"
1920
log "github.com/sirupsen/logrus"
2021
"k8s.io/apimachinery/pkg/util/sets"
2122

@@ -35,9 +36,11 @@ func NewReleaseFallbackMiddleware(
3536
provider dataprovider.DataProvider,
3637
reqOptions reqopts.RequestOptions,
3738
releaseConfigs []v1.Release,
39+
dbc *db.DB,
3840
) *ReleaseFallback {
3941
return &ReleaseFallback{
4042
dataProvider: provider,
43+
dbc: dbc,
4144
log: log.WithField("middleware", "ReleaseFallback"),
4245
reqOptions: reqOptions,
4346
releaseConfigs: releaseConfigs,
@@ -55,6 +58,7 @@ func NewReleaseFallbackMiddleware(
5558
// This is done when we have sufficient test coverage, and a better pass rate.
5659
type ReleaseFallback struct {
5760
dataProvider dataprovider.DataProvider
61+
dbc *db.DB
5862
cachedFallbackTestStatuses *FallbackReleases
5963
log log.FieldLogger
6064
reqOptions reqopts.RequestOptions
@@ -173,7 +177,7 @@ func (r *ReleaseFallback) PostAnalysis(testKey crtest.Identification, testStats
173177
func (r *ReleaseFallback) getFallbackBaseQueryStatus(ctx context.Context,
174178
allJobVariants crtest.JobVariants,
175179
release string, start, end time.Time) []error {
176-
generator := newFallbackTestQueryReleasesGenerator(r.dataProvider, r.reqOptions, allJobVariants, release, start, end, r.releaseConfigs)
180+
generator := newFallbackTestQueryReleasesGenerator(r.dataProvider, r.dbc, r.reqOptions, allJobVariants, release, start, end, r.releaseConfigs)
177181

178182
cachedFallbackTestStatuses, errs := api.GetDataFromCacheOrGenerate[*FallbackReleases](
179183
ctx, r.dataProvider.Cache(), r.reqOptions.CacheOption,
@@ -193,9 +197,9 @@ func (r *ReleaseFallback) QueryTestDetails(ctx context.Context, wg *sync.WaitGro
193197
r.log.Infof("Querying fallback override test statuses for %d test ID options", len(r.reqOptions.TestIDOptions))
194198

195199
// Lookup all release dates, we're going to need them
196-
timeRanges, errs := r.dataProvider.QueryReleaseDates(ctx, r.reqOptions)
197-
if errs != nil {
198-
utils.EnqueueAsync(wg, errCh, errs...)
200+
timeRanges, err := api.GetReleaseDatesFromDB(ctx, r.dbc, r.reqOptions)
201+
if err != nil {
202+
utils.EnqueueAsync(wg, errCh, err)
199203
return
200204
}
201205

@@ -296,6 +300,7 @@ func (r *ReleaseFallback) TestDetailsAnalyze(report *testdetails.Report) error {
296300
// each, which can then be used to return the best basis data from those past releases for comparison.
297301
type fallbackTestQueryReleasesGenerator struct {
298302
dataProvider dataprovider.DataProvider
303+
dbc *db.DB
299304
cacheOption apiCache.RequestOptions
300305
allJobVariants crtest.JobVariants
301306
BaseRelease string
@@ -309,6 +314,7 @@ type fallbackTestQueryReleasesGenerator struct {
309314

310315
func newFallbackTestQueryReleasesGenerator(
311316
provider dataprovider.DataProvider,
317+
dbc *db.DB,
312318
reqOptions reqopts.RequestOptions,
313319
allJobVariants crtest.JobVariants,
314320
release string, start, end time.Time,
@@ -317,6 +323,7 @@ func newFallbackTestQueryReleasesGenerator(
317323

318324
generator := fallbackTestQueryReleasesGenerator{
319325
dataProvider: provider,
326+
dbc: dbc,
320327
cacheOption: reqOptions.CacheOption,
321328
allJobVariants: allJobVariants,
322329
BaseRelease: release,
@@ -335,7 +342,7 @@ type fallbackTestQueryReleasesGeneratorCacheKey struct {
335342
BaseEnd time.Time
336343
// VariantDBGroupBy is the only field within VariantOption that is used here
337344
VariantDBGroupBy sets.Set[string]
338-
// CRTimeRoundingFactor is used by GetReleaseDatesFromBigQuery
345+
// CRTimeRoundingFactor is used by GetReleaseDatesFromDB
339346
CRTimeRoundingFactor time.Duration
340347
CRTimeRoundingOffset time.Duration
341348
// KeyTestNames affects the BuildComponentReportQuery results via filtering logic
@@ -360,10 +367,10 @@ func (f *fallbackTestQueryReleasesGenerator) getCacheKey() fallbackTestQueryRele
360367
func (f *fallbackTestQueryReleasesGenerator) getTestFallbackReleases(ctx context.Context) (*FallbackReleases, []error) {
361368
wg := sync.WaitGroup{}
362369
f.CachedFallbackTestStatuses = newFallbackReleases()
363-
timeRanges, errs := f.dataProvider.QueryReleaseDates(ctx, f.ReqOptions)
370+
timeRanges, err := api.GetReleaseDatesFromDB(ctx, f.dbc, f.ReqOptions)
364371

365-
if errs != nil {
366-
return nil, errs
372+
if err != nil {
373+
return nil, []error{err}
367374
}
368375

369376
selectedTimeRanges := calculateDefaultFallbackReleases(f.BaseRelease, timeRanges, f.releaseConfigs)

pkg/api/componentreadiness/middleware/releasefallback/releasefallback_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func Test_PreAnalysis(t *testing.T) {
164164
}
165165
for i, test := range tests {
166166
t.Run(test.name, func(t *testing.T) {
167-
rfb := NewReleaseFallbackMiddleware(nil, test.reqOpts, releaseConfigs)
167+
rfb := NewReleaseFallbackMiddleware(nil, test.reqOpts, releaseConfigs, nil)
168168
rfb.cachedFallbackTestStatuses = &tests[i].fallbackReleases
169169
err := rfb.PreAnalysis(test.testKey, test.testStats)
170170
assert.NoError(t, err)

0 commit comments

Comments
 (0)