From 53407f090d16600836a77dbad989f0f3e5044d57 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 9 Jun 2026 09:32:25 +0100 Subject: [PATCH] docs(release): document release procedure in AGENTS.MD; remove deprecated createRelease.sh (#7920) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(release): remove deprecated bin/createRelease.sh This script has carried a "DEPRECATED since Etherpad 1.7.0 (2018-08-17), left here just for documentation" banner for years and is dead code: - It authenticates to the GitHub API with the `?access_token=` query parameter, which GitHub removed in 2021 — every API call (token check, branch merge, release publish) now fails outright. - It targets the old `ether/etherpad-lite` repo paths and calls `bin/buildForWindows.sh` / `make docs`, neither of which is how releases are built anymore. - Nothing references it (no workflow, script, or doc). The current release flow is the "Release etherpad" workflow (.github/workflows/release.yml) driving bin/release.ts, then the tag-push triggers handleRelease.yml + releaseEtherpad.yml. createRelease.sh only adds confusion, so remove it. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(agents): document the release procedure and docs publishing Add a "Releasing" section to AGENTS.MD so maintainers have a single reference for cutting a release, instead of reverse-engineering it from bin/release.ts and the workflow files. Covers: - Prerequisites: the CHANGELOG `# X.Y.Z` guard, and the requirement that all four package.json files agree (release.ts reads the current version from src/package.json) — the desync that blocked the 3.3.0 release. - The one-dispatch flow: "Release etherpad" -> bin/release.ts -> tag push, and what the vX.Y.Z tag auto-triggers (handleRelease GitHub Release, docker, snap-publish), plus the separate manual npm publish dispatch. - Documentation: the two distinct kinds of doc work — per-PR doc/ updates in behaviour-change PRs, and the automated release-time versioned-docs publish into the ether.github.com sibling repo. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- AGENTS.MD | 32 +++++++ bin/createRelease.sh | 203 ------------------------------------------- 2 files changed, 32 insertions(+), 203 deletions(-) delete mode 100755 bin/createRelease.sh diff --git a/AGENTS.MD b/AGENTS.MD index 5a5fbc4e9..c3cb1115e 100644 --- a/AGENTS.MD +++ b/AGENTS.MD @@ -211,6 +211,38 @@ pnpm run plugins ls # List installed ### Settings Configured via `settings.json`. A template is available at `settings.json.template`. Environment variables can override any setting using `"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. +## Releasing + +Releases are driven almost entirely by GitHub Actions. A maintainer dispatches **one** workflow; the version bump, tagging, GitHub Release, Docker images, and snap all cascade off the pushed tag. The npm publish is a separate manual dispatch. + +### Prerequisites (check these before dispatching) +- **A `# X.Y.Z` changelog section for the _target_ version must already be at the top of `CHANGELOG.md`.** `bin/release.ts` aborts with `No changelog record for X.Y.Z, please create changelog record` if it's missing. Write the section before dispatching. +- **All four `package.json` files must agree on the current version:** root `package.json`, `src/package.json`, `admin/package.json`, `bin/package.json`. `release.ts` reads the *current* version from **`src/package.json`** and computes the next with `semver.inc(current, type)`. If the files are out of sync (e.g. one was hand-edited), the computed target is wrong and the changelog guard fails. *(This exact desync — `src`/`bin` left at 3.3.0 while root/admin were 3.2.0 — blocked the 3.3.0 release in June 2026.)* + +### Cutting a release +1. **Actions → "Release etherpad"** → Run workflow (`workflow_dispatch`), choose `patch` / `minor` / `major`. Cadence is monthly **minors** (3.0.0 → 3.1.0 → 3.2.0 → …); use `major` only for breaking changes. +2. The **Prepare release** step runs `bin/release.ts`, which: + - sanity-checks the tree (clean working dir, on `develop`, `develop`/`master` upstreams in sync, `../ether.github.com` cloned & clean on `master`); + - bumps the version in all four `package.json` files; + - commits `bump version`, merges `develop` → `master`, creates both `X.Y.Z` **and** `vX.Y.Z` tags, merges `master` back to `develop`; + - builds and stages the versioned docs into the website repo (see **Documentation** below). +3. The **Push after release** step (`bin/push-after-release.sh`) pushes `master`, `develop`, the tag, `--tags`, and the `ether.github.com` docs commit. +4. The pushed **`vX.Y.Z` tag auto-triggers** three workflows: + - `handleRelease.yml` → builds Etherpad, extracts the matching changelog section via `generateChangelog` (`bin/generateReleaseNotes.ts`), and publishes the **GitHub Release** (`make_latest: true`); + - `docker.yml` → builds & pushes the Docker images; + - `snap-publish.yml` → publishes the snap. +5. **npm publish is a separate manual step:** dispatch **"releaseEtherpad.yaml"** (`workflow_dispatch`), which runs `npm publish --provenance --access public` via npm **OIDC trusted publishing**. It is *not* fired by the tag. + +### Documentation + +Two distinct things, both important: + +**1. Per-PR doc updates — your responsibility in every behaviour-change PR.** +The `doc/` workspace holds the user/admin/API docs (Markdown + AsciiDoc). Whenever a PR changes API responses, CLI flags, settings keys, hooks, or error formats, update the relevant files in `doc/` **in the same PR** — don't defer it to release time. The HTTP API reference is `doc/api/http_api.{md,adoc}` (keep both in sync). Preview locally with `pnpm run makeDocs`. + +**2. Release-time versioned docs publishing — automated, no manual step.** +During a release, `release.ts` runs `pnpm run makeDocs` (→ `bin/make_docs.ts`) to render `doc/` into `out/doc/`, then copies it into the sibling website repo at `../ether.github.com/public/doc/vX.Y.Z`, bumps that repo's version, and commits `X.Y.Z docs`; `push-after-release.sh` pushes it, publishing the versioned docs on etherpad.org. This requires `ether.github.com` checked out as a **sibling directory** — the **Release etherpad** workflow checks it out automatically. If you ever run `release.ts` by hand, clone it first: `cd .. && git clone git@github.com:ether/ether.github.com.git`. + ## Monorepo Structure This project uses pnpm workspaces. The workspaces are: diff --git a/bin/createRelease.sh b/bin/createRelease.sh deleted file mode 100755 index 9777a1d8c..000000000 --- a/bin/createRelease.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/bin/bash -# -# WARNING: since Etherpad 1.7.0 (2018-08-17), this script is DEPRECATED, and -# will be removed/modified in a future version. -# It's left here just for documentation. -# The branching policies for releases have been changed. -# -# This script is used to publish a new release/version of etherpad on github -# -# Work that is done by this script: -# ETHER_REPO: -# - Add text to CHANGELOG.md -# - Replace version of etherpad in src/package.json -# - Create a release branch and push it to github -# - Merges this release branch into master branch -# - Creating the windows build and the docs -# ETHER_WEB_REPO: -# - Creating a new branch with the docs and the windows build -# - Replacing the version numbers in the index.html -# - Push this branch and merge it to master -# ETHER_REPO: -# - Create a new release on github - -printf "WARNING: since Etherpad 1.7.0 this script is DEPRECATED, and will be removed/modified in a future version.\n\n" -while true; do - read -p "Do you want to continue? This is discouraged. [y/N]" yn - case $yn in - [Yy]* ) break;; - [Nn]* ) exit;; - * ) printf "Please answer yes or no.\n\n";; - esac -done - -ETHER_REPO="https://github.com/ether/etherpad.git" -ETHER_WEB_REPO="https://github.com/ether/ether.github.com.git" -TMP_DIR="/tmp/" - -echo "WARNING: You can only run this script if your github api token is allowed to create and merge branches on $ETHER_REPO and $ETHER_WEB_REPO." -echo "This script automatically changes the version number in package.json and adds a text to CHANGELOG.md." -echo "When you use this script you should be in the branch that you want to release (develop probably) on latest version. Any changes that are currently not committed will be committed." -echo "-----" - -# Get the latest version -LATEST_GIT_TAG=$(git tag | tail -n 1) - -# Current environment -echo "Current environment: " -echo "- branch: $(git branch | grep '* ')" -echo "- last commit date: $(git show --quiet --pretty=format:%ad)" -echo "- current version: $LATEST_GIT_TAG" -echo "- temp dir: $TMP_DIR" - -# Get new version number -# format: x.x.x -echo -n "Enter new version (x.x.x): " -read VERSION - -# Get the message for the changelogs -read -p "Enter new changelog entries (press enter): " -tmp=$(mktemp) -"${EDITOR:-vi}" $tmp -changelogText=$(<$tmp) -echo "$changelogText" -rm $tmp - -if [ "$changelogText" != "" ]; then - changelogText="# $VERSION\n$changelogText" -fi - -# get the token for the github api -echo -n "Enter your github api token: " -read API_TOKEN - -function check_api_token { - echo "Checking if github api token is valid..." - CURL_RESPONSE=$(curl --silent -i https://api.github.com/user?access_token=$API_TOKEN | iconv -f utf8) - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Invalid github api token" && exit 1 -} - -function modify_files { - # Add changelog text to first line of CHANGELOG.md - - msg="" - # source: https://unix.stackexchange.com/questions/9784/how-can-i-read-line-by-line-from-a-variable-in-bash#9789 - while IFS= read -r line - do - # replace newlines with literal "\n" for using with sed - msg+="$line\n" - done < <(printf '%s\n' "${changelogText}") - - sed -i "1s/^/${msg}\n/" CHANGELOG.md - [[ $? != 0 ]] && echo "Aborting: Error modifying CHANGELOG.md" && exit 1 - - # Replace version number of etherpad in package.json - sed -i -r "s/(\"version\"[ ]*: \").*(\")/\1$VERSION\2/" src/package.json - [[ $? != 0 ]] && echo "Aborting: Error modifying package.json" && exit 1 -} - -function create_release_branch { - echo "Creating new release branch..." - git rev-parse --verify release/$VERSION 2>/dev/null - if [ $? == 0 ]; then - echo "Aborting: Release branch already present" - exit 1 - fi - git checkout -b release/$VERSION - [[ $? != 0 ]] && echo "Aborting: Error creating release branch" && exit 1 - - echo "Committing CHANGELOG.md and package.json" - git add CHANGELOG.md - git add src/package.json - git commit -m "Release version $VERSION" - - echo "Pushing release branch to github..." - git push -u $ETHER_REPO release/$VERSION - [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 -} - -function merge_release_branch { - echo "Merging release to master branch on github..." - API_JSON=$(printf '{"base": "master","head": "release/%s","commit_message": "Merge new release into master branch!"}' $VERSION) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/merges?access_token=$API_TOKEN | iconv -f utf8) - echo $CURL_RESPONSE - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch on github" && exit 1 -} - -function create_builds { - echo "Cloning etherpad-lite repo and ether.github.com repo..." - cd $TMP_DIR - rm -rf etherpad-lite ether.github.com - git clone $ETHER_REPO --branch master - git clone $ETHER_WEB_REPO - echo "Creating windows build..." - cd etherpad-lite - bin/buildForWindows.sh - [[ $? != 0 ]] && echo "Aborting: Error creating build for windows" && exit 1 - echo "Creating docs..." - make docs - [[ $? != 0 ]] && echo "Aborting: Error generating docs" && exit 1 -} - -function push_builds { - cd $TMP_DIR/etherpad-lite/ - echo "Copying windows build and docs to website repo..." - GIT_SHA=$(git rev-parse HEAD | cut -c1-10) - mv etherpad-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-win-$VERSION-$GIT_SHA.zip - - mv out/doc $TMP_DIR/ether.github.com/doc/v$VERSION - - cd $TMP_DIR/ether.github.com/ - sed -i "s/etherpad-win.*\.zip/etherpad-win-$VERSION-$GIT_SHA.zip/" index.html - sed -i "s/$LATEST_GIT_TAG/$VERSION/g" index.html - git checkout -b release_$VERSION - [[ $? != 0 ]] && echo "Aborting: Error creating new release branch" && exit 1 - git add doc/ - git add downloads/ - git commit -a -m "Release version $VERSION" - git push -u $ETHER_WEB_REPO release_$VERSION - [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 -} - -function merge_web_branch { - echo "Merging release to master branch on github..." - API_JSON=$(printf '{"base": "master","head": "release_%s","commit_message": "Release version %s"}' $VERSION $VERSION) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/ether.github.com/merges?access_token=$API_TOKEN | iconv -f utf8) - echo $CURL_RESPONSE - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch" && exit 1 -} - -function publish_release { - echo -n "Do you want to publish a new release on github (y/n)? " - read PUBLISH_RELEASE - if [ $PUBLISH_RELEASE = "y" ]; then - # create a new release on github - API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "Release %s","body": "%s","draft": false,"prerelease": false}' $VERSION $VERSION $changelogText) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/releases?access_token=$API_TOKEN | iconv -f utf8) - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "201" ]] && echo "Aborting: Error publishing release on github" && exit 1 - else - echo "No release published on github!" - fi -} - -function todo_notification { - echo "Release procedure was successful, but you have to do some steps manually:" - echo "- Update the wiki at https://github.com/ether/etherpad/wiki" - echo "- Create a pull request on github to merge the master branch back to develop" - echo "- Announce the new release on the mailing list, blog.etherpad.org and Twitter" -} - -# Call functions -check_api_token -modify_files -create_release_branch -merge_release_branch -create_builds -push_builds -merge_web_branch -publish_release -todo_notification