-
Notifications
You must be signed in to change notification settings - Fork 15
fix: poll for publish completion in interactive sdk publish #315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mrafnadeem-apimatic
merged 12 commits into
dev
from
fix/interactive-sdk-publish-polling
Aug 11, 2026
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
cd38dd0
fix: poll for publish completion in interactive sdk publish
mrafnadeem-apimatic 03c9c40
temp: grilling notes
mrafnadeem-apimatic 221cb63
fix: reach the cancel notice when Ctrl+C stops the publish wait
mrafnadeem-apimatic d296a32
Revert "fix: reach the cancel notice when Ctrl+C stops the publish wait"
mrafnadeem-apimatic 27b657e
fix: change logs link print order
mrafnadeem-apimatic defa0c1
refactor: use existing prop instead of bool
mrafnadeem-apimatic 0c0d743
fix: don't recheck after getting sdk publishing log
mrafnadeem-apimatic 49ce016
refactor: remove abort handling
mrafnadeem-apimatic 7e56163
Revert "refactor: remove abort handling"
mrafnadeem-apimatic 51ec92a
fix: update cancel message
mrafnadeem-apimatic 9471af4
doc: remove comment
mrafnadeem-apimatic a7dfa76
doc: remove design notes
mrafnadeem-apimatic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,26 +1,111 @@ | ||
| import { log } from '@clack/prompts'; | ||
| import { Result } from 'neverthrow'; | ||
| import { ServiceError } from '../../infrastructure/service-error.js'; | ||
| import { PublishingInfo } from '../../types/publish-api/publishing-info.js'; | ||
| import { PublishType } from '../../types/publish-api/publishing-profile-item.js'; | ||
| import { SemVersion } from '../../types/publish/version.js'; | ||
| import { Language } from '../../types/sdk/generate.js'; | ||
| import { withSpinner } from '../prompt.js'; | ||
| import { PublishingProfile } from '../../types/publish/publishing-profile.js'; | ||
|
|
||
| export class SdkPublishPrompts { | ||
| public publishSdk(fn: Promise<Result<PublishingInfo, ServiceError>>) { | ||
| return withSpinner('Publishing SDK', 'Publishing initiated.', 'SDK Publishing failed.', fn); | ||
| } | ||
|
|
||
| public sdkPublishingServiceError(serviceError: ServiceError) { | ||
| log.error(serviceError.errorMessage); | ||
| } | ||
|
|
||
| public dryRunNotice(publishingProfile: PublishingProfile, language: Language, version: SemVersion, publishType: PublishType[]): void { | ||
| const targets = publishType.map((t) => (t === PublishType.PackagePublishing ? 'Package' : 'Source Code')).join(' + '); | ||
| log.info( | ||
| `You can publish this SDK by removing the --dry-run flag. It will be published for the following:\n\n Profile: ${publishingProfile}\n Language: ${language}\n Version: ${version}\n Targets: ${targets}` | ||
| ); | ||
| } | ||
| } | ||
| import { log, spinner } from '@clack/prompts'; | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| import { Result } from 'neverthrow'; | ||
| import { ServiceError } from '../../infrastructure/service-error.js'; | ||
| import { PublishLogItem } from '../../types/publish-api/publish-log.js'; | ||
| import { PublishingInfo } from '../../types/publish-api/publishing-info.js'; | ||
| import { PublishType } from '../../types/publish-api/publishing-profile-item.js'; | ||
| import { SemVersion } from '../../types/publish/version.js'; | ||
| import { Language } from '../../types/sdk/generate.js'; | ||
| import { noteWrapped, withSpinner } from '../prompt.js'; | ||
| import { format as f } from '../format.js'; | ||
| import { PublishingProfile } from '../../types/publish/publishing-profile.js'; | ||
|
|
||
| export type PublishingOutcome = 'succeeded' | 'failed' | 'cancelled'; | ||
|
|
||
| export class SdkPublishPrompts { | ||
| public publishSdk(fn: Promise<Result<PublishingInfo, ServiceError>>) { | ||
| return withSpinner('Publishing SDK', 'Publishing initiated.', 'SDK Publishing failed.', fn); | ||
| } | ||
|
|
||
| public sdkPublishingServiceError(serviceError: ServiceError) { | ||
| log.error(serviceError.errorMessage); | ||
| } | ||
|
|
||
| public dryRunNotice(publishingProfile: PublishingProfile, language: Language, version: SemVersion, publishType: PublishType[]): void { | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| const targets = publishType.map((t) => (t === PublishType.PackagePublishing ? 'Package' : 'Source Code')).join(' + '); | ||
| log.info( | ||
| `You can publish this SDK by removing the --dry-run flag. It will be published for the following:\n\n Profile: ${publishingProfile}\n Language: ${language}\n Version: ${version}\n Targets: ${targets}` | ||
| ); | ||
| } | ||
|
|
||
| public publishingRunningNotice( | ||
| profile: PublishingProfile, | ||
| language: Language, | ||
| version: SemVersion, | ||
| publishType: PublishType[] | ||
| ): void { | ||
| const targets = [...publishType] | ||
| .sort((a, b) => (a === PublishType.SourceCodePublishing ? -1 : b === PublishType.SourceCodePublishing ? 1 : 0)) | ||
|
Check warning on line 38 in src/prompts/sdk/publish.ts
|
||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| .map((t) => (t === PublishType.PackagePublishing ? 'Package' : 'Source Code')) | ||
| .join(' + '); | ||
| log.info( | ||
| `Publishing is running for the following:\n\n Profile: ${profile}\n Language: ${language}\n Version: ${version}\n Targets: ${targets}` | ||
| ); | ||
| } | ||
|
|
||
| public publishingLogsMessage(publishingLogUrl: string) { | ||
| const message = `To track progress and view publishing logs, please visit: | ||
| ${f.link(publishingLogUrl)}`; | ||
| noteWrapped(message, 'Publishing Logs'); | ||
| } | ||
|
|
||
| public async pollPublishingStatus( | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| getSdkPublishingLogFn: () => Promise<Result<PublishLogItem, ServiceError>> | ||
| ): Promise<PublishingOutcome> { | ||
| const TERMINAL_STATES = new Set(['Succeeded', 'Failed', 'Exception', 'InternalError']); | ||
| const POLL_INTERVAL_MS = 10000; // poll after every 10 seconds. | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
|
|
||
| let abortWait: (() => void) | undefined; | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| const spin = spinner({ | ||
| onCancel: () => { | ||
| abortWait?.(); | ||
| }, | ||
| cancelMessage: 'Publishing is still running on APIMatic and will continue without the CLI.' | ||
| }); | ||
|
|
||
| spin.start('Waiting for publishing status...'); | ||
|
|
||
| while (!spin.isCancelled) { | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| const publishingLogResult = await getSdkPublishingLogFn(); | ||
|
|
||
| if (publishingLogResult.isErr()) { | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| spin.stop('Failed to fetch publishing status.', 1); | ||
| return 'failed'; | ||
| } | ||
|
|
||
| const { events } = publishingLogResult.value; | ||
| const executionCompleted = events.every((event) => TERMINAL_STATES.has(event.eventType)); | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| const statusMessage = [...events] | ||
| .sort((a, b) => (a.publishType === 'SourceCode' ? -1 : b.publishType === 'SourceCode' ? 1 : 0)) | ||
|
Check warning on line 79 in src/prompts/sdk/publish.ts
|
||
| .map((event) => { | ||
| const target = event.publishType === 'SourceCode' ? 'Source Code' : 'Package'; | ||
| const eventLabels: Record<string, string> = { | ||
| Queued: 'Queued', | ||
| InProgress: 'In Progress', | ||
| Succeeded: 'Published' | ||
| }; | ||
| const label = eventLabels[event.eventType] ?? 'Failed'; | ||
| return `${target}: [${label}]`; | ||
| }) | ||
| .join(' | '); | ||
|
|
||
| if (executionCompleted) { | ||
| const isExecutionSuccessful = events.every((event) => event.eventType === 'Succeeded'); | ||
| spin.stop(statusMessage, isExecutionSuccessful ? 0 : 1); | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| return isExecutionSuccessful ? 'succeeded' : 'failed'; | ||
| } | ||
|
|
||
| spin.message(statusMessage); | ||
| await new Promise<void>((resolve) => { | ||
| const timer = setTimeout(resolve, POLL_INTERVAL_MS); | ||
| abortWait = () => { | ||
| clearTimeout(timer); | ||
| resolve(); | ||
| }; | ||
| }); | ||
| abortWait = undefined; | ||
|
mrafnadeem-apimatic marked this conversation as resolved.
|
||
| } | ||
|
|
||
| return 'cancelled'; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.