Skip to content

Commit 60ce1e3

Browse files
committed
updates
1 parent cf3bdda commit 60ce1e3

8 files changed

Lines changed: 180 additions & 697 deletions

File tree

.changeset/loud-spiders-end.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
---
2-
"chainlink-deployments-framework": major
2+
"chainlink-deployments-framework": minor
33
---
44

5-
feat!: add catalog service integration for datastore operations
6-
7-
BREAKING CHANGES:
8-
- `EnvDir.MergeMigrationDataStore` now requires `context.Context` as first parameter and `datastore.CatalogStore` as last parameter
9-
- Signature changed from `MergeMigrationDataStore(migkey, timestamp string)` to `MergeMigrationDataStore(ctx context.Context, migkey, timestamp string, catalog datastore.CatalogStore)`
5+
feat: add catalog service integration for datastore operations
106

117
Features:
12-
- Add catalog service support for datastore management
13-
- Add `SyncDataStoreToCatalog` function to push entire local datastore to catalog
14-
- Add `MergeDataStoreToCatalog` function to merge migration datastores to catalog
8+
- Add catalog service support for datastore management as alternative to local file storage
9+
- Add `MergeMigrationDataStoreCatalog` method for catalog-based datastore persistence
10+
- Existing `MergeMigrationDataStore` method continues to work for file-based storage (no breaking changes)
11+
- Add unified `MergeDataStoreToCatalog` function for both initial migration and ongoing merge operations
1512
- All catalog operations are transactional to prevent data inconsistencies
16-
- Add `DatastoreType` configuration option to switch between `file` and `catalog` modes
13+
- Add `DatastoreType` configuration option (`file`/`catalog`) in domain.yaml to control storage backend
14+
- Add new CLI command `datastore sync-to-catalog` for initial migration from file-based to catalog storage in CI
15+
- Add `SyncDataStoreToCatalog` method to sync entire local datastore to catalog
16+
- CLI automatically selects the appropriate merge method based on domain.yaml configuration
17+
- Catalog mode does not modify local files - all updates go directly to the catalog service
18+
19+
Configuration:
20+
- Set `datastore: catalog` in domain.yaml to enable catalog mode
21+
- Set `datastore: file` or omit the setting to use traditional file-based storage
22+
- CLI commands automatically detect the configuration and use the appropriate storage backend

datastore/catalog_syncer.go

Lines changed: 17 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,81 +6,21 @@ import (
66
"fmt"
77
)
88

