fix: identify submitted server version in publish diagnostics (#1621)

Publishing a manifest with a stale version currently produces a
duplicate-version error without identifying the version that was
submitted. This made a request containing `0.4.5` look like a rejected
publication of `0.4.6` in #1615.

Include the submitted `name@version` in the CLI output before sending
the request and in the API duplicate-version error. HTTP 400, the
response structure, and duplicate-rejection behavior remain unchanged.
The service wraps the existing error sentinel so `errors.Is` continues
to work.

Adds a CLI regression test for a failed publication and updates the API
duplicate-error assertion.

Validation:
- Publish command tests passed (`go test ./cmd/publisher/commands -run
TestPublishCommand -count=1`).
- `git diff --check` passed.
- API endpoint tests were attempted but could not run because PostgreSQL
was unavailable on localhost:5432; Docker was also unavailable locally.

Related to #1615.
This commit is contained in:
Radoslav Dimitrov 2026-09-06 00:18:27 +03:00 • committed by GitHub
commit 068a97a2f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 4 deletions

View file

@ -64,7 +64,7 @@ func PublishCommand(args []string) error {
}
// Publish to registry
_, _ = fmt.Fprintf(os.Stdout, "Publishing to %s...\n", registryURL)
_, _ = fmt.Fprintf(os.Stdout, "Publishing %s@%s to %s...\n", serverJSON.Name, serverJSON.Version, registryURL)
response, statusCode, err := publishToRegistry(registryURL, serverData, token)
if err != nil {
// If publish failed with 422, call validate endpoint to show detailed errors

View file

@ -39,6 +39,36 @@ func TestPublishCommand_Success(t *testing.T) {
assert.NoError(t, err)
}
func TestPublishCommand_PrintsSubmittedIdentityOnFailure(t *testing.T) {
server := SetupMockRegistryServer(t, func(w http.ResponseWriter, _ *http.Request) {
http.Error(w, "duplicate version", http.StatusBadRequest)
}, nil)
SetupTestToken(t, server.URL, "test-token")
CreateTestServerJSON(t, apiv0.ServerJSON{
Schema: model.CurrentSchemaURL,
Name: "io.github.BargLabs/cejel",
Description: "A test server",
Version: "0.4.5",
})
output, err := os.CreateTemp(t.TempDir(), "stdout")
require.NoError(t, err)
originalStdout := os.Stdout
os.Stdout = output
t.Cleanup(func() {
os.Stdout = originalStdout
_ = output.Close()
})
err = commands.PublishCommand(nil)
require.ErrorContains(t, err, "duplicate version")
_, err = output.Seek(0, io.SeekStart)
require.NoError(t, err)
data, err := io.ReadAll(output)
require.NoError(t, err)
assert.Equal(t, "Publishing io.github.BargLabs/cejel@0.4.5 to "+server.URL+"...\n", string(data))
}
func TestPublishCommand_PreservesNonASCIIDescription(t *testing.T) {
server := SetupMockRegistryServer(t,
func(w http.ResponseWriter, r *http.Request) {

View file

@ -168,7 +168,7 @@ func TestPublishEndpoint(t *testing.T) {
expectedError: "You do not have permission to publish this server",
},
{
name: "registry service error",
name: "duplicate version includes submitted server identity",
requestBody: apiv0.ServerJSON{
Schema: model.CurrentSchemaURL,
Name: "example/test-server",
@ -202,7 +202,7 @@ func TestPublishEndpoint(t *testing.T) {
_, _ = registry.CreateServer(context.Background(), &existingServer)
},
expectedStatus: http.StatusBadRequest,
expectedError: "invalid version: cannot publish duplicate version",
expectedError: "invalid version: cannot publish duplicate version: example/test-server@1.0.0 already exists",
},
{
name: "package validation success - MCPB package",

View file

@ -190,7 +190,7 @@ func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx
return e
}
if versionExists {
return database.ErrInvalidVersion
return fmt.Errorf("%w: %s@%s already exists", database.ErrInvalidVersion, serverJSON.Name, serverJSON.Version)
}
currentLatest, e = s.db.GetCurrentLatestVersion(ctx, tx, serverJSON.Name)
if e != nil && !errors.Is(e, database.ErrNotFound) {