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)
+
+&rarr; 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)
 
 &rarr; 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);