Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
richm committed Aug 16, 2024
1 parent 91a731d commit 30890a4
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 113 deletions.
111 changes: 59 additions & 52 deletions manage-role-repos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,63 @@ if [ -n "${LSR_BASE_DIR:-}" ] && [ ! -d "$LSR_BASE_DIR" ]; then
mkdir -p "$LSR_BASE_DIR"
fi

clone_repo() {
local base_dir org repo def_repo prot_save forked newname origin_repo
base_dir="$1"
org="$2"
repo="$3"
# get a local clone of the repo
if [ ! -d "$base_dir/$repo" ]; then
gh repo clone "$org/$repo" -- -o upstream
fi
pushd "$base_dir/$repo" > /dev/null
# should have a remote called upstream that points to lsr/repo
if ! git remote get-url upstream | grep -q "$org/$repo"; then
echo Error: non-standard git remote config - upstream does not point
echo to "$org/$repo"
git remote get-url upstream
echo please use git remote to configure upstream to point to "$org/$repo"
exit 1
fi
def_repo="$(gh repo set-default xxx/xxx --view 2>&1)"
if [ -z "$def_repo" ] || [[ "$def_repo" =~ "no default repository" ]]; then
gh repo set-default "$org/$repo"
fi
# make sure we have a fork of this under our personal space
# this will also create a git remote in the local repo if there
# is not already one - adds a remote called "origin" that points
# to our fork
if [ "${MAKE_FORK:-true}" = true ]; then
prot_save=$(gh config -h github.com get git_protocol)
gh config -h github.com set git_protocol ssh
forked=false
if ! gh repo fork --remote; then
echo cannot fork
else
forked=true
fi
gh config -h github.com set git_protocol "$prot_save"
if [ "$forked" = true ]; then
if [[ "$(git remote get-url origin)" =~ .*:([^/]+)/([^/]+)$ ]]; then
origin_org="${BASH_REMATCH[1]}"
origin_repo="${BASH_REMATCH[2]/.git/}"
else
echo Error: origin remote points to unknown url "$(git remote get-url origin)"
exit 1
fi
if [ "${RENAME_FORK:-false}" = true ]; then
newname="${org}"-"$repo"
if [ "$origin_repo" = "$newname" ]; then
: # already renamed
else
gh repo rename "$newname" -R "$origin_org/$origin_repo"
fi
fi
fi
fi
git fetch --all --quiet
}

