diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45c47ad..e8be9a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -56,7 +56,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -84,7 +84,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -107,7 +107,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -159,7 +159,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 diff --git a/.github/workflows/release-candidate.yml b/.github/workflows/release-candidate.yml index aa603ec..fe7eb60 100644 --- a/.github/workflows/release-candidate.yml +++ b/.github/workflows/release-candidate.yml @@ -25,7 +25,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -52,7 +52,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -80,7 +80,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -103,7 +103,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -130,7 +130,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -184,7 +184,7 @@ jobs: with: persist-credentials: false - - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -233,12 +233,12 @@ jobs: digest-mismatch: error - name: Attest VSIX build provenance - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-checksums: SHA256SUMS.txt - name: Attest VSIX SBOM - uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-checksums: SHA256SUMS.txt sbom-path: vscode-hydra-room-0.8.2.spdx.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2c5aa2..8f217b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,7 +8,7 @@ overrides: brace-expansion@5.0.8: 5.0.9 diff: ^8.0.4 fast-uri@3.1.5: 3.1.7 - js-yaml@4.3.0: 4.3.1 + js-yaml@>=4.0.0 <4.3.2: 4.3.2 minimatch@9.0.9: 10.2.5 qs@6.15.3: 6.16.0 serialize-javascript: ^7.0.6 @@ -836,8 +836,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.3.1: - resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true json-schema-traverse@1.0.0: @@ -1737,7 +1737,7 @@ snapshots: '@textlint/types': 15.7.1 chalk: 4.1.2 debug: 4.4.3(supports-color@8.1.1) - js-yaml: 4.3.1 + js-yaml: 4.3.2 lodash: 4.18.1 pluralize: 2.0.0 string-width: 4.2.3 @@ -2424,7 +2424,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.3.1: + js-yaml@4.3.2: dependencies: argparse: 2.0.1 @@ -2587,7 +2587,7 @@ snapshots: glob: 10.5.0 he: 1.2.0 is-path-inside: 3.0.3 - js-yaml: 4.3.1 + js-yaml: 4.3.2 log-symbols: 4.1.0 minimatch: 10.2.5 ms: 2.1.3 @@ -2759,7 +2759,7 @@ snapshots: rc-config-loader@4.1.4: dependencies: debug: 4.4.3(supports-color@8.1.1) - js-yaml: 4.3.1 + js-yaml: 4.3.2 json5: 2.2.3 require-from-string: 2.0.2 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a58b1c1..e51de72 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,7 +3,7 @@ overrides: brace-expansion@5.0.8: 5.0.9 diff: ^8.0.4 fast-uri@3.1.5: 3.1.7 - js-yaml@4.3.0: 4.3.1 + js-yaml@>=4.0.0 <4.3.2: 4.3.2 minimatch@9.0.9: 10.2.5 qs@6.15.3: 6.16.0 serialize-javascript: ^7.0.6 diff --git a/test/ciWorkflow.test.ts b/test/ciWorkflow.test.ts index f7f29d7..cfc28eb 100644 --- a/test/ciWorkflow.test.ts +++ b/test/ciWorkflow.test.ts @@ -52,7 +52,7 @@ describe("CI workflow contracts", () => { assert.match(workflow, /actions\/setup-node@[a-f0-9]{40} # v7\.0\.0/); assert.match( workflow, - /pnpm\/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6/, + /pnpm\/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6/, ); assert.match( release, @@ -94,7 +94,7 @@ describe("CI workflow contracts", () => { assert.match(workflow, /pnpm run test:coverage/); assert.match(release, /pnpm run test:coverage/); assert.doesNotMatch(release, /uses:\s+[^\s]+@v\d+/); - assert.equal((release.match(/pnpm\/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86/g) ?? []).length, 6); + assert.equal((release.match(/pnpm\/action-setup@ea17c68df8912ef543352723c149a84f56e3d413/g) ?? []).length, 6); assert.doesNotMatch(release, /pnpm\/setup@|install: false/); assert.match(release, /actions\/upload-artifact@[a-f0-9]{40} # v7\.0\.1/); assert.match(release, /retention-days: 14/); @@ -153,7 +153,7 @@ describe("CI workflow contracts", () => { assert.match(attestJob, /permissions:\s*\n\s+contents: read\s*\n\s+id-token: write\s*\n\s+attestations: write/u); assert.match(attestJob, /actions\/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8\.0\.1/u); assert.doesNotMatch(attestJob, /(?:^|\n)\s+-?\s*run:|checkout@|pnpm|node /u); - assert.equal((attestJob.match(/actions\/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4\.2\.1/g) ?? []).length, 2); + assert.equal((attestJob.match(/actions\/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4\.2\.2/g) ?? []).length, 2); assert.equal((release.match(/actions\/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c/g) ?? []).length, 2); assert.equal((release.match(/actions\/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a/g) ?? []).length, 1); diff --git a/test/telegramControllerLifecycle.test.ts b/test/telegramControllerLifecycle.test.ts index fff3ede..ce473b3 100644 --- a/test/telegramControllerLifecycle.test.ts +++ b/test/telegramControllerLifecycle.test.ts @@ -15,6 +15,7 @@ import { telegramCoordinatorPaths, } from "../src/telegramCoordinator"; import type { TelegramUpdatesResult } from "../src/telegram"; +import { HANG_NET_TIMEOUT_MS } from "./testBudgets"; interface PollableTelegramController { inboundGeneration: number; @@ -22,13 +23,15 @@ interface PollableTelegramController { } describe("TelegramController lifecycle", () => { - test("dispose aborts the active poll and its stale completion does not dispatch room work", async () => { + test("dispose aborts the active poll and its stale completion does not dispatch room work", { timeout: HANG_NET_TIMEOUT_MS }, async () => { const environment = await useTempTelegramEnvironment(); const restoreSettings = installTelegramSettings(environment.botToken); const telegramModule = require("../src/telegram") as Record; const originalGetUpdates = telegramModule.getTelegramUpdates; let resolveUpdates: ((result: TelegramUpdatesResult) => void) | undefined; let pollSignal: AbortSignal | undefined; + let markPollStarted: () => void = () => {}; + const pollStarted = new Promise((resolve) => { markPollStarted = resolve; }); telegramModule.getTelegramUpdates = ( _config: unknown, options: { signal?: AbortSignal } @@ -36,6 +39,7 @@ describe("TelegramController lifecycle", () => { pollSignal = options.signal; return new Promise((resolve) => { resolveUpdates = resolve; + markPollStarted(); }); }; @@ -48,7 +52,13 @@ describe("TelegramController lifecycle", () => { pollable.inboundGeneration = 1; try { const pending = pollable.pollInboundOnce(1); - await waitUntil(() => pollSignal !== undefined); + // Coordinator file/lease setup can take longer on loaded CI workers. + // Wait for the mocked transport itself, not a wall-clock guess. An early + // poll completion or rejection is still a test failure. + await Promise.race([ + pollStarted, + pending.then(() => { throw new Error("Telegram poll completed before its transport started"); }), + ]); controller.dispose(); assert.equal(pollSignal?.aborted, true); resolveUpdates?.({ ok: false, updates: [], error: "aborted" }); @@ -400,11 +410,3 @@ async function useTempTelegramEnvironment(): Promise { }, }; } - -async function waitUntil(predicate: () => boolean): Promise { - for (let attempt = 0; attempt < 100; attempt += 1) { - if (predicate()) return; - await new Promise((resolve) => setTimeout(resolve, 2)); - } - throw new Error("Timed out waiting for Telegram poll to start"); -}