From 7a68ab349c8602dc6947d852c7c72daa9068c27e Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:57:19 +0530 Subject: [PATCH 01/15] docs: add RELEASE.md Co-authored-by: Radu-Cristian Popa --- RELEASE.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..0a22b108 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,85 @@ +# Web Monetization Extension Release Pipeline + +Two channels of the extensions will be maintained: + +- Preview +- Stable + +A separate Nightly release channel will be available via GitHub releases (without publishing to stores). + +## Extension versioning + +Web extensions do not follow SEMVER. The version string consists of 1 to 4 numbers separated by dots, for example, 1.2.3.4 (major.minor.patch.build). This is essentially SEMVER but with an additional build number, but does not support the alpha, beta or other suffixes. + +### Major version bump + +A major version bump (2.0.0.0) signifies the start of a block of product features. + +Before the extension is available first on the Stable channel, we only increase the build number (2.0.0.x) when publishing to the Preview channel. After that, we follow SEMVER (2.x.y). + +### Minor version bump + +New features and enhancements will be released under a minor version bump. + +### Patch version bump + +Bug fixes, performance and small updates will be released under a patch version bump. + +### Build version bump + +The build version bump should only happen when starting the work on a new major version. Once a major version (e.g. v1) goes into maintenance mode, the extension major version is bumped to 2.0.0.0. Until the new major version is made available on the Stable channel, only build number should be incremented. + +Multiple "build" version bumps can be made available in the Preview channel. e.g. we can have 2.0.0.1, 2.0.0.2, ..., 2.0.0.90 in the Preview channel before we make it available in the Stable channel. + +Note: When the new major version is going to be available in the Stable channel, it will have the last published version as in the Preview channel (i.e. the first Stable channel build could be 2.0.0.90, not necessarily 2.0.0 or 2.0.1). + +## Nightly + +The Nightly version will be built every day at 12AM UTC and it will be added to GitHub releases with the tag nightly. + +Nightly releases will correspond to the latest commit in the main branch of the repository at the time of the build. The tag reference will get updated on every release (rolling tags). Whenever a new release is happening, the previous one gets deleted first. + +### Versioning for the Nightly build + +On every action run, the workflow will update the following properties in the manifest: + +- `version`: will be set to the current date in `YYYY.M.D` format (note: not `YYYY.MM.DD` as we cannot have zero as prefix in these numbers) +- `version_name`: will be set to `Nightly YYYY.M.D ({short_commit_hash})` + +### Release Artifacts: + +Artifacts follow the name: `nightly-{browser}-{version}.zip`, e.g. `nightly-chrome-2024.7.13.zip`, `nightly-edge-2024.7.13.zip`, `nightly-firefox-2024.7.13.zip` + +## Preview + +The Preview version represents a release candidate on the main branch. They are less stable than the Stable version. + +Releases are triggered manually (via GitHub Actions), and can have a minor/patch/build version bump. + +Once a new development stage starts for a new major version and we start publishing it to the Preview channel, we will not be able to push an older version to the Preview channel - they will only be available in GitHub. But the releases for the older version are to be promoted to Stable immediately. + +### Release Artifacts: + +Artifacts follow the name `preview-{browser}-{version}.zip`, e.g. `preview-chrome-1.0.4.zip`, `preview-edge-2.0.0.12.zip`, `preview-firefox-2.1.1.zip` + +## Release + +Some of the releases from the Preview channel (that are considered stable enough) are **promoted** to the Stable channel. + +Release promotions are triggered manually (via GitHub Actions). + +### Release artifacts: + +Artifacts follow the name `{browser}-{version}.zip`, e.g. `chrome-1.0.4.zip`, `edge-2.0.0.12.zip`, `firefox-2.1.1.zip`. + +--- + +## Branching strategy + +Whenever a major version goes into maintenance mode, `v{major}.x` is branched-off main (e.g. when we work at v2, we split a `v1.x` branch from main, and then main will correspond to `v2.x`). The maintenance branch will mostly receive bug fixes and security updates. Changes to the build process must be back-ported to maintenance branches, to keep workflows consistent. + +We primarily work over the main branch. For the maintenance of previous major versions, PRs can be sent to the `v{major}.x` branch. If some commits in main need to be available on earlier major versions as well, they can be back-ported (after being merged into main) by sending a PR with the other major branch (e.g. `v1.x`) as base. + +### Pull requests + +When there's a commit that needs to be back-ported, the PR corresponding to that commit should have a needs backport label. Once back-ported, the label should be removed (or replaced with back-ported). From a44175264a8c7f945818484e37f7457cd18b78f2 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:34:44 +0300 Subject: [PATCH 02/15] Add bump manifest version action and workflow Co-authored-by: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> --- .github/actions/bump-manifest-version.cjs | 47 +++++++++++++++++++ .github/workflows/bump-manifest-version.yml | 52 +++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 .github/actions/bump-manifest-version.cjs create mode 100644 .github/workflows/bump-manifest-version.yml diff --git a/.github/actions/bump-manifest-version.cjs b/.github/actions/bump-manifest-version.cjs new file mode 100644 index 00000000..f94108fa --- /dev/null +++ b/.github/actions/bump-manifest-version.cjs @@ -0,0 +1,47 @@ +// @ts-check +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable no-console */ +const fs = require("node:fs/promises"); + +/** @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments */ +module.exports = async ({ core }) => { + const manifestPath = "./src/manifest.json"; + const manifestFile = await fs.readFile(manifestPath, "utf8"); + const manifest = JSON.parse(manifestFile); + /**@type {string} */ + const existingVersion = manifest.version; + + const bumpType = /** @type {BumpType} */ (process.env.INPUT_VERSION); + if (!bumpType) { + throw new Error("Missing bump type"); + } + + const version = bumpVersion(existingVersion, bumpType).join("."); + + console.log({ existingVersion, bumpType, version }); + + manifest.version = version; + await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2)); + core.setOutput("version", version); +}; + +/** + * @typedef {'build' | 'patch' | 'minor'} BumpType + * @param {string} existingVersion + * @param {BumpType} type + * @return {[major: number, minor: number, patch: number, build: number]} + */ +function bumpVersion(existingVersion, type) { + const [major, minor, patch, build] = existingVersion.split(".").map(Number); + + switch (type) { + case "build": + return [major, minor, patch, build + 1]; + case "patch": + return [major, minor, patch + 1, 0]; + case "minor": + return [major, minor + 1, 0, 0]; + default: + throw new Error("Unknown bump type: " + type); + } +} diff --git a/.github/workflows/bump-manifest-version.yml b/.github/workflows/bump-manifest-version.yml new file mode 100644 index 00000000..1a37c045 --- /dev/null +++ b/.github/workflows/bump-manifest-version.yml @@ -0,0 +1,52 @@ +name: Bump Manifest Version + +on: + workflow_dispatch: + inputs: + version: + description: "Version to bump to" + required: true + default: "build" + type: choice + options: + - build + - patch + - minor + +permissions: + contents: write + pull-requests: write + +jobs: + bump-version: + name: Bump version + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: { node-version-file: ".nvmrc" } + + - name: Bump version + id: bump + uses: actions/github-script@v7 + env: + INPUT_VERSION: ${{ github.event.inputs.version }} + with: + script: | + const script = require('./.github/actions/bump-manifest-version.cjs') + await script({ github, context, core }) + + - name: Create pull request + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: release version ${{ steps.bump.outputs.version }}" + title: "chore: release version ${{ steps.bump.outputs.version }}" + body: | + Bump extension version to ${{ steps.bump.outputs.version }} + branch: preview/${{ steps.bump.outputs.version }} + labels: preview + From 21b8233daf3dd1292d98915bd7d828cb1056f684 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:41:14 +0300 Subject: [PATCH 03/15] Add release preview workflow Co-authored-by: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> --- .github/workflows/release-preview.yml | 57 +++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/release-preview.yml diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml new file mode 100644 index 00000000..7e9214de --- /dev/null +++ b/.github/workflows/release-preview.yml @@ -0,0 +1,57 @@ +name: Release for Preview Channel + +on: + push: + branches: + - main + - "v[0-9]+.x" + paths: + - "src/manifest.json" + +defaults: + run: + shell: bash + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + release-preview: + if: "${{ startsWith(github.event.head_commit.message, 'chore: release version') }}" + runs-on: ubuntu-latest + environment: production + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Environment setup + uses: ./.github/actions/setup + + - name: Build + run: pnpm build --channel=preview + + - name: Get built version + uses: actions/github-script@v7 + id: version + with: + script: | + const script = require('./.github/actions/get-built-version.cjs') + await script({ github, context, core }) + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: | + dist/*.zip + tag_name: v${{ steps.version.outputs.version }}-preview + name: Preview v${{ steps.version.outputs.version }} + prerelease: true + + # - name: Upload to stores + # if: github.ref_name == 'main' + # run: | + # echo 'TODO' From 95505df297b571c263c82695a2dea653e86c5cc1 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:42:35 +0300 Subject: [PATCH 04/15] Update ESLint comment Co-authored-by: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> --- .github/actions/bump-manifest-version.cjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/bump-manifest-version.cjs b/.github/actions/bump-manifest-version.cjs index f94108fa..a5db7d40 100644 --- a/.github/actions/bump-manifest-version.cjs +++ b/.github/actions/bump-manifest-version.cjs @@ -1,6 +1,5 @@ // @ts-check -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-var-requires, no-console */ const fs = require("node:fs/promises"); /** @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments */ From 8c3a6a2bf535d6684970804e6855dcb45771b8bc Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:43:07 +0300 Subject: [PATCH 05/15] Format --- .github/actions/bump-manifest-version.cjs | 42 ++++++++++----------- .github/workflows/bump-manifest-version.yml | 11 +++--- .github/workflows/release-preview.yml | 4 +- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/.github/actions/bump-manifest-version.cjs b/.github/actions/bump-manifest-version.cjs index a5db7d40..21ceef30 100644 --- a/.github/actions/bump-manifest-version.cjs +++ b/.github/actions/bump-manifest-version.cjs @@ -1,28 +1,28 @@ // @ts-check /* eslint-disable @typescript-eslint/no-var-requires, no-console */ -const fs = require("node:fs/promises"); +const fs = require('node:fs/promises') /** @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments */ module.exports = async ({ core }) => { - const manifestPath = "./src/manifest.json"; - const manifestFile = await fs.readFile(manifestPath, "utf8"); - const manifest = JSON.parse(manifestFile); + const manifestPath = './src/manifest.json' + const manifestFile = await fs.readFile(manifestPath, 'utf8') + const manifest = JSON.parse(manifestFile) /**@type {string} */ - const existingVersion = manifest.version; + const existingVersion = manifest.version - const bumpType = /** @type {BumpType} */ (process.env.INPUT_VERSION); + const bumpType = /** @type {BumpType} */ (process.env.INPUT_VERSION) if (!bumpType) { - throw new Error("Missing bump type"); + throw new Error('Missing bump type') } - const version = bumpVersion(existingVersion, bumpType).join("."); + const version = bumpVersion(existingVersion, bumpType).join('.') - console.log({ existingVersion, bumpType, version }); + console.log({ existingVersion, bumpType, version }) - manifest.version = version; - await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2)); - core.setOutput("version", version); -}; + manifest.version = version + await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2)) + core.setOutput('version', version) +} /** * @typedef {'build' | 'patch' | 'minor'} BumpType @@ -31,16 +31,16 @@ module.exports = async ({ core }) => { * @return {[major: number, minor: number, patch: number, build: number]} */ function bumpVersion(existingVersion, type) { - const [major, minor, patch, build] = existingVersion.split(".").map(Number); + const [major, minor, patch, build] = existingVersion.split('.').map(Number) switch (type) { - case "build": - return [major, minor, patch, build + 1]; - case "patch": - return [major, minor, patch + 1, 0]; - case "minor": - return [major, minor + 1, 0, 0]; + case 'build': + return [major, minor, patch, build + 1] + case 'patch': + return [major, minor, patch + 1, 0] + case 'minor': + return [major, minor + 1, 0, 0] default: - throw new Error("Unknown bump type: " + type); + throw new Error('Unknown bump type: ' + type) } } diff --git a/.github/workflows/bump-manifest-version.yml b/.github/workflows/bump-manifest-version.yml index 1a37c045..77b1c9a2 100644 --- a/.github/workflows/bump-manifest-version.yml +++ b/.github/workflows/bump-manifest-version.yml @@ -4,9 +4,9 @@ on: workflow_dispatch: inputs: version: - description: "Version to bump to" + description: 'Version to bump to' required: true - default: "build" + default: 'build' type: choice options: - build @@ -27,7 +27,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v4 - with: { node-version-file: ".nvmrc" } + with: { node-version-file: '.nvmrc' } - name: Bump version id: bump @@ -43,10 +43,9 @@ jobs: uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "chore: release version ${{ steps.bump.outputs.version }}" - title: "chore: release version ${{ steps.bump.outputs.version }}" + commit-message: 'chore: release version ${{ steps.bump.outputs.version }}' + title: 'chore: release version ${{ steps.bump.outputs.version }}' body: | Bump extension version to ${{ steps.bump.outputs.version }} branch: preview/${{ steps.bump.outputs.version }} labels: preview - diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml index 7e9214de..596d5d7a 100644 --- a/.github/workflows/release-preview.yml +++ b/.github/workflows/release-preview.yml @@ -4,9 +4,9 @@ on: push: branches: - main - - "v[0-9]+.x" + - 'v[0-9]+.x' paths: - - "src/manifest.json" + - 'src/manifest.json' defaults: run: From 45257e0206595c8643418445733fe1f39f7ba824 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:46:45 +0300 Subject: [PATCH 06/15] Update .github/actions/bump-manifest-version.cjs Co-authored-by: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> --- .github/actions/bump-manifest-version.cjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/bump-manifest-version.cjs b/.github/actions/bump-manifest-version.cjs index 21ceef30..554543c7 100644 --- a/.github/actions/bump-manifest-version.cjs +++ b/.github/actions/bump-manifest-version.cjs @@ -31,7 +31,11 @@ module.exports = async ({ core }) => { * @return {[major: number, minor: number, patch: number, build: number]} */ function bumpVersion(existingVersion, type) { - const [major, minor, patch, build] = existingVersion.split('.').map(Number) + const parts = existingVersion.split('.').map(Number) + if (parts.length !== 4 || parts.some(e => !Number.isSafeInteger(e))) { + throw new Error("Existing version does not have right format") + } + const [major, minor, patch, build] = parts switch (type) { case 'build': From b56de1b8dc1ffe0246cde2bbe734f1b2c4e4d774 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Tue, 20 Aug 2024 13:47:09 +0300 Subject: [PATCH 07/15] Format --- .github/actions/bump-manifest-version.cjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/bump-manifest-version.cjs b/.github/actions/bump-manifest-version.cjs index 554543c7..622c6fbf 100644 --- a/.github/actions/bump-manifest-version.cjs +++ b/.github/actions/bump-manifest-version.cjs @@ -32,8 +32,8 @@ module.exports = async ({ core }) => { */ function bumpVersion(existingVersion, type) { const parts = existingVersion.split('.').map(Number) - if (parts.length !== 4 || parts.some(e => !Number.isSafeInteger(e))) { - throw new Error("Existing version does not have right format") + if (parts.length !== 4 || parts.some((e) => !Number.isSafeInteger(e))) { + throw new Error('Existing version does not have right format') } const [major, minor, patch, build] = parts From cb439742035d694d1d1da38f94f5a43e63409571 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:15:42 +0530 Subject: [PATCH 08/15] add release-stable workflow Co-authored-by: Radu-Cristian Popa --- .github/actions/validate-stable-release.cjs | 36 +++++++++++ .github/workflows/release-preview.yml | 2 +- .github/workflows/release-stable.yml | 69 +++++++++++++++++++++ tsconfig.json | 1 + 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 .github/actions/validate-stable-release.cjs create mode 100644 .github/workflows/release-stable.yml diff --git a/.github/actions/validate-stable-release.cjs b/.github/actions/validate-stable-release.cjs new file mode 100644 index 00000000..d5a3a422 --- /dev/null +++ b/.github/actions/validate-stable-release.cjs @@ -0,0 +1,36 @@ +// @ts-check + +/** + * 1. Validate input version. + * 2. Check if given tag/release is already promoted to stable. If so, crash. + * @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments + */ +module.exports = async ({ github, context }) => { + const { owner, repo } = context.repo + const previewVersionTag = process.env.INPUT_VERSION + if (!previewVersionTag) { + throw new Error('Missing env.INPUT_VERSION') + } + if (!previewVersionTag.match(/^v[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+-preview$/)) { + throw new Error('Input "version" must match vX.X.X.X-preview') + } + + const versionTag = previewVersionTag.replace('-preview', '') + try { + await github.rest.repos.getReleaseByTag({ + owner, + repo, + tag: versionTag + }) + throw new Error('Release already promoted to stable') + } catch (error) { + if (!error.status) { + throw error + } + if (error.status === 404) { + // do nothing + } else { + throw new Error(`Failed to check: HTTP ${error.status}`, { cause: error }) + } + } +} diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml index 596d5d7a..c5665c21 100644 --- a/.github/workflows/release-preview.yml +++ b/.github/workflows/release-preview.yml @@ -23,7 +23,7 @@ jobs: release-preview: if: "${{ startsWith(github.event.head_commit.message, 'chore: release version') }}" runs-on: ubuntu-latest - environment: production + # environment: production steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml new file mode 100644 index 00000000..64816dc0 --- /dev/null +++ b/.github/workflows/release-stable.yml @@ -0,0 +1,69 @@ +name: Release Stable Version +run-name: Release Stable ${{ github.event.inputs.version }} + +on: + workflow_dispatch: + inputs: + version: + description: 'Tag (vX.X.X.X-preview)' + required: true + type: string + +defaults: + run: + shell: bash + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + release-stable: + runs-on: ubuntu-latest + # environment: production + name: Release + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + # We want to build extension using the code and dependencies as of + # this tag. The scripts, workflows are back-ported, so they can be + # used consistently. + ref: ${{ github.event.inputs.version }} + + - name: Environment setup + uses: ./.github/actions/setup + + - name: Validate input + uses: actions/github-script@v7 + env: + INPUT_VERSION: ${{ github.event.inputs.version }} + with: + script: | + const script = require('./.github/actions/validate-stable-release.cjs') + await script({ github, context, core }) + + - name: Build + run: pnpm build --channel=release + + - name: Get built version + uses: actions/github-script@v7 + id: version + with: + script: | + const script = require('./.github/actions/get-built-version.cjs') + await script({ github, context, core }) + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: | + dist/*.zip + tag_name: v${{ steps.version.outputs.version }} + name: v${{ steps.version.outputs.version }} + prerelease: false + fail_on_unmatched_files: true diff --git a/tsconfig.json b/tsconfig.json index 220b0cb4..bcc0319d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,7 @@ "./jest.config.ts", "./jest.setup.ts", "./scripts/**/*", + "./.github/actions/*.cjs", "esbuild/**/*" ], "exclude": ["dist", "dev"] From f69bcc27f9286c31785cb09257a9f72c6921b45c Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:46:05 +0530 Subject: [PATCH 09/15] move into docs --- RELEASE.md => docs/RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename RELEASE.md => docs/RELEASE.md (99%) diff --git a/RELEASE.md b/docs/RELEASE.md similarity index 99% rename from RELEASE.md rename to docs/RELEASE.md index 0a22b108..16856021 100644 --- a/RELEASE.md +++ b/docs/RELEASE.md @@ -80,6 +80,6 @@ Whenever a major version goes into maintenance mode, `v{major}.x` is branched-of We primarily work over the main branch. For the maintenance of previous major versions, PRs can be sent to the `v{major}.x` branch. If some commits in main need to be available on earlier major versions as well, they can be back-ported (after being merged into main) by sending a PR with the other major branch (e.g. `v1.x`) as base. -### Pull requests +## Pull requests When there's a commit that needs to be back-ported, the PR corresponding to that commit should have a needs backport label. Once back-ported, the label should be removed (or replaced with back-ported). From 543b8ddc42f3f0834a08f6bcdb12bcaf5e109428 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:25:52 +0530 Subject: [PATCH 10/15] add release workflow doc; make workflows idempotent Co-authored-by: Radu-Cristian Popa --- .github/actions/validate-stable-release.cjs | 4 +++ .github/workflows/release-preview.yml | 6 +++++ .github/workflows/release-stable.yml | 14 +++++++++-- docs/RELEASE.md | 27 +++++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/.github/actions/validate-stable-release.cjs b/.github/actions/validate-stable-release.cjs index d5a3a422..d3f3ebd0 100644 --- a/.github/actions/validate-stable-release.cjs +++ b/.github/actions/validate-stable-release.cjs @@ -6,6 +6,10 @@ * @param {import('github-script').AsyncFunctionArguments} AsyncFunctionArguments */ module.exports = async ({ github, context }) => { + if (context.ref !== 'refs/heads/main') { + throw new Error('This action only works on main branch') + } + const { owner, repo } = context.repo const previewVersionTag = process.env.INPUT_VERSION if (!previewVersionTag) { diff --git a/.github/workflows/release-preview.yml b/.github/workflows/release-preview.yml index c5665c21..45d5a1c5 100644 --- a/.github/workflows/release-preview.yml +++ b/.github/workflows/release-preview.yml @@ -42,6 +42,12 @@ jobs: const script = require('./.github/actions/get-built-version.cjs') await script({ github, context, core }) + - name: Delete existing release # To keep the workflow idempotent. + run: gh release delete v${{ steps.version.outputs.version }}-preview --cleanup-tag --yes + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + - name: Release uses: softprops/action-gh-release@v2 with: diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index 64816dc0..2bdc6e80 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -1,4 +1,4 @@ -name: Release Stable Version +name: Release Stable run-name: Release Stable ${{ github.event.inputs.version }} on: @@ -38,7 +38,7 @@ jobs: - name: Environment setup uses: ./.github/actions/setup - - name: Validate input + - name: Validate stable release uses: actions/github-script@v7 env: INPUT_VERSION: ${{ github.event.inputs.version }} @@ -58,6 +58,12 @@ jobs: const script = require('./.github/actions/get-built-version.cjs') await script({ github, context, core }) + - name: Delete existing release # To keep the workflow idempotent. + run: gh release delete v${{ steps.version.outputs.version }} --cleanup-tag --yes + continue-on-error: true + env: + GH_TOKEN: ${{ github.token }} + - name: Release uses: softprops/action-gh-release@v2 with: @@ -67,3 +73,7 @@ jobs: name: v${{ steps.version.outputs.version }} prerelease: false fail_on_unmatched_files: true + + # - name: Upload to stores + # run: | + # echo 'TODO' diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 16856021..9c4c096e 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -83,3 +83,30 @@ We primarily work over the main branch. For the maintenance of previous major ve ## Pull requests When there's a commit that needs to be back-ported, the PR corresponding to that commit should have a needs backport label. Once back-ported, the label should be removed (or replaced with back-ported). + +--- + +# Release Workflow + +## Releasing to Preview channel + +1. Visit ["Bump Manifest Version" manual dispatch workflow](https://github.com/interledger/web-monetization-extension/actions/workflows/bump-manifest-version.yml) and click the "Run workflow" button. + - Choose the version bump - build, patch, or minor as described above. + - For branch, choose `main` (default) if releasing for the latest major version. Otherwise, select the required `v{major}.x` branch. + - When releasing for a `v{major}.x` branch: + - The extension will not be uploaded to the extension web stores' Preview channel. + - As the extension won't be available on the web store's Preview channel, the [GitHub Release](https://github.com/interledger/web-monetization-extension/releases/) can be shared if testing is required before the promotion to the Stable channel. +1. Validate and approve PR sent from workflow. + - Do not update the PR/commit title. + - Squash and merge the PR. +1. Extension will be released automatically (via ["Release for Preview Channel" workflow](https://github.com/interledger/web-monetization-extension/actions/workflows/release-preview.yml)) as the PR is merged. + - If there's a temporary failure in the action run, re-run the workflow. + +## Releasing to Stable channel + +To promote a Preview channel release to Stable: + +1. Run the ["Release Stable" manual-dispatch workflow](https://github.com/interledger/web-monetization-extension/actions/workflows/release-stable.yml). + - Specify the Preview version tag that should be promoted to Stable, e.g. `v1.2.3.5-preview`. + - Do not change the branch from "main". +1. Extension will be released on as the workflow runs. From db7d872a1a79fe8bd9e5edab8b95472105625f39 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:35:15 +0530 Subject: [PATCH 11/15] markdown formatting Co-authored-by: Radu-Cristian Popa --- docs/RELEASE.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 9c4c096e..ce1e3160 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -9,13 +9,13 @@ A separate Nightly release channel will be available via GitHub releases (withou ## Extension versioning -Web extensions do not follow SEMVER. The version string consists of 1 to 4 numbers separated by dots, for example, 1.2.3.4 (major.minor.patch.build). This is essentially SEMVER but with an additional build number, but does not support the alpha, beta or other suffixes. +Web extensions do not follow SEMVER. The version string consists of 1 to 4 numbers separated by dots, for example, `1.2.3.4` (`major.minor.patch.build`). This is essentially SEMVER but with an additional build number, but does not support the alpha, beta or other suffixes. ### Major version bump -A major version bump (2.0.0.0) signifies the start of a block of product features. +A major version bump (`2.0.0.0`) signifies the start of a block of product features. -Before the extension is available first on the Stable channel, we only increase the build number (2.0.0.x) when publishing to the Preview channel. After that, we follow SEMVER (2.x.y). +Before the extension is available first on the Stable channel, we only increase the build number (`2.0.0.x`) when publishing to the Preview channel. After that, we follow SEMVER (`2.x.y`). ### Minor version bump @@ -27,24 +27,25 @@ Bug fixes, performance and small updates will be released under a patch version ### Build version bump -The build version bump should only happen when starting the work on a new major version. Once a major version (e.g. v1) goes into maintenance mode, the extension major version is bumped to 2.0.0.0. Until the new major version is made available on the Stable channel, only build number should be incremented. +The build version bump should only happen when starting the work on a new major version. Once a major version (e.g. `v1`) goes into maintenance mode, the extension major version is bumped to `2.0.0.0`. Until the new major version is made available on the Stable channel, only build number should be incremented. -Multiple "build" version bumps can be made available in the Preview channel. e.g. we can have 2.0.0.1, 2.0.0.2, ..., 2.0.0.90 in the Preview channel before we make it available in the Stable channel. +Multiple "build" version bumps can be made available in the Preview channel. e.g. we can have `2.0.0.1`, `2.0.0.2`, ..., `2.0.0.90` in the Preview channel before we make it available in the Stable channel. -Note: When the new major version is going to be available in the Stable channel, it will have the last published version as in the Preview channel (i.e. the first Stable channel build could be 2.0.0.90, not necessarily 2.0.0 or 2.0.1). +> [!Note] +> When the new major version is going to be available in the Stable channel, it will have the last published version as in the Preview channel (i.e. the first Stable channel build could be `2.0.0.90`, not necessarily `2.0.0` or `2.0.1`). ## Nightly -The Nightly version will be built every day at 12AM UTC and it will be added to GitHub releases with the tag nightly. +The Nightly version will be built every day (except Sundays) at 12AM UTC and it will be added to GitHub releases with the tag `nightly`. -Nightly releases will correspond to the latest commit in the main branch of the repository at the time of the build. The tag reference will get updated on every release (rolling tags). Whenever a new release is happening, the previous one gets deleted first. +Nightly releases will correspond to the latest commit in the `main` branch of the repository at the time of the build. The tag reference will get updated on every release (rolling tags). Whenever a new release is happening, the previous one gets deleted first. ### Versioning for the Nightly build On every action run, the workflow will update the following properties in the manifest: - `version`: will be set to the current date in `YYYY.M.D` format (note: not `YYYY.MM.DD` as we cannot have zero as prefix in these numbers) -- `version_name`: will be set to `Nightly YYYY.M.D ({short_commit_hash})` +- `version_name`: will be set to `Nightly YYYY.M.D` ### Release Artifacts: @@ -52,7 +53,7 @@ Artifacts follow the name: `nightly-{browser}-{version}.zip`, e.g. `nightly-chro ## Preview -The Preview version represents a release candidate on the main branch. They are less stable than the Stable version. +The Preview version represents a release candidate on the `main` branch. They are less stable than the Stable version. Releases are triggered manually (via GitHub Actions), and can have a minor/patch/build version bump. @@ -76,13 +77,13 @@ Artifacts follow the name `{browser}-{version}.zip`, e.g. `chrome-1.0.4.zip`, `e ## Branching strategy -Whenever a major version goes into maintenance mode, `v{major}.x` is branched-off main (e.g. when we work at v2, we split a `v1.x` branch from main, and then main will correspond to `v2.x`). The maintenance branch will mostly receive bug fixes and security updates. Changes to the build process must be back-ported to maintenance branches, to keep workflows consistent. +Whenever a major version goes into maintenance mode, `v{major}.x` is branched-off `main` (e.g. when we work at `v2`, we split a `v1.x` branch from `main`, and then `main` will correspond to `v2.x`). The maintenance branch will mostly receive bug fixes and security updates. Changes to the build process must be back-ported to maintenance branches, to keep workflows consistent. -We primarily work over the main branch. For the maintenance of previous major versions, PRs can be sent to the `v{major}.x` branch. If some commits in main need to be available on earlier major versions as well, they can be back-ported (after being merged into main) by sending a PR with the other major branch (e.g. `v1.x`) as base. +We primarily work over the `main` branch. For the maintenance of previous major versions, PRs can be sent to the `v{major}.x` branch. If some commits from the `main` branch need to be available on an earlier major version as well, they can be back-ported (after being merged into `main`) by sending a PR with the other major branch (e.g. `v1.x`) as base. ## Pull requests -When there's a commit that needs to be back-ported, the PR corresponding to that commit should have a needs backport label. Once back-ported, the label should be removed (or replaced with back-ported). +When there's a commit that needs to be back-ported, the PR corresponding to that commit should have a "needs backport" label. Once back-ported, the label should be removed (or replaced with "backported"). --- From 8ba78fa1563fc13b69f7151523bbd844be37dcc3 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Wed, 21 Aug 2024 11:09:51 +0300 Subject: [PATCH 12/15] markdown format --- docs/RELEASE.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index ce1e3160..4984eb89 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -31,8 +31,7 @@ The build version bump should only happen when starting the work on a new major Multiple "build" version bumps can be made available in the Preview channel. e.g. we can have `2.0.0.1`, `2.0.0.2`, ..., `2.0.0.90` in the Preview channel before we make it available in the Stable channel. -> [!Note] -> When the new major version is going to be available in the Stable channel, it will have the last published version as in the Preview channel (i.e. the first Stable channel build could be `2.0.0.90`, not necessarily `2.0.0` or `2.0.1`). +When the new major version is going to be available in the Stable channel, it will have the last published version as in the Preview channel (i.e. the first Stable channel build could be `2.0.0.90`, not necessarily `2.0.0` or `2.0.1`). ## Nightly @@ -47,7 +46,7 @@ On every action run, the workflow will update the following properties in the ma - `version`: will be set to the current date in `YYYY.M.D` format (note: not `YYYY.MM.DD` as we cannot have zero as prefix in these numbers) - `version_name`: will be set to `Nightly YYYY.M.D` -### Release Artifacts: +### Release artifacts Artifacts follow the name: `nightly-{browser}-{version}.zip`, e.g. `nightly-chrome-2024.7.13.zip`, `nightly-edge-2024.7.13.zip`, `nightly-firefox-2024.7.13.zip` @@ -59,7 +58,7 @@ Releases are triggered manually (via GitHub Actions), and can have a minor/patch Once a new development stage starts for a new major version and we start publishing it to the Preview channel, we will not be able to push an older version to the Preview channel - they will only be available in GitHub. But the releases for the older version are to be promoted to Stable immediately. -### Release Artifacts: +### Release artifacts Artifacts follow the name `preview-{browser}-{version}.zip`, e.g. `preview-chrome-1.0.4.zip`, `preview-edge-2.0.0.12.zip`, `preview-firefox-2.1.1.zip` @@ -69,7 +68,7 @@ Some of the releases from the Preview channel (that are considered stable enough Release promotions are triggered manually (via GitHub Actions). -### Release artifacts: +### Release artifacts Artifacts follow the name `{browser}-{version}.zip`, e.g. `chrome-1.0.4.zip`, `edge-2.0.0.12.zip`, `firefox-2.1.1.zip`. From 90f1aa3458ea28f7cb843612a5c363c1d12962b5 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Wed, 21 Aug 2024 11:12:00 +0300 Subject: [PATCH 13/15] update cspell dictionary --- cspell-dictionary.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell-dictionary.txt b/cspell-dictionary.txt index 4a243c63..a891859c 100644 --- a/cspell-dictionary.txt +++ b/cspell-dictionary.txt @@ -24,6 +24,7 @@ linkcode endregion metafile iife +backported # packages and 3rd party tools/libraries awilix From 481f2ae1cf6625805e62e22589ff751a8575b7b2 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Wed, 21 Aug 2024 11:36:41 +0300 Subject: [PATCH 14/15] Fix SEMVER usage in release doc --- docs/RELEASE.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 4984eb89..a842a1a4 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -15,7 +15,8 @@ Web extensions do not follow SEMVER. The version string consists of 1 to 4 numbe A major version bump (`2.0.0.0`) signifies the start of a block of product features. -Before the extension is available first on the Stable channel, we only increase the build number (`2.0.0.x`) when publishing to the Preview channel. After that, we follow SEMVER (`2.x.y`). +Before the extension is available first on the Stable channel, we only increase the build number (`2.0.0.x`) when publishing to the Preview channel. After that (during +maintenance mode), we follow SEMVER (`2.x.y.0`). ### Minor version bump @@ -60,7 +61,7 @@ Once a new development stage starts for a new major version and we start publish ### Release artifacts -Artifacts follow the name `preview-{browser}-{version}.zip`, e.g. `preview-chrome-1.0.4.zip`, `preview-edge-2.0.0.12.zip`, `preview-firefox-2.1.1.zip` +Artifacts follow the name `preview-{browser}-{version}.zip`, e.g. `preview-chrome-1.0.4.0.zip`, `preview-edge-2.0.0.12.zip`, `preview-firefox-2.1.1.0.zip` ## Release @@ -70,7 +71,7 @@ Release promotions are triggered manually (via GitHub Actions). ### Release artifacts -Artifacts follow the name `{browser}-{version}.zip`, e.g. `chrome-1.0.4.zip`, `edge-2.0.0.12.zip`, `firefox-2.1.1.zip`. +Artifacts follow the name `{browser}-{version}.zip`, e.g. `chrome-1.0.4.0.zip`, `edge-2.0.0.12.zip`, `firefox-2.1.1.0.zip`. --- From 7a26ca260f6f39998031ebdab559c9ec0b779e97 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Wed, 21 Aug 2024 11:38:24 +0300 Subject: [PATCH 15/15] Format --- docs/RELEASE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index a842a1a4..4a05ea39 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -15,8 +15,7 @@ Web extensions do not follow SEMVER. The version string consists of 1 to 4 numbe A major version bump (`2.0.0.0`) signifies the start of a block of product features. -Before the extension is available first on the Stable channel, we only increase the build number (`2.0.0.x`) when publishing to the Preview channel. After that (during -maintenance mode), we follow SEMVER (`2.x.y.0`). +Before the extension is available first on the Stable channel, we only increase the build number (`2.0.0.x`) when publishing to the Preview channel. After that (during maintenance mode), we follow SEMVER (`2.x.y.0`). ### Minor version bump