Repository navigation
Releasing
This page covers how a change on main becomes a tagged GitHub release with a Chrome zip and a Firefox zip. Read it before you merge a pull request you want to ship, or when a release comes out wrong. For the checks each pull request passes first, see Development.
Release Please owns the version number, the changelog and the GitHub release. Nobody bumps the version by hand. A release goes through these stages:
- A pull request with a Conventional Commits title merges into
main. The repo allows only squash merges, so the pull request title becomes the commit message Release Please reads. - On that push, the Release Please workflow opens or updates a release pull request titled
chore(main): release <version>. The release pull request bumpsversioninpackage.json, updates.release-please-manifest.json, and adds the new section toCHANGELOG.md. - When you merge the release pull request, the same workflow tags
v<version>and creates the GitHub release, with the changelog section as its notes. - A second job in the workflow builds the extension from the tag for both browsers and attaches
screen-tools-v<version>.zip(Chrome) andscreen-tools-v<version>-firefox.zipto the release.
Merge the release pull request when you want to ship. Until then it collects every releasable commit merged after the last release.
Release Please picks the next version from the commit types since the last tag:
| Commit type | Version bump | Changelog section |
|---|---|---|
feat: |
Minor | Features |
fix: |
Patch | Bug Fixes |
feat!: or BREAKING CHANGE:
|
Major | ⚠ BREAKING CHANGES |
chore:, docs: and the rest |
None | Left out |
The changelog shows the commit subject, so write the pull request title as the line users read. The extension bundles CHANGELOG.md at build time: the home page that opens after an update shows the section for the installed version, or the latest section when a dev build is ahead of the changelog, and the changelog page shows the whole file. See src/pages/home.tsx and src/pages/changelog.tsx.
Two files at the repo root configure Release Please:
-
release-please-config.jsonsets one package at the repo root with thenoderelease type, so the bump lands inpackage.json. Tags take the formv1.4.0, with no component prefix, and the changelog goes toCHANGELOG.md. The first release was1.0.0. -
.release-please-manifest.jsonholds the version of the latest release. Release Please updates it in each release pull request, so don't edit it.
WXT copies version from package.json into the extension manifest, so the release pull request is the only change a version needs.
.github/workflows/release-please.yml runs on every push to main and has two jobs:
-
release-pleaserunsgoogleapis/release-please-actionwith the two configuration files. It outputsrelease_createdandtag_name. -
upload-zipruns only whenrelease_createdistrue. It checks out the tag, installs with the frozen lockfile, and runspnpm zipandpnpm zip:firefox. It then renames.output/screen-tools-<version>-chrome.ziptoscreen-tools-<tag>.zipand.output/screen-tools-<version>-firefox.ziptoscreen-tools-<tag>-firefox.zip, and uploads both withgh release upload --clobber. v1.5.0 is the first release with a Firefox zip.
The workflow needs contents: write to create tags and releases and pull-requests: write to open the release pull request. Both are set in the workflow file, so the repo needs no extra token.
The Chrome zip is what users install: they unzip it and load the folder unpacked, so they need neither Node nor a clone. The Firefox zip is the package to load in Firefox or submit to addons.mozilla.org. The README's Install and Updating sections cover the user's side, and Installation and Updating covers it in more detail.
The zip steps pass the upload services' build variables from the repository's Actions variables (vars), not secrets, because they're public identifiers:
| Variable | Passed to | Holds |
|---|---|---|
WXT_GOOGLE_CLIENT_ID |
Both zips | Google OAuth client ID |
WXT_DROPBOX_APP_KEY |
Both zips | Dropbox app key |
WXT_EXTENSION_KEY |
Chrome zip only | The Chrome Web Store public key |
The key pins the Chrome extension ID, so the OAuth redirect URL is the same wherever a user unpacks the zip. Firefox gets its ID from browser_specific_settings in the manifest, so the Firefox manifest never includes the key. When a variable is missing, the build still succeeds and that service shows as "Not available in this build" in Settings. Check the variables are set under Settings → Secrets and variables → Actions → Variables before a release that should offer uploads. Development covers the same variables for local builds.
Keep immutable releases turned off in the repo settings. Release Please publishes the release before the upload-zip job builds the zips, and GitHub rejects uploads to an immutable release, so the release ships with no zips. v1.0.0 has no zip for this reason, and every release from v1.0.1 on has one.
If a release ends up without its zips, check the upload-zip job log first. To attach them by hand, build from the tag with the upload variables set in .env.local or the shell, and upload both:
git checkout v<version>
pnpm install --frozen-lockfile
pnpm zip
pnpm zip:firefox
mv .output/screen-tools-*-chrome.zip screen-tools-v<version>.zip
mv .output/screen-tools-*-firefox.zip screen-tools-v<version>-firefox.zip
gh release upload v<version> screen-tools-v<version>.zip screen-tools-v<version>-firefox.zip --clobberUsing Screen Tools
- Installation and Updating
- Firefox
- Recording
- Screenshots
- Uploading
- Settings
- Troubleshooting and FAQ
- Privacy
How it works
Contributing