Skip to content

Commit

Permalink
Add release tracks to the Monorepo CLI. (#38095)
Browse files Browse the repository at this point in the history
* Added a tracks sending script.

* Added a version diff function.

* Added release start event tracking.

* Added the point release number check.

* Added more logic to the start event data.

* Update tools/includes/version-compare.sh

Co-authored-by: Brad Jorsch <[email protected]>

* Update tools/includes/version-compare.sh

Co-authored-by: Brad Jorsch <[email protected]>

* Update tools/includes/version-compare.sh

Co-authored-by: Brad Jorsch <[email protected]>

* Update tools/release-plugin.sh

Co-authored-by: Brad Jorsch <[email protected]>

* Changed the increment function name to better reflect the getter status.

* Changed the version_diff to output actual values.

* Optimized the logic a bit, h/t @anomiex.

* Removed the unneded function, h/t @anomiex.

* Added release step tracking events.

* Update tools/includes/send_tracks_event.sh

Co-authored-by: tbradsha <[email protected]>

* Added a return statement.

* Fixed the additional data to be like a flat object.

---------

Co-authored-by: Brad Jorsch <[email protected]>
Co-authored-by: tbradsha <[email protected]>
  • Loading branch information
3 people authored Jul 5, 2024
1 parent fb3c2bd commit 6e9ff5d
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 1 deletion.
41 changes: 41 additions & 0 deletions tools/includes/send_tracks_event.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# Sends a tracks event.
# - 1: Event name
# - 2: An optional JSON-formatted payload of extra tracks params, e.g. `{"a":1, "b":2}`
function send_tracks_event {
# Bail if no event name is provided.
if [[ -z "$1" ]]; then
return
fi

local TRACKS_URL TRACKS_RESPONSE USER_AGENT PAYLOAD
TRACKS_URL='https://public-api.wordpress.com/rest/v1.1/tracks/record?http_envelope=1'
USER_AGENT='jetpack-monorepo-cli'
PAYLOAD=$(jq -nr --arg email "$(git config --get user.email)" '.commonProps._ul = $email')

# Add event name to payload.
PAYLOAD=$(jq -r --arg eventName "$1" '.events = [{_en: $eventName}]' <<< "$PAYLOAD")

# Add extra params to payload if provided.
if [[ -n "$2" ]]; then
PAYLOAD=$(jq --argjson extraParams "$2" '.events[0] += $extraParams' <<< "$PAYLOAD")
fi

# True on fail to bypass pipefail.
TRACKS_RESPONSE=$(curl --fail -sS "$TRACKS_URL" \
-H "User-Agent: $USER_AGENT" \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
--data "$PAYLOAD" \
--compressed 2>&1 || true)

if ! jq -e . <<< "$TRACKS_RESPONSE" &> /dev/null; then
# Likely a cURL error response.
echo "Invalid response: $TRACKS_RESPONSE"
elif ! jq -e '.code == 202' <<< "$TRACKS_RESPONSE" &> /dev/null; then
# Likely a Tracks error response.
echo "Failed Tracks call: $TRACKS_RESPONSE"
fi
}
86 changes: 86 additions & 0 deletions tools/includes/version-compare.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,89 @@ function version_compare {
[[ ${#A[@]} -gt ${#B[@]} ]]
fi
}

# Compute the difference between two version numbers, semver style.
#
# Note this is a bit looser than `pnpm semver`, as it accepts 4-part versions.
#
# @param $1 First version.
# @param $2 Second version.
# Outputs: equal, suffix, patch, minor, or major.
function version_diff {
# Variable for the version_difference call
local INCREMENT

# Returning 0 if neither $1 > $2, nor $2 > $1
if ! version_compare "$1" "$2" 1 && ! version_compare "$2" "$1" 1; then
echo "equal"
return
fi

if version_compare "$1" "$2"; then

# $1 is greater than $2
version_get_increment "$2" "$1"
else

# $2 is greater than $1
version_get_increment "$1" "$2"
fi

case "$INCREMENT" in
"1")
echo "prerelease"
;;
"2")
echo "patch"
;;
"3")
echo "minor"
;;
"4")
echo "major"
;;
esac
}

