diff --git a/.github/workflows/webplat-relnotes.yaml b/.github/workflows/webplat-relnotes.yaml index 167fd689db..6c9c0f7c72 100644 --- a/.github/workflows/webplat-relnotes.yaml +++ b/.github/workflows/webplat-relnotes.yaml @@ -1,5 +1,5 @@ # This workflow checks if it's time to generate the next beta relnotes. -# And if so, it generates the beta relnotes and opens a PR with them. +# And if so, it generates a draft and opens an issue to notify the team. name: Generate beta relnotes @@ -28,13 +28,17 @@ jobs: - name: Generate release notes run: | cd scripts - node web-platform-release-notes.js + token=${{ secrets.GITHUB_TOKEN }} node web-platform-release-notes.js - name: Commit changes run: | - git checkout -b web-platform-release-notes - git config --local user.email "${{ github.actor }}@users.noreply.github.com" - git config --local user.name "${{ github.actor }}" - git add . - git commit -m "New beta web platform release notes" - git push origin web-platform-release-notes + if ! git diff --quiet; then + git config --local user.email "${{ github.actor }}@users.noreply.github.com" + git config --local user.name "${{ github.actor }}" + git checkout -b web-platform-release-notes + git add . + git commit -m "New beta web platform release notes" + git push origin web-platform-release-notes + else + echo "No changes to commit." + fi diff --git a/microsoft-edge/webview2/concepts/distribution-images/runtime-distrib-options.png b/microsoft-edge/webview2/concepts/distribution-images/runtime-distrib-options.png index e9047522eb..63bc0ae5a2 100644 Binary files a/microsoft-edge/webview2/concepts/distribution-images/runtime-distrib-options.png and b/microsoft-edge/webview2/concepts/distribution-images/runtime-distrib-options.png differ diff --git a/microsoft-edge/webview2/concepts/windowed-vs-visual-hosting.md b/microsoft-edge/webview2/concepts/windowed-vs-visual-hosting.md index 53b847109a..c9cf423038 100644 --- a/microsoft-edge/webview2/concepts/windowed-vs-visual-hosting.md +++ b/microsoft-edge/webview2/concepts/windowed-vs-visual-hosting.md @@ -164,10 +164,10 @@ Key compatibility limitations include the operating system and rendering in fram #### Operating systems -All hosting modes are supported wherever WebView2 is supported; that is, Windows 10 and later, and certain Windows Server versions. Windows 7, 8 and 8.1 are no longer supported; Windows 7 and Windows 8 only support Windowed hosting, not Visual hosting. +All hosting modes are supported wherever WebView2 is supported. See also: -* [Windows 7 and 8](../index.md#windows-7-and-8) in _Introduction to Microsoft Edge WebView2_. +* [Supported Windows versions](../index.md#supported-windows-versions) in _Introduction to Microsoft Edge WebView2_. @@ -181,7 +181,6 @@ See also: * [Overview of WebView2 APIs](./overview-features-apis.md) -* [Windows 7 and 8](../index.md#windows-7-and-8) in _Introduction to Microsoft Edge WebView2_. diff --git a/microsoft-edge/webview2/index.md b/microsoft-edge/webview2/index.md index 268dbf1036..45ae7193e8 100644 --- a/microsoft-edge/webview2/index.md +++ b/microsoft-edge/webview2/index.md @@ -67,6 +67,8 @@ Hybrid apps, in the middle of this spectrum, allow you to enjoy the best of both The Windows operating systems that are supported by Webview2 are the same as those supported by Microsoft Edge. +For more information about other supported operating systems, see [Microsoft Edge supported Operating Systems](/deployedge/microsoft-edge-supported-operating-systems). + #### Windows Client @@ -82,8 +84,10 @@ WebView2 apps can run on the following versions of Windows Client: * Windows 10 Enterprise multi-session * Windows 10 IoT Enterprise SAC * Windows 10 IoT Enterprise 2019 LTSC +* Windows 10 IoT Enterprise 2021 LTSC * Windows 11 * Windows 11 Enterprise multi-session +* Windows 11 IoT Enterprise 2024 LTSC For details, see [Windows Client](/deployedge/microsoft-edge-supported-operating-systems#windows-client) in _Microsoft Edge supported Operating Systems_. @@ -101,22 +105,6 @@ WebView2 apps can run on the following versions of Windows Server: For details, see [Windows Server](/deployedge/microsoft-edge-supported-operating-systems#windows-server) in _Microsoft Edge supported Operating Systems_. - -#### Windows 7 and 8 - -WebView2 Runtime version 109 is the final version that supports the following versions of Windows. WebView2 Runtime and SDK version 110.0.1519.0 and higher don't support these operating systems. - -* Windows Server 2008 R2 -* Windows Server 2012 -* Windows Server 2012 R2 -* Windows 7 -* Windows 8/8.1 - -See also: -* [Microsoft Edge supported Operating Systems](/deployedge/microsoft-edge-supported-operating-systems) - WebView2 support for Windows 7 and Windows Server 2008 R2 have the same support timeline as Microsoft Edge. -* [Microsoft Edge and WebView2 ending support for Windows 7 and Windows 8/8.1](https://blogs.windows.com/msedgedev/2022/12/09/microsoft-edge-and-webview2-ending-support-for-windows-7-and-windows-8-8-1/) - - ## Supported programming environments and devices diff --git a/microsoft-edge/webview2/release-notes/archive.md b/microsoft-edge/webview2/release-notes/archive.md index 0b3a9c4766..9289db7c3b 100644 --- a/microsoft-edge/webview2/release-notes/archive.md +++ b/microsoft-edge/webview2/release-notes/archive.md @@ -8594,7 +8594,7 @@ This version of the WebView2 SDK requires Microsoft Edge version 80.0.314.0 or h #### Changes -* Added support for Windows 7, Windows 8, and Windows 8.1. See [Windows 7 and 8](../index.md#windows-7-and-8) in _Introduction to Microsoft Edge WebView2_. +* Added support for Windows 7, Windows 8, and Windows 8.1. See [Supported Windows versions](../index.md#supported-windows-versions) in _Introduction to Microsoft Edge WebView2_. * Added Visual Studio and Visual Studio Code debug support for WebView2. Now, debug your script in the WebView2 right from your IDE. See [How to debug when developing with WebView2 controls](../how-to/debug.md). * Added `Native Object Injection` for the running script in WebView2 to access an IDispatch object from the Win32 component of the app and access the properties of the IDispatch object. See [AddRemoteObject](/microsoft-edge/webview2/reference/win32/iwebview2webview4?view=webview2-0.8.355&preserve-view=true#addremoteobject) ([#17](https://github.com/MicrosoftEdge/WebViewFeedback/issues/17)). * Added `AcceleratorKeyPressed` event. See [add_AcceleratorKeyPressed](/microsoft-edge/webview2/reference/win32/iwebview2webview4?view=webview2-0.8.355&preserve-view=true#add_acceleratorkeypressed) ([#57](https://github.com/MicrosoftEdge/WebViewFeedback/issues/57)). diff --git a/scripts/package-lock.json b/scripts/package-lock.json index 7dcd6f0da9..3c79a008b9 100644 --- a/scripts/package-lock.json +++ b/scripts/package-lock.json @@ -13,7 +13,8 @@ "@octokit/auth-action": "^5.1.1", "@octokit/request": "^9.2.1", "glob": "^7.1.7", - "node-fetch": "3.2.10" + "node-fetch": "3.2.10", + "playwright": "^1.54.1" } }, "node_modules/@11ty/dependency-tree": { @@ -2018,6 +2019,50 @@ "node": ">=0.10.0" } }, + "node_modules/playwright": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", + "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.54.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", + "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==", + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -4003,6 +4048,28 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" }, + "playwright": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", + "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.54.1" + }, + "dependencies": { + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + } + } + }, + "playwright-core": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", + "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==" + }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", diff --git a/scripts/package.json b/scripts/package.json index 431ed362d2..3d8d6575fc 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -8,6 +8,7 @@ "@octokit/auth-action": "^5.1.1", "@octokit/request": "^9.2.1", "glob": "^7.1.7", - "node-fetch": "3.2.10" + "node-fetch": "3.2.10", + "playwright": "^1.54.1" } } diff --git a/scripts/web-platform-release-notes.js b/scripts/web-platform-release-notes.js index 824ae052fc..545859d845 100644 --- a/scripts/web-platform-release-notes.js +++ b/scripts/web-platform-release-notes.js @@ -1,10 +1,15 @@ // Script runs daily. -import { request } from "@octokit/request"; +import github from '@actions/github'; import Eleventy from "@11ty/eleventy"; import fs from "fs/promises"; +import playwright from "playwright"; -const RELEASE_NOTES_PR_LABEL = "web-platform-release-notes"; +const EDGE_OT_ROOT = "https://developer.microsoft.com/en-us"; +const EDGE_OT_PAGE = `${EDGE_OT_ROOT}/microsoft-edge/origin-trials/trials`; +// If Beta becomes stable within the next N coming days, generate the release notes for Canary. +// This way, the release notes are ready for when Canary becomes Beta. +const DAYS_NUMBER_BEFORE_RELNOTES_NOTICE = 15; async function fetchChromeStatusAPI(url) { const response = await fetch(url); @@ -23,6 +28,81 @@ function longDate(dateString) { }); } +async function getActiveEdgeOTs() { + const scrapingBrowser = await playwright.chromium.launch({ headless: true }); + const context = await scrapingBrowser.newContext(); + + const page = await context.newPage(); + console.log(`Navigating to ${EDGE_OT_PAGE}`); + await page.goto(EDGE_OT_PAGE); + + // Wait for the OTs to have loaded. We check for the existence of a trial-card + // that has a __tags element in it. This element is used to display the + // "Microsoft Edge Only" tag. + await page.waitForSelector(".trial-card .trial-card__tags"); + + // Get the list of all origin trial elements + const microsoftOriginTrialEls = await page.locator("css=.trial-card", { hasText: "Microsoft Edge Only" }); + const otCards = await microsoftOriginTrialEls.all(); + console.log(`Found ${otCards.length} MS-only origin trials`); + + const otLinks = []; + for (const otCard of otCards) { + const otLink = await otCard.locator("css=a", { hasText: "Details" }); + const href = await otLink.getAttribute("href"); + console.log(href); + otLinks.push(EDGE_OT_ROOT + href); + } + + await page.close(); + + // Go to each OT page to find more information. + const ots = []; + for (const otLink of otLinks) { + const page = await context.newPage(); + console.log(`Navigating to ${otLink}`); + await page.goto(otLink); + + const trialInfoContainer = await page.locator("css=.block-container__content", { hasText: "Trial Expiration Date" }); + console.log("Found the trial info container"); + + const titleEl = await trialInfoContainer.locator("css=.common-heading__title"); + const title = await titleEl.textContent(); + console.log(`Found trial title: ${title}`); + + const descriptionEl = await trialInfoContainer.locator("css=.common-heading__description"); + const description = await descriptionEl.textContent(); + console.log(`Found trial description: ${description}`); + + const expirationDateEl = await trialInfoContainer.locator("css=.trial-id__trial-date", { hasText: "Trial Expiration Date" }).locator("css=p"); + const expiration = await expirationDateEl.textContent(); + console.log(`Found trial expiration date: ${expiration}`); + + const explainerLinkEl = await trialInfoContainer.locator("css=a", { hasText: "Explainer" }); + const explainer = await explainerLinkEl.getAttribute("href"); + console.log(`Found trial explainer: ${explainer}`); + + const feedbackLinkEl = await trialInfoContainer.locator("css=a", { hasText: "Feedback" }); + const feedback = await feedbackLinkEl.getAttribute("href"); + console.log(`Found trial feedback: ${feedback}`); + + ots.push({ + title, + description, + expiration: longDate(expiration), + explainer, + feedback, + registration: otLink + }); + + await page.close(); + } + + await scrapingBrowser.close(); + + return ots; +} + async function main() { // -------------------------------------------------- // 1. Check which is the next release (first date that's in the future compared to today). @@ -31,9 +111,6 @@ async function main() { // do the release note for the next beta: N+1. // -------------------------------------------------- - // If the next beta becomes stable within the next 6 days, start working on the next next beta. - const DAYS_NUMBER_BEFORE_RELNOTES_NOTICE = 6; - const edgeVersionsResponse = await fetch( "https://raw.githubusercontent.com/mdn/browser-compat-data/main/browsers/edge.json" ); @@ -54,17 +131,19 @@ async function main() { date > today && date - today <= DAYS_NUMBER_BEFORE_RELNOTES_NOTICE * 24 * 60 * 60 * 1000 ) { - // Find the next item in the list. nextBetaVersion = releasesAsArray[i + 1].engine_version; nextBetaReleaseDate = releasesAsArray[i + 1].release_date; nextBetaReleaseDateYear = nextBetaReleaseDate?.split("-")[0]; nextBetaReleaseDateMonth = nextBetaReleaseDate?.split("-")[1]; + console.log(`The next beta release is ${release.engine_version} (${release.release_date}), so we will prepare the release notes for ${nextBetaVersion} (${nextBetaReleaseDate}).`); break; + } else { + console.log(`Skipping release ${release.engine_version} (${release.release_date}).`); } } if (!nextBetaReleaseDate || !nextBetaVersion) { - console.error("It's not time to create the next beta release notes."); + console.error("Now is not the time to create the next beta release notes yet."); process.exit(0); } @@ -73,36 +152,11 @@ async function main() { ); // -------------------------------------------------- - // 2. Check if there isn't already a PR for the N+1 release notes by search for the existence of a label. - // If there is, do nothing. - // If there isn't, note the beta version number N' of release date D', and continue. - // -------------------------------------------------- - - const prListResponse = await request( - "GET /repos/MicrosoftDocs/edge-developer/pulls" - ); - const prs = prListResponse.data; - - for (const pr of prs) { - for (const label of pr.labels) { - if ( - label.name === RELEASE_NOTES_PR_LABEL && - pr.title.includes(nextBetaVersion) - ) { - console.error( - `Already found an open PR for the ${nextBetaVersion} release notes: ${pr.html_url}` - ); - process.exit(0); - } - } - } - - // -------------------------------------------------- - // 3. Fetch Chrome Status features for the N+1 milestone. + // 2. Fetch Chrome Status features for the N+1 milestone. // -------------------------------------------------- console.log( - `Fetching the features for ${nextBetaVersion} from Chrome Status.` + `Fetching ${nextBetaVersion} features from chromestatus.com.` ); const csMilestoneData = await fetchChromeStatusAPI( `https://chromestatus.com/api/v0/features?milestone=${nextBetaVersion}` @@ -110,7 +164,7 @@ async function main() { const csFeatures = csMilestoneData.features_by_type; // -------------------------------------------------- - // 4. Fetch Chrome Status new origin trials in N+1. + // 3. Fetch Chrome Status new origin trials in N+1. // -------------------------------------------------- console.log( @@ -136,17 +190,16 @@ async function main() { }); // -------------------------------------------------- - // 5. Fetch current Edge origin trials. + // 4. Fetch current Edge origin trials. // -------------------------------------------------- - // TODO... console.log( `Fetching the Edge OTs.` ); - const edgeOTs = []; + const edgeOTs = await getActiveEdgeOTs(); // -------------------------------------------------- - // 6. Generate the release notes draft content. + // 5. Generate the release notes draft content. // -------------------------------------------------- // Write the fetched data locally for 11ty to use, run 11ty, and then delete the file. @@ -188,31 +241,43 @@ async function main() { console.log("Generating the release notes content from the 11ty template."); const generated = await eleventy.toJSON(); - + // Remove the first empty line, which is added to the template just to avoid // eleventy from interpreting the front-matter const releaseNotesContent = generated[0].content - .split("\n") + .split("\n") .slice(1) .join("\n"); await fs.rmdir("_data", { recursive: true, force: true }); // -------------------------------------------------- - // 7. Write the release notes draft content to a file. + // 6. Write the release notes draft content to a file. // -------------------------------------------------- // All release notes go into /microsoft-edge/web-platform/release-notes/. // The file name should be the next beta version number. - + console.log("Writing the release notes content to a new md file in the repo."); const releaseNotesPath = `../microsoft-edge/web-platform/release-notes/${nextBetaVersion}.md`; await fs.writeFile(releaseNotesPath, releaseNotesContent); // -------------------------------------------------- - // 8. Create a new branch, commit the new file, and open a PR from this branch. + // 7. Open an issue on the repo to notify the team about the new release notes draft. // -------------------------------------------------- - + console.log("Opening an issue to notify the team about the new release notes draft."); + const title = `New beta web platform release notes for ${nextBetaVersion}`; + const body = `The release notes draft for the next beta version ${nextBetaVersion} has been generated in [${releaseNotesPath}](${releaseNotesPath}) on the web-platform-release-notes branch.\n\nPlease update the content as needed.`; + + const octokit = github.getOctokit(process.env.token); + const { data: issue } = await octokit.rest.issues.create({ + owner: "MicrosoftDocs", + repo: "edge-developer", + title, + body + }); + + console.log("Release notes draft generation completed successfully."); } main();