From 5da55dc4cc7ccdd54d29b0ed06f056c5836e2b98 Mon Sep 17 00:00:00 2001
From: Release Bot <107104610+sourcegraph-release-bot@users.noreply.github.com>
Date: Thu, 30 Jan 2025 01:10:37 -0800
Subject: [PATCH] [Backport M66] chore/build: Teach JetBrains
push-git-tag-for-next-release.sh about release branches (#6884)
These scripts predate release branches and used to always look at global
tags. This change makes it work on release branches. It uses git to list
the commits on the release branch, then does the same version bump
calculation using the branch's tags.
It takes care to handle newly budding branches which are just a commit
on `main` that has no backports yet. In that case it looks at all of the
available tags.
It will work carrying a branch from prerelease through to release:
```
# At the start of the branch
$ ./scripts/push-git-tag-for-next-release.sh --minor --nightly
# During prerelease, assume we have accumulated some commits on the branch now:
$ ./scripts/push-git-tag-for-next-release.sh --patch --nightly
# Transitioning to release:
$ ./scripts/push-git-tag-for-next-release.sh --minor
# Hopefully never needed, but making emergency patches on stable:
$ ./scripts/push-git-tag-for-next-release.sh --patch
```
There are some caveats with this tool:
- When working on a release branch, it only has *local* view of *that
branch's tags.* Misusing it should be harmless because creating a
tag which conflicts with an existing tag will fail when the tag is
pushed.
- It does not enforce the new practice of stable builds having even
version numbers and prerelease builds having odd version numbers.
If you ever need to work around this tool, just author and push git tags
yourself. To this point release captains have been doing that anyway.
Adds a `--dry-run` option which makes testing easier. Removes outdated
docs and points to Notion instead.
## Test plan
```
# Pretend you're just cooking up a release branch
$ git remote update origin
$ git checkout -b my-release-branch origin/main
$ cd jetbrains
$ ./scripts/push-git-tag-for-next-release.sh --minor --nightly --dry-run
# It should suggest a minor version bump based on all the version tags in the repo
...
# Pretend you're on a release branch, we're doing a patch release
$ git fetch origin refs/heads/jb-v7.8.x
$ git checkout FETCH_HEAD
$ git checkout <this PR> -- scripts/next-release.sh scripts/push-git-tag-for-next-release.sh
$ git commit -m 'test test test do not push' # script insists the repo is clean
$ ./scripts/push-git-tag-for-next-release.sh --minor --dry-run
# It should suggest v7.8.1
```
I am the release captain and will dogfood this script in the current
release.
Backport b912145e22b669e9b63f5a12f185770f448e2a26 from
#6881
Co-authored-by: Dominic Cooney
---
jetbrains/CONTRIBUTING.md | 60 ++----------
jetbrains/scripts/next-release.sh | 17 +++-
.../scripts/push-git-tag-for-next-release.sh | 93 +++++++++++++------
3 files changed, 88 insertions(+), 82 deletions(-)
diff --git a/jetbrains/CONTRIBUTING.md b/jetbrains/CONTRIBUTING.md
index bf4ddeaae184..610d39bf4a25 100644
--- a/jetbrains/CONTRIBUTING.md
+++ b/jetbrains/CONTRIBUTING.md
@@ -148,70 +148,28 @@ Take the steps below _before_ [running JetBrains plugin with agent](#developing-
## Publishing a New Release
-### Historical context
-We used to publish both stable and nightly channel versions at once.
-In that approach QA testing and JB approval happened in parallel.
-However, it consumed a lot of CI time and JB time for the releases that did not pass our QA
-(and did not go public eventually). Hence, we decided to use a sequential process.
-We trigger the stable channel release only after the nightly channel release passes QA.
-
-```mermaid
-graph TD;
- Title --> nightly["Nightly Release / Experimental Release"];
- Title["JetBrains Plugin Release"] --> stable["Stable Release"];
- stable --> trigger_stable["Manually trigger 'Stable Release' workflow in GitHub Actions"];
- release_stable --> marketplace_approval["Wait for JetBrains approval"];
- marketplace_approval --> |Automated approval, up to 48hr| unhide["unhide"];
- unhide --> available_to_end_users_stable["Available for download"];
- marketplace_approval --> |Manual quick-approve| slack_approval["Request JetBrains Marketplace team to manually approve it via Slack"];
- slack_approval --> unhide["Unhide the approved release (requires admin access)"];
- nightly --> push_tag["Run 'push-git-tag-for-next-release.sh'"];
- trigger_stable --> release_stable["Wait for 'Stable Release' workflow to complete"];
- push_tag --> release_nightly["Wait for 'Nightly Release' / 'Experimental Release' workflow to complete"];
- release_nightly --> available_to_end_users_nightly["Available for download"];
-```
-
-We aim to cut a new release to "nightly" mid week, every week. If QA or dogfood find issues we backport fixes and
-do updated nightly releases. At the end of a week, we re-cut the best build as "stable".
-
-### 1. Push a git tag & publish a nightly release
-
-Use the following command for a **patch** release:
-
-```shell
-./scripts/push-git-tag-for-next-release.sh --patch
-```
-
-Or this one for a **minor** release:
+See [Cody Client Releases.](https://sourcegraph.notion.site/Cody-Client-Releases-82244a6d1d90420d839f432b8cc00cd8?pvs=74)
-```shell
-./scripts/push-git-tag-for-next-release.sh --minor
-```
+### Publishing an experimental release
-Or this one for a **major** release
-(note it should be user only on special occasions):
+Use the following command for a **experimental** releases:
```shell
-./scripts/push-git-tag-for-next-release.sh --major
+./scripts/push-git-tag-for-next-release.sh --patch --experimental
```
This script runs `verify-release.sh`, which takes a long time to run with a clean cache, which is why we don't run it in
CI. When you have a local cache of IDEA installations then this script can run decently fast (~1-2min).
-After successfully pushing the new tag (for example: `v6.0.15`), we are now able to publish.
-
-Wait for the `Release to Marketplace` GitHub workflow to complete.
-
-### 2. Publish a stable release
+After successfully pushing the new tag (for example: `jb-v7.66.3-experimental`), we are now able to publish. Wait for the `release-jetbrains-experimental` GitHub workflow to complete.
-Go to [Stable Release workflow](https://github.com/sourcegraph/cody/actions/workflows/stable-release.yml),
-click `Run workflow` and select the tag that has been pushed before (and tested by QA team), run it.
+### Expediting Stable Releases
It can take up to 48hr for stable releases to get approved by the JetBrains Marketplace team.
It's possible to expedite this process by posting a message in the `#marketplace` channel in
the [JetBrains Slack workspace](https://plugins.jetbrains.com/slack/).
-### 3. Publish a New Release on GitHub
+### Release Notes on GitHub
For every stable release, create a GitHub release summarizing the changes.
@@ -225,10 +183,10 @@ to [our first release](https://github.com/sourcegraph/jetbrains/releases/tag/v5.
It's also optional create GitHub releases for nightly builds where it makes sense.
-### 4. Announce the New Release on our internal Slack channel
+### Announce the New Release on our internal Slack channel
It is mandatory to post about both stable and nightly releases on our internal
-`#team-cody-clients` Slack channel. You can refer to past posts in the channel's
+`#team-cody-core` Slack channel. You can refer to past posts in the channel's
history for examples.
## Enabling web view debugging
diff --git a/jetbrains/scripts/next-release.sh b/jetbrains/scripts/next-release.sh
index e373b700f4ea..5ce16ca51f3a 100755
--- a/jetbrains/scripts/next-release.sh
+++ b/jetbrains/scripts/next-release.sh
@@ -1,13 +1,24 @@
#!/usr/bin/env bash
set -eu
+# Note: This script requires you to fetch version tags.
+# git fetch origin +refs/tags/jb-v*:refs/tags/jb-v*
+
# Check the number of arguments
-if [ "$#" -ne 1 ]; then
- echo "Usage: $0 [--major | --minor | --patch]"
+if [ "$#" -ne 2 ]; then
+ echo "Usage: $0 --major|--minor|--patch "
exit 1
fi
-LAST_MAJOR_MINOR_ZERO_RELEASE=$(git tag -l | grep "jb-v\d*\\.\d*\\.\d*" | uniq | sort -V | tail -1 | sed 's/-nightly//' | sed 's/-experimental//')
+MERGE_BASE="$2"
+
+LAST_MAJOR_MINOR_ZERO_RELEASE=$(git rev-list "$MERGE_BASE~1"..HEAD | xargs -I{} git tag -l --points-at {} jb-v* | sort -V | tail -1 | sed 's/-nightly//' | sed 's/-experimental//')
+
+if [ -z "$LAST_MAJOR_MINOR_ZERO_RELEASE" ]; then
+ # This is a new release branch.
+ LAST_MAJOR_MINOR_ZERO_RELEASE=$(git tag -l | grep -E 'jb-v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1 | sed 's/-nightly//' | sed 's/-experimental//')
+fi
+
MAJOR=$(echo $LAST_MAJOR_MINOR_ZERO_RELEASE | sed 's/jb-v//' | cut -d. -f1)
MINOR=$(echo $LAST_MAJOR_MINOR_ZERO_RELEASE | sed 's/jb-v//' | cut -d. -f2)
PATCH=$(echo $LAST_MAJOR_MINOR_ZERO_RELEASE | sed 's/jb-v//' | cut -d. -f3)
diff --git a/jetbrains/scripts/push-git-tag-for-next-release.sh b/jetbrains/scripts/push-git-tag-for-next-release.sh
index 4cc2ac54f833..c2e06526e7cc 100755
--- a/jetbrains/scripts/push-git-tag-for-next-release.sh
+++ b/jetbrains/scripts/push-git-tag-for-next-release.sh
@@ -1,19 +1,19 @@
#!/usr/bin/env bash
-# Run this script to cut a new release.
-# No arguments needed, the version is automatically computed.
-set -eux
-
-# Check if the current branch is 'main'
-CURRENT_BRANCH=$(git symbolic-ref --short HEAD)
-if [ "$CURRENT_BRANCH" != "main" ]; then
- echo "Warning: You are not on the 'main' branch. You are on '$CURRENT_BRANCH'."
- # shellcheck disable=SC2162
- read -p "Are you sure you want to proceed? (y/N): " proceed
- if [ "$proceed" != "y" ]; then
- echo "Aborted."
- exit 1
+# Run this script to push a tag that will trigger CI to publish a new release.
+set -eu
+
+usage() {
+ echo "Usage: $0 --major|--minor|--patch [ --nightly|--experimental ] [ --dry-run ]"
+ exit 1
+}
+
+execute() {
+ if [ -z "$DRY_RUN" ]; then
+ "$@"
+ else
+ echo "DRY RUN: $*"
fi
-fi
+}
# Check if the working tree is clean
if ! git diff-index --quiet HEAD --; then
@@ -21,25 +21,61 @@ if ! git diff-index --quiet HEAD --; then
exit 1
fi
-# Check the number of arguments
-if [ "$#" -ne 2 ]; then
- echo "Usage: $0 [--major | --minor | --patch] [ --nightly | --experimental ]"
- exit 1
+VERSION_INCREMENT=""
+CHANNEL=""
+DRY_RUN=""
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --major|--minor|--patch)
+ VERSION_INCREMENT="$1"
+ shift
+ ;;
+ --nightly|--experimental)
+ CHANNEL="${1:1}" # Trim one of the leading -s to make a version suffix like -nightly.
+ shift
+ ;;
+ --dry-run)
+ DRY_RUN="true"
+ shift
+ ;;
+ *)
+ echo "Unknown option: $1"
+ usage
+ ;;
+ esac
+done
+
+# Check one of --major, --minor or --patch was specified.
+if [ -z "$VERSION_INCREMENT" ]; then
+ usage
fi
-CHANNEL="${2#--}"
-if [ "$CHANNEL" != "nightly" ] && [ "$CHANNEL" != "experimental" ]; then
- echo "Invalid argument. Usage: $0 [--major | --minor | --patch] [ --nightly | --experimental ]"
+# Fetch git tags so we can compute an accurate next version.
+echo Fetching git tags to compute next version...
+git fetch origin +refs/tags/jb-v*:refs/tags/jb-v*
+
+MERGE_BASE=$(git merge-base HEAD origin/main)
+echo "Your current commit:"
+git show -s --format=oneline HEAD
+echo "Your branch base:"
+git show -s --format=oneline "$MERGE_BASE"
+echo "Other releases from this branch:"
+git rev-list "$MERGE_BASE~1"..HEAD | xargs -I{} git tag -l --points-at {} jb-v*
+
+# shellcheck disable=SC2162
+read -p "Are you sure you want to proceed? (y/N): " proceed
+if [ "$proceed" != "y" ]; then
+ echo "Aborted."
exit 1
fi
SCRIPT_DIR="$(dirname "$0")"
SCRIPT_DIR="$(readlink -f "$SCRIPT_DIR")"
-NEXT_RELEASE_ARG="$1"
-NEXT_VERSION="$(bash "$SCRIPT_DIR/next-release.sh" $NEXT_RELEASE_ARG)"
+NEXT_VERSION="$(bash "$SCRIPT_DIR/next-release.sh" $VERSION_INCREMENT "$MERGE_BASE")"
# Check the argument and take appropriate action
-if [ "$NEXT_RELEASE_ARG" == "--major" ]; then
+if [ "$VERSION_INCREMENT" == "--major" ]; then
read -p "[WARNING] Upgrade of the major version in a special event, do you want to proceed? (y/N): " choice
if [ "$choice" != "y" ]; then
echo "Aborted."
@@ -48,7 +84,7 @@ if [ "$NEXT_RELEASE_ARG" == "--major" ]; then
fi
# shellcheck disable=SC2162
-read -p "Confirm that you want to run the release v$NEXT_VERSION-$CHANNEL (y/N): " choice
+read -p "Confirm that you want to ${DRY_RUN:+"DRY "}run the release v$NEXT_VERSION$CHANNEL (y/N): " choice
if [ "$choice" == "y" ]; then
echo "Running release..."
else
@@ -56,7 +92,8 @@ else
exit 1
fi
-bash "$SCRIPT_DIR/verify-release.sh"
-TAG="jb-v$NEXT_VERSION-$CHANNEL"
+execute bash "$SCRIPT_DIR/verify-release.sh"
+TAG="jb-v$NEXT_VERSION$CHANNEL"
echo "$TAG"
-git tag -a "$TAG" -m "$TAG" && git push origin "$TAG"
+
+execute git tag -a "$TAG" -m "$TAG" && execute git push origin "$TAG"