diff --git a/how-to-release.md b/how-to-release.md index 1d5e67f50..fbebebbc7 100644 --- a/how-to-release.md +++ b/how-to-release.md @@ -1,8 +1,7 @@ # Release Guide **Publishing packages to NPM** -In `package.json` verify the name and update the version. Add additional files -if needed. +In `package.json` verify the name and update the version. ```json { @@ -11,15 +10,33 @@ if needed. ... "files": [ "dist", - "*.md", - "Add more here if needed" + "LICENSE.md", + "README.md", + "CONTRIBUTING.md", + "RELEASE-NOTES-0.18.0.md" ] } ``` +Keep the `files` array as an explicit allowlist. Do **not** delete it: with no +`files` field, npm publishes the entire repo minus standard ignores (`src/`, +`test/`, configs, etc.), which bloats the package and leaks dev files. Avoid +globs like `"*.md"` here — they can sweep in transient files (e.g. per-release +notes) you did not intend to ship. Add a new entry only when a file genuinely +needs to ship, and prefer stable filenames over version-specific ones. + +Release notes are **not** shipped in the npm tarball — they live on the GitHub +release (see "Preparing release notes" below), so there is nothing to add here +for them. + Note that when releasing on npm, you are distributing leaflet, proj4 etc., so you need to distribute the text of their licenses with the dist folder. +Verify the exact contents of the tarball before publishing: +```bash +npm pack --dry-run +``` + Open the command prompt and cd into the MapML.js project directory. Type in – @@ -35,17 +52,49 @@ When it publishes successfully you should see: +@maps4html/mapml@X.X.X ``` +**Preparing release notes** + +Release notes live on the GitHub release, not in the repo or the npm package. +To write them ahead of time and still be able to edit before publishing, draft +them in a local, **uncommitted** scratch file (any name, e.g. +`RELEASE-NOTES-X.Y.Z.md`). Seed the file from the commit history since the last tag, +replacing `` with the actual prior release tag (e.g. `v0.18.0`): + +```bash +git log ..HEAD --pretty=format:'- %s (%h, %an)' +``` + +Edit that file freely — it is disposable and never committed or shipped. + **GitHub release procedure** -To create a new release on GitHub, visit the [release page](https://github.com/Maps4HTML/MapML.js/releases), -then click `Draft a new release`. +Create the release from the canonical `Maps4HTML/MapML.js` repository so the tag +and release are authoritative. Two options: + +_Via the web UI:_ visit the [release page](https://github.com/Maps4HTML/MapML.js/releases) +and click `Draft a new release`. In the `Choose a tag` dropdown, type the new +`vX.Y.Z` tag (GitHub creates it on publish), set the target to the merged +release commit on `main`, paste in your notes, and publish. + +_Via the GitHub CLI_ (lets you create an editable **draft** from your notes +file, then review/publish): +```bash +gh release create vX.Y.Z --draft --title "vX.Y.Z" --notes-file RELEASE-NOTES-X.Y.Z.md +``` +Open the draft, make any final edits, then publish it. Publishing the release is +what creates and pushes the `vX.Y.Z` tag, so no separate `git push` of a tag is +required (useful when branch protection prevents pushing tags directly). -Enter the new release version in the `Choose a tag` dropdown, fill in the title and description -if needed, and then publish the release. +After the tag exists upstream, publish to npm from that tagged state: +```bash +git fetch upstream --tags +git checkout vX.Y.Z +npm ci && npm publish --access=public +``` **Publishing packages to GitHub** -Create a personal access token on [GitHub](https://github.com/settings/tokens/new) +Create a personal access (classic) token on [GitHub](https://github.com/settings/tokens/new) and check `write:packages` and `delete:packages`. Open the command prompt and cd into the MapML.js project directory. Enter: diff --git a/test/e2e/elements/map-link/map-link-security.test.js b/test/e2e/elements/map-link/map-link-security.test.js index 505ed590d..541a2f698 100644 --- a/test/e2e/elements/map-link/map-link-security.test.js +++ b/test/e2e/elements/map-link/map-link-security.test.js @@ -34,7 +34,7 @@ test.describe('map-link security: XSS via ', () => page = context.pages().find((p) => p.url() === 'about:blank') || (await context.newPage()); - await page.goto('map-link-security.html'); + await page.goto('map-link-security.html', { waitUntil: "networkidle" }); // Give the viewer a beat to attach the malicious layers to the // attribution / layer control before we probe. await page.waitForSelector('mapml-viewer'); @@ -102,6 +102,21 @@ test.describe('map-link security: XSS via ', () => test('legitimate https license still renders as an anchor', async () => { // The `good_license` layer must produce a proper anchor in the // attribution control, with the sanitised href and escaped title. + // The good_license layer is initialised asynchronously; on slower + // CI runners the anchor may not have been added to the attribution + // control by the time the earlier tests finish, so wait for it + // explicitly before probing. + await page.waitForFunction(() => { + const viewer = document.querySelector('mapml-viewer'); + const container = + viewer && viewer._map && viewer._map.attributionControl + ? viewer._map.attributionControl._container + : null; + if (!container) return false; + return Array.from(container.querySelectorAll('a')).some( + (a) => a.textContent && a.textContent.includes('Terms of service') + ); + }); const legit = await page.evaluate(() => { const container = document.querySelector('mapml-viewer')._map.attributionControl