Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions bash/aws.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,26 @@ function aws::get_tags {
}

function aws::scan {
@doc Iterate over every ECR repository and refresh the scan for the \
given tag, skipping any repository named in AWS_SCAN_SKIP_REPOS. \
AWS_SCAN_SKIP_REPOS is comma-separated and defaults to \
blockchaintp/busybox, preserving the historical BTP behaviour. \
SUR-2832.
@arg _1_ tag to scan - when empty every tag is rescanned
local tag=$1
local skip_list=${AWS_SCAN_SKIP_REPOS:-blockchaintp/busybox}
for repository in $(aws::get_repositories); do
if [ "$repository" = "blockchaintp/busybox" ]; then
log::info "Skipping busybox repository"
local skip
local match=false
IFS=',' read -ra skip <<<"$skip_list"
for skip_entry in "${skip[@]}"; do
if [ "$repository" = "$skip_entry" ]; then
match=true
break
fi
done
if [ "$match" = "true" ]; then
log::info "Skipping $repository repository (AWS_SCAN_SKIP_REPOS)"
continue
fi
log::info "Scanning $repository $tag"
Expand Down
31 changes: 27 additions & 4 deletions bash/docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ source "$(dirname "${BASH_SOURCE[0]}")/includer.sh"
@package docker

function docker::cmd() {
@doc Smart command for docker.
@doc Smart command for docker. \
When the SIMULATE environment variable is non-empty every docker \
invocation is echoed to stdout instead of executed. release-images -d \
sets SIMULATE=true to provide a dry-run mode and callers that want \
the same behaviour for ad-hoc scripts can export SIMULATE themselves.
if [ -z "$SIMULATE" ]; then
$(commands::use docker) "$@"
else
Expand Down Expand Up @@ -209,18 +213,37 @@ function docker::list_tags {
}

function docker::list_versions {
@doc List repository tags matching the version pattern, sorted by \
semver. The pattern defaults to the historical BTP regex. \
Override by passing an explicit pattern argument or by setting \
DOCKER_VERSION_PATTERN in the environment. SUR-2832.
@arg _1_ repository name
@arg _2_ registry url
@arg _3_ optional ERE pattern - defaults to historical BTP regex or DOCKER_VERSION_PATTERN
local repository=${1:?}
local registry=${2?}
local default_pattern='BTP[0-9]+.[0-9]+.[0-9]+(rc[0-9]+)?(-[0-9]+-[a-z0-9]{8,10})?(-[0-9]+.[0-9]+.[0-9]+(p[0-9]+(-[0-9]+-[a-z0-9]{8,10})?)?)?'
local pattern=${3:-${DOCKER_VERSION_PATTERN:-$default_pattern}}
docker::list_tags "$repository" "$registry" |
grep -E 'BTP[0-9]+.[0-9]+.[0-9]+(rc[0-9]+)?(-[0-9]+-[a-z0-9]{8,10})?(-[0-9]+.[0-9]+.[0-9]+(p[0-9]+(-[0-9]+-[a-z0-9]{8,10})?)?)?' |
grep -E "$pattern" |
sort -V
}

function docker::list_official_versions {
@doc List repository tags matching the official-release pattern, \
sorted by semver. The pattern defaults to the historical BTP \
anchored regex. Override by passing an explicit pattern argument or \
by setting DOCKER_OFFICIAL_VERSION_PATTERN in the environment. \
SUR-2832.
@arg _1_ repository name
@arg _2_ registry url
@arg _3_ optional ERE pattern - defaults to anchored BTP regex or DOCKER_OFFICIAL_VERSION_PATTERN
local repository=${1:?}
local registry=${2?}
docker::list_tags "$repository" "$registry" | grep -E \
'^BTP[0-9]+.[0-9]+.[0-9]+(rc[0-9]+)?(-[0-9]+.[0-9]+.[0-9]+(p[0-9]+)?)?$' |
local default_pattern='^BTP[0-9]+.[0-9]+.[0-9]+(rc[0-9]+)?(-[0-9]+.[0-9]+.[0-9]+(p[0-9]+)?)?$'
local pattern=${3:-${DOCKER_OFFICIAL_VERSION_PATTERN:-$default_pattern}}
docker::list_tags "$repository" "$registry" |
grep -E "$pattern" |
sort -V
}

Expand Down
35 changes: 26 additions & 9 deletions bash/find-squashable
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,42 @@ options::parse "$@"

previous_cmt=
previous_files=
first_squash="true"
group_open=false
group_first=
# SUR-2840: separate `group_open` (bool) from `group_first` (SHA) so the
# state isn't overloaded onto one sentinel. Cache git::files_changed |
# cksum once per iteration and flush a trailing same-files group after
# the loop — pre-fix, a group that ran to the oldest commit in range
# never printed because the emit branch only fired on a different
# following commit.
for cmt in $(git::commits "$START_FROM" "$END_AT"); do
these_files=$(git::files_changed "$cmt" | cksum)
if [ -n "$previous_cmt" ]; then
these_files=$(git::files_changed "$cmt" | cksum)
if [ "$these_files" = "$previous_files" ]; then
if [ "$first_squash" = "true" ]; then
first_squash=$previous_cmt
if [ "$group_open" = "false" ]; then
group_first=$previous_cmt
group_open=true
fi
else
if [ "$first_squash" != "true" ]; then
if [ "$group_open" = "true" ]; then
echo
echo "$first_squash" to "$previous_cmt" could be squashed
git::log_fromto "${previous_cmt}~1" "$first_squash"
echo "$group_first" to "$previous_cmt" could be squashed
git::log_fromto "${previous_cmt}~1" "$group_first"
echo
git::files_changed "$previous_cmt"
group_open=false
group_first=
fi
first_squash="true"
fi
fi
previous_cmt=$cmt
previous_files=$(git::files_changed "$cmt" | cksum)
previous_files=$these_files
done

if [ "$group_open" = "true" ]; then
echo
echo "$group_first" to "$previous_cmt" could be squashed
git::log_fromto "${previous_cmt}~1" "$group_first"
echo
git::files_changed "$previous_cmt"
fi
30 changes: 26 additions & 4 deletions bash/git-check
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ function set_client() {

options::standard
options::description "Check all the repositories according to the\
parameters and update keep them in sync with the origin if possible"
parameters and update keep them in sync with the origin if possible.\
GH_PR_CHECK is only consulted for orgs in GIT_CHECK_GH_ORGS\
(space-separated; default \"blockchaintp catenasys scealiontach\");\
BitBucket PR counts are only fetched for orgs in GIT_CHECK_BB_ORGS\
(default \"TASE\"). Override either to extend the toolkit beyond the\
historical BTP setup."
options::add -o o -d "organization to scan" -a -f set_organization
options::add -o b -d "base directory to scan" -a -e BASE
options::add -o p -d "check for pull requests" -x GH_PR_CHECK
Expand Down Expand Up @@ -92,8 +97,16 @@ function get_gh_pr_count {
return
fi
if command -v gh >/dev/null; then
if [ "$orgname" = "blockchaintp" ] ||
[ "$orgname" = "catenasys" ] || [ "$orgname" = "scealiontach" ]; then
local gh_orgs=${GIT_CHECK_GH_ORGS:-"blockchaintp catenasys scealiontach"}
local org
local match=false
for org in $gh_orgs; do
if [ "$orgname" = "$org" ]; then
match=true
break
fi
done
if [ "$match" = "true" ]; then
log::debug "Checking pull requests for $base_name"
gh pr list -R "$base_name" --draft=false | grep -cv "no open"
else
Expand All @@ -114,7 +127,16 @@ function get_bb_pr_count {
return
fi
if command -v bb >/dev/null; then
if [ "$orgname" = "TASE" ]; then
local bb_orgs=${GIT_CHECK_BB_ORGS:-TASE}
local org
local match=false
for org in $bb_orgs; do
if [ "$orgname" = "$org" ]; then
match=true
break
fi
done
if [ "$match" = "true" ]; then
log::debug "Checking pull requests for $base_name"
bb -c "$orgname" pr-count "$base_name"
else
Expand Down
33 changes: 10 additions & 23 deletions bash/log.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,16 @@ function log::level() {
LOG_LEVEL=$level
}

# Initialise the LOG_DISABLE_* flags from LOG_LEVEL at source time so
# scripts that don't pass -v still get deterministic gating. Each flag is
# initialised independently: SUR-2347 — pre-fix, if a caller pre-set any
# single flag (e.g. LOG_DISABLE_INFO=false) the entire block was skipped,
# leaving the other three unset (empty), and `[ "$LOG_DISABLE_TRACE" =
# "false" ]` evaluated false, silently disabling output. Snapshot the
# caller's explicit pre-sets, let log::level recompute defaults from
# LOG_LEVEL, then restore the snapshots so explicit values win.
__log_preset_trace=${LOG_DISABLE_TRACE+x}
__log_preset_debug=${LOG_DISABLE_DEBUG+x}
__log_preset_info=${LOG_DISABLE_INFO+x}
__log_preset_warning=${LOG_DISABLE_WARNING+x}
__log_value_trace=${LOG_DISABLE_TRACE-}
__log_value_debug=${LOG_DISABLE_DEBUG-}
__log_value_info=${LOG_DISABLE_INFO-}
__log_value_warning=${LOG_DISABLE_WARNING-}
log::level "$LOG_LEVEL"
[ "$__log_preset_trace" = x ] && LOG_DISABLE_TRACE=$__log_value_trace
[ "$__log_preset_debug" = x ] && LOG_DISABLE_DEBUG=$__log_value_debug
[ "$__log_preset_info" = x ] && LOG_DISABLE_INFO=$__log_value_info
[ "$__log_preset_warning" = x ] && LOG_DISABLE_WARNING=$__log_value_warning
unset __log_preset_trace __log_preset_debug __log_preset_info __log_preset_warning
unset __log_value_trace __log_value_debug __log_value_info __log_value_warning
# Initialise each LOG_DISABLE_* flag from LOG_LEVEL at source time,
# honouring any caller pre-set. The ${VAR+x} guard treats an explicit
# pre-set as authoritative; only unset flags are computed from
# LOG_LEVEL. log::level (above) still recomputes unconditionally, which
# is what log::level_increase / log::level_decrease rely on.
# (SUR-2347; simplified SUR-2843)
[ -z "${LOG_DISABLE_TRACE+x}" ] && { ((LOG_LEVEL > 3)) && LOG_DISABLE_TRACE=false || LOG_DISABLE_TRACE=true; }
[ -z "${LOG_DISABLE_DEBUG+x}" ] && { ((LOG_LEVEL > 2)) && LOG_DISABLE_DEBUG=false || LOG_DISABLE_DEBUG=true; }
[ -z "${LOG_DISABLE_INFO+x}" ] && { ((LOG_LEVEL > 1)) && LOG_DISABLE_INFO=false || LOG_DISABLE_INFO=true; }
[ -z "${LOG_DISABLE_WARNING+x}" ] && { ((LOG_LEVEL > 0)) && LOG_DISABLE_WARNING=false || LOG_DISABLE_WARNING=true; }

function log::level_increase() {
@doc Increase the LOG_LEVEL
Expand Down
6 changes: 4 additions & 2 deletions bash/pagerduty-alert
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ source "$(dirname "${BASH_SOURCE[0]}")/includer.sh"

log::level 2
options::standard
options::description "Creates PagerDuty alert (incident)"
options::description "Creates PagerDuty alert (incident). When -f is not\
supplied the From address defaults to the value of PAGERDUTY_FROM_DEFAULT\
(historical default: \"no-reply@blockchaintp.com\")."
options::add -o a -d "Alert API Token" -a -m -e ALERT_TOKEN
options::add -o s -d "PagerDuty ServiceID" -a -m -e SERVICE_ID
options::add -o i -d "Alert Type (incident)" -a -m -e ALERT_TYPE
Expand All @@ -35,7 +37,7 @@ options::add -o f -d "Alert From Email Address" -a -e ALERT_FROM
options::parse_available "$@"

ALERT_TITLE=${ALERT_TITLE:="Test Alert"}
ALERT_FROM=${ALERT_FROM:="no-reply@blockchaintp.com"}
ALERT_FROM=${ALERT_FROM:="${PAGERDUTY_FROM_DEFAULT:-no-reply@blockchaintp.com}"}

case $ALERT_TYPE in
incident)
Expand Down
10 changes: 8 additions & 2 deletions bash/release-images
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ function _add_additional_registry {
}

options::standard
options::description "various tools to do with releasing and publishing images"
options::description "various tools to do with releasing and publishing\
images. The source organization filtered against the registry catalogue\
defaults to \"blockchaintp\" for historical compatibility; override via\
the RELEASE_IMAGES_ORG env var. -d sets SIMULATE=true so docker::cmd\
echoes commands instead of executing them."
options::add -o t -d "Target tag pattern to copy" -a -m -e target_tag
options::add -o r -d "Source registry to find images" -a -m -e target_registry
options::add -o a -d "target registry url to copy to, may be repeated" -a -m -f _add_additional_registry
Expand All @@ -40,12 +44,14 @@ if [ "$DRY_RUN" = "true" ]; then
export SIMULATE=true
fi

RELEASE_IMAGES_ORG=${RELEASE_IMAGES_ORG:-blockchaintp}

if [ -z "$IMAGES_FILE" ]; then
# docker::promote_latest accepts variadic extras after shift 3, so call
# it once with every additional_registry instead of looping — this
# collapses N redundant pulls per repo into one (60 pulls -> 20 across
# a 30-repo / 3-extra-registry org).
docker::promote_latest blockchaintp "${target_registry:?}" \
docker::promote_latest "$RELEASE_IMAGES_ORG" "${target_registry:?}" \
"${target_tag:?}" \
"${additional_registries[@]}"
else
Expand Down
17 changes: 14 additions & 3 deletions bash/review-prs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ function usage() {
true
}
options::standard
options::description "Opens a browser to review all pull requests for the specified organizations."
options::description "Opens a browser to review all pull requests for the\
specified organizations. If no -o orgs are given, the default organization\
list comes from REVIEW_PRS_ORGS (space-separated; historical default is\
\"391agency btpworks blockchaintp catenasys\"). REVIEW_PRS_INTEREST_ORGS\
plays the same role for -i."

declare -a -g ORGANIZATIONS
function local::add_organization {
Expand All @@ -47,12 +51,19 @@ shift $((OPTIND - 1))

OPEN_BROWSER=${OPEN_BROWSER:-false}
GIT_HOME=${GIT_HOME:-$HOME/git}
# SUR-2832: defaults preserved for the BTP-era invocation; override
# REVIEW_PRS_ORGS / REVIEW_PRS_INTEREST_ORGS (space-separated) to scan
# different organizations without editing the script.
REVIEW_PRS_ORGS=${REVIEW_PRS_ORGS:-"391agency btpworks blockchaintp catenasys"}
REVIEW_PRS_INTEREST_ORGS=${REVIEW_PRS_INTEREST_ORGS:-hyperledger}
if [ -z "${INTERESTED_ORGANIZATIONS[*]}" ]; then
INTERESTED_ORGANIZATIONS+=(hyperledger)
# shellcheck disable=SC2206 # intentional word-splitting on space-separated env var
INTERESTED_ORGANIZATIONS+=(${REVIEW_PRS_INTEREST_ORGS})
fi

if [ -z "${ORGANIZATIONS[*]}" ]; then
ORGANIZATIONS+=(391agency btpworks blockchaintp catenasys)
# shellcheck disable=SC2206 # intentional word-splitting on space-separated env var
ORGANIZATIONS+=(${REVIEW_PRS_ORGS})
fi

function review_prs {
Expand Down
12 changes: 10 additions & 2 deletions bash/update-repo-tags
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ source "$(dirname "${BASH_SOURCE[0]}")/includer.sh"

options::standard
options::description "Add a new tag to the repository based on semver and\
conventional commits."
conventional commits. Annotated tags are GPG-signed (git tag -s), which\
requires a configured signing key (user.signingkey + gpg-agent or\
equivalent); pass -U to write an unsigned annotated tag instead."
options::add -o t -d "target directory to examine and update" -a -m \
-e TARGET_DIR
options::add -o p -d "Patch tag" \
Expand All @@ -33,6 +35,8 @@ options::add -o b -d "proceed to bump minor version if breaking changes are foun
-x ALLOW_BREAKING
options::add -o c -d "generate and commit change before tagging" \
-x GENERATE_CHANGELOG
options::add -o U -d "skip GPG signing of the annotated tag" \
-x NO_SIGN_TAG
options::parse "$@"

pushd "$TARGET_DIR" >/dev/null || exit 1
Expand Down Expand Up @@ -128,7 +132,11 @@ if [ "$skip" = "false" ]; then
log::notice "No prior changelog found. Will not generate a new one."
fi
fi
git::cmd tag -a -s "$TAG" -m "Auto Tagging $TAG"
if [ "$NO_SIGN_TAG" = "true" ]; then
git::cmd tag -a "$TAG" -m "Auto Tagging $TAG"
else
git::cmd tag -a -s "$TAG" -m "Auto Tagging $TAG"
fi
fi
fi
popd >/dev/null || exit 1
31 changes: 31 additions & 0 deletions tests/find-squashable.bats
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,34 @@ teardown() {
[ "$status" -eq 0 ]
[[ "$output" == *"could be squashed"* ]]
}

# SUR-2840: when a same-files run extends to the oldest commit in the
# iteration range, the historical emit branch never fired because it
# required a different following commit. Build a history where every
# in-range commit touches the same file and assert the trailing group is
# still reported.
@test "find-squashable flushes a same-files group that extends to the last commit (SUR-2840)" {
TAIL_FIXTURE=$(mktemp -d)
(
cd "$TAIL_FIXTURE" || exit 1
git init -q -b main .
helpers::set_git_identity
echo "initial" >file_a.txt
git add file_a.txt
git -c commit.gpgsign=false commit -q -m "feat: initial"
echo "c1" >>file_a.txt
git add file_a.txt
git -c commit.gpgsign=false commit -q -m "feat: change file_a 1"
echo "c2" >>file_a.txt
git add file_a.txt
git -c commit.gpgsign=false commit -q -m "feat: change file_a 2"
echo "c3" >>file_a.txt
git add file_a.txt
git -c commit.gpgsign=false commit -q -m "feat: change file_a 3"
)
TAIL_START=$(git -C "$TAIL_FIXTURE" rev-list --reverse HEAD | head -1)
run bash -c "cd '$TAIL_FIXTURE' && '$SQUASHABLE' -s '$TAIL_START'"
rm -rf "$TAIL_FIXTURE"
[ "$status" -eq 0 ]
[[ "$output" == *"could be squashed"* ]]
}
Loading
Loading