9-
// SyncDataStoreToCatalog pushes all data from a local DataStore to a remote CatalogStore within
10-
// a transaction. This ensures atomic updates - either all data is successfully synced or the
11-
// entire operation is rolled back on failure.
9+
// MergeDataStoreToCatalog merges data from a source DataStore (either full local state or migration-specific)
10+
// into a remote CatalogStore within a transaction. This ensures atomic updates - either all data is
11+
// successfully merged or the entire operation is rolled back on failure.
1212
//
13-
// This function is the inverse of LoadDataStoreFromCatalog - while that function reads from
14-
// catalog to local, this function writes from local to catalog.
15-
func SyncDataStoreToCatalog(ctx context.Context, localDS DataStore, catalog CatalogStore) error {
16-
return catalog.WithTransaction(ctx, func(ctx context.Context, txCatalog BaseCatalogStore) error {
17-
// Sync all address references to the catalog
18-
addressRefs, err := localDS.Addresses().Fetch()
19-
if err != nil {
20-
return fmt.Errorf("failed to fetch address references from local store: %w", err)
21-
}
22-
23-
for _, ref := range addressRefs {
24-
if upsertErr := txCatalog.Addresses().Upsert(ctx, ref); upsertErr != nil {
25-
return fmt.Errorf("failed to upsert address reference to catalog: %w", upsertErr)
26-
}
27-
}
28-
29-
// Sync all chain metadata to the catalog
30-
chainMetadata, err := localDS.ChainMetadata().Fetch()
31-
if err != nil {
32-
return fmt.Errorf("failed to fetch chain metadata from local store: %w", err)
33-
}
34-
35-
for _, metadata := range chainMetadata {
36-
key := NewChainMetadataKey(metadata.ChainSelector)
37-
if upsertErr := txCatalog.ChainMetadata().Upsert(ctx, key, metadata.Metadata); upsertErr != nil {
38-
return fmt.Errorf("failed to upsert chain metadata to catalog: %w", upsertErr)
39-
}
40-
}
41-
42-
// Sync all contract metadata to the catalog
43-
contractMetadata, err := localDS.ContractMetadata().Fetch()
44-
if err != nil {
45-
return fmt.Errorf("failed to fetch contract metadata from local store: %w", err)
46-
}
47-
48-
for _, metadata := range contractMetadata {
49-
key := NewContractMetadataKey(metadata.ChainSelector, metadata.Address)
50-
if upsertErr := txCatalog.ContractMetadata().Upsert(ctx, key, metadata.Metadata); upsertErr != nil {
51-
return fmt.Errorf("failed to upsert contract metadata to catalog: %w", upsertErr)
52-
}
53-
}
54-
55-
// Sync environment metadata to the catalog
56-
envMetadata, err := localDS.EnvMetadata().Get()
57-
if err != nil {
58-
// EnvMetadata might not be set, which is okay
59-
if !errors.Is(err, ErrEnvMetadataNotSet) {
60-
return fmt.Errorf("failed to fetch environment metadata from local store: %w", err)
61-
}
62-
// If it's ErrEnvMetadataNotSet, skip syncing env metadata
63-
return nil
64-
}
65-
66-
// Sync the environment metadata
67-
if setErr := txCatalog.EnvMetadata().Set(ctx, envMetadata.Metadata); setErr != nil {
68-
return fmt.Errorf("failed to set environment metadata in catalog: %w", setErr)
69-
}
70-
71-
return nil
72-
})
73-
}
74-
75-
// MergeDataStoreToCatalog merges data from a migration/changeset DataStore into the catalog
76-
// within a transaction. This is used after a migration/changeset execution to persist new
77-
// contract deployments and metadata to the catalog.
78-
func MergeDataStoreToCatalog(ctx context.Context, migrationDS DataStore, catalog CatalogStore) error {
13+
// This function serves two purposes:
14+
// 1. Initial migration: sync entire local datastore to catalog (full state push)
15+
// 2. Ongoing operations: merge migration/changeset artifacts into catalog (incremental updates)
16+
//
17+
// The operation is transactional to prevent partial failures that could lead to data inconsistencies.
18+
func MergeDataStoreToCatalog(ctx context.Context, sourceDS DataStore, catalog CatalogStore) error {
7919
return catalog.WithTransaction(ctx, func(ctx context.Context, txCatalog BaseCatalogStore) error {
8020
// Merge all address references to the catalog
81-
addressRefs, err := migrationDS.Addresses().Fetch()
21+
addressRefs, err := sourceDS.Addresses().Fetch()
8222
if err != nil {
83-
return fmt.Errorf("failed to fetch address references from migration store: %w", err)
23+
return fmt.Errorf("failed to fetch address references from source store: %w", err)
8424
}
8525

8626
for _, ref := range addressRefs {
@@ -90,9 +30,9 @@ func MergeDataStoreToCatalog(ctx context.Context, migrationDS DataStore, catalog
9030
}
9131

9232
// Merge all chain metadata to the catalog
93-
chainMetadata, err := migrationDS.ChainMetadata().Fetch()
33+
chainMetadata, err := sourceDS.ChainMetadata().Fetch()
9434
if err != nil {
95-
return fmt.Errorf("failed to fetch chain metadata from migration store: %w", err)
35+
return fmt.Errorf("failed to fetch chain metadata from source store: %w", err)
9636
}
9737

9838
for _, metadata := range chainMetadata {
@@ -103,9 +43,9 @@ func MergeDataStoreToCatalog(ctx context.Context, migrationDS DataStore, catalog
10343
}
10444

10545
// Merge all contract metadata to the catalog
106-
contractMetadata, err := migrationDS.ContractMetadata().Fetch()
46+
contractMetadata, err := sourceDS.ContractMetadata().Fetch()
10747
if err != nil {
108-
return fmt.Errorf("failed to fetch contract metadata from migration store: %w", err)
48+
return fmt.Errorf("failed to fetch contract metadata from source store: %w", err)
10949
}
11050

11151
for _, metadata := range contractMetadata {
@@ -116,10 +56,10 @@ func MergeDataStoreToCatalog(ctx context.Context, migrationDS DataStore, catalog
11656
}
11757

11858
// Merge environment metadata to the catalog
119-
envMetadata, err := migrationDS.EnvMetadata().Get()
59+
envMetadata, err := sourceDS.EnvMetadata().Get()
12060
if err != nil {
12161
if !errors.Is(err, ErrEnvMetadataNotSet) {
122-
return fmt.Errorf("failed to fetch environment metadata from migration store: %w", err)
62+
return fmt.Errorf("failed to fetch environment metadata from source store: %w", err)
12363
}
12464

12565
return nil

datastore/catalog_syncer_integration_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
)
1616

1717
// Temporary on demand local tests for catalog syncer - these can be converted to proper testcontainers later
18-
// TestSyncDataStoreToCatalog_Integration tests the full sync workflow with a real catalog service
19-
func TestSyncDataStoreToCatalog_Integration(t *testing.T) {
18+
// TestMergeDataStoreToCatalog_FullSync tests syncing entire local datastore to catalog (initial migration use case)
19+
func TestMergeDataStoreToCatalog_FullSync(t *testing.T) {
2020
t.Parallel()
2121

2222
ctx := context.Background()
@@ -151,11 +151,11 @@ func TestSyncDataStoreToCatalog_Integration(t *testing.T) {
151151
t.Log(" - 2 contract metadata")
152152
t.Log(" - 1 environment metadata")
153153

154-
// Step 2: Sync datastore to catalog
155-
t.Log("Step 2: Syncing local datastore to catalog...")
156-
err = datastore.SyncDataStoreToCatalog(ctx, sealedDS, catalogStore)
157-
require.NoError(t, err, "Failed to sync datastore to catalog")
158-
t.Log("✅ Sync completed successfully!")
154+
// Step 2: Merge datastore to catalog (full sync for initial migration)
155+
t.Log("Step 2: Merging local datastore to catalog...")
156+
err = datastore.MergeDataStoreToCatalog(ctx, sealedDS, catalogStore)
157+
require.NoError(t, err, "Failed to merge datastore to catalog")
158+
t.Log("✅ Merge completed successfully!")
159159

160160
// Step 3: Verify data was synced correctly by reading back from catalog
161161
t.Log("Step 3: Verifying data in catalog...")
@@ -230,8 +230,8 @@ func TestSyncDataStoreToCatalog_Integration(t *testing.T) {
230230
t.Logf("ℹ️ Data is stored in catalog under domain='%s', environment='%s'", testDomain, testEnv)
231231
}
232232

233-
// TestMergeDataStoreToCatalog_Integration tests merging migration data to catalog
234-
func TestMergeDataStoreToCatalog_Integration(t *testing.T) {
233+
// TestMergeDataStoreToCatalog_Incremental tests merging migration data to catalog (ongoing operations use case)
234+
func TestMergeDataStoreToCatalog_Incremental(t *testing.T) {
235235
t.Parallel()
236236

237237
ctx := context.Background()
@@ -297,10 +297,10 @@ func TestMergeDataStoreToCatalog_Integration(t *testing.T) {
297297
err = initialDS.Addresses().Add(initialAddr)
298298
require.NoError(t, err)
299299

300-
// Sync initial state
301-
err = datastore.SyncDataStoreToCatalog(ctx, initialDS.Seal(), catalogStore)
300+
// Merge initial state to catalog
301+
err = datastore.MergeDataStoreToCatalog(ctx, initialDS.Seal(), catalogStore)
302302
require.NoError(t, err)
303-
t.Log("✅ Initial state synced")
303+
t.Log("✅ Initial state merged")
304304

305305
// Step 2: Create a migration datastore with new contracts
306306
t.Log("Step 2: Creating migration datastore...")
@@ -377,8 +377,8 @@ func TestMergeDataStoreToCatalog_Integration(t *testing.T) {
377377
t.Logf("ℹ️ Catalog now contains both original and migrated data under domain='%s', environment='%s'", testDomain, testEnv)
378378
}
379379

380-
// TestSyncDataStoreToCatalog_TransactionRollback tests that failed syncs rollback properly
381-
func TestSyncDataStoreToCatalog_TransactionRollback(t *testing.T) {
380+
// TestMergeDataStoreToCatalog_TransactionRollback tests that failed merges rollback properly
381+
func TestMergeDataStoreToCatalog_TransactionRollback(t *testing.T) {
382382
t.Parallel()
383383

384384
ctx := context.Background()
@@ -443,8 +443,8 @@ func TestSyncDataStoreToCatalog_TransactionRollback(t *testing.T) {
443443
err = localDS.Addresses().Add(testAddr)
444444
require.NoError(t, err)
445445

446-
// Sync should succeed
447-
err = datastore.SyncDataStoreToCatalog(ctx, localDS.Seal(), catalogStore)
446+
// Merge should succeed
447+
err = datastore.MergeDataStoreToCatalog(ctx, localDS.Seal(), catalogStore)
448448
require.NoError(t, err)
449449

450450
// Verify data was written
@@ -458,7 +458,7 @@ func TestSyncDataStoreToCatalog_TransactionRollback(t *testing.T) {
458458
break
459459
}
460460
}
461-
assert.True(t, found, "Data should be committed after successful sync")
461+
assert.True(t, found, "Data should be committed after successful merge")
462462

463-
t.Log("✅ Transaction semantics verified - data committed after successful sync")
463+
t.Log("✅ Transaction semantics verified - data committed after successful merge")
464464
}

0 commit comments

Comments
 (0)