From 52ffa393c5099a29eccc96d02d15a32de204169f Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Thu, 22 Oct 2026 12:44:44 +0200 Subject: [PATCH 1/2] relnote(159): Add 159 release notes --- release-notes/firefox.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/release-notes/firefox.md b/release-notes/firefox.md index 2b55119..19ee844 100644 --- a/release-notes/firefox.md +++ b/release-notes/firefox.md @@ -3,6 +3,21 @@ # Firefox release notes for enterprise admins +## 159 - 2026-10-27 + +_Upcoming, not yet released._ + +These changes apply to Firefox 159, Firefox ESR 153.6.0 and Firefox Enterprise 159 unless explicitly stated. +Firefox ESR 153 is the current ESR. + +### Changes + +- [`SignOut`](/reference/policies/signout/): Added `Crash.Action` to define whether users are fully signed out or if the browser is locked when the browser crashes. + Firefox Enterprise only. ([bug 2068950](https://bugzil.la/2068950)) +- [`SkipTermsOfUse`](/reference/policies/skiptermsofuse/): Now supported in Firefox Enterprise. ([bug 2074742](https://bugzil.la/2074742)) +- [`Cookies`](/reference/policies/cookies/): Cookies for hosts listed in `Block` are now cleared every time the policy is applied, not only when the list changes. + Firefox Enterprise only. + ## 158 - 2026-10-13 These changes apply to Firefox 158 and Firefox ESR 153.5.0 unless explicitly stated. @@ -39,7 +54,6 @@ Firefox ESR 153 is the current ESR. ### Fixes - Policy URL fields rejected some valid URLs, such as internationalized domain names, non-ASCII paths and URLs containing spaces. ([bug 2067819](https://bugzil.la/2067819)) - Firefox 158 only. ([bug 2065295](https://bugzil.la/2065295)) - [`DisableFirefoxAccounts`](/reference/policies/disablefirefoxaccounts/): The toolbar could report a signed-in account when accounts were disabled. Firefox 158 only. ([bug 2066062](https://bugzil.la/2066062)) - The Labs quick action in the address bar was still shown when Firefox Labs was turned off with [`UserMessaging`](/reference/policies/usermessaging/), and Manage AI was still shown when `browser.preferences.aiControls` was `false`. From 932057e163d9f7e087e5ba67bbe230cf19248d9b Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 27 Oct 2026 09:47:18 +0100 Subject: [PATCH 2/2] fix: don't use the API to check releases, just check dates --- .github/workflows/release-dates.yml | 2 +- CONTRIBUTING.md | 3 +- scripts/sync-release-dates.mjs | 53 ++++++----------------------- 3 files changed, 14 insertions(+), 44 deletions(-) diff --git a/.github/workflows/release-dates.yml b/.github/workflows/release-dates.yml index 8446122..c0ebfde 100644 --- a/.github/workflows/release-dates.yml +++ b/.github/workflows/release-dates.yml @@ -63,7 +63,7 @@ jobs: else gh pr create \ --title "docs(release-notes): mark shipped releases as released" \ - --body "Automated daily check against [product-details](https://product-details.mozilla.org/1.0/firefox_history_major_releases.json). + --body "Automated daily check for upcoming releases whose heading date has arrived. _Opened by the [\`.github/workflows/release-dates.yml\`](https://github.com/${{ github.repository }}/tree/main/.github/workflows/release-dates.yml) workflow._" \ --label "automated pr" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f361576..ad03474 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,7 +153,8 @@ The following details matter for the generated pages: - Headings are the version number and release date: a `process` hook strips the date and prefixes `Firefox`, so `## 154 - 2026-08-18` is published as `Firefox 154` at `/release-notes/version/firefox-154/`. Any other heading text changes the page URL, so the build fails on a malformed date. - For a release that has not shipped, use the expected date and add `_Upcoming, not yet released._` after one blank line under the heading. - The daily `release-dates.yml` workflow opens a PR that removes it and corrects the date once the release ships. + The daily `release-dates.yml` workflow opens a PR that removes it once the heading date arrives. + If a release slips, update the heading date before then. - Link each policy to its reference page, at the lowercased policy name. Builds fail on broken internal links, so a policy with no reference page yet can be left unlinked. - Anything that deviates from co-shipping needs a scope note, like `Firefox 154 only.`, `Does not apply to the ESR.` at the end of the sentence before the bug link. diff --git a/scripts/sync-release-dates.mjs b/scripts/sync-release-dates.mjs index 95ee369..4c26bf0 100644 --- a/scripts/sync-release-dates.mjs +++ b/scripts/sync-release-dates.mjs @@ -3,9 +3,6 @@ import { readFile, writeFile } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { dirname, resolve } from "node:path"; -// Upstream only lists a version when it's shipped -const RELEASES_URL = "https://product-details.mozilla.org/1.0/firefox_history_major_releases.json"; - // Local config const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const NOTES_PATH = resolve(REPO_ROOT, "release-notes/firefox.md"); @@ -13,61 +10,33 @@ const NOTES_PATH = resolve(REPO_ROOT, "release-notes/firefox.md"); // An upcoming release heading is followed, after a blank line, by `_Upcoming, not yet released._`. const UPCOMING = /^\s*[_*]Upcoming\b/; const HEADING = /^## (\d+) - (\d{4}-\d{2}-\d{2})\s*$/; -const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/; async function main() { - const res = await fetch(RELEASES_URL); - if (!res.ok) { - throw new Error(`Failed to fetch releases: ${res.status} ${res.statusText}`); - } - const releases = await res.json(); + // ISO dates compare correctly as strings + const today = new Date().toISOString().slice(0, 10); const content = await readFile(NOTES_PATH, "utf8"); const eol = content.includes("\r\n") ? "\r\n" : "\n"; const lines = content.split(/\r?\n/); - // Find each dated heading's Upcoming line before editing anything - const upcoming = []; - for (let i = 0; i < lines.length; i++) { + // Edit from the bottom up so earlier line numbers stay valid + const shipped = []; + for (let i = lines.length - 1; i >= 0; i--) { const heading = HEADING.exec(lines[i]); - if (!heading) continue; + if (!heading || heading[2] > today) continue; let status = i + 1; while (status < lines.length && lines[status].trim() === "") status++; - if (UPCOMING.test(lines[status] ?? "")) { - upcoming.push({ index: i, status, version: heading[1], expected: heading[2] }); - } - } - - // Any other Upcoming line would never be updated, so fail rather than skip it - const known = new Set(upcoming.map(({ status }) => status)); - const stray = lines.filter((line, n) => UPCOMING.test(line) && !known.has(n)); - if (stray.length > 0) { - throw new Error( - `Upcoming line not directly under a \`## N - YYYY-MM-DD\` heading: ${stray.join(" | ")}`, - ); - } - - // Edit from the bottom up so earlier line numbers stay valid - const shipped = []; - for (const { index, status, version, expected } of upcoming.reverse()) { - const released = releases[`${version}.0`]; - if (!released) continue; - if (!ISO_DATE.test(released)) { - throw new Error(`Unexpected date for ${version}.0 in product-details: ${released}`); - } + if (!UPCOMING.test(lines[status] ?? "")) continue; - lines[index] = `## ${version} - ${released}`; // Drop the status line and the blank lines above it, keeping one blank line under the heading - lines.splice(index + 1, status - index); - if (lines[index + 1] !== "") lines.splice(index + 1, 0, ""); - shipped.unshift( - released === expected ? version : `${version} (moved from ${expected} to ${released})`, - ); + lines.splice(i + 1, status - i); + if (lines[i + 1] !== "") lines.splice(i + 1, 0, ""); + shipped.unshift(heading[1]); } if (shipped.length === 0) { - console.log("No upcoming releases have shipped."); + console.log("No upcoming releases are due."); return; }