Skip to content

Commit 15ea0c3

Browse files
committed
Add release automation workflow.
This change adds the necessary gh workfows to automate releases for minor releases. Workflows are split into 3 components: 1. Prep 2. Tests 3. Release Creation 1. Prep Prep workflow will validate compatibilty.yaml, and ensure the minor branches (e.g. 1.3.x) are not already created. If branches already exist, the Prep workflow will fail. If comptability.yaml does not contain the minor version entry, the workflow will fail. If compatibility.yaml contains the minor version entry, but comptaiblity.md is not up to date, then workflow will create the necessary PR and exit early, notifying the user to retry the Prep workflow once this PR is merged and compatiblity docs are in sync. If all pre-requisites are met, Prep workflow will create the necessary minor branches in DSP and DSPO repositories, then continue to perform all the necessary image builds for DSPO + DSP components. Once the builds are done, the Prep workfow will generate the necessary follow up PR to the minor release branch, updating the params.env with the SHAs of the newly built images. 2. Tests This is a placeholder workflow to add future tests required to perform a stable release. These are ci tests that run on the PR created via Prep workflow above. Once the CI tests pass, the PR will need to be manually merged, the workflow does not auto merge PRs (nor does it auto push commits to any branches). 3. Release Creation Once the PR from (1) is merged. A trigger workflow is launched, this workflow exists to trigger the "Create Release" workflow. The trigger workflow will package required information that is pulled from the PR body (in the form of a yaml) and will upload it to GH workflow cache, for the "Create Release" workflow to utilize. Once the trigger workflow completes, the "Create Release" worklfow will begin. The "Create Release" workflow Validates the triggering PR from (1), this step is to prevent unauthorized entities from triggering this workflow. Validation confirms the PR info being passed into this workflow originates from a PR authored by a user in the "approvers" list in DSPO repo's OWNERS file. Once validated, "Create Release" workflow will create releases in DSP/DSPO, providing links to these releases in the workflow summary, as well as a PR comment to the PR created in (1). Signed-off-by: Humair Khan <[email protected]>
1 parent 0443de9 commit 15ea0c3

File tree

16 files changed

+622
-0
lines changed

16 files changed

