diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index afc0108d2..94ffa3acd 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -152,8 +152,11 @@ jobs: # form is the documented best-practice (signs the immutable digest, # not the mutable tag — so a future re-tag doesn't invalidate the # signature). + # + # cosign-installer publishes no floating `v4` tag (only v4.x.y), + # so pin the exact release. v4 still installs cosign v2.x. - name: Install cosign - uses: sigstore/cosign-installer@v4 + uses: sigstore/cosign-installer@v4.1.2 with: cosign-release: 'v2.4.1' diff --git a/CHANGELOG.md b/CHANGELOG.md index 44ec23cc5..f8b337fae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,15 @@ Legend: ? = Other stuff ``` +(29/10/26): Version 2.2.9-srcdslab +----------------------- +``` +01. ! CI: the Docker image workflow failed on every push to main since + the Actions bump; cosign-installer is now pinned to v4.1.2 +02. ? E2E: the "bulk select → assign web group" test no longer races + the page reload that follows the bulk action +``` + (29/10/26): Version 2.2.8-srcdslab ----------------------- ``` diff --git a/web/tests/e2e/specs/flows/admin-deactivate-bulk.spec.ts b/web/tests/e2e/specs/flows/admin-deactivate-bulk.spec.ts index 35a52dc0f..6373fc905 100644 --- a/web/tests/e2e/specs/flows/admin-deactivate-bulk.spec.ts +++ b/web/tests/e2e/specs/flows/admin-deactivate-bulk.spec.ts @@ -351,13 +351,32 @@ test.describe('flow: admin deactivate + bulk (#1509)', () => { .toBe('visible'); await dialog.locator('[data-testid="admins-bulk-web-group-select"]').selectOption(String(group.gid)); - const bulkResp = page.waitForResponse( - (r) => r.url().includes('api.php') && r.request().method() === 'POST' && r.status() === 200, - ); + // The page reloads as soon as admins.bulk resolves (no rehash + // SIDs here), so a waitForResponse() body can be evicted before + // .json() reads it. Read the real response inside the route. + const bulk: { body: { ok?: boolean; data?: { op?: string; applied?: number[] } } | null } = { + body: null, + }; + await page.route((url) => url.pathname.endsWith('/api.php'), async (route) => { + const req = route.request(); + let action = ''; + try { + action = JSON.parse(req.postData() ?? '{}').action ?? ''; + } catch { + action = ''; + } + if (req.method() !== 'POST' || action !== 'admins.bulk') { + await route.continue(); + return; + } + const response = await route.fetch(); + bulk.body = await response.json(); + await route.fulfill({ response }); + }); await dialog.locator('[data-testid="admins-bulk-web-group-submit"]').click(); - const body = await (await bulkResp).json(); - expect(body.ok).toBe(true); - expect(body.data?.op).toBe('set_web_group'); - expect(body.data?.applied).toEqual([aid]); + await expect.poll(() => bulk.body).not.toBeNull(); + expect(bulk.body?.ok).toBe(true); + expect(bulk.body?.data?.op).toBe('set_web_group'); + expect(bulk.body?.data?.applied).toEqual([aid]); }); });