Skip to content

Conversation

@panwaranuj01
Copy link
Contributor

@panwaranuj01 panwaranuj01 commented Sep 18, 2025

What do you want to achieve?

  • Fix the multiple socket connection issue when opening the widget immediately
  • Added the test cases to test the socket connection issues

PR Checklist

  • I have tested it locally and all functionalities are working fine.
  • I have compared it with mocks and all design elements are the same.
  • I have tested it in IE Browser.

How was the code tested?

What new thing you came across while writing this code?

In case you fixed a bug then please describe the root cause of it?

Screenshot

NOTE: Make sure you're comparing your branch with the correct base branch

Summary by CodeRabbit

  • Bug Fixes

    • Safer socket lifecycle: prevents overlapping inits, adds explicit initialized state, improves disconnect handling, and reduces reconnect/race failures.
  • Tests

    • New end-to-end Playwright tests validating widget socket lifecycle: single-connection behavior, reconnect handling after manual disconnect, and proper cleanup.
  • Chores

    • Updated bundled chat library to a newer compatible version.

@github-actions
Copy link

github-actions bot commented Sep 18, 2025

Warnings
⚠️ Please add the JIRA issue key to the PR title (e.g. FW-123)
Messages
📖

New Files in this PR:

  • playwright_test/tests/socketConnection.spec.js , webplugin/js/app/applozic.chat-6.3.0.min.js

Generated by 🚫 dangerJS against e431dee

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Walkthrough

Adds explicit socket lifecycle state and race guards in mck-sidebox-1.0.js (new IS_SOCKET_INITIALIZED, disconnect handling, in-flight guards, MCK_BOT_MESSAGE_QUEUE, reconnect on inactive socket). Adds Playwright tests validating widget WebSocket lifecycle and updates build/config to use Applozic v6.3.0 scripts.

Changes

Cohort / File(s) Summary
Socket lifecycle & guards
webplugin/js/app/mck-sidebox-1.0.js
Adds var IS_SOCKET_INITIALIZED, MCK_BOT_MESSAGE_QUEUE, updates socket event handlers (new onDisconnect sets IS_SOCKET_CONNECTED=false and IS_SOCKET_INITIALIZED=false), starts SOCKET_DISCONNECT_PROCEDURE under widget-click connect conditions, and adds guards that call connectToSocket(true) when socket-reliant ops detect inactive socket to avoid races.
Playwright socket lifecycle tests
playwright_test/tests/socketConnection.spec.js
New Playwright test suite and helpers to track/filter WebSocket events for the widget iframe, poll IS_SOCKET_CONNECTED, assert single socket creation on launcher click, validate manual disconnect and reconnection behavior, and provide utilities for frame/UI interaction and socket record tracking.
Applozic script version bumps / build
webplugin/development.js, webplugin/gulpfile.js, webplugin/js/app/mck-app.js
Updated build/copy targets and external script URLs from Applozic v6.2.x/6.2.9 to v6.3.0 (applozic.chat-6.3.0.min.js) — build artifact/config change only.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant W as Widget (mck-sidebox)
  participant S as ALSocket
  Note over W: IS_SOCKET_INITIALIZED=false\nIS_SOCKET_CONNECTED=false\nMCK_BOT_MESSAGE_QUEUE=[]
  U->>W: launcher click / initializeSocketConnection(reInit?)
  alt Already initialized and not reInit
    W-->>U: no-op
  else Start init
    W->>W: IS_SOCKET_INITIALIZED = true
    rect rgba(200,230,255,0.18)
      W->>S: connect()
      alt connect success
        S-->>W: onConnect
        W->>W: IS_SOCKET_CONNECTED = true\nIS_SOCKET_INITIALIZED = false
      else connect failure
        S-->>W: onConnectFailed
        W->>W: IS_SOCKET_CONNECTED = false\nIS_SOCKET_INITIALIZED = false
      end
    end
  end
