Skip to content

Commit

Permalink
chore(RHTAPREL-645): script to promote overlays
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Hebert <[email protected]>
  • Loading branch information
scoheb committed Oct 24, 2023
1 parent 1fc3e7d commit 232121a
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 0 deletions.
88 changes: 88 additions & 0 deletions ci/promote-overlay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

# Promotion of Release Service overlays in the infra-deployments repo

## Introduction

The Release Service in RHTAP is deployed to environments using ArgoCD. The specific content to be deployed to each environment is controlled by overlays.

There are 3 overlays:
- development
- staging
- production

Currently, when a PR is merged in the release-service repo, a PR in the infra-deployments repo is created by a RHTAP release pipeline which updates the **development** overlay.

Promotion from a lower environment to higher environment is done manually by updating the target overlay.

This script helps to automate this promotion. It analyzes the commits between the source and the target overlays and creates an infra-deployments PR updating the overlay file and includes a changelog.

![Example PR](infra-pr.png)

## Setup

* The script requires an environment variable called _**GITHUB_TOKEN**_ to exist. This token should have the following scopes:

![Required Github token scopes](github-token-scopes.png)

* The script also has 3 required arguments
* **source-overlay**: Name of the source overlay to promote to target
* **target-overlay**: Name of the overlay to target for promotion
* **fork-owner**: Name of the owner of your infra-deployments fork in Github

## Running the script

```
% ./ci/promote-overlay/promote-overlay.sh --source-overlay development --target-overlay staging --fork-owner scoheb
```

## Example output
```
---
Promoting release-service development to staging in redhat-appstudio/infra-deployments
---
Sync fork with upstream:
This branch is not behind the upstream redhat-appstudio:main.
Cloning into 'infra-deployments'...
remote: Enumerating objects: 21113, done.
remote: Counting objects: 100% (3766/3766), done.
remote: Compressing objects: 100% (430/430), done.
remote: Total 21113 (delta 3391), reused 3417 (delta 3324), pack-reused 17347
Receiving objects: 100% (21113/21113), 3.52 MiB | 3.78 MiB/s, done.
Resolving deltas: 100% (13649/13649), done.
Cloning into 'release-service'...
remote: Enumerating objects: 2995, done.
remote: Counting objects: 100% (801/801), done.
remote: Compressing objects: 100% (287/287), done.
remote: Total 2995 (delta 566), reused 673 (delta 505), pack-reused 2194
Receiving objects: 100% (2995/2995), 30.64 MiB | 4.33 MiB/s, done.
Resolving deltas: 100% (1749/1749), done.
HEAD is now at 2421fc66 release-service update (#2595)
branch 'release-service-staging-update-2023_10_22__12_33_39' set up to track 'origin/main'.
Switched to a new branch 'release-service-staging-update-2023_10_22__12_33_39'
release-service source overlay commit -> 68f2f2c678f726ffa20166adcab8e7e0204a8c69
release-service target overlay commit -> 9a0f08573e4ca3f0d5deda2cbda2575b7e7093bd
Run standard RH pre-commit checks........................................Passed
[release-service-staging-update-2023_10_22__12_33_39 e5f53283] Promote release-service from development to staging
1 file changed, 2 insertions(+), 2 deletions(-)
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 16 threads
Compressing objects: 100% (1/1), done.
Writing objects: 100% (6/6), 728 bytes | 728.00 KiB/s, done.
Total 6 (delta 4), reused 5 (delta 4), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
remote:
remote: Create a pull request for 'release-service-staging-update-2023_10_22__12_33_39' on GitHub by visiting:
remote: https://github.com/scoheb/infra-deployments/pull/new/release-service-staging-update-2023_10_22__12_33_39
remote:
To github.com:scoheb/infra-deployments.git
* [new branch] release-service-staging-update-2023_10_22__12_33_39 -> release-service-staging-update-2023_10_22__12_33_39
==================================
Pull request created successfully:
- https://github.com/redhat-appstudio/infra-deployments/pull/2606
==================================
```
Binary file added ci/promote-overlay/github-token-scopes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ci/promote-overlay/infra-pr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
176 changes: 176 additions & 0 deletions ci/promote-overlay/promote-overlay.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#!/usr/bin/env bash
set -e

# Function to make a string JSON-safe
make_json_safe() {
local json_safe_string
json_safe_string=$(jq -s -R -r @json <<< "$1")
echo "$json_safe_string"
}

OPTIONS=$(getopt -l "skip-cleanup,source-overlay:,target-overlay:,fork-owner:,help" -o "sc,src:,tgt:,fo:,h" -a -- "$@")
eval set -- "$OPTIONS"
while true; do
case "$1" in
-sc|--skip-cleanup)
CLEANUP="true"
;;
-src|--source-overlay)
SOURCE_OVERLAY="$2"
shift 2
;;
-tgt|--target-overlay)
TARGET_OVERLAY="$2"
shift 2
;;
-fo|--fork-owner)
FORK_OWNER="$2"
shift 2
;;
-h|--help)
print_help
exit
;;
--)
shift
break
;;
*) echo "Error: Unexpected option: $1" % >2
esac
done

