diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 000000000..85bd88faf --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,27 @@ +name: Release-plz + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + +jobs: + release-plz: + name: Release-plz + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} \ No newline at end of file diff --git a/bin/README.md b/bin/README.md deleted file mode 100644 index 3a4d21ac6..000000000 --- a/bin/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# tokio-console dev scripts - -This directory contains shell scripts useful for Tokio Console development. -Currently, all the scripts in this directory are related to publishing releases. - -- `release.sh`: Releases a new version of a Tokio Console crate. This includes - updating the crate's version in its `Cargo.toml`, updating the changelog, - running pre-release tests, creating a release tag, and publishing the crate to - crates.io. - - Invoked with the name of the crate to release, and the version of the new - release. For example: - - ```console - $ bin/release.sh tokio-console 0.1.9 - ``` - - The script will validate whether a new release can be published prior to - updating the changelog and crate version. Then, the script will display the - git diff for the generated release commit, and prompt the user to confirm - that it is correct prior to publishing the release. - - Releases should be published on the `main` branch. Note that this script - requires that the user is authenticated to publish releases of the crate in - question to crates.io. - -- `update-changelog.sh`: Updates the generated `CHANGELOG.md` for a given crate - and version, without committing the changelog update or publishing a tag. - - Invoked with the path to the crate to generate change notes for, and the name - that will be used for the new release's Git tag. For example: - - ```console - $ bin/update-changelog.sh tokio-console tokio-console-v0.1.9 - ``` - - The `release.sh` script will run this script automatically as part of the - release process. However, it can also be invoked separately to just update the - changelog. - -- `_util.sh`: Contains utilities used by other shell scripts. This script is not - run directly. diff --git a/bin/_util.sh b/bin/_util.sh deleted file mode 100644 index a2d499bb9..000000000 --- a/bin/_util.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash -# utility functions used in other shell scripts. -# -# currently, this includes: -# - cargo-style stderr logging (`err`, `note`, and `status` functions) -# - confirmation prompts (`confirm` function) -set -euo pipefail - -# Log an error to stderr -# -# Args: -# $1: message to log -err() { - echo -e "\e[31m\e[1merror:\e[0m" "$@" 1>&2; -} - -# Log a note to stderr -# -# Args: -# $1: message to log -note() { - echo -e "\e[31m\e[1mnote:\e[0m" "$@" 1>&2; -} - -# Log a cargo-style status message to stderr -# -# Args: -# $1: a "tag" for the log message (should be 12 characters or less in -# length) -# $2: message to log -status() { - local width=12 - local tag="$1" - local msg="$2" - printf "\e[32m\e[1m%${width}s\e[0m %s\n" "$tag" "$msg" -} - -# Prompt the user to confirm an action -# -# Args: -# $1: message to display to the user along with the `[y/N]` prompt -# -# Returns: -# 0 if the user confirmed, 1 otherwise -confirm() { - while read -r -p "$1 [Y/n] " input - do - case "$input" in - [yY][eE][sS]|[yY]) - return 0 - ;; - [nN][oO]|[nN]) - return 1 - ;; - *) - err "invalid input $input" - ;; - esac - done -} - -# Returns the path to a Mycelium crate. -# -# Args: -# $1: crate name -# -# Returns: -# 0 if the crate exists, 0 if it does not exist. -crate_path() { - local crate="$1" - local mycoprefix='mycelium-'; - if [[ -d $crate ]]; then - echo "$crate" - elif [[ -d "${crate#"$mycoprefix"}" ]]; then - echo "${crate#"$mycoprefix"}" - else - err "unknown crate $crate" - return 1; - fi -} diff --git a/bin/release.sh b/bin/release.sh deleted file mode 100755 index 1111e4f1c..000000000 --- a/bin/release.sh +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env bash -usage="Releases a tokio-console crate. - -USAGE: - $(basename "$0") [FLAGS] - -FLAGS: - -h, --help Show this help text and exit. - -v, --verbose Enable verbose output. - -d, --dry-run Do not change any files or commit a git tag. - --publish-dry-run Perform a dry run on the publish step only." - -set -euo pipefail - -bindir=$( cd "${BASH_SOURCE[0]%/*}" && pwd ) -rootdir=$( cd "$bindir"/.. && pwd ) - -# shellcheck source=_util.sh -. "$bindir"/_util.sh - -cd "$rootdir" - -verify() { - status "Verifying" "if $crate v$version can be released" - - local branch - branch=$(git rev-parse --abbrev-ref HEAD) - if [[ "$branch" != "main" ]]; then - err "you are not on the 'main' branch" - if ! confirm " are you sure you want to release from the '$branch' branch?"; then - echo "okay, exiting" - exit 1 - fi - fi - - if ! cargo --list | grep -q "hack"; then - err "missing cargo-hack executable" - if confirm " install it?"; then - cargo install cargo-hack - else - echo "okay, exiting" - exit 1 - fi - fi - - status "Checking" "if $crate builds across feature combinations" - - local cargo_hack=(cargo hack -p "$crate" --feature-powerset --no-dev-deps) - - if [[ "$verbose" ]]; then - cargo_hack+=("$verbose" check) - else - cargo_hack+=(check --quiet) - fi - - "${cargo_hack[@]}" - local cargo_hack_status="$?" - - if [[ "$cargo_hack_status" != "0" ]] ; then - err "$crate did not build with all feature combinations (cargo hack exited with $cargo_hack_status)!" - exit 1 - fi - - - if git tag -l | grep -Fxq "$tag" ; then - err "git tag \`$tag\` already exists" - exit 1 - fi -} - -update_version() { - # check the current version of the crate - local curr_version - curr_version=$(cargo pkgid -p "$crate" | sed -n 's/.*#\(.*\)/\1/p') - - if ! cargo --list | grep -q "set-version"; then - err "missing cargo-set-version executable (from cargo-edit)" - if confirm " install it?"; then - cargo install cargo-edit - else - echo "okay, exiting" - exit 1 - fi - fi - - if [[ "$curr_version" == "$version" ]]; then - err "crate $crate is already at version $version!" - if ! confirm " are you sure you want to release $version?"; then - echo "okay, exiting" - exit 0 - fi - else - status "Updating" "$crate from $curr_version to $version" - cargo set-version -p $crate $version - fi - - # If we're releasing console-api, we need to update its version in - # the other crates in the workspace too. - if [[ "$crate" == "console-api" ]]; then - local cargo_upgrade=(cargo upgrade --offline -p console-api@$version) - if [[ "$verbose" ]]; then - cargo_upgrade+=("$verbose") - fi - - "${cargo_upgrade[@]}" - files+=($(ls Cargo.lock */Cargo.toml)) - fi -} - -commit() { - if ! [[ -z "${1+1}" ]] && [[ "$1" == "--amend" ]]; then - status "Amending" "release commit" - amend="$1" - else - status "Creating" "release commit" - amend="" - fi - - # Prepare a commit message including the changelog from just this release. - tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t 'tokio-console-release') - tmp_changelog_path="$tmp_dir/tmp-changelog" - tmp_commit_msg_path="$tmp_dir/tmp-commit-msg" - "$bindir/update-changelog.sh" --unreleased --changelog-path "$tmp_changelog_path" "$crate" "$crate-v$version" - (echo -e "chore($slug): prepare to release $crate $version\n" && cat $tmp_changelog_path | grep -v "generated by git-cliff") > $tmp_commit_msg_path - - git_commit=(git commit -sS -F $tmp_commit_msg_path) - - if [[ "$amend" ]]; then - git_commit+=($amend) - fi - - if [[ "$dry_run" ]]; then - echo "" - echo "# " "${git_commit[@]}" - else - "${git_commit[@]}" - fi -} - -publish() { - status "Publishing" "$crate v$version" - cd "$path" - local cargo_package=(cargo package) - local cargo_publish=(cargo publish) - - if [[ "$verbose" ]]; then - cargo_package+=("$verbose") - cargo_publish+=("$verbose") - fi - - if [[ "$dry_run" ]]; then - cargo_publish+=("$dry_run") - elif [[ "$publish_dry_run" ]]; then - cargo_publish+=("$publish_dry_run") - fi - - "${cargo_package[@]}" - "${cargo_publish[@]}" - - cd "$rootdir" - - status "Adding" "Cargo.lock after publish" - git add "Cargo.lock" - commit --amend - - status "Tagging" "$tag" - local git_tag=(git tag "$tag") - local git_push_tags=(git push --tags) - if [[ "$dry_run" ]]; then - echo "# " "${git_tag[@]}" - echo "# " "${git_push_tags[@]}" - else - "${git_tag[@]}" - fi -} - -push() { - status "Pushing" "release commit and tag $tag" - local git_push=(git push -u origin) - local git_push_tag=(git push origin "$tag") - - if [[ "$dry_run" ]]; then - echo "# " "${git_push[@]}" - echo "# " "${git_push_tag[@]}" - else - "${git_push[@]}" - "${git_push_tag[@]}" - fi -} - -update_changelog() { - # shellcheck source=update-changelog - . "$bindir"/update-changelog.sh --prepend --unreleased - changelog_status="$?" - - if [[ $changelog_status -ne 0 ]]; then - err "failed to update changelog" - exit "$changelog_status" - fi -} - - -verbose='' -dry_run='' -publish_dry_run='' - -for arg in "$@" -do - case "$arg" in - -h|--help) - echo "$usage" - exit 0 - ;; - -v|--verbose) - verbose="--verbose" - ;; - -d|--dry-run) - dry_run="--dry-run" - ;; - --publish-dry-run) - publish_dry_run="--dry-run" - ;; - -*) - err "unknown flag $arg" - echo "$usage" - exit 1 - ;; - *) # crate or version - if [[ -z "${crate+crate}" ]]; then - crate="$arg" - elif [[ -z "${version+version}" ]]; then - version="$arg" - else - err "unknown positional argument \"$arg\"" - echo "$usage" - exit 1 - fi - ;; - esac -done - -if [[ "$verbose" ]]; then - set -x -fi - -if [[ -z "${version+version}" ]]; then - err "no version specified!" - errexit=1 -fi - -if [[ "${crate+crate}" ]]; then - tag="$crate-v$version" -else - err "no crate specified!" - errexit=1 -fi - -case "$crate" in - console-subscriber) - slug="subscriber" - ;; - console-api) - slug="api" - ;; - tokio-console) - slug="console" - ;; - *) - slug="$crate" - ;; -esac - -if [[ "${errexit+errexit}" ]]; then - echo "$usage" - exit 1 -fi - -path=$(crate_path "$crate") - -cargo_toml="${path}/Cargo.toml" -changelog="${path}/CHANGELOG.md" - -files=("$cargo_toml" "$changelog") - -is_uncommitted='' -for file in "${files[@]}"; do - if ! git diff-index --quiet HEAD -- "$file"; then - err "would overwrite uncommitted changes to $file!" - is_uncommitted=1 - fi -done - -if [[ "$is_uncommitted" ]]; then - exit 1 -fi - -verify -update_version -update_changelog - -staged="$(git diff-index --cached --name-only HEAD --)" -if [[ "$staged" ]]; then - err "skipping commit, as it would include the following unrelated staged files:" - echo "$staged" - exit 1 -fi - -status "Ready" "to prepare release commit!" -echo "" - -git add "${files[@]}" -git diff --staged - -if [[ "$dry_run" ]]; then - git reset HEAD -- "${files[@]}" - git checkout HEAD -- "${files[@]}" -fi - -echo "" -status "Running" "cargo dist plan" -cargo dist plan - -if confirm "commit?"; then - echo "" - commit -else - echo "okay, exiting" - exit 1 -fi - -if confirm "publish the crate?"; then - echo "" - publish -else - echo "okay, exiting" - exit 1 -fi - -if confirm "push release commit and tag?"; then - echo "" - push -else - echo "okay, exiting" - exit 1 -fi \ No newline at end of file diff --git a/bin/update-changelog.sh b/bin/update-changelog.sh deleted file mode 100755 index 4a8da86e0..000000000 --- a/bin/update-changelog.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash -usage="Updates the changelog for a Tokio Console crate. - -USAGE: - $(basename "$0") [FLAGS] - -FLAGS: - -h, --help Show this help text and exit. - -v, --verbose Enable verbose output. - -u, --unreleased Only add unreleased changes to changelog - --changelog-path Write the changelog to this path. - default: /CHANGELOG.md - -p, --prepend Prepend the changelog to the existing file. - default: regenerate the entire file." - -set -euo pipefail - -bindir=$( cd "${BASH_SOURCE[0]%/*}" && pwd ) -rootdir=$( cd "$bindir"/.. && pwd ) - -# shellcheck source=_util.sh -. "$bindir"/_util.sh - -cd "$rootdir" - -verbose='' -unreleased='' -changelog_path='' -prepend='' - -while [[ $# -gt 0 ]] -do - arg=$1 - shift - case "$arg" in - -h|--help) - echo "$usage" - exit 0 - ;; - -v|--verbose) - verbose="--verbose" - ;; - -u|--unreleased) - unreleased="--unreleased" - ;; - -p|--prepend) - prepend="--prepend" - ;; - --changelog-path) - changelog_path="$1" - shift - ;; - -*) - err "unknown flag $arg" - echo "$usage" - exit 1 - ;; - *) # crate or version - if [[ -z "${path+path}" ]]; then - path="$arg" - elif [[ -z "${tag+tag}" ]]; then - tag="$arg" - else - err "unknown positional argument \"$arg\"" - echo "$usage" - exit 1 - fi - ;; - esac -done - -if [[ -z "${path+path}" ]]; then - err "no version specified!" - errexit=1 -fi - -if [[ -z "${tag+tag}" ]]; then - err "no tag specified!" - errexit=1 -fi - -if [[ "${errexit+errexit}" ]]; then - echo "$usage" - exit 1 -fi - -if ! [[ -x "$(command -v git-cliff)" ]]; then - err "missing git-cliff executable" - if confirm " install it?"; then - cargo install git-cliff - else - echo "okay, exiting" - exit 0 - fi -fi - -if [[ -z "$changelog_path" ]]; then - changelog_path="${path}/CHANGELOG.md" -fi - -status "Updating" "$changelog_path for tag $tag" - -git_cliff=( - git-cliff - --include-path "${path}/**" - --config cliff.toml - --tag "$tag" -) -if [[ "$verbose" ]]; then - git_cliff+=("$verbose") -fi - -if [[ "$unreleased" ]]; then - git_cliff+=("$unreleased") -fi - -if [[ "$prepend" ]]; then - git_cliff+=("--prepend") -else - git_cliff+=("--output") -fi - -git_cliff+=("$changelog_path") - -export GIT_CLIFF__GIT__TAG_PATTERN="${path}-v[0-9]*" -"${git_cliff[@]}" \ No newline at end of file diff --git a/cliff.toml b/cliff.toml index 16f2c3f17..2b0b9d38d 100644 --- a/cliff.toml +++ b/cliff.toml @@ -55,9 +55,7 @@ body = """ # remove the leading and trailing whitespace from the template trim = true # changelog footer -footer = """ - -""" +footer = "" [git] # parse the commits based on https://www.conventionalcommits.org diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 000000000..72bc4273e --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,11 @@ +[workspace] +changelog_config = "cliff.toml" + +[[package]] +name = "console-api" + +[[package]] +name = "console-subscriber" + +[[package]] +name = "tokio-console"