Loading
sequenceDiagram
  autonumber
  participant UI as User UI
  participant W as Widget
  participant S as ALSocket
  Note over W: CONNECT_SOCKET_ON_WIDGET_CLICK may trigger\nSOCKET_DISCONNECT_PROCEDURE when closing
  UI->>W: user closes widget
  W->>W: start SOCKET_DISCONNECT_PROCEDURE
  W->>S: disconnect()
  S-->>W: onDisconnect
  W->>W: IS_SOCKET_CONNECTED = false\nIS_SOCKET_INITIALIZED = false
  Note right of W: Later operations check\nif !S.isSocketActive() -> connectToSocket(true)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • devashishmamgain
  • kandpal025

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description follows the repository template and includes the main objective and checklist entries but leaves key sections such as detailed testing steps, root cause analysis, and implementation insights blank. Please provide detailed steps on how the changes were tested, describe the root cause of the issue that was fixed, and share any new findings encountered during development to complete the pull request template.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly describes the primary change to address multiple socket connection issues when opening the widget immediately and aligns with the core modifications made in the pull request.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch multi-socket-issue

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6a066a and e431dee.

📒 Files selected for processing (1)
  • playwright_test/tests/socketConnection.spec.js (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
webplugin/js/app/mck-sidebox-1.0.js (3)

621-626: Keep state consistent even if disconnect throws

Wrap ALSocket.disconnect() in try/finally so flags are always reset.

-                                window.Applozic.ALSocket.disconnect();
-                                window.Applozic.SOCKET_DISCONNECT_PROCEDURE.DISCONNECTED = true;
-                                IS_SOCKET_INITIALIZING = false;
-                                IS_SOCKET_CONNECTED = false;
-                                console.debug('disconnected');
+                                try {
+                                    window.Applozic.ALSocket.disconnect();
+                                    window.Applozic.SOCKET_DISCONNECT_PROCEDURE.DISCONNECTED = true;
+                                } catch (e) {
+                                    console.error('[KM] ALSocket.disconnect() threw:', e);
+                                } finally {
+                                    IS_SOCKET_INITIALIZING = false;
+                                    IS_SOCKET_CONNECTED = false;
+                                    console.debug('disconnected');
+                                }

720-723: Reset retry counter on successful connect

Prevents stale SOCKET_RECONNECT_FAIL_COUNT from showing disconnect UI unnecessarily.

                 IS_SOCKET_INITIALIZING = false;
                 IS_SOCKET_CONNECTED = true;
-                console.debug('connected..');
+                console.debug('[KM] connected');
+                SOCKET_RECONNECT_FAIL_COUNT = 0;

1218-1220: Logout path: also clear connected flag and guard disconnect

Ensure consistent state even if disconnect throws.

-                window.Applozic.ALSocket.disconnect();
-                IS_SOCKET_INITIALIZING = false;
+                try {
+                    window.Applozic.ALSocket.disconnect();
+                } catch (e) {
+                    console.error('[KM] ALSocket.disconnect() threw during logout:', e);
+                } finally {
+                    IS_SOCKET_INITIALIZING = false;
+                    IS_SOCKET_CONNECTED = false;
+                }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4523ddd and f215f60.

📒 Files selected for processing (1)
  • webplugin/js/app/mck-sidebox-1.0.js (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-25T05:44:56.580Z
Learnt from: panwaranuj01
PR: Kommunicate-io/Kommunicate-Web-SDK#1320
File: webplugin/js/app/voice/mck-voice.js:758-758
Timestamp: 2025-06-25T05:44:56.580Z
Learning: The code in webplugin/js/app/voice/mck-voice.js runs in an isolated scope and does not pollute the global namespace of other windows or the host page. Global variables within this isolated scope are acceptable as they don't affect the embedding environment.

Applied to files:

  • webplugin/js/app/mck-sidebox-1.0.js
🔇 Additional comments (1)
webplugin/js/app/mck-sidebox-1.0.js (1)

14-14: Good: single-flight guard for socket init

The IS_SOCKET_INITIALIZING flag is the right approach to serialize init/reconnect.

@github-actions
Copy link

A friendly reminder that this PR had no activity for 15 days.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (2)
webplugin/js/app/mck-sidebox-1.0.js (2)

700-712: Unblock recovery: reset flag before returning and stop rethrowing here.

Line 701 still exits before clearing IS_SOCKET_INITIALIZING, so any caller that hits this branch will leave the flag stuck true, blocking all future init/reconnect attempts. In the same block, rethrowing the sync reconnect error (Line 711) aborts the fail-count/backoff path, undoing the main objective of the PR. This was raised earlier and remains unresolved. Please ensure the flags are cleared before return and keep the catch non-throwing so the retry flow continues.

-                    kommunicate.reloadWidget();
-                    return;
-                }
-                IS_SOCKET_INITIALIZING = false;
-                IS_SOCKET_CONNECTED = false;
+                    IS_SOCKET_INITIALIZING = false;
+                    IS_SOCKET_CONNECTED = false;
+                    kommunicate.reloadWidget();
+                    return;
+                }
+                IS_SOCKET_INITIALIZING = false;
+                IS_SOCKET_CONNECTED = false;
                 if (navigator.onLine) {
                     try {
                         IS_SOCKET_INITIALIZING = true;
                         window.Applozic.ALSocket.reconnect();
                     } catch (error) {
                         IS_SOCKET_INITIALIZING = false;
-                        throw error;
+                        console.error('[KM] Socket reconnect threw synchronously:', error);
                     }
                 }

