diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3b8c044..5e5ec85b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -325,27 +325,37 @@ jobs: command: ./gradlew --no-daemon :app:assembleSideloadDebug - task: bundle-playstore command: ./gradlew --no-daemon :app:bundlePlaystoreRelease + requires_signing: true steps: - name: Checkout + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" uses: actions/checkout@v4 with: submodules: false + - name: Skip (no signing secrets) + if: matrix.requires_signing && secrets.KEYSTORE_FILE == '' + run: echo "Skipping ${{ matrix.task }} — KEYSTORE_FILE secret not configured" + - name: Setup Java + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 - name: Setup Android SDK + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" uses: android-actions/setup-android@v3 with: accept-android-sdk-licenses: false - name: Setup Gradle + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" uses: gradle/actions/setup-gradle@v4 - name: Install Android SDK packages + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" run: | yes | sdkmanager --licenses >/dev/null sdkmanager --install \ @@ -353,6 +363,17 @@ jobs: "platforms;android-36" \ "build-tools;36.0.0" + - name: Decode keystore + if: matrix.requires_signing && secrets.KEYSTORE_FILE != '' + working-directory: apps/android/app + run: echo "${{ secrets.KEYSTORE_FILE }}" | base64 -d > release.keystore + - name: Run Android ${{ matrix.task }} + if: "!matrix.requires_signing || secrets.KEYSTORE_FILE != ''" working-directory: apps/android run: ${{ matrix.command }} + env: + KEYSTORE_FILE: ${{ matrix.requires_signing && 'release.keystore' || '' }} + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} diff --git a/src/discord/monitor.tool-result.sends-status-replies-responseprefix.test.ts b/src/discord/monitor.tool-result.sends-status-replies-responseprefix.test.ts index d1b66160..09d52359 100644 --- a/src/discord/monitor.tool-result.sends-status-replies-responseprefix.test.ts +++ b/src/discord/monitor.tool-result.sends-status-replies-responseprefix.test.ts @@ -236,5 +236,5 @@ describe("discord tool result dispatch", () => { expect(sendMock).toHaveBeenCalledTimes(1); expect(String(sendMock.mock.calls[0]?.[1] ?? "")).toContain("Your Discord user id: u2"); expect(String(sendMock.mock.calls[0]?.[1] ?? "")).toContain("Pairing code: PAIRCODE"); - }, 10000); + }, 60_000); }); diff --git a/src/plugins/discovery.test.ts b/src/plugins/discovery.test.ts index ac95dddb..4c8b9160 100644 --- a/src/plugins/discovery.test.ts +++ b/src/plugins/discovery.test.ts @@ -114,7 +114,7 @@ describe("discoverMayrosPlugins", () => { }); const ids = candidates.map((c) => c.idHint); - expect(ids).toContain("mayros-voice-call"); + expect(ids).toContain("voice-call"); }); it("treats configured directory paths as plugin packages", async () => { @@ -137,7 +137,7 @@ describe("discoverMayrosPlugins", () => { }); const ids = candidates.map((c) => c.idHint); - expect(ids).toContain("mayros-demo-plugin-dir"); + expect(ids).toContain("demo-plugin-dir"); }); it("blocks extension entries that escape package directory", async () => { const stateDir = makeTempDir(); diff --git a/src/plugins/discovery.ts b/src/plugins/discovery.ts index 309ce10f..4f38f235 100644 --- a/src/plugins/discovery.ts +++ b/src/plugins/discovery.ts @@ -239,11 +239,17 @@ function deriveIdHint(params: { } // Prefer the unscoped name so config keys stay stable even when the npm - // package is scoped (example: @apilium/mayros-voice-call -> mayros-voice-call). - const unscoped = rawPackageName.includes("/") + // package is scoped (example: @apilium/mayros-voice-call -> voice-call). + let unscoped = rawPackageName.includes("/") ? (rawPackageName.split("/").pop() ?? rawPackageName) : rawPackageName; + // Strip the "mayros-" prefix so the hint matches the short manifest id + // used in config keys (e.g. "mayros-bluebubbles" -> "bluebubbles"). + if (unscoped.startsWith("mayros-")) { + unscoped = unscoped.slice("mayros-".length); + } + if (!params.hasMultipleExtensions) { return unscoped; }