# Compute the increment needed to get from $1 to $2, semver style.
#
# Note this is a bit looser than `pnpm semver`, as it accepts 4-part versions.
#
# @param $1 First version.
# @param $2 Second version.
function version_get_increment {

local V1="${1%%+*}" V2="${2%%+*}"

local A=() B=() i DIFF

# First, compare the version parts.
IFS='.' read -r -a A <<<"${V1%%-*}"
IFS='.' read -r -a B <<<"${V2%%-*}"

while [[ ${#A[@]} -lt ${#B[@]} ]]; do
A+=( 0 )
done
while [[ ${#B[@]} -lt ${#A[@]} ]]; do
B+=( 0 )
done

i=0

# If AA is ahead of BB, we have found our difference.
while [[ $i -lt ${#A[@]} && $i -lt ${#B[@]} ]]; do
local AA=${A[$i]}
local BB=${B[$i]}

if [[ $AA -lt $BB ]]; then
let DIFF="4 - $i"

INCREMENT=$DIFF
return
fi
i=$((i + 1))
done

# Version parts were equal, this means that the difference is the suffix.
INCREMENT=1
}
53 changes: 52 additions & 1 deletion tools/release-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ BASE=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
. "$BASE/tools/includes/version-compare.sh"
. "$BASE/tools/includes/normalize-version.sh"
. "$BASE/tools/includes/changelogger.sh"

. "$BASE/tools/includes/send_tracks_event.sh"

# Instructions
function usage {
Expand Down Expand Up @@ -143,6 +143,50 @@ done

proceed_p "" "Proceed releasing above projects?" Y

# Sending tracking event
TRACKING_DATA="{}"
RELEASED_PLUGINS="{}"
for PLUGIN in "${!PROJECTS[@]}"; do

CUR_VERSION=$("$BASE/tools/plugin-version.sh" "$PLUGIN")
VERSION_DIFF=$( version_diff "$CUR_VERSION" "${PROJECTS[$PLUGIN]}" )

if [[ "${PROJECTS[$PLUGIN]}" == *-* ]]; then

# The version is a prerelease.
if proceed_p "" "Is this $PLUGIN release fixing a known problem caused by a previous release?" N; then
VERSION_DIFF="bugfix"
fi

elif [[ "${PROJECTS[$PLUGIN]}" =~ ^[0-9]+\.[0-9]+\.[0.]*[1-9] ]]; then

# The version in patch-level.
VERSION_DIFF="bugfix"

# If a project follows semver versioning, we prompt.
if jq -e '.extra.changelogger["versioning"] == "semver"' "$BASE/projects/$PLUGIN/composer.json" &>/dev/null; then
if ! proceed_p "" "Is this $PLUGIN release fixing a known problem caused by a previous release?" N; then
VERSION_DIFF="patch"
fi
fi
fi

RELEASED_PLUGINS=$(
jq \
--arg property "$( echo "$PLUGIN" | sed 's/\//_/' )_release_type" \
--arg value "$VERSION_DIFF" \
'.[ $property ] = $value' <<< "$RELEASED_PLUGINS"
)
RELEASED_PLUGINS=$(
jq \
--arg property "$( echo "$PLUGIN" | sed 's/\//_/' )_version" \
--arg value "${PROJECTS[$PLUGIN]}" \
'.[ $property ] = $value' <<< "$RELEASED_PLUGINS"
)
done

send_tracks_event "jetpack_release_start" "$RELEASED_PLUGINS"

# Figure out which release branch prefixes to use.
PREFIXDATA=$(jq -n 'reduce inputs as $in ({}; .[ $in.extra["release-branch-prefix"] | if . == null then empty elif type == "array" then .[] else . end ] += [ input_filename | capture( "projects/plugins/(?<p>[^/]+)/composer\\.json$" ).p ] ) | to_entries | sort_by( ( .value | -length ), .key ) | from_entries' "$BASE"/projects/plugins/*/composer.json)
TMP=$(jq -rn --argjson d "$PREFIXDATA" '$d | reduce to_entries[] as $p ({ s: ( $ARGS.positional | map( sub( "^plugins/"; "" ) ) ), o: []}; if $p.value - .s == [] then .o += [ $p.key ] | .s -= $p.value else . end) | .o[]' --args "${!PROJECTS[@]}")
Expand Down Expand Up @@ -173,9 +217,11 @@ fi

git checkout -b prerelease
if ! git push -u origin HEAD; then
send_tracks_event "jetpack_release_prerelease_push" '{"result": "failure"}'
die "Branch push failed. Check #jetpack-releases and make sure no one is doing a release already, then delete the branch at https://github.com/Automattic/jetpack/branches"
fi
GITBASE=$( git rev-parse --verify HEAD )
send_tracks_event "jetpack_release_prerelease_push" '{"result": "success"}'

# Loop through the projects and update the changelogs after building the arguments.
for PLUGIN in "${!PROJECTS[@]}"; do
Expand Down Expand Up @@ -246,14 +292,17 @@ while [[ $SECONDS -lt $TIMEOUT && -z "$BUILDID" ]]; do
done

if [[ -z "$BUILDID" ]]; then
send_tracks_event "jetpack_release_github_build" '{"result": "not_found"}'
die "Build ID not found. Check GitHub actions to see if build on prerelease branch is running, then continue with manual steps."
fi

yellow "Build ID found, waiting for build to complete and push to mirror repos."
if ! gh run watch "${BUILDID[0]}" --exit-status; then
send_tracks_event "jetpack_release_github_build" '{"result": "failure"}'
echo "Build failed! Check for build errors on GitHub for more information." && die
fi

send_tracks_event "jetpack_release_github_build" '{"result": "success"}'
yellow "Build is complete."

# Wait for new versions of any composer packages to be up.
Expand Down Expand Up @@ -409,3 +458,5 @@ if [[ ${#MANUALBOTH[@]} -gt 0 ]]; then
the stable tag with \`./tools/stable-tag.sh <plugin>\` and you're all set.
EOM
fi

send_tracks_event "jetpack_release_done"

0 comments on commit 6e9ff5d

Please sign in to comment.