+622
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
echo "Create a tag release for ${TARGET_VERSION_TAG} in ${REPOSITORY}"
6+
7+
RELEASE_REPO_DIR=$(dirname ${WORKING_DIR})/repo_dir
8+
git clone \
9+
--depth=1 \
10+
--branch=${RELEASE_BRANCH} \
11+
https://${GH_USER_NAME}:${GH_TOKEN}@github.com/${REPOSITORY} \
12+
${RELEASE_REPO_DIR}
13+
cd ${RELEASE_REPO_DIR}
14+
15+
gh release create ${TARGET_VERSION_TAG} --target ${RELEASE_BRANCH} --generate-notes --notes-start-tag ${PREVIOUS_VERSION_TAG}
16+
17+
cat <<EOF >> /tmp/release-notes.md
18+
19+
This is a release comprising of multiple repos:
20+
* DSP component for ${TARGET_VERSION_TAG} can be found [here](https://github.com/${GH_ORG}/data-science-pipelines/releases/tag/${TARGET_VERSION_TAG})
21+
* DSPO component for ${TARGET_VERSION_TAG} can be found [here](https://github.com/${GH_ORG}/data-science-pipelines-operator/releases/tag/${TARGET_VERSION_TAG})
22+
23+
Version Table for components can be found [here](https://github.com/${GH_ORG}/data-science-pipelines-operator/blob/main/docs/release/compatibility.md)
24+
EOF
25+
26+
echo "$(gh release view ${TARGET_VERSION_TAG} --json body --jq .body)" >> /tmp/release-notes.md
27+
28+
echo "Release notes to be created:"
29+
cat /tmp/release-notes.md
30+
31+
gh release edit ${TARGET_VERSION_TAG} --notes-file /tmp/release-notes.md
32+
rm /tmp/release-notes.md
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
cat <<EOF >> /tmp/body-file.txt
6+
Release created successfully:
7+
8+
https://github.com/${GH_ORG}/data-science-pipelines-operator/releases/tag/${TARGET_VERSION_TAG}
9+
10+
https://github.com/${GH_ORG}/data-science-pipelines/releases/tag/${TARGET_VERSION_TAG}
11+
EOF
12+
13+
gh pr comment ${PR_NUMBER} --body-file /tmp/body-file.txt
14+
15+
echo "::notice:: DSPO Release: https://github.com/${GH_ORG}/data-science-pipelines-operator/releases/tag/${TARGET_VERSION_TAG}"
16+
echo "::notice:: DSP Release: https://github.com/${GH_ORG}/data-science-pipelines/releases/tag/${TARGET_VERSION_TAG}"
17+
echo "::notice:: Feedback sent to PR."
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
echo "::notice:: Performing Release PR Validation for: ${PR_NUMBER}"
6+
7+
# Retrive PR Author:
8+
PR_AUTHOR=$(gh pr view ${PR_NUMBER} --json author -q .author.login)
9+
10+
echo "Current OWNERS:"
11+
cat ./OWNERS
12+
13+
echo "::notice:: Checking if PR author ${PR_AUTHOR} is DSPO Owner..."
14+
15+
is_owner=$(cat ./OWNERS | var=${PR_AUTHOR} yq '[.approvers] | contains([env(var)])')
16+
if [[ $is_owner == "false" ]]; then
17+
echo "::error:: PR author ${PR_AUTHOR} is not an approver in OWNERS file. Only approvers can create releases."
18+
exit 1
19+
fi
20+
21+
echo "::notice:: PR author ${PR_AUTHOR} is an approver in DSPO OWNERS."
22+
23+
echo "::notice:: Validation successful."
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
cat ./config.yaml
6+
target_version_tag=$(yq .target_version_tag ./config.yaml)
7+
previous_version_tag=$(yq .previous_release_tag ./config.yaml)
8+
release_branch=$(yq .release_branch ./config.yaml)
9+
odh_org=$(yq .odh_org ./config.yaml)
10+
pr_number=$(cat ./pr_number)
11+
12+
echo "pr_number=${pr_number}" >> $GITHUB_OUTPUT
13+
echo "target_version_tag=${target_version_tag}" >> $GITHUB_OUTPUT
14+
echo "previous_version_tag=${previous_version_tag}" >> $GITHUB_OUTPUT
15+
echo "release_branch=${release_branch}" >> $GITHUB_OUTPUT
16+
echo "odh_org=${odh_org}" >> $GITHUB_OUTPUT
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
echo "Cut branch ${MINOR_RELEASE_BRANCH} from main/master"
6+
7+
echo "Current branches in ${DSPO_REPOSITORY_FULL}"
8+
git branch -r
9+
10+
git checkout -B ${MINOR_RELEASE_BRANCH}
11+
git push origin ${MINOR_RELEASE_BRANCH}
12+
echo "::notice:: Created DSPO ${MINOR_RELEASE_BRANCH} branch"
13+
14+
echo "Current branches in ${DSP_REPOSITORY_FULL}"
15+
DSP_DIR=$(dirname ${WORKING_DIR})/data-science-pipelines
16+
git clone \
17+
--depth=1 \
18+
--branch=master \
19+
https://${GH_USER_NAME}:${GH_TOKEN}@github.com/${DSP_REPOSITORY_FULL} \
20+
${DSP_DIR}
21+
cd ${DSP_DIR}
22+
git checkout -B ${MINOR_RELEASE_BRANCH}
23+
git push origin ${MINOR_RELEASE_BRANCH}
24+
echo "::notice:: Created DSP ${MINOR_RELEASE_BRANCH} branch"
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env bash
2+
3+
# Note: The yaml in the body of the PR is used to feed inputs into the release workflow
4+
# since there's no easy way to communicate information between the pr closing, and then triggering the
5+
# release creation workflow.
6+
# Therefore, take extra care when adding new code blocks in the PR body, or updating the existing one.
7+
# Ensure any changes are compatible with the release_create workflow.
8+
9+
set -ex
10+
set -o pipefail
11+
12+
echo "Retrieve the sha images from the resulting workflow (check quay.io for the digests)."
13+
echo "Using [release-tools] generate a params.env and submit a new pr to vx.y+1.**x** branch."
14+
echo "For images pulled from registry, ensure latest images are upto date"
15+
16+
BRANCH_NAME="release-${TARGET_RELEASE}"
17+
git config --global user.email "${GH_USER_EMAIL}"
18+
git config --global user.name "${GH_USER_NAME}"
19+
git remote add ${GH_USER_NAME} https://${GH_USER_NAME}:${GH_TOKEN}@github.com/${GH_USER_NAME}/${DSPO_REPOSITORY}.git
20+
git checkout -B ${BRANCH_NAME}
21+
22+
echo "Created branch: ${BRANCH_NAME}"
23+
24+
python ./scripts/release/release.py params --quay_org ${QUAY_ORG} --tag ${MINOR_RELEASE_TAG} --out_file ./config/base/params.env \
25+
--override="IMAGES_OAUTHPROXY=registry.redhat.io/openshift4/ose-oauth-proxy@sha256:ab112105ac37352a2a4916a39d6736f5db6ab4c29bad4467de8d613e80e9bb33"
26+
27+
git add .
28+
git commit -m "Generate params for ${TARGET_RELEASE}"
29+
git push ${GH_USER_NAME} $BRANCH_NAME -f
30+
31+
# Used to feed inputs to release creation workflow.
32+
# target_version is used as the GH TAG
33+
tmp_config="/tmp/body-config.txt"
34+
body_txt="/tmp/body-text.txt"
35+
cp $CONFIG_TEMPLATE $tmp_config
36+
37+
var=${GH_ORG} yq -i '.odh_org=env(var)' $tmp_config
38+
var=${MINOR_RELEASE_BRANCH} yq -i '.release_branch=env(var)' $tmp_config
39+
var=${MINOR_RELEASE_TAG} yq -i '.target_version_tag=env(var)' $tmp_config
40+
var=${PREVIOUS_RELEASE_TAG} yq -i '.previous_release_tag=env(var)' $tmp_config
41+
42+
43+
cat <<"EOF" > $body_txt
44+
This is an automated PR to prep Data Science Pipelines Operator for release.
45+
```yaml
46+
<CONFIG_HERE>
47+
```
48+
EOF
49+
50+
sed -i "/<CONFIG_HERE>/{
51+
s/<CONFIG_HERE>//g
52+
r ${tmp_config}
53+
}" $body_txt
54+
55+
56+
pr_url=$(gh pr create \
57+
--repo https://github.com/${DSPO_REPOSITORY_FULL} \
58+
--body-file $body_txt \
59+
--title "Release ${MINOR_RELEASE_TAG}" \
60+
--head "${GH_USER_NAME}:$BRANCH_NAME" \
61+
--label "release-automation" \
62+
--base "${MINOR_RELEASE_BRANCH}")
63+
64+
65+
66+
echo "::notice:: PR successfully created: ${pr_url}"
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
check_branch_exists(){
6+
branch_exists=$(git ls-remote --heads https://github.com/${1}.git refs/heads/${2})
7+
echo "Checking for existence of branch ${2} in GH Repo ${1}"
8+
if [[ $branch_exists ]]; then
9+
echo "::error:: Branch ${2} already exist in GH Repo ${1}"
10+
exit 1
11+
fi
12+
echo "::notice:: Confirmed Branch ${2} does not exist in GH Repo ${1}"
13+
}
14+
15+
check_branch_exists ${DSPO_REPOSITORY_FULL} ${MINOR_RELEASE_BRANCH}
16+
check_branch_exists ${DSP_REPOSITORY_FULL} ${MINOR_RELEASE_BRANCH}
17+
18+
echo "Ensure compatibility.yaml is upto date, and generate a new compatibility.md. Use [release-tools] to accomplish this"
19+
20+
BRANCH_NAME="compatibility-doc-generate-${TARGET_RELEASE}"
21+
22+
git config --global user.email "${GH_USER_EMAIL}"
23+
git config --global user.name "${GH_USER_NAME}"
24+
git remote add ${GH_USER_NAME} https://${GH_USER_NAME}:${GH_TOKEN}@github.com/${GH_USER_NAME}/${DSPO_REPOSITORY}.git
25+
git checkout -B ${BRANCH_NAME}
26+
27+
echo "Created branch: ${BRANCH_NAME}"
28+
echo "Checking if compatibility.yaml contains ${TARGET_RELEASE} release...."
29+
30+
contains_rel=$(cat docs/release/compatibility.yaml | rel=${MINOR_RELEASE_WILDCARD} yq '[.[].dsp] | contains([env(rel)])')
31+
32+
if [[ "$contains_rel" == "false" ]]; then
33+
34+
cat <<EOF >> /tmp/error.txt
35+
compatibility.yaml has NOT been updated with target release.
36+
37+
Please add ${MINOR_RELEASE_WILDCARD} dsp row in compatibility.yaml,
38+
39+
then regenerate the compatibility.md by following the instructions here:
40+
https://github.com/opendatahub-io/data-science-pipelines-operator/tree/main/scripts/release#compatibility-doc-generation
41+
EOF
42+
43+
echo ::error::$(cat /tmp/error.txt)
44+
exit 1
45+
46+
fi
47+
48+
echo "::notice:: Confirmed existence of ${MINOR_RELEASE_BRANCH} in compatibility.yaml."
49+
50+
echo "Confirming that compatibility.md is upto date."
51+
python ./scripts/release/release.py version_doc --input_file docs/release/compatibility.yaml --out_file docs/release/compatibility.md
52+
53+
git status
54+
55+
prereqs_successful=true
56+
57+
if [[ `git status --porcelain` ]]; then
58+
echo "::notice:: Compatibility.md is not up to date with Compatibility.yaml, creating pr to synchronize."
59+
60+
git add .
61+
git commit -m "Update DSPO to $TARGET_RELEASE"
62+
git push ${GH_USER_NAME} $BRANCH_NAME -f
63+
gh pr create \
64+
--repo https://github.com/${DSPO_REPOSITORY_FULL} \
65+
--body "This is an automated PR to update Data Science Pipelines Operator version compatibility doc." \
66+
--title "Update DSP version compatibility doc." \
67+
--head "${GH_USER_NAME}:$BRANCH_NAME" \
68+
--base "main"
69+
70+
echo "::notice:: PR to update compatibility doc has been created, please re-run this workflow once this PR is merged."
71+
prereqs_successful=false
72+
else
73+
echo "::notice:: Compatibility.md doc is up to date with Compatibility.yaml, continuing with workflow..."
74+
fi
75+
76+
# Save step outputs
77+
echo "prereqs_successful=${prereqs_successful}"
78+
echo "prereqs_successful=${prereqs_successful}" >> $GITHUB_OUTPUT
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
odh_org: placeholder
2+
release_branch: placeholder
3+
target_version_tag: placeholder
4+
previous_release_tag: placeholder
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
set -o pipefail
4+
5+
mkdir -p ./pr
6+
7+
cat <<EOF >> /tmp/body-file-raw.txt
8+
${PR_BODY}
9+
EOF
10+
11+
sed -n '/^```yaml/,/^```/ p' < /tmp/body-file-raw.txt | sed '/^```/ d' > ./pr/config.yaml
12+
echo Parsed config from PR body:
13+
yq ./pr/config.yaml
14+
15+
# Also store pr details
16+
echo ${PR_NUMBER} >> ./pr/pr_number
17+
echo ${PR_STATE} >> ./pr/pr_state
18+
echo ${PR_HEAD_SHA} >> ./pr/head_sha

.github/scripts/tests/tests.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
set -ex
4+
5+
echo "Perform any tests on the branch, confirm stability. If issues are found, they should be corrected in `main/master` and be cherry-picked into this branch."

0 commit comments

Comments
 (0)