repos=${REPOS:-$(gh repo list "$LSR_GH_ORG" -L 100 --json name -q '.[].name')}
DEFAULT_EXCLIST=${DEFAULT_EXCLIST:-"tft-tests test-harness linux-system-roles.github.io sap-base-settings \
sap-hana-preconfigure experimental-azure-firstboot sap-preconfigure \
Expand All @@ -48,7 +105,7 @@ DEFAULT_EXCLIST=${DEFAULT_EXCLIST:-"tft-tests test-harness linux-system-roles.gi
declare -A EXARRAY
for repo in $DEFAULT_EXCLIST ${EXCLIST:-}; do
# EXARRAY is a "set" of excluded repos
EXARRAY[$repo]=$repo
EXARRAY["$repo"]="$repo"
done

if [ -n "${LSR_BASE_DIR:-}" ]; then
Expand All @@ -65,57 +122,7 @@ for repo in $repos; do

echo Repo: "$repo"
if [ -n "${LSR_BASE_DIR:-}" ]; then
# get a local clone of the repo
if [ ! -d "$LSR_BASE_DIR/$repo" ]; then
gh repo clone "$LSR_GH_ORG/$repo" -- -o upstream
fi
pushd "$LSR_BASE_DIR/$repo" > /dev/null
# should have a remote called upstream that points to lsr/repo
if ! git remote get-url upstream | grep -q "$LSR_GH_ORG/$repo"; then
echo Error: non-standard git remote config - upstream does not point
echo to "$LSR_GH_ORG/$repo"
git remote get-url upstream
echo please use git remote to configure upstream to point to "$LSR_GH_ORG/$repo"
exit 1
fi
def_repo="$(gh repo set-default xxx/xxx --view 2>&1)"
if [ -z "$def_repo" ] || [[ "$def_repo" =~ "no default repository" ]]; then
gh repo set-default "$LSR_GH_ORG/$repo"
fi
# make sure we have a fork of this under our personal space
# this will also create a git remote in the local repo if there
# is not already one - adds a remote called "origin" that points
# to our fork
if [ "${MAKE_FORK:-true}" = true ]; then
prot_save=$(gh config -h github.com get git_protocol)
gh config -h github.com set git_protocol ssh
forked=false
if ! gh repo fork --remote; then
echo cannot fork
else
forked=true
fi
gh config -h github.com set git_protocol "$prot_save"
if [ "$forked" = true ]; then
if [[ "$(git remote get-url origin)" =~ .*:([^/]+)/([^/]+)$ ]]; then
origin_org="${BASH_REMATCH[1]}"
origin_repo="${BASH_REMATCH[2]/.git/}"
else
echo Error: origin remote points to unknown url "$(git remote get-url origin)"
exit 1
fi
if [ "${RENAME_FORK:-false}" = true ]; then
newname="${LSR_GH_ORG}"-"$repo"
if [ "$origin_repo" = "$newname" ]; then
: # already renamed
else
gh repo rename "$newname" -R "$origin_org/$origin_repo"
origin_repo="$newname"
fi
fi
fi
fi
git fetch
clone_repo "$LSR_BASE_DIR" "$LSR_GH_ORG" "$repo"
fi
if [ -z "${origin_org:-}" ]; then
origin_org="$LSR_GH_ORG"
Expand Down
134 changes: 73 additions & 61 deletions role-make-version-changelog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

set -euo pipefail

# By default, this script will skip doing a release of roles
# that do not appear to have any changes since the last release.
# If you really want to have a chance to view and perhaps release
# such roles, set AUTOSKIP=false
# also, if you want to prompt to release role, set AUTOSKIP=false.
# otherwise, the script will go directly to the role release
AUTOSKIP="${AUTOSKIP:-true}"

# Find the last tag in each role
# Look at the merged PRs since that tag
# Automatically figure out what version to use for the new tag
Expand All @@ -21,6 +28,13 @@ ALLOW_BAD_PRS="${ALLOW_BAD_PRS:-false}"
# PR descriptions too.
USE_PR_BODY="${USE_PR_BODY:-false}"

# By default, AUTOSKIP=true will also skip roles that have only ci
# changes. If you want to release roles that have only ci changes,
# set AUTOSKIP_PR_TYPES=none
# If the role has only changes for PR types in this list, the role
# will be skipped. Otherwise, a new role release will be proposed.
AUTOSKIP_PR_TYPES="${AUTOSKIP_PR_TYPES:-ci}"

repo_entries="$(gh repo view --json name,owner)"
repo=${repo:-$(echo "$repo_entries" | jq -r .name)}
owner=${owner:-$(echo "$repo_entries" | jq -r .owner.login)}
Expand All @@ -35,23 +49,8 @@ for no_release_role in $NO_RELEASE_ROLES; do
fi
done

# To be used in conjunction with local-repo-dev-sync.sh
# This script is called from every role

get_main_branch() {
local br
br=$(git branch --list main)
if [ -n "$br" ]; then
echo main
return 0
fi
br=$(git branch --list master)
if [ -n "$br" ]; then
echo master
return 0
fi
echo UNKNOWN
return 1
gh api "/repos/$owner/$repo" -q .default_branch
}

if ! type -p npm > /dev/null 2>&1; then
Expand All @@ -74,38 +73,16 @@ if ! npm list @commitlint/config-conventional > /dev/null 2>&1; then
fi
export NODE_PATH="$npm_config_prefix/lib/node_modules/@commitlint/config-conventional/node_modules"

git fetch --all --force
# get the main branch
mainbr=$(get_main_branch)
currbr=$(git branch --show-current)
# see if BRANCH already exists - editing an existing PR
if [ -n "${BRANCH:-}" ]; then
BRANCH_EXISTS=$(git branch --list "$BRANCH")
else # assume user wants to use the currently checked out branch
BRANCH="$currbr"
fi
if [ "$BRANCH" = "$mainbr" ]; then
echo ERROR: need a branch to use for the commit/PR
echo please set BRANCH to the branch you want to use for the PR
echo or git checkout the branch
exit 1
fi
if [ "$BRANCH" = "$currbr" ]; then
: # using current branch "$currbr"
elif [ -n "${BRANCH_EXISTS:-}" ]; then
git checkout "$BRANCH"
else
git checkout "$mainbr"
git checkout -b "$BRANCH"
fi
echo Using branch "$BRANCH" for the changelog commit/PR

# get latest release
releases_latest=$(gh api repos/"$owner"/"$repo"/releases/latest -q '.tag_name,.published_at' 2> /dev/null || :)
skip=false
pr_titles_file=".pr_titles.txt"
prs_file=".prs.json"
commitlint_errors_file=".commitlint_errors.txt"
workdir="$(mktemp -d --suffix=_lsr)"
pushd "$workdir" > /dev/null 2>&1
# shellcheck disable=SC2064
trap "popd > /dev/null 2>&1; rm -rf $workdir" EXIT
pr_titles_file="$workdir/.pr_titles.txt"
prs_file="$workdir/.prs.json"
commitlint_errors_file="$workdir/.commitlint_errors.txt"
if [[ "$releases_latest" == *"Not Found"* ]]; then
# repo and LSR_GH_ORG are referenced but not assigned.
# shellcheck disable=SC2154
Expand All @@ -116,6 +93,7 @@ else
latest_tag="$(echo "$releases_latest" | sed -n 1p)"
tag_range="closed:>$(echo "$releases_latest" | sed -n 2p)"
fi

# Note that first: 100 is a maximum, it would work only if there are <100 PRs since last tag
prs_query="$(cat <<EOF
query {
Expand All @@ -135,7 +113,7 @@ query {
}
EOF
)"
gh api graphql -f query="$prs_query" -q '.data.search' > $prs_file
gh api graphql -f query="$prs_query" -q .data.search > "$prs_file"
count=$(jq '.issueCount' "$prs_file")
if [ "${count:-0}" = 0 ]; then
echo There are no merged PRs since latest tag "$latest_tag"
Expand All @@ -147,11 +125,12 @@ if [ "${count:-0}" = 0 ]; then
else
echo Pull requests since latest tag "$latest_tag":
echo ""
: > $pr_titles_file
: > "$pr_titles_file"
pr_descriptions=()
skip=true
# loop through pr_list in reverse to populate changelog in chronological order
for ((i="$count"-1; i>=0; i--)); do
pr_entry="$(jq '.edges['$i'].node' $prs_file)"
pr_entry="$(jq '.edges['$i'].node' "$prs_file")"
pr_title="$(echo "$pr_entry" | jq -r '.title')"
pr_num="$(echo "$pr_entry" | jq -r '.number')"
pr_body="$(echo "$pr_entry" | jq -r '.body')"
Expand All @@ -175,23 +154,39 @@ else
printf -v pr_description -- "- %s (#%s)" "$pr_title" "$pr_num"
fi
pr_descriptions+=("$pr_description")
for pr_type in $AUTOSKIP_PR_TYPES; do
if [ "$pr_type" = none ]; then
skip=false # user does not want to skip
elif [[ "$pr_title" =~ ^"$pr_type": ]]; then
: # do nothing - do not touch skip value
else
skip=false # cannot skip - this is a "real" change
fi
done
done
cat $pr_titles_file
echo ""
cat "$pr_titles_file"
# see the changes?
read -r -p 'Release this role? (y/n)? (default: y) ' release_role
if [ "${release_role:-y}" = n ]; then
skip=true
if [ "$AUTOSKIP" = false ]; then
read -r -p 'Release this role? (y/n)? (default: y) ' release_role
if [ "${release_role:-y}" = n ]; then
skip=true
fi
elif [ "$skip" = true ]; then
echo Autoskip enabled - the role has only PRs of type "$AUTOSKIP_PR_TYPES"
echo If you want to this role, set AUTOSKIP_PR_TYPES=none and re-run this command
fi
fi
if [ "$skip" = false ]; then
if [ -s "$pr_titles_file" ] && [ "${ALLOW_BAD_PRS}" = false ] && [ "${count:-0}" != 0 ]; then
# get commitlint rc file
gh api /repos/"$owner"/"$repo"/contents/.commitlintrc.js -q .content | \
base64 --decode > "$workdir/.commitlintrc.js"
echo ""
echo Verifying if all PR titles comply with the conventional commits format
: > $commitlint_errors_file
: > "$commitlint_errors_file"
while read -r pr_title; do
echo "$pr_title" | npx commitlint >> $commitlint_errors_file 2>&1 || :
done < $pr_titles_file
echo "$pr_title" | npx commitlint >> "$commitlint_errors_file" 2>&1 || :
done < "$pr_titles_file"
if [ -s "$commitlint_errors_file" ]; then
echo ERROR: the following PR titles failed commitlint the check:
cat "$commitlint_errors_file"
Expand Down Expand Up @@ -270,11 +265,12 @@ You have three options:
fi
done
if [ -n "${new_tag_in}" ]; then
rel_notes_file=".release-notes-${new_tag}.md"
new_features_file=.new_features.md
bug_fixes_file=.bug_fixes.md
other_changes_file=.other_changes.md
tmp_changelog_file=.tmp-changelog
mainbr=$(get_main_branch)
rel_notes_file="$workdir/.release-notes-${new_tag}.md"
new_features_file="$workdir/.new_features.md"
bug_fixes_file="$workdir/.bug_fixes.md"
other_changes_file="$workdir/.other_changes.md"
tmp_changelog_file="$workdir/.tmp-changelog"
rm -f "$new_features_file" "$bug_fixes_file" "$other_changes_file"
for pr_description in "${pr_descriptions[@]}"; do
if echo "$pr_description" | sed -n 1p | grep '^- feat.*'; then
Expand Down Expand Up @@ -313,6 +309,15 @@ You have three options:
fi
fi
${EDITOR:-vi} "$rel_notes_file"
# this also will do a pushd to the checkedout repo dir
clone_repo . "$origin_org" "$repo"
git checkout "$mainbr"
if [ -n "$(git branch --list "$BRANCH")" ]; then
git checkout "$BRANCH"
git rebase "$mainbr"
else
git checkout -b "$BRANCH"
fi
myheader="Changelog
========="
if [ -f CHANGELOG.md ]; then
Expand Down Expand Up @@ -345,5 +350,12 @@ You have three options:
git push -u origin "$BRANCH"
gh pr create --fill --base "$mainbr" --head "$origin_org":"$BRANCH"
fi
popd > /dev/null 2>&1 # clone_repo does a pushd to repo dir
fi
fi

trap - EXIT
popd > /dev/null 2>&1
if [[ "$workdir" =~ ^/tmp ]]; then
rm -rf "$workdir"
fi

0 comments on commit 30890a4

Please sign in to comment.