print_help(){
echo -e "$0 --source-overlay SOURCE_OVERLAY --target-overlay TARGET_OVERLAY --fork-owner FORK_OWNER \
[ --skip-cleanup ]\n"
echo -e "\t--source-overlay SOURCE_OVERLAY\tName of the source overlay to promote to target"
echo -e "\t--target-overlay TARGET_OVERLAY\tName of the overlay to target for promotion"
echo -e "\t--fork-owner FORK_OWNER\tName of the owner of your infra-deployments fork in Github"
echo -e "\t--skip-cleanup\tDisable cleanup after test. Useful for debugging"
}

if [ -z "${SOURCE_OVERLAY}" ]; then
echo -e "Error: missing 'source-overlay' argument\n\n"
print_help
exit 1
fi
if [ -z "${TARGET_OVERLAY}" ]; then
echo -e "Error: missing 'target-overlay' argument\n\n"
print_help
exit 1
fi
if [ -z "${FORK_OWNER}" ]; then
echo -e "Error: missing 'fork-owner' argument\n\n"
print_help
exit 1
fi
if [ -z "${GITHUB_TOKEN}" ]; then
echo -e "Error: missing 'GITHUB_TOKEN' environment variable\n\n"
print_help
exit 1
fi

UPDATE_BRANCH_NAME="release-service-${TARGET_OVERLAY}-update-"$(date '+%Y_%m_%d__%H_%M_%S')

# GitHub repository details
owner="redhat-appstudio"
repo="infra-deployments"

# Personal access token with appropriate permissions
token="${GITHUB_TOKEN}"

# New branch and commit details
new_branch=${UPDATE_BRANCH_NAME}
commit_message="Promote release-service from ${SOURCE_OVERLAY} to ${TARGET_OVERLAY}"

# Fork repository and branch parameters
fork_repo="infra-deployments" # Change this to your fork's repository
base_branch="main" # Change this to the base branch you want to create the PR against

# PR description
description="Included PRs:\r\n"

# Clone the repository
tmpDir=$(mktemp -d)
infraDeploymentDir=${tmpDir}/infra-deployments
releaseServiceDir=${tmpDir}/release-service
mkdir -p ${infraDeploymentDir}
mkdir -p ${releaseServiceDir}

if [ "${CLEANUP}" != "true" ]; then
trap "rm -rf ${tmpDir}" EXIT
else
echo "Temporary git clone directory: ${tmpDir}"
fi

echo -e "---\nPromoting release-service ${SOURCE_OVERLAY} to ${TARGET_OVERLAY} in ${owner}/${repo}\n---\n"
cd ${tmpDir}

echo -e "Sync fork with upstream:"
sync_fork_json=$(curl -s -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${FORK_OWNER}/infra-deployments/merge-upstream \
-d '{"branch":"'${base_branch}'"}')

echo $sync_fork_json

git clone "[email protected]:$FORK_OWNER/$repo.git"
git clone "[email protected]:$owner/release-service.git"
cd ${infraDeploymentDir}

git fetch --all --tags --prune

# Create a new branch
git reset --hard HEAD
git checkout -b "$new_branch" origin/"$base_branch"

RS_SOURCE_OVERLAY_COMMIT=$(yq '.images[0].newTag' < components/release/${SOURCE_OVERLAY}/kustomization.yaml)
RS_TARGET_OVERLAY_COMMIT=$(yq '.images[0].newTag' < components/release/${TARGET_OVERLAY}/kustomization.yaml)

echo ""
echo 'release-service source overlay commit -> '"$RS_SOURCE_OVERLAY_COMMIT"
echo 'release-service target overlay commit -> '"$RS_TARGET_OVERLAY_COMMIT"
echo ""

cd ${releaseServiceDir}
git fetch --all --tags --prune
RS_COMMITS=($(git rev-list --first-parent --ancestry-path "$RS_TARGET_OVERLAY_COMMIT"'...'"$RS_SOURCE_OVERLAY_COMMIT"))
## now loop through the above array
for RS_COMMIT in "${RS_COMMITS[@]}"
do
PR_URL=$(curl -s -H 'Authorization: token '"$token" 'https://api.github.com/search/issues?q=sha:'"$RS_COMMIT" | jq -r '.items[0].pull_request.html_url')
# or do whatever with individual element of the array
description="$description"' - '"$PR_URL"'\r\n'
done

cd ${infraDeploymentDir}
sed -i "s/$RS_TARGET_OVERLAY_COMMIT/$RS_SOURCE_OVERLAY_COMMIT/g" components/release/${TARGET_OVERLAY}/kustomization.yaml

git add components/release/${TARGET_OVERLAY}/kustomization.yaml
git commit -m "$commit_message"

git push origin "$new_branch"

# Create a pull request using GitHub API
pr_creation_json=$(curl -s -X POST "https://api.github.com/repos/$owner/$repo/pulls" \
-H "Authorization: token $token" \
-d '{
"title": "'"$commit_message"'",
"head": "'"$FORK_OWNER:$new_branch"'",
"base": "'"$base_branch"'",
"body": "'"$description"'"
}')

pr_url=$(echo $pr_creation_json | jq -r .html_url)

if [ "${pr_url}" == "null" ]; then
echo -e "\nError: failed to create PR. See output: \n${pr_creation_json}"
exit 1
fi


echo -e "\n=================================="
echo -e "Pull request created successfully:\n- ${pr_url}"
echo "=================================="

0 comments on commit 232121a

Please sign in to comment.