Skip to content

Commit

Permalink
[Backport M66] chore/build: Teach JetBrains push-git-tag-for-next-rel…
Browse files Browse the repository at this point in the history
…ease.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. <br> Backport b912145 from
#6881

Co-authored-by: Dominic Cooney <[email protected]>
  • Loading branch information
sourcegraph-release-bot and dominiccooney authored Jan 30, 2025
1 parent a5ef411 commit 5da55dc
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 82 deletions.
60 changes: 9 additions & 51 deletions jetbrains/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
Expand Down
17 changes: 14 additions & 3 deletions jetbrains/scripts/next-release.sh
Original file line number Diff line number Diff line change
@@ -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 <git commit for merge base>"
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)
Expand Down
93 changes: 65 additions & 28 deletions jetbrains/scripts/push-git-tag-for-next-release.sh
Original file line number Diff line number Diff line change
@@ -1,45 +1,81 @@
#!/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
echo "Error: Your working tree is not clean. Please commit or stash your changes."
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."
Expand All @@ -48,15 +84,16 @@ 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
echo "Aborted."
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"

0 comments on commit 5da55dc

Please sign in to comment.