Skip to content

Commit 353776a

Browse files
tadasantclaude
andcommitted
Fix server ID consistency across versions
Previously, each version of a server was getting a unique ID, but the intent was for all versions of the same server to share a consistent ID. Changes: - Modified registry_service.go to reuse the ID from the earliest version - Updated database schema via migration to use separate record_id and server_id - Fixed PostgreSQL and memory database implementations to handle the new schema - Corrected UpdateServer logic to update specific versions, not just latest - Added comprehensive tests to verify ID consistency - Fixed edit test that incorrectly tried to change version during edit The database now uses record_id as the primary key (unique per version) while server_id remains consistent across all versions of the same server. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent da2965f commit 353776a

27 files changed

+618
-178
lines changed

cmd/publisher/commands/init.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ func createServerJSON(
309309
URL: repoURL,
310310
Source: repoSource,
311311
},
312-
Version: version,
312+
Version: version,
313313
Packages: []model.Package{pkg},
314314
}
315315
}

cmd/publisher/commands/logout.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func LogoutCommand() error {
1313
}
1414

1515
tokenPath := filepath.Join(homeDir, TokenFileName)
16-
16+
1717
// Check if token file exists
1818
if _, err := os.Stat(tokenPath); os.IsNotExist(err) {
1919
_, _ = fmt.Fprintln(os.Stdout, "Not logged in")
@@ -30,7 +30,7 @@ func LogoutCommand() error {
3030
".mcpregistry_github_token",
3131
".mcpregistry_registry_token",
3232
}
33-
33+
3434
for _, file := range legacyFiles {
3535
path := filepath.Join(homeDir, file)
3636
if _, err := os.Stat(path); err == nil {
@@ -40,4 +40,4 @@ func LogoutCommand() error {
4040

4141
_, _ = fmt.Fprintln(os.Stdout, "✓ Successfully logged out")
4242
return nil
43-
}
43+
}

cmd/publisher/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@ func printUsage() {
6767
_, _ = fmt.Fprintln(os.Stdout, " publish Publish server.json to the registry")
6868
_, _ = fmt.Fprintln(os.Stdout)
6969
_, _ = fmt.Fprintln(os.Stdout, "Use 'mcp-publisher <command> --help' for more information about a command.")
70-
}
70+
}

deploy/pkg/k8s/ingress.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func SetupIngressController(ctx *pulumi.Context, cluster *providers.ProviderInfo
5151
Values: pulumi.Map{
5252
"controller": pulumi.Map{
5353
"service": pulumi.Map{
54-
"type": serviceType,
54+
"type": serviceType,
5555
"annotations": pulumi.Map{},
5656
},
5757
"config": pulumi.Map{

deploy/pkg/providers/gcp/provider.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ type Provider struct{}
2222
// createGCPProvider creates a GCP provider with explicit credentials if configured
2323
func createGCPProvider(ctx *pulumi.Context, name string) (*gcp.Provider, error) {
2424
gcpConf := config.New(ctx, "gcp")
25-
25+
2626
// Get project ID from config
2727
projectID := gcpConf.Get("project")
2828
if projectID == "" {
2929
return nil, fmt.Errorf("GCP project ID not configured. Set gcp:project")
3030
}
31-
31+
3232
// Get region from config or use default
3333
region := gcpConf.Get("region")
3434
if region == "" {
3535
region = "us-central1"
3636
}
37-
37+
3838
// Get credentials from config (base64 encoded service account JSON)
3939
credentials := gcpConf.Get("credentials")
4040
if credentials != "" {
@@ -45,7 +45,7 @@ func createGCPProvider(ctx *pulumi.Context, name string) (*gcp.Provider, error)
4545
}
4646
credentials = string(decodedCreds)
4747
}
48-
48+
4949
// Create a GCP provider with explicit credentials if provided
5050
if credentials != "" {
5151
return gcp.NewProvider(ctx, name, &gcp.ProviderArgs{
@@ -54,7 +54,7 @@ func createGCPProvider(ctx *pulumi.Context, name string) (*gcp.Provider, error)
5454
Credentials: pulumi.String(credentials),
5555
})
5656
}
57-
57+
5858
return nil, nil
5959
}
6060

internal/api/handlers/v0/edit_test.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func TestEditServerEndpoint(t *testing.T) {
114114
Source: "github",
115115
ID: "domdomegg/test-server",
116116
},
117-
Version: "1.0.1",
117+
Version: "1.0.0",
118118
},
119119
serverID: testServerID,
120120
expectedStatus: http.StatusOK,
@@ -131,9 +131,9 @@ func TestEditServerEndpoint(t *testing.T) {
131131
name: "invalid authorization header format",
132132
authHeader: "InvalidFormat token123",
133133
requestBody: apiv0.ServerJSON{
134-
Name: "io.github.domdomegg/test-server",
135-
Description: "Test server",
136-
Version: "1.0.0",
134+
Name: "io.github.domdomegg/test-server",
135+
Description: "Test server",
136+
Version: "1.0.0",
137137
},
138138
serverID: testServerID,
139139
expectedStatus: http.StatusUnauthorized,
@@ -143,9 +143,9 @@ func TestEditServerEndpoint(t *testing.T) {
143143
name: "invalid token",
144144
authHeader: "Bearer invalid-token",
145145
requestBody: apiv0.ServerJSON{
146-
Name: "io.github.domdomegg/test-server",
147-
Description: "Test server",
148-
Version: "1.0.0",
146+
Name: "io.github.domdomegg/test-server",
147+
Description: "Test server",
148+
Version: "1.0.0",
149149
},
150150
serverID: testServerID,
151151
expectedStatus: http.StatusUnauthorized,
@@ -165,9 +165,9 @@ func TestEditServerEndpoint(t *testing.T) {
165165
return "Bearer " + token
166166
}(),
167167
requestBody: apiv0.ServerJSON{
168-
Name: "io.github.domdomegg/test-server",
169-
Description: "Updated test server",
170-
Version: "1.0.0",
168+
Name: "io.github.domdomegg/test-server",
169+
Description: "Updated test server",
170+
Version: "1.0.0",
171171
},
172172
serverID: testServerID,
173173
expectedStatus: http.StatusForbidden,
@@ -187,9 +187,9 @@ func TestEditServerEndpoint(t *testing.T) {
187187
return "Bearer " + token
188188
}(),
189189
requestBody: apiv0.ServerJSON{
190-
Name: "io.github.other/test-server",
191-
Description: "Updated test server",
192-
Version: "1.0.0",
190+
Name: "io.github.other/test-server",
191+
Description: "Updated test server",
192+
Version: "1.0.0",
193193
},
194194
serverID: otherServerID,
195195
expectedStatus: http.StatusForbidden,
@@ -209,9 +209,9 @@ func TestEditServerEndpoint(t *testing.T) {
209209
return "Bearer " + token
210210
}(),
211211
requestBody: apiv0.ServerJSON{
212-
Name: "io.github.domdomegg/nonexistent-server",
213-
Description: "Updated test server",
214-
Version: "1.0.0",
212+
Name: "io.github.domdomegg/nonexistent-server",
213+
Description: "Updated test server",
214+
Version: "1.0.0",
215215
},
216216
serverID: "550e8400-e29b-41d4-a716-446655440999", // Non-existent ID
217217
expectedStatus: http.StatusNotFound,
@@ -231,9 +231,9 @@ func TestEditServerEndpoint(t *testing.T) {
231231
return "Bearer " + token
232232
}(),
233233
requestBody: apiv0.ServerJSON{
234-
Name: "invalid-name-format", // Missing namespace/name format
235-
Description: "Test server",
236-
Version: "1.0.0",
234+
Name: "invalid-name-format", // Missing namespace/name format
235+
Description: "Test server",
236+
Version: "1.0.0",
237237
},
238238
serverID: testServerID,
239239
expectedStatus: http.StatusBadRequest,

internal/api/handlers/v0/publish_integration_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ func TestPublishIntegration(t *testing.T) {
160160

161161
t.Run("publish fails with invalid token", func(t *testing.T) {
162162
publishReq := apiv0.ServerJSON{
163-
Name: "io.github.domdomegg/test-server",
164-
Description: "Test server",
165-
Version: "1.0.0",
163+
Name: "io.github.domdomegg/test-server",
164+
Description: "Test server",
165+
Version: "1.0.0",
166166
}
167167

168168
body, err := json.Marshal(publishReq)
@@ -183,7 +183,7 @@ func TestPublishIntegration(t *testing.T) {
183183
publishReq := apiv0.ServerJSON{
184184
Name: "io.github.other/test-server",
185185
Description: "A test server",
186-
Version: "1.0.0",
186+
Version: "1.0.0",
187187
Repository: model.Repository{
188188
URL: "https://github.com/example/test-server",
189189
Source: "github",
@@ -219,8 +219,8 @@ func TestPublishIntegration(t *testing.T) {
219219
publishReq := apiv0.ServerJSON{
220220
Name: "io.github.domdomegg/airtable-mcp-server",
221221
Description: "A test server with MCPB package",
222-
Version: "1.7.2",
223-
Status: model.StatusActive,
222+
Version: "1.7.2",
223+
Status: model.StatusActive,
224224
Packages: []model.Package{
225225
{
226226
RegistryType: model.RegistryTypeMCPB,

internal/api/handlers/v0/publish_registry_validation_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func TestPublishRegistryValidation(t *testing.T) {
4747
publishReq := apiv0.ServerJSON{
4848
Name: "com.example/test-server-with-npm",
4949
Description: "A test server with invalid npm package reference",
50-
Version: "1.0.0",
50+
Version: "1.0.0",
5151
Packages: []model.Package{
5252
{
5353
RegistryType: model.RegistryTypeNPM,
@@ -88,7 +88,7 @@ func TestPublishRegistryValidation(t *testing.T) {
8888
publishReq := apiv0.ServerJSON{
8989
Name: "com.example/test-server-mcpb-validation",
9090
Description: "A test server with MCPB package and registry validation enabled",
91-
Version: "0.0.36",
91+
Version: "0.0.36",
9292
Packages: []model.Package{
9393
{
9494
RegistryType: model.RegistryTypeMCPB,
@@ -138,7 +138,7 @@ func TestPublishRegistryValidation(t *testing.T) {
138138
publishReq := apiv0.ServerJSON{
139139
Name: "com.example/test-server-multiple-packages",
140140
Description: "A test server with multiple packages where second fails",
141-
Version: "1.0.0",
141+
Version: "1.0.0",
142142
Packages: []model.Package{
143143
{
144144
RegistryType: model.RegistryTypeMCPB,
@@ -189,7 +189,7 @@ func TestPublishRegistryValidation(t *testing.T) {
189189
publishReq := apiv0.ServerJSON{
190190
Name: "com.example/test-server-first-package-fails",
191191
Description: "A test server where first package fails",
192-
Version: "1.0.0",
192+
Version: "1.0.0",
193193
Packages: []model.Package{
194194
{
195195
RegistryType: model.RegistryTypeNPM,

internal/api/handlers/v0/publish_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ func TestPublishEndpoint(t *testing.T) {
113113
{
114114
name: "invalid authorization header format",
115115
requestBody: apiv0.ServerJSON{
116-
Name: "io.github.domdomegg/test-server",
117-
Description: "Test server",
118-
Version: "1.0.0",
116+
Name: "io.github.domdomegg/test-server",
117+
Description: "Test server",
118+
Version: "1.0.0",
119119
},
120120
authHeader: "InvalidFormat",
121121
setupRegistryService: func(_ service.RegistryService) {
@@ -129,7 +129,7 @@ func TestPublishEndpoint(t *testing.T) {
129129
requestBody: apiv0.ServerJSON{
130130
Name: "test-server",
131131
Description: "A test server",
132-
Version: "1.0.0",
132+
Version: "1.0.0",
133133
},
134134
authHeader: "Bearer invalidToken",
135135
setupRegistryService: func(_ service.RegistryService) {
@@ -143,7 +143,7 @@ func TestPublishEndpoint(t *testing.T) {
143143
requestBody: apiv0.ServerJSON{
144144
Name: "io.github.other/test-server",
145145
Description: "A test server",
146-
Version: "1.0.0",
146+
Version: "1.0.0",
147147
Repository: model.Repository{
148148
URL: "https://github.com/example/test-server",
149149
Source: "github",
@@ -167,7 +167,7 @@ func TestPublishEndpoint(t *testing.T) {
167167
requestBody: apiv0.ServerJSON{
168168
Name: "example/test-server",
169169
Description: "A test server",
170-
Version: "1.0.0",
170+
Version: "1.0.0",
171171
Repository: model.Repository{
172172
URL: "https://github.com/example/test-server",
173173
Source: "github",
@@ -185,7 +185,7 @@ func TestPublishEndpoint(t *testing.T) {
185185
existingServer := apiv0.ServerJSON{
186186
Name: "example/test-server",
187187
Description: "Existing test server",
188-
Version: "1.0.0",
188+
Version: "1.0.0",
189189
Repository: model.Repository{
190190
URL: "https://github.com/example/test-server-existing",
191191
Source: "github",
@@ -202,7 +202,7 @@ func TestPublishEndpoint(t *testing.T) {
202202
requestBody: apiv0.ServerJSON{
203203
Name: "com.example/test-server-mcpb",
204204
Description: "A test server with MCPB package",
205-
Version: "1.0.0",
205+
Version: "1.0.0",
206206
Packages: []model.Package{
207207
{
208208
RegistryType: model.RegistryTypeMCPB,

internal/api/handlers/v0/servers_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ func TestServersListEndpoint(t *testing.T) {
297297
default:
298298
assert.NotEmpty(t, resp.Servers, "Expected at least one server")
299299
}
300-
300+
301301
// General structure validation
302302
for _, server := range resp.Servers {
303303
assert.NotEmpty(t, server.Name)
@@ -336,7 +336,7 @@ func TestServersDetailEndpoint(t *testing.T) {
336336
testServer, err := registryService.Publish(apiv0.ServerJSON{
337337
Name: "com.example/test-server",
338338
Description: "A test server",
339-
Version: "1.0.0",
339+
Version: "1.0.0",
340340
})
341341
assert.NoError(t, err)
342342

0 commit comments

Comments
 (0)