13606-13615: Guard stompClient access and avoid rethrowing reconnect errors.

This block still dereferences window.Applozic.ALSocket.stompClient.connected without verifying the client exists, so a null client crashes with a TypeError and we never reach the retry logic. Additionally, rethrowing the sync reconnect error (Line 13615) unwinds the handler and prevents the recovery/backoff just added. Please add the null guard and keep the catch non-throwing.

-                if (!window.Applozic.ALSocket.stompClient.connected) {
+                if (
+                    !window.Applozic.ALSocket.stompClient ||
+                    !window.Applozic.ALSocket.stompClient.connected
+                ) {
                     if (IS_SOCKET_INITIALIZING) {
                         return;
                     }
                     try {
                         IS_SOCKET_INITIALIZING = true;
                         window.Applozic.ALSocket.reconnect();
                     } catch (error) {
                         IS_SOCKET_INITIALIZING = false;
-                        throw error;
+                        console.error('[KM] Socket reconnect threw synchronously:', error);
                     }
                 }
🧹 Nitpick comments (2)
playwright_test/tests/socketConnection.spec.js (2)

1-6: LGTM! Consider adding JSDoc for the URL filter.

The imports and isWidgetSocketUrl filter are well-structured and appropriate for the test suite.

Optionally, add JSDoc to document the URL patterns:

+/**
+ * Checks if a WebSocket URL is related to the Kommunicate widget.
+ * Matches URLs containing '/stomp' or 'kommunicate.io/ws' or 'kommunicate.net/ws'.
+ * @param {string} url - The WebSocket URL to check
+ * @returns {boolean} True if the URL matches widget socket patterns
+ */
 const isWidgetSocketUrl = (url) => /\/stomp/i.test(url) || /kommunicate\.(?:io|net)\/ws/i.test(url);

8-46: LGTM! Minor strictness improvement.

The createSocketTracker utility is well-designed and provides clear methods for tracking socket lifecycle. The event handling and filtering logic are correct.

Consider using strict equality for consistency:

     const waitForRecordClose = async (record) => {
-        if (record.closedAt != null) {
+        if (record.closedAt !== null) {
             return;
         }
         await new Promise((resolve) => record.ws.on('close', resolve));
     };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8eba26b and 30d5692.

📒 Files selected for processing (2)
  • playwright_test/tests/socketConnection.spec.js (1 hunks)
  • webplugin/js/app/mck-sidebox-1.0.js (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-25T05:44:56.580Z
Learnt from: panwaranuj01
PR: Kommunicate-io/Kommunicate-Web-SDK#1320
File: webplugin/js/app/voice/mck-voice.js:758-758
Timestamp: 2025-06-25T05:44:56.580Z
Learning: The code in webplugin/js/app/voice/mck-voice.js runs in an isolated scope and does not pollute the global namespace of other windows or the host page. Global variables within this isolated scope are acceptable as they don't affect the embedding environment.

Applied to files:

  • webplugin/js/app/mck-sidebox-1.0.js
🔇 Additional comments (1)
playwright_test/tests/socketConnection.spec.js (1)

70-74: Verify global variable existence and extract hardcoded iframe name.

The function assumes window.IS_SOCKET_CONNECTED exists in the iframe context. If this variable is undefined or the widget doesn't set it, the test will hang until timeout.

Extract the hardcoded iframe name to a constant:

+const WIDGET_IFRAME_NAME = 'Kommunicate widget iframe';
+
 const waitForSocketStatus = async (page, expectedStatus) => {
-    const iframe = await page.frame({ name: 'Kommunicate widget iframe' });
+    const iframe = await page.frame({ name: WIDGET_IFRAME_NAME });
     await iframe.waitForFunction((status) => window.IS_SOCKET_CONNECTED === status, expectedStatus);
     return iframe;
 };

Additionally, verify that IS_SOCKET_CONNECTED is reliably set by the widget:

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (5)
webplugin/js/app/mck-sidebox-1.0.js (1)

1841-1847: Don’t rethrow from init/reconnect catch; guarantee flag reset before any early return

Rethrowing aborts backoff/retry and can leave flags stuck. Ensure IS_SOCKET_INITIALIZING resets on all paths and avoid rethrow, as previously noted.

Run to verify there’s no throw in ALSocket init/reconnect catch blocks and flags reset before returns:

#!/bin/bash
# Catch blocks around ALSocket init/reconnect that rethrow or don't reset flags
rg -nP -C3 '(try\s*\{(?s).*?ALSocket\.(init|reconnect)\(.*\).*?\}\s*catch\s*\(\w+\)\s*\{(?s:.*?)throw\s+)' --type=js webplugin/js/app/mck-sidebox-1.0.js

# Ensure IS_SOCKET_INITIALIZING is reset near early returns after init/reconnect attempts
rg -nP -C2 '(IS_SOCKET_INITIALIZING\s*=\s*false).*?\n.*return;' --type=js webplugin/js/app/mck-sidebox-1.0.js
playwright_test/tests/socketConnection.spec.js (4)

54-59: Use cross‑platform, deterministic input (avoid Meta+A).

Use locator.fill() to replace value directly; this removes OS‑specific shortcuts and reduces flakiness. Based on learnings.

-    await page.click(LOCATORS.appIdField);
-    await page.keyboard.press('Meta+A');
-    await page.type(LOCATORS.appIdField, APP_ID.kmAppId);
+    await page.fill(LOCATORS.appIdField, APP_ID.kmAppId);
     await page.click(LOCATORS.scriptFiled);
-    await page.keyboard.press('Meta+A');
-    await page.keyboard.press('Delete');
-    await page.type(LOCATORS.scriptFiled, SCRIPT.kmAllBooleanIsTrue);
+    await page.fill(LOCATORS.scriptFiled, SCRIPT.kmAllBooleanIsTrue);

91-91: Replace arbitrary timeouts with condition‑based waits.

These sleeps are flaky and slow. Rely on element state or a specific readiness signal you already wait for (close button visible/hidden, socket status). Based on learnings.

-        await page.waitForTimeout(2000);
-        await page.waitForTimeout(500);
-        await page.waitForTimeout(500);
-        await page.waitForTimeout(1000);
-        await page.waitForTimeout(500);
-            await page.waitForTimeout(500);
-            await page.waitForTimeout(500);
-            await page.waitForTimeout(300);

Example replacements already present in your code:

  • Use await closeButton.waitFor({ state: 'visible' }) and state: 'hidden' instead of 500ms sleeps.
  • For stabilization after socket connect, prefer a deterministic selector inside iframe (e.g., a “ready” attribute) or reuse waitForSocketStatus.

Also applies to: 95-95, 102-102, 128-128, 136-136, 159-159, 168-168, 176-176


108-112: Guard ALSocket.disconnect with a function check.

Avoid throwing if ALSocket exists but disconnect is missing/not a function.

-        await iframe.evaluate(() => {
-            if (window.Applozic?.ALSocket) {
-                window.Applozic.ALSocket.disconnect();
-            }
-        });
+        await iframe.evaluate(() => {
+            const disconnect = window.Applozic?.ALSocket?.disconnect;
+            if (typeof disconnect === 'function') {
+                disconnect.call(window.Applozic.ALSocket);
+            }
+        });

Apply the same change to the other two cleanup blocks:

-        await iframe.evaluate(() => {
-            if (window.Applozic?.ALSocket) {
-                window.Applozic.ALSocket.disconnect();
-            }
-        });
+        await iframe.evaluate(() => {
+            const disconnect = window.Applozic?.ALSocket?.disconnect;
+            if (typeof disconnect === 'function') {
+                disconnect.call(window.Applozic.ALSocket);
+            }
+        });
-        await iframe.evaluate(() => {
-            if (window.Applozic?.ALSocket) {
-                window.Applozic.ALSocket.disconnect();
-            }
-        });
+        await iframe.evaluate(() => {
+            const disconnect = window.Applozic?.ALSocket?.disconnect;
+            if (typeof disconnect === 'function') {
+                disconnect.call(window.Applozic.ALSocket);
+            }
+        });

Also applies to: 144-146, 201-203


153-177: Extract openWidget/closeWidget helpers to top‑level for reuse and clarity.

These inline helpers duplicate logic and make tests longer. Move them to a shared creator (returning openWidget/closeWidget) and reuse across tests.

Example:

// Top-level (near configureWidgetPreview)
const createWidgetHelpers = (launcher, getCloseButtonLocator, tracker) => ({
  openWidget: async ({ expectNewSocket }) => {
    const before = tracker.socketRecords.length;
    const socketPromise = expectNewSocket ? tracker.waitForSocketRecord() : null;
    await launcher.click();
    await getCloseButtonLocator().waitFor({ state: 'visible' });
    if (expectNewSocket) {
      const record = await socketPromise;
      expect(tracker.socketRecords.length).toBe(before + 1);
      expect(record.closedAt).toBeNull();
      return record;
    }
    expect(tracker.socketRecords.length).toBe(before);
    return tracker.socketRecords[tracker.socketRecords.length - 1];
  },
  closeWidget: async () => {
    await getCloseButtonLocator().click();
    await getCloseButtonLocator().waitFor({ state: 'hidden' });
  },
});

Then replace the inline definitions with:

const { openWidget, closeWidget } = createWidgetHelpers(launcher, getCloseButtonLocator, tracker);
🧹 Nitpick comments (3)
webplugin/js/app/mck-sidebox-1.0.js (1)

14-16: Clarify socket lifecycle flags; bound and drain the new bot queue

  • Ensure IS_SOCKET_INITIALIZED is set true only after onConnect and cleared on all failure/early-return paths.
  • Bound/clear MCK_BOT_MESSAGE_QUEUE on disconnect/destroy to avoid leaks.

Based on learnings

playwright_test/tests/socketConnection.spec.js (2)

25-28: Avoid race: return the exact WebSocket record instead of “last element.”

Concurrent sockets could make “last item” brittle. Capture the ws from waitForEvent and map back to its record.

-    const waitForSocketRecord = async () => {
-        await page.waitForEvent('websocket', (ws) => isWidgetSocketUrl(ws.url()));
-        return socketRecords[socketRecords.length - 1];
-    };
+    const waitForSocketRecord = async () => {
+        const ws = await page.waitForEvent('websocket', (w) => isWidgetSocketUrl(w.url()));
+        return socketRecords.find((r) => r.ws === ws);
+    };

62-63: Drop unused iframeLocator and inline frameLocator usage.

iframeLocator is only used to build launcher and not returned/used elsewhere.

-    const iframeLocator = await page.frameLocator(WIDGET_LOCATORS.kmIframe);
-    const launcher = iframeLocator.locator(WIDGET_LOCATORS.kmLaunchWidget);
+    const launcher = page.frameLocator(WIDGET_LOCATORS.kmIframe).locator(WIDGET_LOCATORS.kmLaunchWidget);
@@
-    return { iframeLocator, launcher, getCloseButtonLocator };
+    return { launcher, getCloseButtonLocator };

Also applies to: 67-67

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30d5692 and d6a066a.

⛔ Files ignored due to path filters (2)
  • webplugin/js/app/applozic.chat-6.2.9.min.js is excluded by !**/*.min.js
  • webplugin/js/app/applozic.chat-6.3.0.min.js is excluded by !**/*.min.js
📒 Files selected for processing (5)
  • playwright_test/tests/socketConnection.spec.js (1 hunks)
  • webplugin/development.js (1 hunks)
  • webplugin/gulpfile.js (1 hunks)
  • webplugin/js/app/mck-app.js (1 hunks)
  • webplugin/js/app/mck-sidebox-1.0.js (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-25T05:44:56.580Z
Learnt from: panwaranuj01
PR: Kommunicate-io/Kommunicate-Web-SDK#1320
File: webplugin/js/app/voice/mck-voice.js:758-758
Timestamp: 2025-06-25T05:44:56.580Z
Learning: The code in webplugin/js/app/voice/mck-voice.js runs in an isolated scope and does not pollute the global namespace of other windows or the host page. Global variables within this isolated scope are acceptable as they don't affect the embedding environment.

Applied to files:

  • webplugin/js/app/mck-sidebox-1.0.js
🧬 Code graph analysis (3)
webplugin/js/app/mck-app.js (1)
webplugin/controller.js (1)
  • MCK_CONTEXTPATH (23-23)
webplugin/gulpfile.js (2)
webplugin/development.js (2)
  • copyFileToBuild (122-129)
  • buildDir (16-16)
webplugin/bundleFiles.js (1)
  • buildDir (2-2)
webplugin/development.js (2)
webplugin/gulpfile.js (2)
  • copyFileToBuild (360-368)
  • buildDir (28-28)
webplugin/bundleFiles.js (1)
  • buildDir (2-2)
🔇 Additional comments (2)
webplugin/js/app/mck-app.js (1)

31-33: Sync all loaders with the 6.3.0 URL

Please double‑check that every loader/optimizer (e.g., pluginOptimizer.js, deployment manifests) now points to applozic.chat-6.3.0.min.js; the inline comment still applies, and any forgotten reference will serve the wrong asset.

webplugin/gulpfile.js (1)

255-257: Ensure the 6.3.0 asset is actually present

The copy step will now fail if webplugin/js/app/applozic.chat-6.3.0.min.js hasn’t been added to the repo/build pipeline. Please confirm the new artifact exists (and is committed) so the task doesn’t break.

@github-actions
Copy link

A friendly reminder that this PR had no activity for 15 days.

@github-actions github-actions bot closed this Nov 2, 2025
@panwaranuj01 panwaranuj01 reopened this Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants