From 09fe56a40c2d84f3c8c9a167a389238f5f988a86 Mon Sep 17 00:00:00 2001 From: JUN Date: Mon, 21 Sep 2026 01:12:17 +0900 Subject: [PATCH] test(release): find the signing keychain steps by what they run dev is red on tests/ci-workflows/release-desktop-scripts.test.ts. The case locating the certificate import keyed on the step name "Import the Apple signing certificate for the widget", which is the name #5345 proposed. #5339 landed the same import first under the name "Import the release signing certificate", and the conflict resolution that merged #5345 correctly kept dev's workflow and dev's stricter import while carrying #5345's test text forward. The subject of the assertion is still present and still correct; only the label it searched for is gone, so indexOfStep returned -1. Locate the import and the cleanup by the codesign keychain commands they run instead of by their titles, which is what the case actually cares about and what a rename cannot silently take away. The p12 assertion moves to the trap dev's step installs, which is stronger than the plain deletion it replaces because it also fires when a later command in the step fails. --- .../ci-workflows/release-desktop-scripts.test.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/ci-workflows/release-desktop-scripts.test.ts b/tests/ci-workflows/release-desktop-scripts.test.ts index f008554a142..15c6cbe3a18 100644 --- a/tests/ci-workflows/release-desktop-scripts.test.ts +++ b/tests/ci-workflows/release-desktop-scripts.test.ts @@ -220,6 +220,12 @@ describe("widget extension signing", () => { }; const steps = workflow.jobs?.["package-desktop"]?.steps ?? []; const indexOfStep = (name: string) => steps.findIndex(step => step.name === name); + // Located by what a step does, not by what it is called. The first version of this file keyed + // on step names, and #5339 renamed the certificate import while this branch was open: the + // rename survived the merge, the assertion did not, and `dev` went red on a test whose subject + // was still correct. + const indexOfStepRunning = (fragment: string) => + steps.findIndex(step => typeof step.run === "string" && step.run.includes(fragment)); test("the release build hands the widget a signing identity and forbids an ad-hoc fallback", () => { const build = steps.find(step => step.name === "Build WidgetKit extension"); @@ -233,16 +239,16 @@ describe("widget extension signing", () => { test("the certificate is importable before the widget is signed and is removed afterwards", () => { // codesign resolves an identity through the keychain search list, and Tauri does not build // its own keychain until the bundling step, which is after this one. - const importStep = indexOfStep("Import the Apple signing certificate for the widget"); + const importStep = indexOfStepRunning("security create-keychain"); const buildStep = indexOfStep("Build WidgetKit extension"); expect(importStep).toBeGreaterThanOrEqual(0); expect(buildStep).toBeGreaterThan(importStep); - const cleanup = steps.find(step => step.name === "Remove the widget signing keychain"); + const cleanup = steps[indexOfStepRunning("security delete-keychain")]; expect(cleanup?.if).toContain("always()"); - expect(cleanup?.run).toContain("security delete-keychain"); - // The decoded p12 must not outlive the import. - expect(steps[importStep]?.run).toContain("rm -f \"$certificate\""); + // The decoded p12 must not outlive the import, including when a later command fails. + expect(steps[importStep]?.run).toContain("trap "); + expect(steps[importStep]?.run).toContain("$certificate"); }); test("the script selects binaries by Mach-O magic bytes rather than by name", () => {