Skip to content

Commit

Permalink
feat: add cocogitto and github release management process
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesXNelson committed Jan 19, 2024
1 parent cd52fb2 commit 232579b
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ tsconfig.tsbuildinfo
junit.xml

# Allow for local overrides of docker-compose.yml. https://docs.docker.com/compose/multiple-compose-files/merge/
docker-compose.override.yml
docker-compose.override.yml

# Ignore temporary files created during a release
releases/
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,30 @@ services:
# Specifying a data volume here will override the default data folder, and you will not be able to access the default data files (such as the demo data)
- /path/to/mydata/:/data
```
## Release Management
In order to manage changelogs, version bumps and github releases, we use cocogitto, or `cog` for short. [https://github.com/cocogitto/cocogitto]

The main configuration file is cog.toml, which we run using some helper scripts located in the `tools/` directory.

### Cutting a New Release

In order to release a given plugin, you will run the script: `tools/release.sh <pluginName>`.
The must be done on a branch named `main` and will publish to the `git remote -v` named `origin` (you can do test releases on your fork).

`tools/release.sh` will validate that your system has the necessary software installed and setup correctly, then invoke `cog bump --auto --package <pluginName>`,
which will invoke the necessary programs and scripts to automate a version bump and github release.

During development, it is expected that all commit message will adhere to `conventional commit` ([https://www.conventionalcommits.org/en/about/]) formats.
`cog` will then uses your commit messages to compute a new version number, assemble a changelog, update our version in source code, create and push git tags, and perform a github release for the given plugin.

See `cog.toml` to understand the full details of the release process.

### Updating Versions in Source Code

As part of the release process, `cog` will, per our `cog.toml` configuration, invoke `tools/update_version.sh <packageName> <newVersion>`, which is a script that uses `sed` to update a plugin's version number in whatever source file we happen to use as the source of truth for version information in the given plugin.

*[WARNING]* If you change where the source of truth for a plugin's version is located, you must update `tools/update_version.sh` to update the correct file with a new version number.

We use `tools/update_version.sh` to remove any `.dev0` "developer version" suffix before creating a release, and to put the `.dev0` version suffix back after completing the release.
58 changes: 58 additions & 0 deletions cog.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from_latest_tag = true
ignore_merge_commits = false
disable_changelog = false
generate_mono_repository_global_tag = true
branch_whitelist = [ "main" ]
skip_ci = "[skip ci]"
skip_untracked = false
tag_prefix = "v"

# bump hooks for global versions only; we don't use global version, but leaving here for posterity
pre_bump_hooks = []
post_bump_hooks = []

# bump hooks for package versions, which is what we actually use
pre_package_bump_hooks = [
"echo Updating {{package}} to version {{version}}",
"rm -f GITHUB_CHANGELOG.md",
# make sure user has correct software installed and is authenticated with `gh` cli tool
"../../tools/validate.sh",
# change the version number of the given plugin in source, and commit it as a chore(version): commit
"../../tools/update_version.sh {{package}} {{version}}",
]
# between pre_ and post_ bump hooks, cog itself will update the checked in CHANGELOG.md file, per updated plugin.
post_package_bump_hooks = [
# prepare the github release changelog file
"mkdir -p ../../releases",
"cog changelog --at {{package}}-v{{version}} -t full_hash > ../../releases/GITHUB_CHANGELOG-{{package}}.md",
# update the version number to have a .dev0 suffix (when possible, only done for python plugins)
"../../tools/update_version.sh {{package}} {{version}} --dev",
# push the tag and the commits to main
"git push origin {{package}}-v{{version}}",
"git push origin main",
# cut a github release using our conventional-commit changelog
"gh release create {{package}}-v{{version}} --notes-file ../../releases/GITHUB_CHANGELOG-{{package}}.md --title '@deephaven/'{{package}}-v{{version}} --verify-tag"
]

[git_hooks]


[commit_types]

[changelog]
path = "CHANGELOG.md"
authors = []


[bump_profiles]

[packages]
auth-keyclock = { path = "plugins/auth-keyclock" }
dashboard-object-viewer = { path = "plugins/dashboard-object-viewer" }
json = { path = "plugins/json" }
matplotlib = { path = "plugins/matplotlib" }
plotly = { path = "plugins/plotly" }
plotly-express = { path = "plugins/plotly-express" }
table-example = { path = "plugins/table-example" }
ui = { path = "plugins/ui" }

113 changes: 113 additions & 0 deletions tools/release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/bin/bash -i

# This script is designed to automate the version bump + github release process.
# It requires for you to have installed both the github tool `gh` and to cocogitto tool `cog`

tab=$'\t'
log_prefix="$(id -un)$tab - "

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}")

function log_error() {
{ echo -e "\033[31m$log_prefix $(date "+%Y-%m-%d %H:%M:%S")$tab |--- [ERROR] $* \033[0m" ; } 2> /dev/null
} 2>/dev/null

function log_info() {
{ echo "$log_prefix $(date "+%Y-%m-%d %H:%M:%S")$tab |--- $*" ; } 2>/dev/null
} 2>/dev/null

if ! which cog >/dev/null; then
{
log_error "cog command not found!"
log_error "Installation instructions are here: https://github.com/cocogitto/cocogitto?tab=readme-ov-file#installation"
log_error "mac users can install via brew; for other OSes, you should install cargo and then use cargo to install cocogitto (cog)"
log_error "Note that cog must be on your PATH. An alias will not work."
} 2>/dev/null
exit 99
fi

# todo: enforce git remote named origin

all_plugins="$(cd "$ROOT_DIR/plugins" ; find ./ -mindepth 1 -maxdepth 1 -type d | sed 's|./||g')"

function usage() {
log_info "Simple utility to automate version bump + release process"
log_info "This script accepts the following arguments:"
log_info ""
log_info "--help | -h $tab-> Prints this help message"
log_info "--debug | -d $tab-> Turn on xtrace debugging"
log_info "<plugin name> $tab-> Runs the version bump + release for a given plugin"
log_info "Valid <plugin name> choices are:
$all_plugins"
} 2> /dev/null

if [ -n "$(git status --short)" ]; then
{
log_error "Detected uncommitted files via git status:"
git status --short
log_error "Releases can only be performed with a clean git status"
log_error 'You must commit/stash your changes, or `git reset --hard` to erase them'
exit 95
} 2>/dev/null
fi

# Collect arguments
package=
while (( $# > 0 )); do
case "$1" in
--debug) ;&
-d) set -o xtrace ;;
--help) ;&
-h) usage ; exit 0 ;;
*)
if [ -n "$package" ]; then
{
log_error "Illegal argument $1. Already requested release of package '$package'"
log_error "You can only release one package at a time"
} 2>/dev/null
exit 94
fi
if grep -q "$1" <<< "$all_plugins"; then
package="$1"
else
{
log_error "Illegal argument $1. Expected one of:
$all_plugins"
} 2>/dev/null
exit 93
fi
;;
esac
shift
done

# Validate arguments
if [ -z "$package" ]; then
{
log_error "Expected exactly one package name argument"
log_error "Valid choices are:
$all_plugins"
} 2>/dev/null
exit 92
fi

if ! grep -q "plugins/$package" "$ROOT_DIR/cog.toml"; then
{
log_error "Did not see plugins/$package in cog.toml"
log_error "Make sure to list your plugins under the [plugins] section of cog.toml"
} 2>/dev/null
exit 91
fi

# Perform release
{ log_info "Releasing package '$package'" ; } 2>/dev/null
(
cd "$ROOT_DIR"
cog bump --package "$package" --auto
)
140 changes: 140 additions & 0 deletions tools/update_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!/bin/bash -i

# This script is used to update the version of a given plugin in its source code.
# Because this differs for various plugins, this script is used to hide all that complexity
# behind a very simply API. `update_version.sh <plugin-name> <new-version>`

# You should not need to call this script directly.
# It is invoked for you when calling the release.sh script located next to this one.


tab=$'\t'
log_prefix="$(id -un)$tab - "

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}")

function log_error() {
{ echo -e "\033[31m$log_prefix $(date "+%Y-%m-%d %H:%M:%S")$tab |--- [ERROR] $* \033[0m" ; } 2> /dev/null
} 2>/dev/null

function log_info() {
{ echo "$log_prefix $(date "+%Y-%m-%d %H:%M:%S")$tab |--- $*" ; } 2>/dev/null
} 2>/dev/null

all_plugins="$(cd "$ROOT_DIR/plugins" ; find ./ -mindepth 1 -maxdepth 1 -type d | sed 's|./||g')"

function usage() {
log_info "Simple utility to update plugin file in order to change versions."
log_info "This script accepts the following arguments:"
log_info ""
log_info "--help | -h $tab-> Prints this help message"
log_info "--debug | -d $tab-> Turn on xtrace debugging"
log_info "--dev $tab-> Append .dev0 to python plugin versions"
log_info "<plugin name> $tab-> The name of the plugin that we are going to set the version for"
log_info "Valid <plugin name> choices are:
$all_plugins"
log_info "<plugin version> $tab-> Specify the new version of the given plugin"

} 2> /dev/null

package=
version=
dev=false
while (( $# > 0 )); do
case "$1" in
--debug) ;&
-d) set -o xtrace ;;
--dev) dev=true ;;
--help) ;&
-h) usage ; exit 0 ;;
*)
if [ -z "$package" ]; then
if grep -q "$1" <<< "$all_plugins"; then
package="$1"
else
{
log_error "Illegal argument $1. Expected one of:
$all_plugins"
} 2>/dev/null
exit 93
fi
elif [ -z "$version" ]; then
version="${1/v/}"
else
{
log_error "Illegal argument $1. Already saw package '$package' and version '$version'"
log_error "This script expects two and only two non -flag arguments, <package name> and <package version>"
} 2>/dev/null
exit 94
fi
;;
esac
shift
done

if [ -z "$package" ]; then
{
log_error "Expected exactly two arguments <package name> <package version>"
log_error "Valid choices for <package name> are:
$all_plugins"
} 2>/dev/null
exit 92
fi
if [ -z "$version" ]; then
{
log_error "Did not receive a second argument of a version to set $package to"
} 2>/dev/null
exit 91
fi

function update_file() {
local file="$1"
local prefix="$2"
local suffix="$3"
local extra="${4:-}"
sed -i "s/${prefix}.*/${prefix}${version}${extra}${suffix}/g" "$ROOT_DIR/plugins/$file"
git add "$ROOT_DIR/plugins/$file"
git commit -m "chore(version): update $package to version $version${extra}"
}

extra=
[ "$dev" = true ] && extra=".dev0"
case "$package" in
auth-keycloak)
update_file auth-keycloak/src/js/package.json '"version": "' '",'
;;
dashboard-object-viewer)
update_file dashboard-object-viewer/src/js/package.json '"version": "' '",'
;;
json)
update_file json/src/deephaven/plugin/json/__init__.py '__version__ = "' '"' "$extra"
;;
matplotlib)
update_file matplotlib/setup.cfg 'version = ' '' "$extra"
;;
plotly)
update_file plotly/src/deephaven/plugin/plotly/__init__.py '__version__ = "' '"' "$extra"
;;
plotly-express)
update_file plotly-express/setup.cfg 'version = ' '' "$extra"
;;
table-example)
update_file table-example/src/js/package.json '"version": "' '",'
;;
ui)
update_file ui/src/deephaven/ui/__init__.py '__version__ = "' '"' "$extra"
;;
*)
{
log_error "Unhandled plugin $package. You will need to add wiring in $SCRIPT_NAME"
exit 90
}
esac

log_info "Done updating $package version to $version${extra}"
Loading

0 comments on commit 232579b

Please sign in to comment.