GH-704 - Improved script to back-port commits into maintenance branches.
This commit is contained in:
committed by
Oliver Drotbohm
parent
1fb8def139
commit
00081853e9
125
etc/backport-ticket.sh
Executable file
125
etc/backport-ticket.sh
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
|
||||
start_dir=$(pwd)
|
||||
script_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||
|
||||
# Source the functions file
|
||||
functions="$script_dir/functions.sh"
|
||||
[ -x "$functions" ] || { echo -e "\nERROR: $functions is not an executable file"; exit 1; }
|
||||
source "$functions"
|
||||
|
||||
test_filter=""
|
||||
if [[ "$SPRING_MODULITH_BACKPORT_TICKET_TEST_MODE_ENABLED" == "true" ]]; then
|
||||
echo -e "\nTest mode is enabled"
|
||||
test_dir=$(getTestDir)
|
||||
test_repo=$(getTestRepoName)
|
||||
cd "$test_dir/$test_repo" || _exit 1 "Failed to change directory to $test_dir/$test_repo"
|
||||
current_url=$(git remote get-url origin)
|
||||
[[ "$?" == 0 ]] || _exit 1 "Failed to get current git url"
|
||||
[[ "$current_url" != *"spring-projects"* ]] || _exit 1 "Remote URL cannot contain 'spring-projects' when test mode is enabled"
|
||||
# Including a "since" date to enable test mode, wherein a copy of the repo is created (see test scripts)
|
||||
# Issues created in the test env start with 1, which would be matched with old commits rather than new "test" commits
|
||||
# Setting this date to "2023-11-01" will enable backporting open issue 345 if necessaey
|
||||
# Once that issue is closd this date can also be safely set to June 5 (GH-659), Jul 5 (GH-704), or later if these are closed by then
|
||||
test_filter="--since=\"2023-11-01\""
|
||||
fi
|
||||
|
||||
# Check that at least two inputs were provided
|
||||
# Format $ticketNumber $targetVersion1 $targetVersion2 ... $targetVersionN
|
||||
isBlank "$1" || isBlank "$2" && _exit 1 "Two inputs are required: ticketNumber targetVersion[]"
|
||||
|
||||
# Check that first input is valid
|
||||
echo -e "\nChecking that the first input is valid"
|
||||
number=$1
|
||||
isValidIssueNumber "$number" || _exit 1 "The provided issue number is invalid"
|
||||
|
||||
# Check that second input is valid
|
||||
echo -e "\nChecking that the second input is valid"
|
||||
# Convert the second input to an array and check each element
|
||||
versions=("${@:2}")
|
||||
for version in "${versions[@]}"; do
|
||||
isValidVersionNumber "$version" || _exit 1 "The provided version number [$version] is invalid"
|
||||
done
|
||||
|
||||
echo -e "\nChecking the state of the current branch"
|
||||
|
||||
isDefaultBranch || _exit 1 "Current branch is not the default branch"
|
||||
isCleanBranch || _exit 1 "Current branch is not clean"
|
||||
# To repair, run: git cherry-pick --abort &>/dev/null; git fetch origin && git reset --hard origin/$(git symbolic-ref --short HEAD) && git clean -fd; git checkout main
|
||||
|
||||
sourceGh=$(getGHCode "$number")
|
||||
branch=$(git branch --show-current)
|
||||
|
||||
echo -e "\nGathered working values:"
|
||||
echo "sourceGh=$sourceGh"
|
||||
echo "branch=$branch"
|
||||
echo "test_filter=$test_filter"
|
||||
|
||||
# The SHAs of all commits associated with the source ticket
|
||||
echo -e "\nCapturing commits for $sourceGh:"
|
||||
if [[ "$test_filter" == "" ]]; then
|
||||
git log --grep="\<$sourceGh\>" --reverse
|
||||
shas=$(git log --grep="\<$sourceGh\>" --reverse --format="%H")
|
||||
else
|
||||
git log --grep="\<$sourceGh\>" "$test_filter" --reverse
|
||||
shas=$(git log --grep="\<$sourceGh\>" "$test_filter" --reverse --format="%H")
|
||||
fi
|
||||
|
||||
echo -e "\nshas=\n$shas"
|
||||
|
||||
# For each of the target versions
|
||||
for version in "${versions[@]}"
|
||||
do
|
||||
# Turn 1.5.6 into 1.5.x
|
||||
targetBranch=$(getTargetBranch "$version")
|
||||
|
||||
# Checkout target branch and cherry-pick commit
|
||||
echo -e "\nChecking out target branch"
|
||||
|
||||
git checkout $targetBranch
|
||||
isCleanBranch || _exit 1 "Current branch is not clean"
|
||||
# To repair, run: git cherry-pick --abort &>/dev/null; git fetch origin && git reset --hard origin/$(git symbolic-ref --short HEAD) && git clean -fd; git checkout main
|
||||
|
||||
targetGh=""
|
||||
targetMilestone=$(getTargetMilestone "$version")
|
||||
|
||||
# Cherry-pick all previously found SHAs
|
||||
while IFS= read -r sha
|
||||
do
|
||||
|
||||
echo -e "\nCherry-pick commit $sha from $branch"
|
||||
git cherry-pick "$sha"
|
||||
retVal=$?
|
||||
[ "$retVal" == 0 ] || _exit 1 "Cherry-pick of commit $sha failed with return code $retVal"
|
||||
|
||||
if isBlank "$targetGh"; then
|
||||
targetCandidateNumbers=$(getIssueCandidatesForMilestone "$number" "$targetMilestone")
|
||||
IFS=$'\n' read -rd '' -a array <<< "$targetCandidateNumbers"
|
||||
countTargetCandidateNumbers=${#array[@]}
|
||||
[ $countTargetCandidateNumbers -lt 2 ] || _exit 1 "Found multiple candidate target issues [$targetCandidateNumbers] for milestone [$targetMilestone]"
|
||||
if [ $countTargetCandidateNumbers -eq 1 ]; then
|
||||
#targetNumber=$(echo "$targetCandidateNumbers" | tr -d '\n')
|
||||
targetNumber="$targetCandidateNumbers"
|
||||
echo -e "\nRetrieved existing open target issue [$targetNumber] for milestone [$targetMilestone]"
|
||||
isCleanIssue "$targetNumber" || _exit 1 "Target issue [$targetNumber] is not clean"
|
||||
else
|
||||
# count is 0, create a new issue
|
||||
targetNumber=$(createIssueForMilestone "$number" "$targetMilestone")
|
||||
isBlank "$targetNumber" && _exit 1 "Failed to create a new target issue for milestone [$targetMilestone]"
|
||||
echo -e "\nCreated new target issue [$targetNumber] for milestone [$targetMilestone]"
|
||||
fi
|
||||
targetGh=$(getGHCode "$targetNumber")
|
||||
fi
|
||||
|
||||
# Replace ticket reference with new one
|
||||
updateCommitMessage "$sourceGh" "$targetGh"
|
||||
echo "Updated commit message"
|
||||
|
||||
done <<< "$shas"
|
||||
|
||||
done
|
||||
|
||||
# Return to original branch
|
||||
git checkout "$branch"
|
||||
|
||||
cd "$start_dir"
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Format $ticketNumber $targetVersion[]
|
||||
|
||||
sourceGh="GH-$1"
|
||||
branch=$(git branch --show-current)
|
||||
json=$(gh issue view $1 --json=title,labels)
|
||||
|
||||
title=$(echo $json | jq -r '.title')
|
||||
labels=$(echo $json | jq -r '.labels[].name' | paste -sd ',' -)
|
||||
|
||||
number=$1
|
||||
|
||||
# The SHAs of all commits associated with the source ticket
|
||||
shas=$(git log --grep="$sourceGh" --reverse --format="%H")
|
||||
|
||||
# For each of the target versions
|
||||
for version in ${@:2}
|
||||
do
|
||||
# Turn 1.5.6 into 1.5.x
|
||||
targetBranch="$(echo "$version" | grep -oE '^[0-9]+\.[0-9]+').x"
|
||||
|
||||
# Checkout target branch and cherry-pick commit
|
||||
echo "Checking out branch $targetBranch"
|
||||
git checkout $targetBranch
|
||||
|
||||
# Cherry-pick all previously found SHAs
|
||||
while IFS= read -r sha
|
||||
do
|
||||
echo "Cherry-pick commit $sha from $branch"
|
||||
git cherry-pick $sha
|
||||
done <<< $shas
|
||||
|
||||
echo "gh issue create --title \"$title\" --body \"Back-port of $sourceGh.\" --label \"$labels\" --assignee \"@me\" --milestone \"$version\""
|
||||
number=$(gh issue create --title "$title" --body "Back-port of $sourceGh." --label "$labels" --assignee "@me" --milestone "$version" | awk -F '/' '{print $NF}')
|
||||
echo "New ticket number: $number"
|
||||
|
||||
# Replace ticket reference with new one
|
||||
targetGh="GH-$number"
|
||||
expression="s/$sourceGh/$targetGh/g"
|
||||
message=$(git log -1 --pretty=format:"%s" | sed $expression)
|
||||
|
||||
# Update commit message to refer to new ticket
|
||||
echo "Adapt commit message from $sourceGh to $targetGh"
|
||||
git commit --amend -m "$message"
|
||||
done
|
||||
|
||||
# Return to original branch
|
||||
git checkout $branch
|
||||
216
etc/functions.sh
Executable file
216
etc/functions.sh
Executable file
@@ -0,0 +1,216 @@
|
||||
# functions.sh
|
||||
|
||||
# _exit should be called from the main script only. If called from
|
||||
# another function, it will not cause the main script to exit
|
||||
_exit() {
|
||||
local exit_code="$1"
|
||||
local message="$2"
|
||||
if [ "$exit_code" -ne 0 ]; then
|
||||
echo -e "\nERROR: $message"
|
||||
else
|
||||
echo -e "\n$message"
|
||||
fi
|
||||
echo "Exiting script [exit_code=$exit_code]"
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
getTestDir() {
|
||||
echo "/tmp"
|
||||
}
|
||||
|
||||
getTestRepoName() {
|
||||
echo "spring-modulith-temp-copy"
|
||||
}
|
||||
|
||||
isBlank() {
|
||||
[[ "$1" =~ ^[[:space:]]*$ ]]
|
||||
}
|
||||
|
||||
isValidIssueNumber() {
|
||||
local issue="$1"
|
||||
# Check if the provided number matches an existing issue number
|
||||
# Note: The issue status should be "open" (backporting is done before an issue is closed)
|
||||
# But it is not necessary to filter on status - it is preferable not to constrain
|
||||
if ! gh issue list --limit 10000 --state "all" --json number --jq '.[].number' | grep -x -q "^$issue$"; then
|
||||
echo "The provided issue number [$issue] does not match an existing GitHub issue number"
|
||||
# output value
|
||||
false
|
||||
else
|
||||
echo "The provided issue number [$issue] matches an existing GitHub issue number"
|
||||
# output value
|
||||
true
|
||||
fi
|
||||
}
|
||||
|
||||
isValidVersionNumber() {
|
||||
local version="$1"
|
||||
# Check input format
|
||||
local regex='^[0-9]+\.[0-9]+\.[0-9]+$'
|
||||
if [[ "$version" =~ $regex ]]; then
|
||||
echo "Version [$version] matches the required format"
|
||||
# Check for branch
|
||||
local targetBranch=$(getTargetBranch "$version")
|
||||
local branch=$(git ls-remote --heads origin "$targetBranch")
|
||||
if [[ -n "$branch" ]]; then
|
||||
echo "Branch [$targetBranch] exists"
|
||||
# Check for milestone
|
||||
local targetMilestone=$(getTargetMilestone "$version")
|
||||
local milestone=$(gh api repos/:owner/:repo/milestones --jq ".[] | select(.title == \"$targetMilestone\") | .title")
|
||||
if [[ -n "$milestone" ]]; then
|
||||
echo "Milestone [$targetMilestone] exists"
|
||||
true
|
||||
else
|
||||
echo "Milestone [$targetMilestone] does not exist"
|
||||
false
|
||||
fi
|
||||
else
|
||||
echo "Branch [$targetBranch] does not exist"
|
||||
false
|
||||
fi
|
||||
else
|
||||
echo "Version [$version] does not match the required format [$regex]"
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
getTargetBranch() {
|
||||
local version="$1"
|
||||
local targetBranch="$(echo $version | grep -oE '^[0-9]+\.[0-9]+').x"
|
||||
echo "$targetBranch"
|
||||
}
|
||||
|
||||
getTargetMilestone() {
|
||||
local version="$1"
|
||||
local targetMilestone="$version"
|
||||
echo "$targetMilestone"
|
||||
}
|
||||
|
||||
isDefaultBranch() {
|
||||
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
local default_branch=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
|
||||
if [ "$current_branch" != "$default_branch" ]; then
|
||||
echo "Current branch [$current_branch] is NOT the default branch [$default_branch]"
|
||||
# output value
|
||||
false
|
||||
else
|
||||
echo "Current branch [$current_branch] is the default branch"
|
||||
# output value
|
||||
true
|
||||
fi
|
||||
}
|
||||
|
||||
isCleanBranch() {
|
||||
local branch=$(git symbolic-ref --short HEAD)
|
||||
local remote_branch="origin/$branch"
|
||||
|
||||
# Check for ongoing cherry-pick
|
||||
if [ -d .git/sequencer ]; then
|
||||
echo "Error: Ongoing cherry-pick operation detected."
|
||||
# return code
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for uncommitted changes
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
echo "Error: Uncommitted changes in the working directory."
|
||||
# return code
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for untracked files and directories
|
||||
if [ -n "$(git clean -fdn)" ]; then
|
||||
echo "Error: Untracked files or directories present."
|
||||
# return code
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Fetch latest changes from the remote
|
||||
git fetch origin &>/dev/null
|
||||
|
||||
# Check if local branch is ahead/behind the remote branch
|
||||
local local_status=$(git rev-list --left-right --count ${branch}...${remote_branch})
|
||||
local ahead=$(echo $local_status | awk '{print $1}')
|
||||
local behind=$(echo $local_status | awk '{print $2}')
|
||||
|
||||
if [ "$ahead" -ne 0 ]; then
|
||||
echo "Error: Local branch is ahead of the remote branch by $ahead commit(s)."
|
||||
# return code
|
||||
return 1
|
||||
elif [ "$behind" -ne 0 ]; then
|
||||
echo "Error: Local branch is behind the remote branch by $behind commit(s)."
|
||||
# return code
|
||||
return 1
|
||||
fi
|
||||
|
||||
# If all checks pass
|
||||
echo "Local branch matches the remote branch."
|
||||
# return code
|
||||
return 0
|
||||
}
|
||||
|
||||
getGHCode() {
|
||||
echo "GH-$1"
|
||||
}
|
||||
|
||||
getIssueCandidatesForMilestone() {
|
||||
local number="$1"
|
||||
local milestone="$2"
|
||||
|
||||
local json=$(gh issue view "$number" --json=title,labels)
|
||||
local title=$(echo "$json" | jq -r '.title')
|
||||
local labels=$(echo "$json" | jq -r '.labels[].name' | paste -sd ',' -)
|
||||
local body="Back-port of $(getGHCode $number)."
|
||||
|
||||
local targetCandidateNumbers=$(gh issue list --limit 10000 --state "open" --assignee "@me" --label "$labels" --milestone "$targetMilestone" --json number,title,body --jq '
|
||||
.[] | select(.title == "'"$title"'" and (.body | contains("'"$body"'")) ) | .number')
|
||||
echo "$targetCandidateNumbers"
|
||||
}
|
||||
|
||||
createIssueForMilestone() {
|
||||
local number="$1"
|
||||
local milestone="$2"
|
||||
|
||||
local json=$(gh issue view "$number" --json=title,labels)
|
||||
local title=$(echo "$json" | jq -r '.title')
|
||||
local labels=$(echo "$json" | jq -r '.labels[].name' | paste -sd ',' -)
|
||||
local body="Back-port of $(getGHCode $number)."
|
||||
|
||||
local targetNumber=$(gh issue create --assignee "@me" --label "$labels" --milestone "$targetMilestone" --title "$title" --body "$body" | awk -F '/' '{print $NF}')
|
||||
echo "$targetNumber"
|
||||
}
|
||||
|
||||
isCleanIssue() {
|
||||
local targetNumber="$1"
|
||||
local targetGh=$(getGHCode "$targetNumber")
|
||||
|
||||
# Check for commits mentioning the issue number
|
||||
# $test_filter set globally in calling script
|
||||
local commits
|
||||
if [[ "$test_filter" == "" ]]; then
|
||||
commits=$(git log --grep="\b$targetGh\b")
|
||||
else
|
||||
commits=$(git log --grep="\b$targetGh\b" "$test_filter")
|
||||
fi
|
||||
if [ -z "$commits" ]; then
|
||||
# There are no commits that reference this issue
|
||||
# output value
|
||||
true
|
||||
else
|
||||
# output value
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
updateCommitMessage() {
|
||||
local source="$1"
|
||||
local target="$2"
|
||||
local message=$(git log -1 --pretty=format:"%B" | sed "s/$source/$target/g")
|
||||
if [[ $(echo $message | grep "$target") != "" ]]; then
|
||||
# Update commit message to refer to new ticket
|
||||
git commit --amend -m "$message"
|
||||
[ "$?" -eq 0 ] || return 1
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
87
etc/test/includes/copy-repo.sh
Executable file
87
etc/test/includes/copy-repo.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if values set globally by main script. If not, set here.
|
||||
[ "$start_dir" != "" ] || start_dir=$(pwd)
|
||||
[ "$script_dir" != "" ] || script_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||
[ "$functions" != "" ] || functions="$script_dir/../../functions.sh"
|
||||
|
||||
# Source the functions file
|
||||
[ -x "$functions" ] || { echo -e "\nERROR: $functions is not an executable file"; exit 1; }
|
||||
source "$functions"
|
||||
|
||||
test_dir=$(getTestDir)
|
||||
test_repo=$(getTestRepoName)
|
||||
|
||||
cd "$test_dir" || _exit 1 "Failed to change directory to $test_dir"
|
||||
echo -e "\nIn $PWD"
|
||||
|
||||
owner=$(gh api user --jq '.login') || _exit 1 "Failed to get the current GitHub owner"
|
||||
if [[ "$owner" == "spring-projects" ]]; then
|
||||
_exit 1 "GitHub owner cannot be 'spring-projects'"
|
||||
fi
|
||||
|
||||
# Create a new empty target repository on GitHub
|
||||
echo -e "\nDeleting and recreating $owner/$test_repo"
|
||||
gh repo delete "$owner/$test_repo" --yes
|
||||
gh repo create "$owner/$test_repo" --public || _exit 1 "Failed to create an empty target repository on GitHub"
|
||||
|
||||
# Clone the source repository
|
||||
echo -e "\nCloning spring-projects/spring-modulith"
|
||||
rm -rf "$test_repo"
|
||||
gh repo clone spring-projects/spring-modulith "$test_repo" -- --no-tags || _exit 1 "Failed to clone repo spring-projects/spring-modulith"
|
||||
cd "$test_repo" || _exit 1 "Failed to change directory into the cloned repo repository [$test_repo]"
|
||||
echo -e "\nIn $(pwd)"
|
||||
git rev-parse --is-inside-work-tree > /dev/null 2>&1 && git remote -v || _exit 1 "Not a git repository"
|
||||
|
||||
original_branch=$(git branch --show-current)
|
||||
|
||||
# Get list of desired branches
|
||||
branches=()
|
||||
regex='^[0-9]+\.[0-9]+\.x$'
|
||||
branchCandidates=$(git branch -r | grep -v '\->' | sed 's/origin\///' | sed 's/^[ \t]*//;s/[ \t]*$//')
|
||||
while IFS= read -r branchCandidate; do
|
||||
if [[ "$branchCandidate" =~ $regex ]]; then
|
||||
branches+=("$branchCandidate")
|
||||
fi
|
||||
done < <(echo "$branchCandidates")
|
||||
[ ${#branches[@]} -ne 0 ] || _exit 1 "Failed to identify candidate branches"
|
||||
|
||||
for branch in "${branches[@]}"; do
|
||||
echo -e "\nSwitching branches for checkout"
|
||||
git checkout --track "origin/$branch" || _exit 1 "Failed to check out branch $branch"
|
||||
done
|
||||
|
||||
echo -e "\nSwitching back to original branch"
|
||||
git checkout "$original_branch"
|
||||
|
||||
# Set origin url to new empty repo
|
||||
echo -e "\nUpdate origin url to repo $test_repo"
|
||||
current_url=$(git remote get-url origin)
|
||||
if [[ "$current_url" == https* ]]; then
|
||||
new_url="https://github.com/$owner/$test_repo.git"
|
||||
else
|
||||
new_url="git@github.com:$owner/$test_repo.git"
|
||||
fi
|
||||
git remote set-url origin "$new_url"
|
||||
|
||||
# Double check that origin does not point to spring-projects
|
||||
current_url=$(git remote get-url origin)
|
||||
[[ "$?" == 0 ]] || _exit 1 "Failed to get current git url"
|
||||
[[ "$current_url" != *"spring-projects"* ]] || _exit 1 "The remote URL still contains 'spring-projects'"
|
||||
|
||||
# Push local branches to the new repository
|
||||
branches=("$original_branch" "${branches[@]}")
|
||||
for branch in "${branches[@]}"; do
|
||||
echo -e "\nSwitching branches for push"
|
||||
git checkout "$branch" || _exit 1 "Failed to check out branch $branch"
|
||||
git push -u origin "$branch" || _exit 1 "Failed to push branch $branch"
|
||||
done
|
||||
|
||||
echo -e "\nSwitching back to default branch [$original_branch]"
|
||||
git checkout "$original_branch"
|
||||
gh repo edit --default-branch "$original_branch"
|
||||
|
||||
# Clean up
|
||||
cd "$start_dir"
|
||||
|
||||
echo -e "\nSUCCESS: Created new repo [https://github.com/$owner/$test_repo], and cloned to $test_dir/$test_repo"
|
||||
58
etc/test/includes/create-issues-commits-milestones.sh
Executable file
58
etc/test/includes/create-issues-commits-milestones.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if values set globally by main script. If not, set here.
|
||||
[ "$start_dir" != "" ] || start_dir=$(pwd)
|
||||
[ "$script_dir" != "" ] || script_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||
[ "$functions" != "" ] || functions="$script_dir/../../functions.sh"
|
||||
|
||||
# Source the functions file
|
||||
[ -x "$functions" ] || { echo -e "\nERROR: $functions is not an executable file"; exit 1; }
|
||||
source "$functions"
|
||||
|
||||
test_dir=$(getTestDir)
|
||||
test_repo=$(getTestRepoName)
|
||||
|
||||
cd "$test_dir/$test_repo" || _exit 1 "Failed to change directory to $test_dir/$test_repo"
|
||||
echo -e "\nIn $(pwd)"
|
||||
git rev-parse --is-inside-work-tree > /dev/null 2>&1 && git remote -v || _exit 1 "Not a git repository"
|
||||
|
||||
echo -e "\nCreating new issue"
|
||||
url=$(gh issue create --label "bug" --title "Buggy bug" --body "When I try to do this thing, it breaks" | grep "https")
|
||||
number="$(echo "$url" | awk -F/ '{print $NF}')"
|
||||
sourceGh=$(getGHCode "$number")
|
||||
echo "Created issue $number [$sourceGh]"
|
||||
|
||||
echo -e "\nCreating commits, some for issue $number [$sourceGh]"
|
||||
for i in {1..3}; do
|
||||
# Make issue-related commit
|
||||
filename1="file-$number-$i.md"
|
||||
echo "Part $i of the fix for issue $number" > $filename1
|
||||
git add $filename1
|
||||
git commit -m "$sourceGh - Fix part $i"
|
||||
# Make non-related commit
|
||||
filename2="file-0-$i.md"
|
||||
echo "This line is NOT related to issue [$number-$i]" >> $filename2
|
||||
git add $filename2
|
||||
git commit -m "Updates not related to issue [$number-$i]"
|
||||
done
|
||||
# push changes
|
||||
git push
|
||||
|
||||
echo -e "\nCreating milestones"
|
||||
milestones=$(gh api repos/spring-projects/spring-modulith/milestones --jq '.[].title')
|
||||
echo "$milestones" | while IFS= read -r milestone; do
|
||||
if [ "$milestone" != "" ]; then
|
||||
result="$(gh api -X POST repos/:owner/:repo/milestones -f title="$milestone" -f state="open" -f description="" -f due_on=$(date -u -v +1y +"%Y-%m-%dT%H:%M:%SZ") 2>/dev/null)"
|
||||
retVal="$?"
|
||||
if [[ "$retVal" != 0 && "$(echo "$result" | jq -r '.errors[0].code')" == "already_exists" ]]; then
|
||||
echo "Milestone [$milestone] already exists"
|
||||
else
|
||||
echo "Created milestone [$milestone]"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean up
|
||||
cd "$start_dir"
|
||||
|
||||
echo -e "\nSUCCESS: Created new issue [$url], with commits and milestones, using clone in $test_dir/$test_repo"
|
||||
12
etc/test/setup-test-env.sh
Executable file
12
etc/test/setup-test-env.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# main
|
||||
|
||||
start_dir=$(pwd)
|
||||
script_dir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
|
||||
functions="$script_dir/../functions.sh"
|
||||
|
||||
source "$script_dir/includes/copy-repo.sh"
|
||||
source "$script_dir/includes/create-issues-commits-milestones.sh"
|
||||
|
||||
echo "DONE"
|
||||
Reference in New Issue
Block a user