From 8003126aa5cb8035bb0da62d200eb588a79fc3c4 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 10:32:58 +0100 Subject: [PATCH 01/29] chore: version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad3b101..d423507 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@js-soft/codemagic-tools", - "version": "0.0.2", + "version": "0.0.3", "description": "Codemagic extended tooling", "homepage": "https://github.com/js-soft/codemagic-tools#readme", "bugs": { From 65236a8f03dca82fbae8254fd4168963d4b6c9f8 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 10:33:48 +0100 Subject: [PATCH 02/29] feature: create teams publish command --- src/index.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 89123cb..aec12e3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,15 +2,22 @@ import yargs from "yargs" import { TeamsMessaging } from "./commands/TeamsMessaging" +import { TeamsMessagingPublish } from "./commands/TeamsMessagingPublish" async function run() { await yargs(process.argv.slice(2)) - .command("teams", "This command is used to send a teams message via a passed webhook", async (args) => { + .command("teams-build", "After Codemagic Build: MS Teams message about new build", async (args) => { const teamsMessagingCommand = new TeamsMessaging() const options = await teamsMessagingCommand.parseCLIOptions(args) await teamsMessagingCommand.run(options) return options }) + .command("teams-publish", "After Codemagic Publish: MS Teams message about new release", async (args) => { + const teamsMessagePublish = new TeamsMessagingPublish() + const options = await teamsMessagePublish.parseCLIOptions(args) + await teamsMessagePublish.run(options) + return options + }) .demand(1, "Must provide a valid command from the ones listed above.") .scriptName("jscm") .parseAsync() From 145a30aa2a69c6aef446c247e11fd342e7e9db25 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 10:34:08 +0100 Subject: [PATCH 03/29] feature: initial teams publish command --- src/commands/TeamsMessagingPublish.ts | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/commands/TeamsMessagingPublish.ts diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsMessagingPublish.ts new file mode 100644 index 0000000..9b99ad2 --- /dev/null +++ b/src/commands/TeamsMessagingPublish.ts @@ -0,0 +1,81 @@ +import axios from "axios" +import yargs from "yargs" + +export interface TeamsMessagingPublishOptions { + webhook: string + platform: string + artifactUrl: string + wasBuildSuccessful: boolean +} + +export class TeamsMessagingPublish { + public async run(options: TeamsMessagingPublishOptions): Promise<void> { + if (!this.isUrlValid(options.webhook)) { + console.error("The given webhook is not valid.") + process.exit(1) + } + + if (!this.isUrlValid(options.artifactUrl)) { + console.error("The given artifactUrl is not valid.") + process.exit(1) + } + + const statusIdentifier = options.wasBuildSuccessful ? "Successful" : "Failed" + const platformIdentifier = options.platform.toUpperCase() + + const messageContents = { + title: `New ${statusIdentifier.toLocaleLowerCase()} codemagic build - ${platformIdentifier}`, + summary: `${statusIdentifier} build - ${platformIdentifier}`, + text: options.wasBuildSuccessful + ? "The newly released version did build and is now available as an artifact." + : "A problem occurred while building the newly released version. The corresponding logs are available.", + potentialAction: [ + { + "@type": "OpenUri", + name: options.wasBuildSuccessful ? "Download Build" : "Read Logs", + targets: [{ os: "default", uri: options.artifactUrl }] + } + ] + } + + await axios.post(options.webhook, messageContents).catch((_) => { + console.log("Could not send message to teams channel.") + process.exit(1) + }) + } + + public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingPublishOptions | Promise<TeamsMessagingPublishOptions> { + return argv + .option("platform", { + description: "identifier of the platform for which the build was created", + required: true, + type: "string", + choices: ["ios", "android"] + }) + .option("artifactUrl", { + description: "download link for the generated artifact (logs or build)", + required: true, + type: "string" + }) + .option("wasBuildSuccessful", { + description: "status of the finished build", + required: true, + type: "boolean" + }) + .option("webhook", { + description: "the webhook of the teams channel, that should receive the message", + required: true, + type: "string" + }).argv + } + + private isUrlValid(url: string): boolean { + try { + // eslint-disable-next-line no-new + new URL(url) + return true + } catch (err) { + return false + } + } +} From a390823d655abe3f9c7ac61a3992d63c5cb77696 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 11:01:06 +0100 Subject: [PATCH 04/29] feature: extend teams-build command --- src/commands/TeamsMessaging.ts | 38 +++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index c52d4a4..a50cbb9 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -6,6 +6,9 @@ export interface TeamsMessagingOptions { platform: string artifactUrl: string wasBuildSuccessful: boolean + buildNumber: number + buildUrl: string + appName: string } export class TeamsMessaging { @@ -20,20 +23,30 @@ export class TeamsMessaging { process.exit(1) } + if (!this.isUrlValid(options.buildUrl)) { + console.error("The given buildUrl is not valid.") + process.exit(1) + } + const statusIdentifier = options.wasBuildSuccessful ? "Successful" : "Failed" const platformIdentifier = options.platform.toUpperCase() const messageContents = { - title: `New ${statusIdentifier.toLocaleLowerCase()} codemagic build - ${platformIdentifier}`, - summary: `${statusIdentifier} build - ${platformIdentifier}`, + title: `${options.appName}: New ${statusIdentifier.toLocaleLowerCase()} build ${options.buildNumber} - ${platformIdentifier}`, + summary: `${options.appName}: ${statusIdentifier} build ${options.buildNumber} - ${platformIdentifier}`, text: options.wasBuildSuccessful - ? "The newly released version did build and is now available as an artifact." - : "A problem occurred while building the newly released version. The corresponding logs are available.", + ? `Build ${options.buildNumber}: The newly released version did build and is now available as an artifact.` + : `Build ${options.buildNumber}: A problem occurred while building the newly released version. The corresponding logs are available.`, potentialAction: [ { "@type": "OpenUri", - name: options.wasBuildSuccessful ? "Download Build" : "Read Logs", + name: options.wasBuildSuccessful ? `Download ${options.platform}-App` : "Open Logs", targets: [{ os: "default", uri: options.artifactUrl }] + }, + { + "@type": "OpenUri", + name: "Open Build", + targets: [{ os: "default", uri: options.buildUrl }] } ] } @@ -46,6 +59,11 @@ export class TeamsMessaging { public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingOptions | Promise<TeamsMessagingOptions> { return argv + .option("appName", { + description: "name of the App", + required: true, + type: "string" + }) .option("platform", { description: "identifier of the platform for which the build was created", required: true, @@ -66,6 +84,16 @@ export class TeamsMessaging { description: "the webhook of the teams channel, that should receive the message", required: true, type: "string" + }) + .option("buildNumber", { + description: "the number of the run build", + required: true, + type: "number" + }) + .option("buildUrl", { + description: "a link to the build page", + required: true, + type: "string" }).argv } From 8268085a59743f02296b995e3a90b0a5865e958d Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 11:17:16 +0100 Subject: [PATCH 05/29] refactor: minor reordering --- src/commands/TeamsMessaging.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index a50cbb9..7ee0160 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -2,13 +2,13 @@ import axios from "axios" import yargs from "yargs" export interface TeamsMessagingOptions { - webhook: string + appName: string platform: string - artifactUrl: string - wasBuildSuccessful: boolean - buildNumber: number buildUrl: string - appName: string + buildNumber: number + wasBuildSuccessful: boolean + artifactUrl: string + webhook: string } export class TeamsMessaging { @@ -70,28 +70,28 @@ export class TeamsMessaging { type: "string", choices: ["ios", "android"] }) - .option("artifactUrl", { - description: "download link for the generated artifact (logs or build)", + .option("buildUrl", { + description: "a link to the build page", required: true, type: "string" }) + .option("buildNumber", { + description: "the number of the run build", + required: true, + type: "number" + }) .option("wasBuildSuccessful", { description: "status of the finished build", required: true, type: "boolean" }) - .option("webhook", { - description: "the webhook of the teams channel, that should receive the message", + .option("artifactUrl", { + description: "download link for the generated artifact (logs or build)", required: true, type: "string" }) - .option("buildNumber", { - description: "the number of the run build", - required: true, - type: "number" - }) - .option("buildUrl", { - description: "a link to the build page", + .option("webhook", { + description: "the webhook of the teams channel, that should receive the message", required: true, type: "string" }).argv From 2f819bd445ed68139e318ea0bffcd6201fefa7ba Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 12:59:05 +0100 Subject: [PATCH 06/29] refactor: improve parameter names --- src/commands/TeamsMessaging.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index 7ee0160..1fc0fc1 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -2,13 +2,13 @@ import axios from "axios" import yargs from "yargs" export interface TeamsMessagingOptions { - appName: string + projectName: string platform: string buildUrl: string buildNumber: number wasBuildSuccessful: boolean artifactUrl: string - webhook: string + webhook: string } export class TeamsMessaging { @@ -32,8 +32,10 @@ export class TeamsMessaging { const platformIdentifier = options.platform.toUpperCase() const messageContents = { - title: `${options.appName}: New ${statusIdentifier.toLocaleLowerCase()} build ${options.buildNumber} - ${platformIdentifier}`, - summary: `${options.appName}: ${statusIdentifier} build ${options.buildNumber} - ${platformIdentifier}`, + title: `${options.projectName}: New ${statusIdentifier.toLocaleLowerCase()} build ${ + options.buildNumber + } - ${platformIdentifier}`, + summary: `${options.projectName}: ${statusIdentifier} build ${options.buildNumber} - ${platformIdentifier}`, text: options.wasBuildSuccessful ? `Build ${options.buildNumber}: The newly released version did build and is now available as an artifact.` : `Build ${options.buildNumber}: A problem occurred while building the newly released version. The corresponding logs are available.`, @@ -59,8 +61,8 @@ export class TeamsMessaging { public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingOptions | Promise<TeamsMessagingOptions> { return argv - .option("appName", { - description: "name of the App", + .option("projectName", { + description: "name of the Project", required: true, type: "string" }) From 4078267149eadb05a17a16f90d8a7d729efceded Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 13:42:50 +0100 Subject: [PATCH 07/29] refactor: change build-command text slightly to better differentiate between the two types of messages --- src/commands/TeamsMessaging.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index 1fc0fc1..2e12205 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -37,7 +37,7 @@ export class TeamsMessaging { } - ${platformIdentifier}`, summary: `${options.projectName}: ${statusIdentifier} build ${options.buildNumber} - ${platformIdentifier}`, text: options.wasBuildSuccessful - ? `Build ${options.buildNumber}: The newly released version did build and is now available as an artifact.` + ? `Build ${options.buildNumber}: The latest version did build and is now available as an artifact.` : `Build ${options.buildNumber}: A problem occurred while building the newly released version. The corresponding logs are available.`, potentialAction: [ { From 83a0ff33bf460da0ee2380c58666f501bf69ea79 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 14:04:48 +0100 Subject: [PATCH 08/29] feature: refine teams-publish command --- src/commands/TeamsMessaging.ts | 6 ++-- src/commands/TeamsMessagingPublish.ts | 45 ++++++++++++++++++--------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index 2e12205..8a0763e 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -32,10 +32,8 @@ export class TeamsMessaging { const platformIdentifier = options.platform.toUpperCase() const messageContents = { - title: `${options.projectName}: New ${statusIdentifier.toLocaleLowerCase()} build ${ - options.buildNumber - } - ${platformIdentifier}`, - summary: `${options.projectName}: ${statusIdentifier} build ${options.buildNumber} - ${platformIdentifier}`, + title: `${options.projectName}: New ${statusIdentifier.toLocaleLowerCase()} build - ${platformIdentifier}`, + summary: `${options.projectName}: ${statusIdentifier} build - ${platformIdentifier}`, text: options.wasBuildSuccessful ? `Build ${options.buildNumber}: The latest version did build and is now available as an artifact.` : `Build ${options.buildNumber}: A problem occurred while building the newly released version. The corresponding logs are available.`, diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsMessagingPublish.ts index 9b99ad2..0b8522b 100644 --- a/src/commands/TeamsMessagingPublish.ts +++ b/src/commands/TeamsMessagingPublish.ts @@ -2,10 +2,12 @@ import axios from "axios" import yargs from "yargs" export interface TeamsMessagingPublishOptions { - webhook: string + projectName: string platform: string + buildUrl: string + buildNumber: number artifactUrl: string - wasBuildSuccessful: boolean + webhook: string } export class TeamsMessagingPublish { @@ -20,19 +22,22 @@ export class TeamsMessagingPublish { process.exit(1) } - const statusIdentifier = options.wasBuildSuccessful ? "Successful" : "Failed" const platformIdentifier = options.platform.toUpperCase() - + const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store" const messageContents = { - title: `New ${statusIdentifier.toLocaleLowerCase()} codemagic build - ${platformIdentifier}`, - summary: `${statusIdentifier} build - ${platformIdentifier}`, - text: options.wasBuildSuccessful - ? "The newly released version did build and is now available as an artifact." - : "A problem occurred while building the newly released version. The corresponding logs are available.", + title: `${options.projectName}: New release is no available in the ${storeName} [${platformIdentifier}]`, + summary: `New Release - ${platformIdentifier}`, + text: `New Release ${options.buildNumber} - ${platformIdentifier} <br/> + The newly released version is now available in the ${storeName} or can alternatively be directly downloaded below.<br/> `, potentialAction: [ { "@type": "OpenUri", - name: options.wasBuildSuccessful ? "Download Build" : "Read Logs", + name: "Download new Version", + targets: [{ os: "default", uri: options.artifactUrl }] + }, + { + "@type": "OpenUri", + name: "Open Build", targets: [{ os: "default", uri: options.artifactUrl }] } ] @@ -46,21 +51,31 @@ export class TeamsMessagingPublish { public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingPublishOptions | Promise<TeamsMessagingPublishOptions> { return argv + .option("projectName",{ + description: "Name of the project", + required: true, + type: "string", + }) .option("platform", { description: "identifier of the platform for which the build was created", required: true, type: "string", choices: ["ios", "android"] }) - .option("artifactUrl", { - description: "download link for the generated artifact (logs or build)", + .option("buildUrl", { + description: "a link to the build page", required: true, type: "string" }) - .option("wasBuildSuccessful", { - description: "status of the finished build", + .option("buildNumber", { + description: "the number of the run build", + required: true, + type: "number" + }) + .option("artifactUrl", { + description: "download link for the generated artifact (logs or build)", required: true, - type: "boolean" + type: "string" }) .option("webhook", { description: "the webhook of the teams channel, that should receive the message", From b322d9254a4d6ff9bed49cbe5193831f21a9183f Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 14:05:22 +0100 Subject: [PATCH 09/29] refactor: format project --- src/commands/TeamsMessagingPublish.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsMessagingPublish.ts index 0b8522b..4dffb4c 100644 --- a/src/commands/TeamsMessagingPublish.ts +++ b/src/commands/TeamsMessagingPublish.ts @@ -51,10 +51,10 @@ export class TeamsMessagingPublish { public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingPublishOptions | Promise<TeamsMessagingPublishOptions> { return argv - .option("projectName",{ + .option("projectName", { description: "Name of the project", required: true, - type: "string", + type: "string" }) .option("platform", { description: "identifier of the platform for which the build was created", From d9ab0020bc6efa8ff9a32d6e8b540881bb509715 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 14:13:51 +0100 Subject: [PATCH 10/29] refactor: improve output message --- src/commands/TeamsMessaging.ts | 2 +- src/commands/TeamsMessagingPublish.ts | 5 +++++ src/index.ts | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsMessaging.ts index 8a0763e..33b27c9 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsMessaging.ts @@ -71,7 +71,7 @@ export class TeamsMessaging { choices: ["ios", "android"] }) .option("buildUrl", { - description: "a link to the build page", + description: "link to the build process", required: true, type: "string" }) diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsMessagingPublish.ts index 4dffb4c..887aecb 100644 --- a/src/commands/TeamsMessagingPublish.ts +++ b/src/commands/TeamsMessagingPublish.ts @@ -22,6 +22,11 @@ export class TeamsMessagingPublish { process.exit(1) } + if (!this.isUrlValid(options.buildUrl)) { + console.error("The given buildUrl is not valid.") + process.exit(1) + } + const platformIdentifier = options.platform.toUpperCase() const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store" const messageContents = { diff --git a/src/index.ts b/src/index.ts index aec12e3..4e88cca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,13 +6,13 @@ import { TeamsMessagingPublish } from "./commands/TeamsMessagingPublish" async function run() { await yargs(process.argv.slice(2)) - .command("teams-build", "After Codemagic Build: MS Teams message about new build", async (args) => { + .command("teams-build", "After Codemagic Build: Send MS-Teams message informing about the new build", async (args) => { const teamsMessagingCommand = new TeamsMessaging() const options = await teamsMessagingCommand.parseCLIOptions(args) await teamsMessagingCommand.run(options) return options }) - .command("teams-publish", "After Codemagic Publish: MS Teams message about new release", async (args) => { + .command("teams-publish", "After Codemagic Publish: Send MS-Teams message informing about the new release", async (args) => { const teamsMessagePublish = new TeamsMessagingPublish() const options = await teamsMessagePublish.parseCLIOptions(args) await teamsMessagePublish.run(options) From 23381970df9fd115057745c6871d11c1f1ce5e44 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 14:17:37 +0100 Subject: [PATCH 11/29] refactor: reformat project --- src/index.ts | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4e88cca..a8821e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,18 +6,26 @@ import { TeamsMessagingPublish } from "./commands/TeamsMessagingPublish" async function run() { await yargs(process.argv.slice(2)) - .command("teams-build", "After Codemagic Build: Send MS-Teams message informing about the new build", async (args) => { - const teamsMessagingCommand = new TeamsMessaging() - const options = await teamsMessagingCommand.parseCLIOptions(args) - await teamsMessagingCommand.run(options) - return options - }) - .command("teams-publish", "After Codemagic Publish: Send MS-Teams message informing about the new release", async (args) => { - const teamsMessagePublish = new TeamsMessagingPublish() - const options = await teamsMessagePublish.parseCLIOptions(args) - await teamsMessagePublish.run(options) - return options - }) + .command( + "teams-build", + "After Codemagic Build: Send MS-Teams message informing about the new build", + async (args) => { + const teamsMessagingCommand = new TeamsMessaging() + const options = await teamsMessagingCommand.parseCLIOptions(args) + await teamsMessagingCommand.run(options) + return options + } + ) + .command( + "teams-publish", + "After Codemagic Publish: Send MS-Teams message informing about the new release", + async (args) => { + const teamsMessagePublish = new TeamsMessagingPublish() + const options = await teamsMessagePublish.parseCLIOptions(args) + await teamsMessagePublish.run(options) + return options + } + ) .demand(1, "Must provide a valid command from the ones listed above.") .scriptName("jscm") .parseAsync() From 755db0d68c8c26a086d741b217eaccb295cc3a70 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 15:01:21 +0100 Subject: [PATCH 12/29] chore: complete version bump-up --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 582e54c..26e3b55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@js-soft/codemagic-tools", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@js-soft/codemagic-tools", - "version": "0.0.2", + "version": "0.0.3", "license": "MIT", "dependencies": { "axios": "^1.6.2", From ccdec64300b311bb490a1b3b3cd6804eb7f058b5 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 15:07:09 +0100 Subject: [PATCH 13/29] feature: remove artifact link from publish message --- src/commands/TeamsMessagingPublish.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsMessagingPublish.ts index 887aecb..dfae04e 100644 --- a/src/commands/TeamsMessagingPublish.ts +++ b/src/commands/TeamsMessagingPublish.ts @@ -6,7 +6,6 @@ export interface TeamsMessagingPublishOptions { platform: string buildUrl: string buildNumber: number - artifactUrl: string webhook: string } @@ -17,11 +16,6 @@ export class TeamsMessagingPublish { process.exit(1) } - if (!this.isUrlValid(options.artifactUrl)) { - console.error("The given artifactUrl is not valid.") - process.exit(1) - } - if (!this.isUrlValid(options.buildUrl)) { console.error("The given buildUrl is not valid.") process.exit(1) @@ -35,15 +29,10 @@ export class TeamsMessagingPublish { text: `New Release ${options.buildNumber} - ${platformIdentifier} <br/> The newly released version is now available in the ${storeName} or can alternatively be directly downloaded below.<br/> `, potentialAction: [ - { - "@type": "OpenUri", - name: "Download new Version", - targets: [{ os: "default", uri: options.artifactUrl }] - }, { "@type": "OpenUri", name: "Open Build", - targets: [{ os: "default", uri: options.artifactUrl }] + targets: [{ os: "default", uri: options.buildUrl }] } ] } @@ -77,11 +66,6 @@ export class TeamsMessagingPublish { required: true, type: "number" }) - .option("artifactUrl", { - description: "download link for the generated artifact (logs or build)", - required: true, - type: "string" - }) .option("webhook", { description: "the webhook of the teams channel, that should receive the message", required: true, From 520ab0982e9da2723288d9a756cf5807a6cda3bc Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 15:08:53 +0100 Subject: [PATCH 14/29] refactor: rename jscm sub-commands --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index a8821e7..fd0a08d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ import { TeamsMessagingPublish } from "./commands/TeamsMessagingPublish" async function run() { await yargs(process.argv.slice(2)) .command( - "teams-build", + "teams-develop", "After Codemagic Build: Send MS-Teams message informing about the new build", async (args) => { const teamsMessagingCommand = new TeamsMessaging() @@ -17,7 +17,7 @@ async function run() { } ) .command( - "teams-publish", + "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", async (args) => { const teamsMessagePublish = new TeamsMessagingPublish() From c3099336305b7252c9e4451d9854238b6fbe4d18 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 15:19:59 +0100 Subject: [PATCH 15/29] refactor: rename to match command-names --- .../{TeamsMessaging.ts => TeamsDevelopMessaging.ts} | 8 ++++---- ...amsMessagingPublish.ts => TeamsProductionMessaging.ts} | 8 ++++---- src/index.ts | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/commands/{TeamsMessaging.ts => TeamsDevelopMessaging.ts} (91%) rename src/commands/{TeamsMessagingPublish.ts => TeamsProductionMessaging.ts} (88%) diff --git a/src/commands/TeamsMessaging.ts b/src/commands/TeamsDevelopMessaging.ts similarity index 91% rename from src/commands/TeamsMessaging.ts rename to src/commands/TeamsDevelopMessaging.ts index 33b27c9..50733c4 100644 --- a/src/commands/TeamsMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -1,7 +1,7 @@ import axios from "axios" import yargs from "yargs" -export interface TeamsMessagingOptions { +export interface TeamsDevelopMessagingOptions { projectName: string platform: string buildUrl: string @@ -11,8 +11,8 @@ export interface TeamsMessagingOptions { webhook: string } -export class TeamsMessaging { - public async run(options: TeamsMessagingOptions): Promise<void> { +export class TeamsDevelopMessaging { + public async run(options: TeamsDevelopMessagingOptions): Promise<void> { if (!this.isUrlValid(options.webhook)) { console.error("The given webhook is not valid.") process.exit(1) @@ -57,7 +57,7 @@ export class TeamsMessaging { }) } - public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingOptions | Promise<TeamsMessagingOptions> { + public parseCLIOptions(argv: yargs.Argv<{}>): TeamsDevelopMessagingOptions | Promise<TeamsDevelopMessagingOptions> { return argv .option("projectName", { description: "name of the Project", diff --git a/src/commands/TeamsMessagingPublish.ts b/src/commands/TeamsProductionMessaging.ts similarity index 88% rename from src/commands/TeamsMessagingPublish.ts rename to src/commands/TeamsProductionMessaging.ts index dfae04e..bf0157f 100644 --- a/src/commands/TeamsMessagingPublish.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -1,7 +1,7 @@ import axios from "axios" import yargs from "yargs" -export interface TeamsMessagingPublishOptions { +export interface TeamsProductionMessagingOptions { projectName: string platform: string buildUrl: string @@ -9,8 +9,8 @@ export interface TeamsMessagingPublishOptions { webhook: string } -export class TeamsMessagingPublish { - public async run(options: TeamsMessagingPublishOptions): Promise<void> { +export class TeamsProductionMessaging { + public async run(options: TeamsProductionMessagingOptions): Promise<void> { if (!this.isUrlValid(options.webhook)) { console.error("The given webhook is not valid.") process.exit(1) @@ -43,7 +43,7 @@ export class TeamsMessagingPublish { }) } - public parseCLIOptions(argv: yargs.Argv<{}>): TeamsMessagingPublishOptions | Promise<TeamsMessagingPublishOptions> { + public parseCLIOptions(argv: yargs.Argv<{}>): TeamsProductionMessagingOptions | Promise<TeamsProductionMessagingOptions> { return argv .option("projectName", { description: "Name of the project", diff --git a/src/index.ts b/src/index.ts index fd0a08d..51041e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,8 @@ #!/usr/bin/env node import yargs from "yargs" -import { TeamsMessaging } from "./commands/TeamsMessaging" -import { TeamsMessagingPublish } from "./commands/TeamsMessagingPublish" +import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging" +import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging" async function run() { await yargs(process.argv.slice(2)) @@ -10,7 +10,7 @@ async function run() { "teams-develop", "After Codemagic Build: Send MS-Teams message informing about the new build", async (args) => { - const teamsMessagingCommand = new TeamsMessaging() + const teamsMessagingCommand = new TeamsDevelopMessaging() const options = await teamsMessagingCommand.parseCLIOptions(args) await teamsMessagingCommand.run(options) return options @@ -20,7 +20,7 @@ async function run() { "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", async (args) => { - const teamsMessagePublish = new TeamsMessagingPublish() + const teamsMessagePublish = new TeamsProductionMessaging() const options = await teamsMessagePublish.parseCLIOptions(args) await teamsMessagePublish.run(options) return options From c549b39c95e9a3204a2795b095f511b1932883a2 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 13 Dec 2023 15:20:18 +0100 Subject: [PATCH 16/29] refactor: reformat files --- src/commands/TeamsProductionMessaging.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index bf0157f..c402646 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -43,7 +43,9 @@ export class TeamsProductionMessaging { }) } - public parseCLIOptions(argv: yargs.Argv<{}>): TeamsProductionMessagingOptions | Promise<TeamsProductionMessagingOptions> { + public parseCLIOptions( + argv: yargs.Argv<{}> + ): TeamsProductionMessagingOptions | Promise<TeamsProductionMessagingOptions> { return argv .option("projectName", { description: "Name of the project", From 8ab85bf6f9736ef1fe8876b64b715da5dc23bcb2 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Fri, 15 Dec 2023 08:25:31 +0100 Subject: [PATCH 17/29] feature: improve message quality --- src/commands/TeamsDevelopMessaging.ts | 2 +- src/commands/TeamsProductionMessaging.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index 50733c4..3a0bfbb 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -32,7 +32,7 @@ export class TeamsDevelopMessaging { const platformIdentifier = options.platform.toUpperCase() const messageContents = { - title: `${options.projectName}: New ${statusIdentifier.toLocaleLowerCase()} build - ${platformIdentifier}`, + title: `New successful ${options.platform} debug build for the "${options.projectName}" App`, summary: `${options.projectName}: ${statusIdentifier} build - ${platformIdentifier}`, text: options.wasBuildSuccessful ? `Build ${options.buildNumber}: The latest version did build and is now available as an artifact.` diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index c402646..b93e27d 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -24,10 +24,10 @@ export class TeamsProductionMessaging { const platformIdentifier = options.platform.toUpperCase() const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store" const messageContents = { - title: `${options.projectName}: New release is no available in the ${storeName} [${platformIdentifier}]`, + title: `${options.projectName}: New release is now available in the ${storeName} [${platformIdentifier}]`, summary: `New Release - ${platformIdentifier}`, - text: `New Release ${options.buildNumber} - ${platformIdentifier} <br/> - The newly released version is now available in the ${storeName} or can alternatively be directly downloaded below.<br/> `, + text: `New Release: #${options.buildNumber} - ${platformIdentifier} <br/> + The newly released version is now available in the ${storeName}. `, potentialAction: [ { "@type": "OpenUri", From 4a913cbedae46f493093aa07060abf77e1b804fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Fri, 15 Dec 2023 09:01:04 +0100 Subject: [PATCH 18/29] wip --- src/CmArtifactLink.ts | 8 +++++ src/commands/TeamsDevelopMessaging.ts | 45 +++++---------------------- src/index.ts | 15 ++++++++- 3 files changed, 29 insertions(+), 39 deletions(-) create mode 100644 src/CmArtifactLink.ts diff --git a/src/CmArtifactLink.ts b/src/CmArtifactLink.ts new file mode 100644 index 0000000..761f633 --- /dev/null +++ b/src/CmArtifactLink.ts @@ -0,0 +1,8 @@ +export interface CmArtifactLink { + name: string + type: string + url: string + md5: string + versionName: string + bundleId: string +} diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index 3a0bfbb..d1d7d20 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -57,44 +57,13 @@ export class TeamsDevelopMessaging { }) } - public parseCLIOptions(argv: yargs.Argv<{}>): TeamsDevelopMessagingOptions | Promise<TeamsDevelopMessagingOptions> { - return argv - .option("projectName", { - description: "name of the Project", - required: true, - type: "string" - }) - .option("platform", { - description: "identifier of the platform for which the build was created", - required: true, - type: "string", - choices: ["ios", "android"] - }) - .option("buildUrl", { - description: "link to the build process", - required: true, - type: "string" - }) - .option("buildNumber", { - description: "the number of the run build", - required: true, - type: "number" - }) - .option("wasBuildSuccessful", { - description: "status of the finished build", - required: true, - type: "boolean" - }) - .option("artifactUrl", { - description: "download link for the generated artifact (logs or build)", - required: true, - type: "string" - }) - .option("webhook", { - description: "the webhook of the teams channel, that should receive the message", - required: true, - type: "string" - }).argv + public parseCLIOptions(argv: yargs.Argv<{}>): { platform: string } | Promise<{ platform: string }> { + return argv.option("platform", { + description: "identifier of the platform for which the build was created", + required: true, + type: "string", + choices: ["ios", "android"] + }).argv } private isUrlValid(url: string): boolean { diff --git a/src/index.ts b/src/index.ts index 51041e8..274f904 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,19 @@ #!/usr/bin/env node +import fs from "fs" import yargs from "yargs" +import { CmArtifactLink } from "./CmArtifactLink" import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging" import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging" async function run() { + const isSuccess = fs.existsSync("~/SUCCESS") + + const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!) + + console.log("isSuccess: ", isSuccess) + console.log("CM_ARTIFACT_LINKS: ", cmArtifactLinks) + await yargs(process.argv.slice(2)) .command( "teams-develop", @@ -12,7 +21,11 @@ async function run() { async (args) => { const teamsMessagingCommand = new TeamsDevelopMessaging() const options = await teamsMessagingCommand.parseCLIOptions(args) - await teamsMessagingCommand.run(options) + await teamsMessagingCommand.run({ + ...options, + wasBuildSuccessful: isSuccess, + cmArtifactLinks + }) return options } ) From fa0b3161fd63f81ee3d41a4de190eae0da593a17 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 20 Dec 2023 15:41:45 +0100 Subject: [PATCH 19/29] chore: add test artifact-links --- test/artifactLinks.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test/artifactLinks.json diff --git a/test/artifactLinks.json b/test/artifactLinks.json new file mode 100644 index 0000000..dd5dbe2 --- /dev/null +++ b/test/artifactLinks.json @@ -0,0 +1,16 @@ +[ + { + "name": "Codemagic_Release.ipa", + "type": "ipa", + "url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/Codemagic_Release.ipa", + "md5": "d2884be6985dad3ffc4d6f85b3a3642a", + "versionName": "1.0.2", + "bundleId": "io.codemagic.app" + }, + { + "name": "logs.txt", + "type": "txt", + "url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/logs.txt", + "md5": "d2884be6985dad3ffc4d6f85b3a3642a" + } +] From 55fb0d360a26bb8285215fee4e21fa9a10ad5b23 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 20 Dec 2023 15:43:30 +0100 Subject: [PATCH 20/29] feature: adapt command to use environment variables --- src/commands/TeamsCommandLineOptions.ts | 4 + src/commands/TeamsDevelopMessaging.ts | 60 ++++++++++----- src/commands/TeamsProductionMessaging.ts | 38 +++++----- src/index.ts | 96 ++++++++++++++++++++---- 4 files changed, 145 insertions(+), 53 deletions(-) create mode 100644 src/commands/TeamsCommandLineOptions.ts diff --git a/src/commands/TeamsCommandLineOptions.ts b/src/commands/TeamsCommandLineOptions.ts new file mode 100644 index 0000000..0b036c1 --- /dev/null +++ b/src/commands/TeamsCommandLineOptions.ts @@ -0,0 +1,4 @@ +export interface TeamsCommandLineOptions { + platform: string + projectName: string +} diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index d1d7d20..6a3874e 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -1,14 +1,14 @@ import axios from "axios" -import yargs from "yargs" +import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" export interface TeamsDevelopMessagingOptions { projectName: string - platform: string + webhook: string + artifactUrl: string buildUrl: string + buildWasSuccessful: boolean + platform: string buildNumber: number - wasBuildSuccessful: boolean - artifactUrl: string - webhook: string } export class TeamsDevelopMessaging { @@ -28,19 +28,21 @@ export class TeamsDevelopMessaging { process.exit(1) } - const statusIdentifier = options.wasBuildSuccessful ? "Successful" : "Failed" + const statusIdentifier = options.buildWasSuccessful ? "Successful" : "Failed" const platformIdentifier = options.platform.toUpperCase() const messageContents = { - title: `New successful ${options.platform} debug build for the "${options.projectName}" App`, + title: `New ${statusIdentifier.toLowerCase()} ${options.platform} debug build for the "${ + options.projectName + }" App`, summary: `${options.projectName}: ${statusIdentifier} build - ${platformIdentifier}`, - text: options.wasBuildSuccessful - ? `Build ${options.buildNumber}: The latest version did build and is now available as an artifact.` - : `Build ${options.buildNumber}: A problem occurred while building the newly released version. The corresponding logs are available.`, + text: options.buildWasSuccessful + ? `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> The latest version build successfully and is now available as an artifact.` + : `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> A problem occurred while building the newly released version. The corresponding logs are available.`, potentialAction: [ { "@type": "OpenUri", - name: options.wasBuildSuccessful ? `Download ${options.platform}-App` : "Open Logs", + name: options.buildWasSuccessful ? `Download ${options.platform}-App` : "Download Flutter Logs", targets: [{ os: "default", uri: options.artifactUrl }] }, { @@ -57,15 +59,6 @@ export class TeamsDevelopMessaging { }) } - public parseCLIOptions(argv: yargs.Argv<{}>): { platform: string } | Promise<{ platform: string }> { - return argv.option("platform", { - description: "identifier of the platform for which the build was created", - required: true, - type: "string", - choices: ["ios", "android"] - }).argv - } - private isUrlValid(url: string): boolean { try { // eslint-disable-next-line no-new @@ -75,4 +68,31 @@ export class TeamsDevelopMessaging { return false } } + + public extractArguments( + webhook: string, + buildWasSuccessful: boolean, + buildNumber: number, + projectId: string, + buildId: string, + commandLineOptions: TeamsCommandLineOptions, + cmArtifactLink?: string + ): TeamsDevelopMessagingOptions { + if (cmArtifactLink === undefined && buildWasSuccessful) { + console.log("variable CM_ARTIFACT_LINKS must be present in the system, if the build was successful") + process.exit(1) + } + + const teamsDevelopMessagingOptions: TeamsDevelopMessagingOptions = { + projectName: commandLineOptions.projectName, + webhook: webhook, + artifactUrl: buildWasSuccessful ? cmArtifactLink! : `https://codemagic.io/app/${projectId}/build/${buildId}`, + buildUrl: `https://codemagic.io/app/${projectId}/build/${buildId}`, + buildWasSuccessful, + platform: commandLineOptions.platform, + buildNumber: buildNumber + } + + return teamsDevelopMessagingOptions + } } diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index b93e27d..6a4139a 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -1,5 +1,6 @@ import axios from "axios" import yargs from "yargs" +import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" export interface TeamsProductionMessagingOptions { projectName: string @@ -43,9 +44,7 @@ export class TeamsProductionMessaging { }) } - public parseCLIOptions( - argv: yargs.Argv<{}> - ): TeamsProductionMessagingOptions | Promise<TeamsProductionMessagingOptions> { + public parseCLIOptions(argv: yargs.Argv<{}>): TeamsCommandLineOptions | Promise<TeamsCommandLineOptions> { return argv .option("projectName", { description: "Name of the project", @@ -57,21 +56,6 @@ export class TeamsProductionMessaging { required: true, type: "string", choices: ["ios", "android"] - }) - .option("buildUrl", { - description: "a link to the build page", - required: true, - type: "string" - }) - .option("buildNumber", { - description: "the number of the run build", - required: true, - type: "number" - }) - .option("webhook", { - description: "the webhook of the teams channel, that should receive the message", - required: true, - type: "string" }).argv } @@ -84,4 +68,22 @@ export class TeamsProductionMessaging { return false } } + + public extractArguments( + webhook: string, + buildNumber: number, + projectId: string, + buildId: string, + commandLineOptions: TeamsCommandLineOptions + ): TeamsProductionMessagingOptions { + const teamsDevelopMessagingOptions: TeamsProductionMessagingOptions = { + projectName: commandLineOptions.projectName, + platform: commandLineOptions.platform, + buildUrl: `https://codemagic.io/app/${projectId}/build/${buildId}`, + buildNumber: buildNumber, + webhook: webhook + } + + return teamsDevelopMessagingOptions + } } diff --git a/src/index.ts b/src/index.ts index 274f904..22cf246 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,38 +5,78 @@ import yargs from "yargs" import { CmArtifactLink } from "./CmArtifactLink" import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging" import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging" +import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions" async function run() { - const isSuccess = fs.existsSync("~/SUCCESS") + const buildWasSuccessful = fs.existsSync("~/SUCCESS") - const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!) + const webhook = process.env.teams_webhook_url! + const buildId = process.env.CM_BUILD_ID! + const projectId = process.env.CM_PROJECT_ID! + const buildNumber = process.env.BUILD_NUMBER! - console.log("isSuccess: ", isSuccess) - console.log("CM_ARTIFACT_LINKS: ", cmArtifactLinks) + let cmArtifactLink: string + try { + const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( + (element: any) => element.type === "apk" || element.type === "ipa" + ) + let artifactLink: string + if (cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa").length !== 0) { + artifactLink = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url + } else { + // should link to the workflow-log can be determined from buildId and projectId + artifactLink = `https://codemagic.io/app/${projectId}/build/${buildId}` + } + cmArtifactLink = artifactLink + } catch (error) { + console.log(error) + console.log("To ensure correct execution the environment variable CM_ARTIFACT_LINKS must be present in the system") + process.exit(1) + } await yargs(process.argv.slice(2)) .command( "teams-develop", "After Codemagic Build: Send MS-Teams message informing about the new build", - async (args) => { + async () => { const teamsMessagingCommand = new TeamsDevelopMessaging() - const options = await teamsMessagingCommand.parseCLIOptions(args) - await teamsMessagingCommand.run({ - ...options, - wasBuildSuccessful: isSuccess, - cmArtifactLinks - }) - return options + const unresolvedOptions = parseCLIOptionsTeams(yargs) + const resolvedOptions: { platform: string; projectName: string } = + unresolvedOptions instanceof Promise ? await unresolvedOptions : unresolvedOptions + checkArtifactLinkMatchesPlatform(resolvedOptions, cmArtifactLink) + + const parameters = teamsMessagingCommand.extractArguments( + webhook, + buildWasSuccessful, + Number(buildNumber), + projectId, + buildId, + resolvedOptions, + cmArtifactLink + ) + await teamsMessagingCommand.run(parameters) + return } ) .command( "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", - async (args) => { + async () => { const teamsMessagePublish = new TeamsProductionMessaging() - const options = await teamsMessagePublish.parseCLIOptions(args) + const unresolvedOptions = parseCLIOptionsTeams(yargs) + const resolvedOptions: { platform: string; projectName: string } = + unresolvedOptions instanceof Promise ? await unresolvedOptions : unresolvedOptions + checkArtifactLinkMatchesPlatform(resolvedOptions, cmArtifactLink) + + const options = teamsMessagePublish.extractArguments( + webhook, + Number(buildNumber), + projectId, + buildId, + resolvedOptions + ) await teamsMessagePublish.run(options) - return options + return resolvedOptions } ) .demand(1, "Must provide a valid command from the ones listed above.") @@ -44,6 +84,32 @@ async function run() { .parseAsync() } +function parseCLIOptionsTeams(argv: yargs.Argv<{}>): TeamsCommandLineOptions | Promise<TeamsCommandLineOptions> { + return argv + .option("platform", { + description: "identifier of the platform for which the build was created", + required: true, + type: "string", + choices: ["ios", "android"] + }) + .option("projectName", { + description: "objectIdentifier", + required: true, + type: "string" + }).argv +} + +function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { + // throw exception if the artifact link does not have the correct type for the given platform + if ( + (resolvedOptions.platform === "ios" && cmArtifactLink.includes("ipa")!) || + (resolvedOptions.platform === "android" && cmArtifactLink.includes("apk")!) + ) { + console.log("The artifact link does not have the correct type for the given platform") + process.exit(1) + } +} + run() .then(() => process.exit(0)) .catch((error) => { From 1ea68671ee6dd7a706543e72aa312602255aaceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Thu, 21 Dec 2023 08:26:39 +0100 Subject: [PATCH 21/29] chore: move isUrlValid to utility --- src/commands/TeamsDevelopMessaging.ts | 17 ++++------------- src/commands/TeamsProductionMessaging.ts | 15 +++------------ src/commands/isUrlValid.ts | 9 +++++++++ 3 files changed, 16 insertions(+), 25 deletions(-) create mode 100644 src/commands/isUrlValid.ts diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index 6a3874e..efff837 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -1,5 +1,6 @@ import axios from "axios" import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" +import { isUrlValid } from "./isUrlValid" export interface TeamsDevelopMessagingOptions { projectName: string @@ -13,17 +14,17 @@ export interface TeamsDevelopMessagingOptions { export class TeamsDevelopMessaging { public async run(options: TeamsDevelopMessagingOptions): Promise<void> { - if (!this.isUrlValid(options.webhook)) { + if (!isUrlValid(options.webhook)) { console.error("The given webhook is not valid.") process.exit(1) } - if (!this.isUrlValid(options.artifactUrl)) { + if (!isUrlValid(options.artifactUrl)) { console.error("The given artifactUrl is not valid.") process.exit(1) } - if (!this.isUrlValid(options.buildUrl)) { + if (!isUrlValid(options.buildUrl)) { console.error("The given buildUrl is not valid.") process.exit(1) } @@ -59,16 +60,6 @@ export class TeamsDevelopMessaging { }) } - private isUrlValid(url: string): boolean { - try { - // eslint-disable-next-line no-new - new URL(url) - return true - } catch (err) { - return false - } - } - public extractArguments( webhook: string, buildWasSuccessful: boolean, diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index 6a4139a..03cd6fe 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -1,6 +1,7 @@ import axios from "axios" import yargs from "yargs" import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" +import { isUrlValid } from "./isUrlValid" export interface TeamsProductionMessagingOptions { projectName: string @@ -12,12 +13,12 @@ export interface TeamsProductionMessagingOptions { export class TeamsProductionMessaging { public async run(options: TeamsProductionMessagingOptions): Promise<void> { - if (!this.isUrlValid(options.webhook)) { + if (!isUrlValid(options.webhook)) { console.error("The given webhook is not valid.") process.exit(1) } - if (!this.isUrlValid(options.buildUrl)) { + if (!isUrlValid(options.buildUrl)) { console.error("The given buildUrl is not valid.") process.exit(1) } @@ -59,16 +60,6 @@ export class TeamsProductionMessaging { }).argv } - private isUrlValid(url: string): boolean { - try { - // eslint-disable-next-line no-new - new URL(url) - return true - } catch (err) { - return false - } - } - public extractArguments( webhook: string, buildNumber: number, diff --git a/src/commands/isUrlValid.ts b/src/commands/isUrlValid.ts new file mode 100644 index 0000000..fbc4ec5 --- /dev/null +++ b/src/commands/isUrlValid.ts @@ -0,0 +1,9 @@ +export function isUrlValid(url: string): boolean { + try { + // eslint-disable-next-line no-new + new URL(url) + return true + } catch (err) { + return false + } +} From cf3fe4b55333ce431d9648862126c5e0279ca59f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Thu, 21 Dec 2023 08:43:27 +0100 Subject: [PATCH 22/29] chore: simplify everything --- src/commands/TeamsDevelopMessaging.ts | 28 ------ src/commands/TeamsProductionMessaging.ts | 35 -------- src/index.ts | 110 ++++++++++------------- 3 files changed, 49 insertions(+), 124 deletions(-) diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index efff837..e3f9d74 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -1,5 +1,4 @@ import axios from "axios" -import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" import { isUrlValid } from "./isUrlValid" export interface TeamsDevelopMessagingOptions { @@ -59,31 +58,4 @@ export class TeamsDevelopMessaging { process.exit(1) }) } - - public extractArguments( - webhook: string, - buildWasSuccessful: boolean, - buildNumber: number, - projectId: string, - buildId: string, - commandLineOptions: TeamsCommandLineOptions, - cmArtifactLink?: string - ): TeamsDevelopMessagingOptions { - if (cmArtifactLink === undefined && buildWasSuccessful) { - console.log("variable CM_ARTIFACT_LINKS must be present in the system, if the build was successful") - process.exit(1) - } - - const teamsDevelopMessagingOptions: TeamsDevelopMessagingOptions = { - projectName: commandLineOptions.projectName, - webhook: webhook, - artifactUrl: buildWasSuccessful ? cmArtifactLink! : `https://codemagic.io/app/${projectId}/build/${buildId}`, - buildUrl: `https://codemagic.io/app/${projectId}/build/${buildId}`, - buildWasSuccessful, - platform: commandLineOptions.platform, - buildNumber: buildNumber - } - - return teamsDevelopMessagingOptions - } } diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index 03cd6fe..31eee89 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -1,6 +1,4 @@ import axios from "axios" -import yargs from "yargs" -import { TeamsCommandLineOptions } from "./TeamsCommandLineOptions" import { isUrlValid } from "./isUrlValid" export interface TeamsProductionMessagingOptions { @@ -44,37 +42,4 @@ export class TeamsProductionMessaging { process.exit(1) }) } - - public parseCLIOptions(argv: yargs.Argv<{}>): TeamsCommandLineOptions | Promise<TeamsCommandLineOptions> { - return argv - .option("projectName", { - description: "Name of the project", - required: true, - type: "string" - }) - .option("platform", { - description: "identifier of the platform for which the build was created", - required: true, - type: "string", - choices: ["ios", "android"] - }).argv - } - - public extractArguments( - webhook: string, - buildNumber: number, - projectId: string, - buildId: string, - commandLineOptions: TeamsCommandLineOptions - ): TeamsProductionMessagingOptions { - const teamsDevelopMessagingOptions: TeamsProductionMessagingOptions = { - projectName: commandLineOptions.projectName, - platform: commandLineOptions.platform, - buildUrl: `https://codemagic.io/app/${projectId}/build/${buildId}`, - buildNumber: buildNumber, - webhook: webhook - } - - return teamsDevelopMessagingOptions - } } diff --git a/src/index.ts b/src/index.ts index 22cf246..f135f49 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,9 +3,9 @@ import fs from "fs" import yargs from "yargs" import { CmArtifactLink } from "./CmArtifactLink" +import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions" import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging" import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging" -import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions" async function run() { const buildWasSuccessful = fs.existsSync("~/SUCCESS") @@ -13,92 +13,80 @@ async function run() { const webhook = process.env.teams_webhook_url! const buildId = process.env.CM_BUILD_ID! const projectId = process.env.CM_PROJECT_ID! - const buildNumber = process.env.BUILD_NUMBER! + const buildNumber = parseInt(process.env.BUILD_NUMBER!) + const buildUrl = `https://codemagic.io/app/${projectId}/build/${buildId}` - let cmArtifactLink: string - try { - const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( - (element: any) => element.type === "apk" || element.type === "ipa" + if (process.env.CM_ARTIFACT_LINKS === undefined) { + console.error( + "To ensure correct execution the environment variable CM_ARTIFACT_LINKS must be present in the system" ) - let artifactLink: string - if (cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa").length !== 0) { - artifactLink = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url - } else { - // should link to the workflow-log can be determined from buildId and projectId - artifactLink = `https://codemagic.io/app/${projectId}/build/${buildId}` - } - cmArtifactLink = artifactLink - } catch (error) { - console.log(error) - console.log("To ensure correct execution the environment variable CM_ARTIFACT_LINKS must be present in the system") process.exit(1) } + let artifactUrl: string + + const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( + (element: any) => element.type === "apk" || element.type === "ipa" + ) + if (cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa").length !== 0) { + artifactUrl = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url + } else { + // should link to the workflow-log can be determined from buildId and projectId + artifactUrl = buildUrl + } + await yargs(process.argv.slice(2)) + .option("platform", { + description: "identifier of the platform for which the build was created", + required: true, + type: "string", + choices: ["ios", "android"] + }) + .option("projectName", { + description: "Name of the project", + required: true, + type: "string" + }) .command( "teams-develop", "After Codemagic Build: Send MS-Teams message informing about the new build", - async () => { + undefined, + async (args) => { const teamsMessagingCommand = new TeamsDevelopMessaging() - const unresolvedOptions = parseCLIOptionsTeams(yargs) - const resolvedOptions: { platform: string; projectName: string } = - unresolvedOptions instanceof Promise ? await unresolvedOptions : unresolvedOptions - checkArtifactLinkMatchesPlatform(resolvedOptions, cmArtifactLink) + checkArtifactLinkMatchesPlatform(args, artifactUrl) - const parameters = teamsMessagingCommand.extractArguments( + await teamsMessagingCommand.run({ + projectName: args.projectName, webhook, + artifactUrl, + buildUrl, buildWasSuccessful, - Number(buildNumber), - projectId, - buildId, - resolvedOptions, - cmArtifactLink - ) - await teamsMessagingCommand.run(parameters) - return + platform: args.platform, + buildNumber + }) } ) .command( "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", - async () => { + undefined, + async (args) => { const teamsMessagePublish = new TeamsProductionMessaging() - const unresolvedOptions = parseCLIOptionsTeams(yargs) - const resolvedOptions: { platform: string; projectName: string } = - unresolvedOptions instanceof Promise ? await unresolvedOptions : unresolvedOptions - checkArtifactLinkMatchesPlatform(resolvedOptions, cmArtifactLink) - const options = teamsMessagePublish.extractArguments( - webhook, - Number(buildNumber), - projectId, - buildId, - resolvedOptions - ) - await teamsMessagePublish.run(options) - return resolvedOptions + await teamsMessagePublish.run({ + projectName: args.projectName, + platform: args.platform, + buildUrl, + buildNumber, + webhook + }) } ) - .demand(1, "Must provide a valid command from the ones listed above.") + .demandCommand(1, "Must provide a valid command from the ones listed above.") .scriptName("jscm") .parseAsync() } -function parseCLIOptionsTeams(argv: yargs.Argv<{}>): TeamsCommandLineOptions | Promise<TeamsCommandLineOptions> { - return argv - .option("platform", { - description: "identifier of the platform for which the build was created", - required: true, - type: "string", - choices: ["ios", "android"] - }) - .option("projectName", { - description: "objectIdentifier", - required: true, - type: "string" - }).argv -} - function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { // throw exception if the artifact link does not have the correct type for the given platform if ( From 745c878db5694f7fe4f3ac22821392b7dbd5cee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Thu, 21 Dec 2023 09:06:01 +0100 Subject: [PATCH 23/29] refactor: use semis --- .prettierrc | 2 +- src/CmArtifactLink.ts | 12 ++--- src/commands/TeamsCommandLineOptions.ts | 4 +- src/commands/TeamsDevelopMessaging.ts | 42 ++++++++--------- src/commands/TeamsProductionMessaging.ts | 34 +++++++------- src/commands/isUrlValid.ts | 6 +-- src/index.ts | 58 ++++++++++++------------ 7 files changed, 79 insertions(+), 79 deletions(-) diff --git a/.prettierrc b/.prettierrc index 3693121..1f1a17a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,5 @@ "printWidth": 120, "tabWidth": 2, "trailingComma": "none", - "semi": false + "semi": true } diff --git a/src/CmArtifactLink.ts b/src/CmArtifactLink.ts index 761f633..2c3bcd2 100644 --- a/src/CmArtifactLink.ts +++ b/src/CmArtifactLink.ts @@ -1,8 +1,8 @@ export interface CmArtifactLink { - name: string - type: string - url: string - md5: string - versionName: string - bundleId: string + name: string; + type: string; + url: string; + md5: string; + versionName: string; + bundleId: string; } diff --git a/src/commands/TeamsCommandLineOptions.ts b/src/commands/TeamsCommandLineOptions.ts index 0b036c1..54a6663 100644 --- a/src/commands/TeamsCommandLineOptions.ts +++ b/src/commands/TeamsCommandLineOptions.ts @@ -1,4 +1,4 @@ export interface TeamsCommandLineOptions { - platform: string - projectName: string + platform: string; + projectName: string; } diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index e3f9d74..3525974 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -1,35 +1,35 @@ -import axios from "axios" -import { isUrlValid } from "./isUrlValid" +import axios from "axios"; +import { isUrlValid } from "./isUrlValid"; export interface TeamsDevelopMessagingOptions { - projectName: string - webhook: string - artifactUrl: string - buildUrl: string - buildWasSuccessful: boolean - platform: string - buildNumber: number + projectName: string; + webhook: string; + artifactUrl: string; + buildUrl: string; + buildWasSuccessful: boolean; + platform: string; + buildNumber: number; } export class TeamsDevelopMessaging { public async run(options: TeamsDevelopMessagingOptions): Promise<void> { if (!isUrlValid(options.webhook)) { - console.error("The given webhook is not valid.") - process.exit(1) + console.error("The given webhook is not valid."); + process.exit(1); } if (!isUrlValid(options.artifactUrl)) { - console.error("The given artifactUrl is not valid.") - process.exit(1) + console.error("The given artifactUrl is not valid."); + process.exit(1); } if (!isUrlValid(options.buildUrl)) { - console.error("The given buildUrl is not valid.") - process.exit(1) + console.error("The given buildUrl is not valid."); + process.exit(1); } - const statusIdentifier = options.buildWasSuccessful ? "Successful" : "Failed" - const platformIdentifier = options.platform.toUpperCase() + const statusIdentifier = options.buildWasSuccessful ? "Successful" : "Failed"; + const platformIdentifier = options.platform.toUpperCase(); const messageContents = { title: `New ${statusIdentifier.toLowerCase()} ${options.platform} debug build for the "${ @@ -51,11 +51,11 @@ export class TeamsDevelopMessaging { targets: [{ os: "default", uri: options.buildUrl }] } ] - } + }; await axios.post(options.webhook, messageContents).catch((_) => { - console.log("Could not send message to teams channel.") - process.exit(1) - }) + console.log("Could not send message to teams channel."); + process.exit(1); + }); } } diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index 31eee89..227b53e 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -1,28 +1,28 @@ -import axios from "axios" -import { isUrlValid } from "./isUrlValid" +import axios from "axios"; +import { isUrlValid } from "./isUrlValid"; export interface TeamsProductionMessagingOptions { - projectName: string - platform: string - buildUrl: string - buildNumber: number - webhook: string + projectName: string; + platform: string; + buildUrl: string; + buildNumber: number; + webhook: string; } export class TeamsProductionMessaging { public async run(options: TeamsProductionMessagingOptions): Promise<void> { if (!isUrlValid(options.webhook)) { - console.error("The given webhook is not valid.") - process.exit(1) + console.error("The given webhook is not valid."); + process.exit(1); } if (!isUrlValid(options.buildUrl)) { - console.error("The given buildUrl is not valid.") - process.exit(1) + console.error("The given buildUrl is not valid."); + process.exit(1); } - const platformIdentifier = options.platform.toUpperCase() - const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store" + const platformIdentifier = options.platform.toUpperCase(); + const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store"; const messageContents = { title: `${options.projectName}: New release is now available in the ${storeName} [${platformIdentifier}]`, summary: `New Release - ${platformIdentifier}`, @@ -35,11 +35,11 @@ export class TeamsProductionMessaging { targets: [{ os: "default", uri: options.buildUrl }] } ] - } + }; await axios.post(options.webhook, messageContents).catch((_) => { - console.log("Could not send message to teams channel.") - process.exit(1) - }) + console.log("Could not send message to teams channel."); + process.exit(1); + }); } } diff --git a/src/commands/isUrlValid.ts b/src/commands/isUrlValid.ts index fbc4ec5..adf028e 100644 --- a/src/commands/isUrlValid.ts +++ b/src/commands/isUrlValid.ts @@ -1,9 +1,9 @@ export function isUrlValid(url: string): boolean { try { // eslint-disable-next-line no-new - new URL(url) - return true + new URL(url); + return true; } catch (err) { - return false + return false; } } diff --git a/src/index.ts b/src/index.ts index f135f49..a20778e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,38 +1,38 @@ #!/usr/bin/env node -import fs from "fs" -import yargs from "yargs" -import { CmArtifactLink } from "./CmArtifactLink" -import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions" -import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging" -import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging" +import fs from "fs"; +import yargs from "yargs"; +import { CmArtifactLink } from "./CmArtifactLink"; +import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions"; +import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging"; +import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging"; async function run() { - const buildWasSuccessful = fs.existsSync("~/SUCCESS") + const buildWasSuccessful = fs.existsSync("~/SUCCESS"); - const webhook = process.env.teams_webhook_url! - const buildId = process.env.CM_BUILD_ID! - const projectId = process.env.CM_PROJECT_ID! - const buildNumber = parseInt(process.env.BUILD_NUMBER!) - const buildUrl = `https://codemagic.io/app/${projectId}/build/${buildId}` + const webhook = process.env.teams_webhook_url!; + const buildId = process.env.CM_BUILD_ID!; + const projectId = process.env.CM_PROJECT_ID!; + const buildNumber = parseInt(process.env.BUILD_NUMBER!); + const buildUrl = `https://codemagic.io/app/${projectId}/build/${buildId}`; if (process.env.CM_ARTIFACT_LINKS === undefined) { console.error( "To ensure correct execution the environment variable CM_ARTIFACT_LINKS must be present in the system" - ) - process.exit(1) + ); + process.exit(1); } - let artifactUrl: string + let artifactUrl: string; const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( (element: any) => element.type === "apk" || element.type === "ipa" - ) + ); if (cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa").length !== 0) { - artifactUrl = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url + artifactUrl = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url; } else { // should link to the workflow-log can be determined from buildId and projectId - artifactUrl = buildUrl + artifactUrl = buildUrl; } await yargs(process.argv.slice(2)) @@ -52,8 +52,8 @@ async function run() { "After Codemagic Build: Send MS-Teams message informing about the new build", undefined, async (args) => { - const teamsMessagingCommand = new TeamsDevelopMessaging() - checkArtifactLinkMatchesPlatform(args, artifactUrl) + const teamsMessagingCommand = new TeamsDevelopMessaging(); + checkArtifactLinkMatchesPlatform(args, artifactUrl); await teamsMessagingCommand.run({ projectName: args.projectName, @@ -63,7 +63,7 @@ async function run() { buildWasSuccessful, platform: args.platform, buildNumber - }) + }); } ) .command( @@ -71,7 +71,7 @@ async function run() { "After Codemagic Publish: Send MS-Teams message informing about the new release", undefined, async (args) => { - const teamsMessagePublish = new TeamsProductionMessaging() + const teamsMessagePublish = new TeamsProductionMessaging(); await teamsMessagePublish.run({ projectName: args.projectName, @@ -79,12 +79,12 @@ async function run() { buildUrl, buildNumber, webhook - }) + }); } ) .demandCommand(1, "Must provide a valid command from the ones listed above.") .scriptName("jscm") - .parseAsync() + .parseAsync(); } function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { @@ -93,14 +93,14 @@ function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptio (resolvedOptions.platform === "ios" && cmArtifactLink.includes("ipa")!) || (resolvedOptions.platform === "android" && cmArtifactLink.includes("apk")!) ) { - console.log("The artifact link does not have the correct type for the given platform") - process.exit(1) + console.log("The artifact link does not have the correct type for the given platform"); + process.exit(1); } } run() .then(() => process.exit(0)) .catch((error) => { - console.error(error) - process.exit(1) - }) + console.error(error); + process.exit(1); + }); From 96d28ac2e478aab13edf6804d0be4c28c1f0100c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Thu, 21 Dec 2023 09:16:05 +0100 Subject: [PATCH 24/29] refactor: use functions instead of classes --- src/commands/TeamsDevelopMessaging.ts | 80 +++++++++++------------- src/commands/TeamsProductionMessaging.ts | 56 ++++++++--------- src/index.ts | 16 ++--- 3 files changed, 71 insertions(+), 81 deletions(-) diff --git a/src/commands/TeamsDevelopMessaging.ts b/src/commands/TeamsDevelopMessaging.ts index 3525974..c8314eb 100644 --- a/src/commands/TeamsDevelopMessaging.ts +++ b/src/commands/TeamsDevelopMessaging.ts @@ -11,51 +11,47 @@ export interface TeamsDevelopMessagingOptions { buildNumber: number; } -export class TeamsDevelopMessaging { - public async run(options: TeamsDevelopMessagingOptions): Promise<void> { - if (!isUrlValid(options.webhook)) { - console.error("The given webhook is not valid."); - process.exit(1); - } +export async function runTeamsDevelopMessagingCommand(options: TeamsDevelopMessagingOptions): Promise<void> { + if (!isUrlValid(options.webhook)) { + console.error("The given webhook is not valid."); + process.exit(1); + } - if (!isUrlValid(options.artifactUrl)) { - console.error("The given artifactUrl is not valid."); - process.exit(1); - } + if (!isUrlValid(options.artifactUrl)) { + console.error("The given artifactUrl is not valid."); + process.exit(1); + } - if (!isUrlValid(options.buildUrl)) { - console.error("The given buildUrl is not valid."); - process.exit(1); - } + if (!isUrlValid(options.buildUrl)) { + console.error("The given buildUrl is not valid."); + process.exit(1); + } - const statusIdentifier = options.buildWasSuccessful ? "Successful" : "Failed"; - const platformIdentifier = options.platform.toUpperCase(); + const statusIdentifier = options.buildWasSuccessful ? "Successful" : "Failed"; + const platformIdentifier = options.platform.toUpperCase(); - const messageContents = { - title: `New ${statusIdentifier.toLowerCase()} ${options.platform} debug build for the "${ - options.projectName - }" App`, - summary: `${options.projectName}: ${statusIdentifier} build - ${platformIdentifier}`, - text: options.buildWasSuccessful - ? `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> The latest version build successfully and is now available as an artifact.` - : `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> A problem occurred while building the newly released version. The corresponding logs are available.`, - potentialAction: [ - { - "@type": "OpenUri", - name: options.buildWasSuccessful ? `Download ${options.platform}-App` : "Download Flutter Logs", - targets: [{ os: "default", uri: options.artifactUrl }] - }, - { - "@type": "OpenUri", - name: "Open Build", - targets: [{ os: "default", uri: options.buildUrl }] - } - ] - }; + const messageContents = { + title: `New ${statusIdentifier.toLowerCase()} ${options.platform} debug build for the "${options.projectName}" App`, + summary: `${options.projectName}: ${statusIdentifier} build - ${platformIdentifier}`, + text: options.buildWasSuccessful + ? `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> The latest version build successfully and is now available as an artifact.` + : `New Build: #${options.buildNumber} - ${platformIdentifier} <br/> A problem occurred while building the newly released version. The corresponding logs are available.`, + potentialAction: [ + { + "@type": "OpenUri", + name: options.buildWasSuccessful ? `Download ${options.platform}-App` : "Download Flutter Logs", + targets: [{ os: "default", uri: options.artifactUrl }] + }, + { + "@type": "OpenUri", + name: "Open Build", + targets: [{ os: "default", uri: options.buildUrl }] + } + ] + }; - await axios.post(options.webhook, messageContents).catch((_) => { - console.log("Could not send message to teams channel."); - process.exit(1); - }); - } + await axios.post(options.webhook, messageContents).catch((_) => { + console.log("Could not send message to teams channel."); + process.exit(1); + }); } diff --git a/src/commands/TeamsProductionMessaging.ts b/src/commands/TeamsProductionMessaging.ts index 227b53e..3ab08ad 100644 --- a/src/commands/TeamsProductionMessaging.ts +++ b/src/commands/TeamsProductionMessaging.ts @@ -9,37 +9,35 @@ export interface TeamsProductionMessagingOptions { webhook: string; } -export class TeamsProductionMessaging { - public async run(options: TeamsProductionMessagingOptions): Promise<void> { - if (!isUrlValid(options.webhook)) { - console.error("The given webhook is not valid."); - process.exit(1); - } +export async function runTeamsProductionMessagingCommand(options: TeamsProductionMessagingOptions): Promise<void> { + if (!isUrlValid(options.webhook)) { + console.error("The given webhook is not valid."); + process.exit(1); + } - if (!isUrlValid(options.buildUrl)) { - console.error("The given buildUrl is not valid."); - process.exit(1); - } + if (!isUrlValid(options.buildUrl)) { + console.error("The given buildUrl is not valid."); + process.exit(1); + } - const platformIdentifier = options.platform.toUpperCase(); - const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store"; - const messageContents = { - title: `${options.projectName}: New release is now available in the ${storeName} [${platformIdentifier}]`, - summary: `New Release - ${platformIdentifier}`, - text: `New Release: #${options.buildNumber} - ${platformIdentifier} <br/> + const platformIdentifier = options.platform.toUpperCase(); + const storeName = platformIdentifier === "IOS" ? "App Store" : "Google Play Store"; + const messageContents = { + title: `${options.projectName}: New release is now available in the ${storeName} [${platformIdentifier}]`, + summary: `New Release - ${platformIdentifier}`, + text: `New Release: #${options.buildNumber} - ${platformIdentifier} <br/> The newly released version is now available in the ${storeName}. `, - potentialAction: [ - { - "@type": "OpenUri", - name: "Open Build", - targets: [{ os: "default", uri: options.buildUrl }] - } - ] - }; + potentialAction: [ + { + "@type": "OpenUri", + name: "Open Build", + targets: [{ os: "default", uri: options.buildUrl }] + } + ] + }; - await axios.post(options.webhook, messageContents).catch((_) => { - console.log("Could not send message to teams channel."); - process.exit(1); - }); - } + await axios.post(options.webhook, messageContents).catch((_) => { + console.log("Could not send message to teams channel."); + process.exit(1); + }); } diff --git a/src/index.ts b/src/index.ts index a20778e..50dd7ce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,8 @@ import fs from "fs"; import yargs from "yargs"; import { CmArtifactLink } from "./CmArtifactLink"; import { TeamsCommandLineOptions } from "./commands/TeamsCommandLineOptions"; -import { TeamsDevelopMessaging } from "./commands/TeamsDevelopMessaging"; -import { TeamsProductionMessaging } from "./commands/TeamsProductionMessaging"; +import { runTeamsDevelopMessagingCommand } from "./commands/TeamsDevelopMessaging"; +import { runTeamsProductionMessagingCommand } from "./commands/TeamsProductionMessaging"; async function run() { const buildWasSuccessful = fs.existsSync("~/SUCCESS"); @@ -52,10 +52,9 @@ async function run() { "After Codemagic Build: Send MS-Teams message informing about the new build", undefined, async (args) => { - const teamsMessagingCommand = new TeamsDevelopMessaging(); checkArtifactLinkMatchesPlatform(args, artifactUrl); - await teamsMessagingCommand.run({ + await runTeamsDevelopMessagingCommand({ projectName: args.projectName, webhook, artifactUrl, @@ -70,17 +69,14 @@ async function run() { "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", undefined, - async (args) => { - const teamsMessagePublish = new TeamsProductionMessaging(); - - await teamsMessagePublish.run({ + async (args) => + await runTeamsProductionMessagingCommand({ projectName: args.projectName, platform: args.platform, buildUrl, buildNumber, webhook - }); - } + }) ) .demandCommand(1, "Must provide a valid command from the ones listed above.") .scriptName("jscm") From 5b32da64b7d17641781a3e5240e291594af62cb7 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 3 Jan 2024 09:22:10 +0100 Subject: [PATCH 25/29] test: add tests for teams messaging --- README.md | 36 +++++++++++++++++++++++++++++++++++- src/index.ts | 18 ++++++++++++------ test/artifactLinks.json | 10 +++++----- test/test_teams_messaging.sh | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 test/test_teams_messaging.sh diff --git a/README.md b/README.md index 462a264..8ecae55 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,42 @@ npm install @js-soft/codemagic-tools ## Usage +### Teams Messaging + +#### Build Messages +```bash +jscm teams-develop --platform <platform> --projectName <projectName> +``` +This command will inform about a new build and additionally provide a link to the build. In case of a failed build it will also provide a link to the build log. + +### Production Messages +```bash +jscm teams-publish --platform <platform> --projectName <projectName> +``` +This command will inform about a newly released version. It aditionally provides a link to the build logs. + +## Testing +For testing a JSON like created in Codemagic is provided. Additionally a bash-script, which +can be used to test the command is provided. Upon execution the +test script will ask you to specify the following variables: + +* webhook - webhook url you want to send to / or just some valid https-address +* BuildId - a string +* ProjectId - a string +* buildNumber - a number + +After preparation of your local environment the script will execute the jscm command. + +It will execute both possible command: + +* teams-develop (in failed/successful state) +* teams-production (in failed/successful state) + +→ This will result in 4 messages being sent to the specified teams channel + +### Calling the test script ```bash -jscm --help +./test/test_teams_messaging.sh ``` ## License diff --git a/src/index.ts b/src/index.ts index 50dd7ce..3bafec9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,7 +24,7 @@ async function run() { } let artifactUrl: string; - + const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( (element: any) => element.type === "apk" || element.type === "ipa" ); @@ -37,7 +37,7 @@ async function run() { await yargs(process.argv.slice(2)) .option("platform", { - description: "identifier of the platform for which the build was created", + description: "Identifier of the platform for which the build was created", required: true, type: "string", choices: ["ios", "android"] @@ -50,7 +50,10 @@ async function run() { .command( "teams-develop", "After Codemagic Build: Send MS-Teams message informing about the new build", - undefined, + // empty function to avoid yargs internal error + () => { + return + }, async (args) => { checkArtifactLinkMatchesPlatform(args, artifactUrl); @@ -68,7 +71,10 @@ async function run() { .command( "teams-production", "After Codemagic Publish: Send MS-Teams message informing about the new release", - undefined, + // empty function to avoid yargs internal error + () => { + return + }, async (args) => await runTeamsProductionMessagingCommand({ projectName: args.projectName, @@ -86,8 +92,8 @@ async function run() { function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { // throw exception if the artifact link does not have the correct type for the given platform if ( - (resolvedOptions.platform === "ios" && cmArtifactLink.includes("ipa")!) || - (resolvedOptions.platform === "android" && cmArtifactLink.includes("apk")!) + (resolvedOptions.platform === "ios" && !cmArtifactLink.includes("ipa")!) || + (resolvedOptions.platform === "android" && !cmArtifactLink.includes("apk")!) ) { console.log("The artifact link does not have the correct type for the given platform"); process.exit(1); diff --git a/test/artifactLinks.json b/test/artifactLinks.json index dd5dbe2..5925173 100644 --- a/test/artifactLinks.json +++ b/test/artifactLinks.json @@ -2,15 +2,15 @@ { "name": "Codemagic_Release.ipa", "type": "ipa", - "url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/Codemagic_Release.ipa", - "md5": "d2884be6985dad3ffc4d6f85b3a3642a", - "versionName": "1.0.2", + "url": "https://www.test.com", + "md5": "11111111111111111111111111111111", + "versionName": "1.0.0", "bundleId": "io.codemagic.app" }, { "name": "logs.txt", "type": "txt", - "url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/logs.txt", - "md5": "d2884be6985dad3ffc4d6f85b3a3642a" + "url": "https://www.test.com/logs.txt", + "md5": "00000000000000000000000000000000" } ] diff --git a/test/test_teams_messaging.sh b/test/test_teams_messaging.sh new file mode 100644 index 0000000..f17fa85 --- /dev/null +++ b/test/test_teams_messaging.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +#this surely is not the best way to do it, one should use a .enc file which is loaded +echo "Enter a teams_webhook_url: " +read teams_webhook_url_value +export teams_webhook_url=$teams_webhook_url_value + +echo "Enter the CM_BUILD_ID : " +read CM_BUILD_ID_VALUE +export CM_BUILD_ID=$CM_BUILD_ID_VALUE + +echo "Enter the CM_PROJECT_ID : " +read CM_PROJECT_ID_VALUE +export CM_PROJECT_ID=$CM_PROJECT_ID_VALUE + +echo "Enter the BUILD_NUMBER :" +read BUILD_NUMBER_VALUE +export BUILD_NUMBER=$BUILD_NUMBER_VALUE + + +#create a variable and store a json in it +export CM_ARTIFACT_LINKS=$(cat <<EOF +[{"name": "Codemagic_Release.ipa","type": "ipa","url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/Codemagic_Release.ipa","md5": "d2884be6985dad3ffc4d6f85b3a3642a","versionName": "1.0.2","bundleId": "io.codemagic.app"},{"name": "logs.txt","type": "txt","url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/logs.txt","md5": "d2884be6985dad3ffc4d6f85b3a3642a"}] +EOF +) + +echo "webhook url: $teams_webhook_url" + +echo "Starting teams messaging tests" +jscm teams-develop --platform "ios" --projectName "Mein Codemagic Test Projekt" +jscm teams-production --platform "ios" --projectName "Mein Codemagic Test Projekt" +touch ~/SUCCESS +jscm teams-develop --platform "ios" --projectName "Mein Codemagic Test Projekt" +jscm teams-production --platform "ios" --projectName "Mein Codemagic Test Projekt" +rm -f ~/SUCCESS +echo "Finished teams messaging tests" \ No newline at end of file From 24e3b391c034364040b49777d350d9ccd18e0932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Wed, 3 Jan 2024 09:29:34 +0100 Subject: [PATCH 26/29] chore: formatting --- src/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3bafec9..be243e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,7 +24,7 @@ async function run() { } let artifactUrl: string; - + const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( (element: any) => element.type === "apk" || element.type === "ipa" ); @@ -52,7 +52,7 @@ async function run() { "After Codemagic Build: Send MS-Teams message informing about the new build", // empty function to avoid yargs internal error () => { - return + return; }, async (args) => { checkArtifactLinkMatchesPlatform(args, artifactUrl); @@ -73,8 +73,8 @@ async function run() { "After Codemagic Publish: Send MS-Teams message informing about the new release", // empty function to avoid yargs internal error () => { - return - }, + return; + }, async (args) => await runTeamsProductionMessagingCommand({ projectName: args.projectName, @@ -92,8 +92,8 @@ async function run() { function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { // throw exception if the artifact link does not have the correct type for the given platform if ( - (resolvedOptions.platform === "ios" && !cmArtifactLink.includes("ipa")!) || - (resolvedOptions.platform === "android" && !cmArtifactLink.includes("apk")!) + (resolvedOptions.platform === "ios" && !cmArtifactLink.includes("ipa")) || + (resolvedOptions.platform === "android" && !cmArtifactLink.includes("apk")) ) { console.log("The artifact link does not have the correct type for the given platform"); process.exit(1); From b5d190d394cbe2d508685100ffb3c509953ab6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20K=C3=B6nig?= <julian.koenig@js-soft.com> Date: Wed, 3 Jan 2024 09:48:46 +0100 Subject: [PATCH 27/29] chore: formatting --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8ecae55..59af89d 100644 --- a/README.md +++ b/README.md @@ -16,37 +16,43 @@ npm install @js-soft/codemagic-tools ### Teams Messaging #### Build Messages + ```bash jscm teams-develop --platform <platform> --projectName <projectName> ``` + This command will inform about a new build and additionally provide a link to the build. In case of a failed build it will also provide a link to the build log. ### Production Messages + ```bash jscm teams-publish --platform <platform> --projectName <projectName> ``` + This command will inform about a newly released version. It aditionally provides a link to the build logs. ## Testing + For testing a JSON like created in Codemagic is provided. Additionally a bash-script, which can be used to test the command is provided. Upon execution the test script will ask you to specify the following variables: -* webhook - webhook url you want to send to / or just some valid https-address -* BuildId - a string -* ProjectId - a string -* buildNumber - a number +- webhook - webhook url you want to send to / or just some valid https-address +- BuildId - a string +- ProjectId - a string +- buildNumber - a number After preparation of your local environment the script will execute the jscm command. It will execute both possible command: -* teams-develop (in failed/successful state) -* teams-production (in failed/successful state) +- teams-develop (in failed/successful state) +- teams-production (in failed/successful state) → This will result in 4 messages being sent to the specified teams channel ### Calling the test script + ```bash ./test/test_teams_messaging.sh ``` From 552d9c7efd3acef56373d0e264e461b53dc26d4b Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 3 Jan 2024 11:09:58 +0100 Subject: [PATCH 28/29] refactor: use correct artifact links file in testing --- README.md | 6 +++--- test/test_teams_messaging.sh | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 59af89d..14157ba 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ npm install @js-soft/codemagic-tools ### Teams Messaging -#### Build Messages +#### Develop Messages ```bash jscm teams-develop --platform <platform> --projectName <projectName> ``` -This command will inform about a new build and additionally provide a link to the build. In case of a failed build it will also provide a link to the build log. +This command will inform about a new development build and additionally provide a link to the build. In case of a failed build it will also provide a link to the build log. ### Production Messages @@ -29,7 +29,7 @@ This command will inform about a new build and additionally provide a link to th jscm teams-publish --platform <platform> --projectName <projectName> ``` -This command will inform about a newly released version. It aditionally provides a link to the build logs. +This command will inform about an app version, that was released in a store. It additionally provides a link to the build logs. ## Testing diff --git a/test/test_teams_messaging.sh b/test/test_teams_messaging.sh index f17fa85..bb914b6 100644 --- a/test/test_teams_messaging.sh +++ b/test/test_teams_messaging.sh @@ -17,12 +17,7 @@ echo "Enter the BUILD_NUMBER :" read BUILD_NUMBER_VALUE export BUILD_NUMBER=$BUILD_NUMBER_VALUE - -#create a variable and store a json in it -export CM_ARTIFACT_LINKS=$(cat <<EOF -[{"name": "Codemagic_Release.ipa","type": "ipa","url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/Codemagic_Release.ipa","md5": "d2884be6985dad3ffc4d6f85b3a3642a","versionName": "1.0.2","bundleId": "io.codemagic.app"},{"name": "logs.txt","type": "txt","url": "https://api.codemagic.io/artifacts/2e7564b2-9ffa-40c2-b9e0-8980436ac717/81c5a723-b162-488a-854e-3f5f7fdfb22f/logs.txt","md5": "d2884be6985dad3ffc4d6f85b3a3642a"}] -EOF -) +export CM_ARTIFACT_LINKS=$(cat artifactLinks.json) echo "webhook url: $teams_webhook_url" From e33582c1e212bf68542c7871bb40ff34995751d6 Mon Sep 17 00:00:00 2001 From: Jakob Erben <jakob.erben@js-soft.com> Date: Wed, 3 Jan 2024 11:28:05 +0100 Subject: [PATCH 29/29] feature: improve artifact type check --- src/index.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index be243e8..2db3939 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,15 +24,19 @@ async function run() { } let artifactUrl: string; + let artifactType: string; const cmArtifactLinks: CmArtifactLink[] = JSON.parse(process.env.CM_ARTIFACT_LINKS!).filter( (element: any) => element.type === "apk" || element.type === "ipa" ); if (cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa").length !== 0) { - artifactUrl = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0].url; + const pickedElement = cmArtifactLinks.filter((element: any) => element.type === "apk" || element.type === "ipa")[0]; + artifactUrl = pickedElement.url; + artifactType = pickedElement.type; } else { // should link to the workflow-log can be determined from buildId and projectId artifactUrl = buildUrl; + artifactType = "logs"; } await yargs(process.argv.slice(2)) @@ -55,7 +59,7 @@ async function run() { return; }, async (args) => { - checkArtifactLinkMatchesPlatform(args, artifactUrl); + checkArtifactLinkMatchesPlatform(args, artifactType); await runTeamsDevelopMessagingCommand({ projectName: args.projectName, @@ -89,11 +93,15 @@ async function run() { .parseAsync(); } -function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, cmArtifactLink: string) { +function checkArtifactLinkMatchesPlatform(resolvedOptions: TeamsCommandLineOptions, artifactType: string) { // throw exception if the artifact link does not have the correct type for the given platform + if (artifactType === "logs") { + return; + } + if ( - (resolvedOptions.platform === "ios" && !cmArtifactLink.includes("ipa")) || - (resolvedOptions.platform === "android" && !cmArtifactLink.includes("apk")) + (resolvedOptions.platform === "ios" && artifactType === "apk") || + (resolvedOptions.platform === "android" && artifactType === "ipa") ) { console.log("The artifact link does not have the correct type for the given platform"); process.exit(1);