From b080302b4d6da43b932ee5d16e082e60451e941a Mon Sep 17 00:00:00 2001 From: tsemachLi Date: Wed, 30 Aug 2023 10:57:28 +0300 Subject: [PATCH] Feat: support builds (#41) * Feat: support builds * Feat: support builds --------- Co-authored-by: Your Full Name --- README.md | 60 +++++++++++++++++--- package.json | 4 +- src/commands/app-version/builds.ts | 63 +++++++++++++++++++++ src/commands/code/status.ts | 2 - src/consts/urls.ts | 4 ++ src/services/app-builds-service.ts | 29 ++++++++++ src/services/schemas/app-releases-schema.ts | 32 +++++++++++ src/services/schemas/general-schemas.ts | 1 + src/types/general/index.ts | 3 +- 9 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 src/commands/app-version/builds.ts create mode 100644 src/services/app-builds-service.ts create mode 100644 src/services/schemas/app-releases-schema.ts diff --git a/README.md b/README.md index e24728c..7730ed5 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -

Public access to this CLI is currently restricted but will become available in the next few months

+

Public access to this CLI is currently restricted but will become available in the next few +months

--- monday-code-cli @@ -7,12 +8,16 @@ monday-code-cli monday.com cli tool for `` apps management. + * [Usage](#usage) * [Commands](#commands) + # Usage + + ```sh-session $ npm install -g @mondaycom/apps-cli $ mapps COMMAND @@ -24,9 +29,13 @@ USAGE $ mapps COMMAND ... ``` + + # Commands + + * [`mapps app-version:list`](#mapps-app-versionlist) * [`mapps app:list`](#mapps-applist) * [`mapps autocomplete [SHELL]`](#mapps-autocomplete-shell) @@ -59,7 +68,33 @@ EXAMPLES $ mapps app-version:list ``` -_See code: [dist/commands/app-version/list.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/app-version/list.ts)_ +_See +code: [dist/commands/app-version/list.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/app-version/list.ts)_ + +## `mapps app-version:builds` + +List all builds for a specific app-version. + +``` +USAGE + $ mapps app-version:builds [--verbose] [--print-command] [-i ] + +FLAGS + -i, --appVersionId= Please enter the app version id of your app: + +GLOBAL FLAGS + --print-command Print the command that was executed (optional). + --verbose Print advanced logs (optional). + +DESCRIPTION + List all builds for a specific app-version. + +EXAMPLES + $ mapps app-version:builds +``` + +_See +code: [dist/commands/app-version/builds.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/app-version/builds.ts)_ ## `mapps app:list` @@ -80,7 +115,8 @@ EXAMPLES $ mapps app:list ``` -_See code: [dist/commands/app/list.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/app/list.ts)_ +_See +code: [dist/commands/app/list.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/app/list.ts)_ ## `mapps autocomplete [SHELL]` @@ -111,7 +147,8 @@ EXAMPLES $ mapps autocomplete --refresh-cache ``` -_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v2.2.0/src/commands/autocomplete/index.ts)_ +_See +code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v2.2.0/src/commands/autocomplete/index.ts)_ ## `mapps code:env` @@ -140,7 +177,8 @@ EXAMPLES $ mapps code:env ``` -_See code: [dist/commands/code/env.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/env.ts)_ +_See +code: [dist/commands/code/env.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/env.ts)_ ## `mapps code:logs` @@ -173,7 +211,8 @@ EXAMPLES $ mapps code:logs -i APP_VERSION_ID -t LOGS_TYPE ``` -_See code: [dist/commands/code/logs.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/logs.ts)_ +_See +code: [dist/commands/code/logs.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/logs.ts)_ ## `mapps code:push` @@ -201,7 +240,8 @@ EXAMPLES $ mapps code:push -i APP_VERSION_ID_TO_PUSH ``` -_See code: [dist/commands/code/push.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/push.ts)_ +_See +code: [dist/commands/code/push.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/push.ts)_ ## `mapps code:status` @@ -225,7 +265,8 @@ EXAMPLES $ mapps code:status -i APP_VERSION_ID ``` -_See code: [dist/commands/code/status.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/status.ts)_ +_See +code: [dist/commands/code/status.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/code/status.ts)_ ## `mapps help [COMMANDS]` @@ -269,5 +310,6 @@ EXAMPLES $ mapps init -t SECRET_TOKEN ``` -_See code: [dist/commands/init/index.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/init/index.ts)_ +_See +code: [dist/commands/init/index.ts](https://github.com/mondaycom/monday-code-cli/blob/v1.0.0/dist/commands/init/index.ts)_ diff --git a/package.json b/package.json index d3a9c74..1aa9280 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mondaycom/apps-cli", - "version": "1.0.0", + "version": "1.1.0", "description": "A cli tool to manage apps (and monday-code projects) in monday.com", "author": "monday.com Apps Team", "type": "module", @@ -131,4 +131,4 @@ "@oclif/plugin-autocomplete" ] } -} \ No newline at end of file +} diff --git a/src/commands/app-version/builds.ts b/src/commands/app-version/builds.ts new file mode 100644 index 0000000..f0166a6 --- /dev/null +++ b/src/commands/app-version/builds.ts @@ -0,0 +1,63 @@ +import { Flags } from '@oclif/core'; +import { StatusCodes } from 'http-status-codes'; + +import Status from 'commands/code/status'; +import { AuthenticatedCommand } from 'commands-base/authenticated-command'; +import { APP_VERSION_ID_TO_ENTER } from 'consts/messages'; +import { listAppBuilds } from 'services/app-builds-service'; +import { DynamicChoicesService } from 'services/dynamic-choices-service'; +import { AppRelease } from 'services/schemas/app-releases-schema'; +import { HttpError } from 'types/errors'; +import logger from 'utils/logger'; + +const printBuilds = (appBuilds: Array) => { + const appBuildsTable = appBuilds.map(appBuild => { + return { + category: appBuild.category, + ...(appBuild.data?.liveUrl && { 'live url': appBuild.data?.liveUrl }), + ...(appBuild.data?.url && { url: appBuild.data?.url }), + ...(appBuild.data?.latestUrl && { 'static url (latest deployment)': appBuild.data?.latestUrl }), + ...(appBuild.data?.sourceUrl && { 'source url (download)': appBuild.data?.sourceUrl }), + ...(appBuild.data?.microFrontendName && { 'micro frontend name': appBuild.data?.microFrontendName }), + }; + }); + + logger.table(appBuildsTable); +}; + +export default class AppVersionBuilds extends AuthenticatedCommand { + static description = 'List all builds for a specific app version'; + static examples = ['<%= config.bin %> <%= command.id %> -i APP_VERSION_ID']; + static flags = AppVersionBuilds.serializeFlags({ + appVersionId: Flags.integer({ + char: 'i', + aliases: ['v'], + description: APP_VERSION_ID_TO_ENTER, + }), + }); + + DEBUG_TAG = 'app_version_builds'; + + public async run(): Promise { + const { flags } = await this.parse(Status); + let appVersionId = flags.appVersionId; + if (!appVersionId) { + const appAndAppVersion = await DynamicChoicesService.chooseAppAndAppVersion(); + appVersionId = appAndAppVersion.appVersionId; + } + + try { + this.preparePrintCommand(this, { appVersionId }); + const appReleases = await listAppBuilds(appVersionId); + printBuilds(appReleases); + } catch (error: unknown) { + if (error instanceof HttpError && error.code === StatusCodes.NOT_FOUND) { + logger.error(`No builds found for provided app version id - "${appVersionId}"`); + } else { + logger.error(`An unknown error happened while fetching builds for app version id - "${appVersionId}"`); + } + + process.exit(0); + } + } +} diff --git a/src/commands/code/status.ts b/src/commands/code/status.ts index 3ce1ceb..4efaea1 100644 --- a/src/commands/code/status.ts +++ b/src/commands/code/status.ts @@ -12,13 +12,11 @@ import logger from 'utils/logger'; const printDeploymentStatus = (appVersionId: number, deploymentStatus: AppVersionDeploymentStatus) => { const { deployment, status, error } = deploymentStatus; const url = deployment?.url || 'none'; - const latestUrl = deployment?.latestUrl || 'none'; const errorMessage: string | undefined = error?.message; const tableData = { id: appVersionId, status, url, - 'static url (latest deployment)': latestUrl, ...(errorMessage && { errorMessage }), }; diff --git a/src/consts/urls.ts b/src/consts/urls.ts index 2c31e1c..0fd53da 100644 --- a/src/consts/urls.ts +++ b/src/consts/urls.ts @@ -43,3 +43,7 @@ export const appEnvironmentUrl = (appId: AppId, key: string): string => { export const appEnvironmentKeysUrl = (appId: AppId): string => { return `/api/code/${appId}/env-keys`; }; + +export const appReleasesUrl = (appVersionId: AppId): string => { + return `/apps_ms/app-versions/${appVersionId}/releases`; +}; diff --git a/src/services/app-builds-service.ts b/src/services/app-builds-service.ts new file mode 100644 index 0000000..aa06edb --- /dev/null +++ b/src/services/app-builds-service.ts @@ -0,0 +1,29 @@ +import { appReleasesUrl } from 'consts/urls'; +import { execute } from 'services/api-service'; +import { AppRelease, AppReleasesResponse, appReleasesSchema } from 'services/schemas/app-releases-schema'; +import { HttpError } from 'types/errors'; +import { AppVersionId } from 'types/general'; +import { HttpMethodTypes } from 'types/services/api-service'; +import { appsUrlBuilder } from 'utils/urls-builder'; + +export const listAppBuilds = async (appVersionId: AppVersionId): Promise> => { + try { + const path = appReleasesUrl(appVersionId); + const url = appsUrlBuilder(path); + const response = await execute( + { + url, + headers: { Accept: 'application/json' }, + method: HttpMethodTypes.GET, + }, + appReleasesSchema, + ); + return response.appReleases; + } catch (error: any) { + if (error instanceof HttpError) { + throw error; + } + + throw new Error('Failed to list app versions.'); + } +}; diff --git a/src/services/schemas/app-releases-schema.ts b/src/services/schemas/app-releases-schema.ts new file mode 100644 index 0000000..45ed32b --- /dev/null +++ b/src/services/schemas/app-releases-schema.ts @@ -0,0 +1,32 @@ +import { z } from 'zod'; + +import { baseResponseHttpMetaDataSchema } from 'services/schemas/api-service-schemas'; +import { appReleaseIdSchema, appVersionIdSchema } from 'services/schemas/general-schemas'; + +export const appReleaseSchema = z.object({ + id: appReleaseIdSchema, + // eslint-disable-next-line camelcase + app_version_id: appVersionIdSchema, + kind: z.string(), + category: z.string(), + state: z.string(), + data: z + .object({ + url: z.string().optional(), + latestUrl: z.string().optional(), + liveUrl: z.string().optional(), + deploymentState: z.string().optional(), + sourceUrl: z.string().optional(), + microFrontendName: z.string().optional(), + }) + .optional(), +}); + +export const appReleasesSchema = z + .object({ + appReleases: z.array(appReleaseSchema), + }) + .merge(baseResponseHttpMetaDataSchema); + +export type AppReleasesResponse = z.infer; +export type AppRelease = z.infer; diff --git a/src/services/schemas/general-schemas.ts b/src/services/schemas/general-schemas.ts index d854ed5..b311857 100644 --- a/src/services/schemas/general-schemas.ts +++ b/src/services/schemas/general-schemas.ts @@ -2,3 +2,4 @@ import { z } from 'zod'; export const appIdSchema = z.number(); export const appVersionIdSchema = z.number(); +export const appReleaseIdSchema = z.number(); diff --git a/src/types/general/index.ts b/src/types/general/index.ts index 0057a97..c92d12a 100644 --- a/src/types/general/index.ts +++ b/src/types/general/index.ts @@ -1,5 +1,6 @@ import { z } from 'zod'; -import { appIdSchema } from 'services/schemas/general-schemas'; +import { appIdSchema, appVersionIdSchema } from 'services/schemas/general-schemas'; export type AppId = z.infer; +export type AppVersionId = z.infer;