test: harden release and browser gates

This commit is contained in:
KoalaDev
2026-08-21 15:49:51 +02:00
parent 230e7f5932
commit 7286a6db3d
32 changed files with 1150 additions and 201 deletions
+11 -5
View File
@@ -118,17 +118,23 @@ Before starting any task, committing, or pushing, you **MUST** run `git pull --r
> [!CAUTION]
> **AI AGENTS MUST FOLLOW THIS EXACT SEQUENCE WHEN RELEASING A NEW VERSION OR TAGGING.**
>
> **🚫 NO MANUAL VERSION BUMPING**: You MUST **NEVER** manually modify the version strings in `package.json`, `extension/manifest.base.json`, or `website/version.json`. The GitHub Actions CI pipeline automatically extracts the version from the git tag (e.g. `v2.0.5` -> `2.0.5`), injects it into all target files, and commits the updates back to `main` with `[skip ci]`. Manual bumps will cause merge conflicts and build failures.
> **🚫 NO INDEPENDENT VERSION EDITS**: Run `npm run prepare:release -- MAJOR.MINOR.PATCH` on a release-preparation branch. Never edit only one version source, and never expect the tag workflow to modify `main`.
> - **Website Versioning**: **NEVER** manually modify generated version strings in `website/www/`. The website build injects version data from `website/version.json` into generated output.
1. **MANDATORY SYNTAX & LINT CHECKS**: Before staging, committing, or pushing any changes, you **MUST** run both checks on every modified JavaScript file:
- **Syntax Validation**: Run `node -c` on every single modified JavaScript file (e.g., `node -c extension/background.js` and `node -c extension/content.js`). **NEVER** commit or push code that fails this check.
- **ESLint Validation**: Run `npm run lint` (or `npx eslint .`). The output must show **zero errors and zero warnings**. ESLint is configured to catch undefined variables, unused vars, unreachable code, and other semantic issues. **NEVER** commit or push code that fails this check.
2. Commit all verified code changes and push to `main`.
3. Create and push a new tag. **MANDATORY**: Tags MUST start with a `v` (e.g., `v1.4.0`). The GitHub Actions release workflow is strictly configured to ignore any tags without the `v` prefix.
2. Commit the prepared version and release-note changes on a branch, push it,
open a pull request, and wait for required `verify`, `node20`, and `e2e`
checks. Direct pushes to `main` are not part of the release process.
3. After the PR is merged, update local `main` and create an annotated exact
SemVer tag (`git tag -a v1.4.0 -m "Release v1.4.0"`) on the same commit as
`origin/main`.
- **🚫 TAG IMMUTABILITY**: Once a tag is pushed to `origin`, it is **PERMANENT**. You MUST **NEVER** reuse, move, or force-push an existing tag — not even to "fix" a mistake. If a release is missing a fix, increment the version and create a **new** tag (e.g., `v1.7.0``v1.7.1`). Tags are immutable identifiers; moving them breaks CI pipelines, corrupts the release history, and causes unreproducible builds.
- **🚫 WHEN NOT TO TAG**: Do NOT create a release tag for changes that do NOT affect the shipped extension or server artifacts. Website text changes, documentation updates (`.md` files), and landing page content do NOT require a version tag. Tags trigger the full CI pipeline (Docker build, extension packaging, GitHub Release) — running this for a typo fix wastes CI resources and creates meaningless releases. Only tag when extension code (`extension/`), server code (`server/`), or shared protocol constants (`shared/`) have changed.
4. The CI will extract the version from the tag (e.g., `v1.4.0``1.4.0`), inject it into all source files, build the extension artifacts, publish the Docker image, and create a GitHub Release.
5. Verify the release builds on GitHub Actions.
4. The release workflow validates the unchanged tagged source, creates a draft
release, publishes and verifies the relay image, and makes the release public
only after every gate succeeds.
5. Verify GitHub assets, attestations, GHCR platforms/digest, and health smoke.
### 🚫 Force Push Policy
> [!CAUTION]
+4 -1
View File
@@ -35,7 +35,10 @@ The build script performs the following actions:
The system enforces a strict `protocolVersion` check during the `JOIN_ROOM` handshake.
- The version is defined in `shared/constants.js`.
- If the extension and server versions mismatch, the server will reject the connection with an `Incompatible protocol version` error.
- **Never manually bump version numbers**. The CI pipeline automatically injects the version from the git tag into `manifest.base.json`, `shared/constants.js`, and `package.json` during release builds. Run the build script to synchronize other constant updates.
- Never edit release versions independently. Run
`npm run prepare:release -- MAJOR.MINOR.PATCH` on a release-preparation branch;
the release tag is accepted only after that change reaches `main` with all CI
checks passing.
> [!CAUTION]
> **NEVER** edit the files inside `extension/shared/` directly. They will be overwritten the next time the build script is run. Always edit the files in the root `shared/` directory and then run the build script.
+36 -23
View File
@@ -4,30 +4,32 @@ This document describes the deployment and release process for KoalaSync.
## Tag-Based Releases
KoalaSync uses a fully automated release pipeline triggered by Git tags.
KoalaSync uses a gated release pipeline triggered by immutable Git tags.
> [!IMPORTANT]
> **DO NOT** manually bump the version numbers in any files (such as `package.json`, `manifest.base.json`, `shared/constants.js`, etc.) before creating a release.
> Bumping versions manually is redundant, leads to conflicts, and is completely handled by the CI/CD pipeline.
> **DO NOT** edit individual version files or tag an unmerged branch. Run
> `npm run prepare:release -- MAJOR.MINOR.PATCH` on a branch, review all generated
> source changes, and merge them through a pull request with successful CI.
### How it Works
When you push a Git tag matching `v*` (e.g., `v2.5.1`), the GitHub Actions release workflow (`.github/workflows/release.yml`) is triggered. The workflow performs the following actions:
When an annotated tag matching exact `vMAJOR.MINOR.PATCH` is pushed, the GitHub
Actions workflow performs these ordered gates:
1. **Extracts the version** from the tag (e.g., `2.5.1` from `v2.5.1`).
2. **Injects the version** automatically into the following files:
- `extension/manifest.base.json`
- `shared/constants.js` (updates `APP_VERSION`)
- `package.json`
- `package-lock.json` (root package metadata)
- `website/version.json`
- `website/template.html` (updates `softwareVersion` schema)
- `README.md` (updates badge and announcement banner)
- `website/sitemap.xml` (updates `lastmod` dates)
3. **Commits and pushes** these version updates back to the `main` branch automatically with the commit message `chore(release): update versions to vX.X.X [skip ci]`.
4. **Builds the extension** for both Chrome and Firefox and publishes the zipped archives with a `SHA256SUMS` checksum file and signed provenance attestations.
5. **Builds the website** and uploads website artifacts.
6. **Builds and publishes** the Docker image for the relay server to the GitHub Container Registry (`ghcr.io`).
1. Confirms that the tag is annotated, points exactly at current `origin/main`,
and matches every committed version source.
2. Requires successful `verify`, `node20`, and `e2e` checks for that commit.
3. Re-runs release verification, cross-browser E2E, and an unpublished relay
container smoke test.
4. Builds and locally validates Chrome/Firefox archives, checksums, AMO output,
website output, archive parity, and manifests.
5. Creates an attested **draft** GitHub Release.
6. Publishes the multi-architecture relay image, verifies both platforms,
attestation identity, digest, tag source, and a running health check.
7. Makes the GitHub Release public only after every preceding gate succeeds.
The release workflow never writes to `main` and never derives shell code from a
tag. Version changes must pass normal branch protection first.
---
@@ -35,18 +37,29 @@ When you push a Git tag matching `v*` (e.g., `v2.5.1`), the GitHub Actions relea
To release a new version (e.g., `v2.5.1`), follow these steps:
1. Make sure your local repository is synced on `main`:
1. Create a release-preparation branch from current `main` and update every
version source atomically:
```bash
git checkout main
git pull origin main
git checkout -b release/v2.5.1
npm run prepare:release -- 2.5.1
npm run verify
```
2. Create a local Git tag:
2. Commit the release notes and prepared version changes, open a pull request,
and wait for required `verify`, `node20`, and `e2e` checks.
3. After the PR is merged, fast-forward local `main` and create an **annotated**
tag on that exact commit:
```bash
git tag v2.5.1
git checkout main
git pull --ff-only origin main
git tag -a v2.5.1 -m "Release v2.5.1"
```
3. Push the tag to GitHub:
4. Verify the tag target, then push it once:
```bash
test "$(git rev-parse v2.5.1^{commit})" = "$(git rev-parse origin/main)"
git push origin v2.5.1
```
The release pipeline will take care of the rest! You can monitor the progress under the **Actions** tab of the GitHub repository.
Never reuse or move a published tag. Monitor every release job and verify both
the public GitHub assets and GHCR digest before calling the release complete.