Skip to content

sdk publish: missing array length check makes an empty publish-log report a false success #312

Description

@mrafnadeem-apimatic

Problem

SdkPublishNonInteractivePrompts.pollPublishingStatus decides completion with Array.prototype.every, which is vacuously true on an empty array:

https://github.com/apimatic/apimatic-cli/blob/dev/src/prompts/sdk/publish/non-interactive.ts#L125-L144

const { events } = publishingLogResult.value;
const executionCompleted = events.every((event) => TERMINAL_STATES.has(event.eventType));
...
const isExecutionSuccessful = events.every((event) => event.eventType === 'Succeeded');

There is no length check on events, so if the publishing API ever returns { events: [] } for a publish log, the very first poll concludes that publishing both completed and succeeded. The CLI stops the spinner with an empty status line, prints the "Next Steps" note, and exits 0 for a publish whose outcome is unknown.

A related case falls out of the same missing check: if events contains only some of the requested publish targets (e.g. the SourceCode event exists and already reads Succeeded while the Package event has not been created yet), every is satisfied over the partial set and the command reports full success while package publishing has not started. Whether this second case is reachable depends on whether the publishing API creates all event rows atomically when it accepts the publish request — worth confirming before picking a fix.

Impact

apimatic sdk publish exits 0 and prints a success-shaped status line for a publish it never actually observed reaching a terminal state. This now affects interactive mode as well, since interactive polls for completion through the same shared code.

Possible fixes

  1. Guard on target coverage — completion requires an event for every requested publish type and all events terminal. The action already has publishTypes; needs a 'package' -> 'Package' / 'sourcecode' -> 'SourceCode' mapping, since the request-side PublishType enum and the log event's publishType use different casing.
  2. Minimal: require events.length > 0 before evaluating the two predicates. Sufficient only if the API creates all event rows atomically.
  3. Treat a missing/partial event set as an explicit error and stop the spinner with a message naming the missing target(s), rather than continuing to wait.

Whichever is chosen, the failure mode should be distinguishable in the output from "publishing failed" — the CLI does not know the outcome in this state.

Context

Deliberately deferred out of the change that makes interactive sdk publish poll for completion, to keep that change a behavioral-parity fix with no predicate changes. Two adjacent items also parked here:

  • No retry tolerance on status fetches — the first getSdkPublishingLog error ends the poll and exits 1. A single transient blip during a multi-minute wait reports failure for a publish that likely succeeded.
  • Unbounded wait — the poll loop has no ceiling. Interactive relies on Ctrl+C; CI relies on job-level timeouts. Worth revisiting with real publish-duration data.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions