diff --git a/.github/workflows/check-version.yml b/.github/workflows/check-version.yml new file mode 100644 index 00000000..63d40fbb --- /dev/null +++ b/.github/workflows/check-version.yml @@ -0,0 +1,36 @@ +name: Check Version + +# The version in the poms is owned by the Version Bump workflow: a changeset in +# .changeset/ decides it and the release PR carries the bump. A hand-edited +# version would be bumped on top of (7.0.0 + major -> 8.0.0) or drift from the +# released artifacts, so guard the invariant that the parent pom still carries +# the released version, i.e. the top entry of CHANGELOG.md, which the Version +# Bump workflow writes in the same release PR. + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + changelog-matches-pom: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 25 + - name: Compare the pom version with the changelog + run: | + pom_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + changelog_version=$(sed -n 's/^## \([0-9][0-9.]*\)$/\1/p' CHANGELOG.md | head -1) + echo "pom.xml: $pom_version" + echo "CHANGELOG.md: $changelog_version" + if [ -z "$changelog_version" ] || [ "$pom_version" != "$changelog_version" ]; then + echo "::error::The pom version ($pom_version) does not match the latest CHANGELOG.md entry ($changelog_version). Versions are set by the Version Bump workflow from .changeset/ files; do not edit the version in the poms by hand." + exit 1 + fi diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b4d63bbf..4f514120 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,6 +4,9 @@ on: push: branches: - main + # Rebuild the docs by hand after a Hyperbook release, when no push to main + # happened in between (see RELEASING.md). + workflow_dispatch: jobs: documentation: diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index d8eb8b6a..0423acf9 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -177,13 +177,8 @@ jobs: Compatibility artifacts and catalogs are prepared for `${{ env.VERSION }}`. Before merging, review the browser policy and synchronize `openpatch/online-ide` from this release branch: ```bash - mvn -q -DskipTests prepare-package - python3 scripts/browser-compatibility.py --online-ide /path/to/online-ide - python3 scripts/release-catalogs.py --online-ide /path/to/online-ide - python3 scripts/browser-compatibility.py --check --online-ide /path/to/online-ide - python3 scripts/parity-fixture.py --check --strict --online-ide /path/to/online-ide - python3 scripts/release-catalogs.py --check --online-ide /path/to/online-ide + scripts/sync-online-ide.sh /path/to/online-ide ``` - Run the browser compatibility tests and commit and push the browser updates before merging this PR. + The script also verifies the checkout. Commit and push the browser updates in online-ide and run its browser compatibility tests (`npm run test:browser`) before merging this PR. RELEASING.md has the full cross-repository runbook. labels: version diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..9ea6b941 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,117 @@ +# Releasing + +A release spans three repositories, in this order: + +1. **scratch-for-java** (this repo) — Maven Central + a GitHub release with the + fat jar, the NRW jar and the catalogs zip. +2. **online-ide** — the browser runtime, published as an embedded build to + `https://cdn.openpatch.org/onlineide//`. +3. **hyperbook** — pins the online-ide tag in `packages/markdown/ide-releases.json` + and is published to npm. + +The docs site (scratch4j.openpatch.org) builds with `hyperbook@latest`, so it +picks up the new IDE the next time the Documentation workflow runs. + +Steps 2 and 3 do not depend on step 1 being on Maven Central: the browser runtime +is synced from the release branch, not from Central. Do them *before* merging the +release PR, so the docs deploy that follows the merge already uses the new IDE. +(If the release PR is merged first, re-run the Documentation workflow from the +Actions tab — it has a `workflow_dispatch` trigger.) + +## 1. Prepare the changeset + +- Add `.changeset/.md` with frontmatter `type: patch|minor|major`. Only + changes that reach the user get a changeset; documentation, tests, examples, + tooling and CI changes get none. +- The version in the poms is owned by the Version Bump workflow — never edit it + by hand. The Check Version workflow fails on a pom/changelog mismatch. +- Never `mvn install` on a release branch: the poms still carry the released + version, and an install would overwrite it in `~/.m2` for every other project + on the machine (Studio). Build inside the reactor (`mvn package -pl -am`). + +## 2. Merge to main + +Push or merge to `main` with the changeset. The Version Bump workflow bumps every +module in lockstep, regenerates the compatibility artifacts and catalogs +(`compatibility/browser-policy.json` included), and opens the "Release vX.Y.Z" PR. + +## 3. Synchronize online-ide + +From the release branch: + +```bash +scripts/sync-online-ide.sh /path/to/online-ide +``` + +The script runs `mvn -DskipTests prepare-package`, writes the compatibility +contract, the catalogs, the probes and the assets into the online-ide checkout, +and then verifies with `--check` that everything is current. Commit and push the +changes in online-ide, then run its tests: + +```bash +cd /path/to/online-ide +npm ci +npm run test:ci +npm run browser:install -- --with-deps +npm run test:browser +``` + +CI re-runs these checks on every push to `main` and in the release PR's +validation, so a stale online-ide checkout fails the release. + +## 4. Release online-ide + +The embedded build publishes itself when a GitHub release is created. Tag `main` +with the package version and the next `-hyperbook.` number, then create +the release: + +```bash +cd /path/to/online-ide +version=$(node -p "require('./package.json').version") +build=$(( $(git ls-remote --tags origin 'v*-hyperbook.*' | grep -o 'hyperbook\.[0-9]*' | sort -t. -k2 -n | tail -1 | cut -d. -f2) + 1 )) +tag="v$version-hyperbook.$build" +git tag "$tag" && git push origin "$tag" +gh release create "$tag" --notes "Embedded build for Hyperbook: " +``` + +The Release Embedded Build workflow builds `dist-embedded.zip`, attaches it to +the release, and publishes it to `https://cdn.openpatch.org/onlineide/$tag/` +(see online-ide's `docs/cdn-releases.md`). The playground deploys itself on push +to `main`. + +## 5. Point hyperbook at the new build + +In the hyperbook repo: + +1. `packages/markdown/ide-releases.json`: set `"onlineide"` to the new tag. The + tests read the pin from this file, so there is no second place to update. +2. Add `.changeset/online-ide-build-.md`: + + ```md + --- + "@hyperbook/markdown": patch + "hyperbook": patch + --- + + Update the Online IDE runtime to build : . + ``` + +3. Push to `main`; the changesets workflow opens the Version Packages PR. Merge + it to publish to npm. + +## 6. Merge the release PR + +Merge "Release vX.Y.Z" on this repo. The Release workflow deploys to Maven +Central, builds the fat jar, the NRW jar and the catalogs zip, and creates the +GitHub release. The same push runs the Documentation workflow, which builds the +docs with the newest Hyperbook and deploys them to GitHub Pages — consistent +with the new IDE if steps 4–5 are done. Otherwise re-run it from the Actions tab. + +## Afterwards + +- Verify scratch4j.openpatch.org: an interactive example compiles and runs + against the new runtime. +- The browser policy (`compatibility/browser-policy.json`) was regenerated by + the Version Bump workflow; review it in the release PR. +- `online-ide-nrw` is a separate fork. If the NRW IDE should follow a release, + sync it the same way (step 3) and release it separately. diff --git a/scripts/sync-online-ide.sh b/scripts/sync-online-ide.sh new file mode 100755 index 00000000..9f6f098e --- /dev/null +++ b/scripts/sync-online-ide.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# Synchronizes the browser compatibility artifacts and the release catalogs into an +# online-ide checkout, then verifies that the checkout is current. Run it from the +# release branch (see RELEASING.md); the Version Bump PR asks for it. +# +# ./scripts/sync-online-ide.sh use the sibling ../online-ide checkout +# ./scripts/sync-online-ide.sh /path/to/ide use an explicit checkout +# +# Commit and push the changes in the online-ide checkout afterwards; running its +# browser tests (npm run test:browser) is the remaining manual step. +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +online_ide="${1:-$root/../online-ide}" + +if [ ! -f "$online_ide/package.json" ]; then + echo "sync-online-ide: no online-ide checkout at $online_ide" >&2 + echo "usage: scripts/sync-online-ide.sh [path-to-online-ide]" >&2 + exit 1 +fi + +cd "$root" +mvn -q -DskipTests prepare-package +python3 scripts/browser-compatibility.py --online-ide "$online_ide" +python3 scripts/release-catalogs.py --online-ide "$online_ide" +python3 scripts/browser-compatibility.py --check --online-ide "$online_ide" +python3 scripts/parity-fixture.py --check --strict --online-ide "$online_ide" +python3 scripts/release-catalogs.py --check --online-ide "$online_ide" + +echo "sync-online-ide: $online_ide is synchronized; commit and push the changes there."