Skip to content

Commit

Permalink
ODH release automation
Browse files Browse the repository at this point in the history
  • Loading branch information
AjayJagan committed Apr 26, 2024
1 parent 080051b commit 48d338e
Show file tree
Hide file tree
Showing 14 changed files with 489 additions and 16 deletions.
31 changes: 31 additions & 0 deletions .github/actions/create-release-pr/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "Create release pr"
description: "Updates get_all_manifests.sh with relavent tags and creates a pr"
inputs:
pr-branch:
required: true
description: "Branch containing the changes to create pr"
commit-message:
required: true
description: "Commit message for the pr"
title:
required: true
description: "Title of the pr"
runs:
using: "composite"
steps:
- name: Update branches in get_all_manifest.sh
uses: actions/github-script@v7
with:
script: |
const script = require('./.github/scripts/get-release-branches.js')
script({github, core})
- name: Update versions
shell: bash
run: ./.github/scripts/update-manifests-tags.sh ${{ env.CODEFLARE }} ${{ env.KUBERAY }} ${{ env.KUEUE }} ${{ env.DSP }} ${{ env.DASHBOARD }} ${{ env.NOTEBOOK-CONTROLLER }} ${{ env.NOTEBOOK-CONTROLLER }} ${{ env.NOTEBOOKS }} ${{ env.TRUSTYAI }} ${{ env.MODELMESH }} ${{ env.ODH-MODEL-CONTROLLER }} ${{ env.KSERVE }} ${{ env.MODEL-REGISTRY }}
- name: Create release pr
uses: peter-evans/create-pull-request@v6
with:
commit-message: ${{ inputs.commit-message }}
branch: ${{ inputs.pr-branch }}
delete-branch: true
title: ${{ inputs.title }}
40 changes: 40 additions & 0 deletions .github/actions/set-shared-env/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: "Set Shared env vars"
description: "Gets repo env and sets in workflow env"
inputs:
pat-token:
required: true
description: "A personal access token to read repo envs."
runs:
using: "composite"
steps:
- name: Get and set env variables
uses: actions/github-script@v7
with:
github-token: ${{ inputs.pat-token }}
script: |
try{
async function getAndSetVariables(){
const { data: versionData } = await github.request('GET /repos/{owner}/{repo}/actions/variables/{name}', {
owner: context.repo.owner,
repo: context.repo.repo,
name: 'VERSION',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
})
const { data: trackerUrlData } = await github.request('GET /repos/{owner}/{repo}/actions/variables/{name}', {
owner: context.repo.owner,
repo: context.repo.repo,
name: 'TRACKER_URL',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
})
console.log(`The VERSION is ${versionData.value} and the TRACKER_URL is ${trackerUrlData.value}`)
core.exportVariable('VERSION', versionData.value);
core.exportVariable('TRACKER_URL', trackerUrlData.value);
}
getAndSetVariables()
}catch(e){
core.setFailed(`Action failed with error ${e}`);
}
39 changes: 39 additions & 0 deletions .github/scripts/get-component-release-notes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module.exports = ({ github, core }) => {
const { TRACKER_URL } = process.env
console.log(`The TRACKER_URL is ${TRACKER_URL}`)
const arr = TRACKER_URL.split("/")
const owner = arr[3]
const repo = arr[4]
const issue_number = arr[6]

github.request('GET /repos/{owner}/{repo}/issues/{issue_number}/comments', {
owner,
repo,
issue_number,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
'Accept': 'application/vnd.github.text+json'
}
}).then((result) => {
const allowedComponents = ["dashboard", "notebooks", "notebook-controller", "trustyai", "kserve", "modelmesh-serving", "model-registry", "kueue", "codeflare", "kuberay", "dsp"]
let outputStr = "## Component Release Notes\n"
result.data.forEach((issue) => {
issueCommentBody = issue.body_text
if (issueCommentBody.includes("#Release#")) {
let components = issueCommentBody.split("\n")
components = components.splice(2, components.length - 1)
components.forEach(component => {
[componentName, branchUrl, tagUrl] = component.split("|")
if (allowedComponents.includes(componentName)) {
outputStr += `- **${componentName.charAt(0).toUpperCase() + componentName.slice(1)}**: ${tagUrl}\n`
}
})
}
})
console.log("Created component release notes successfully...")
core.setOutput('release-notes-body', outputStr);
}).catch(e => {
core.setFailed(`Action failed with error ${e}`);
})
}

38 changes: 38 additions & 0 deletions .github/scripts/get-release-branches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = ({ github, core }) => {
const { TRACKER_URL } = process.env
console.log(`The tracker url is: ${TRACKER_URL}`)

const arr = TRACKER_URL.split("/")
const owner = arr[3]
const repo = arr[4]
const issue_number = arr[6]

github.request('GET /repos/{owner}/{repo}/issues/{issue_number}/comments', {
owner,
repo,
issue_number,
headers: {
'X-GitHub-Api-Version': '2022-11-28',
'Accept': 'application/vnd.github.text+json'
}
}).then((result) => {
result.data.forEach((issue) => {
issueCommentBody = issue.body_text
if (issueCommentBody.includes("#Release#")) {
let components = issueCommentBody.split("\n")
components = components.splice(2, components.length - 1)
components.forEach(component => {
[componentName, branchUrl] = component.split("|")
const splitArr = branchUrl.split("/")
const idx = splitArr.indexOf("tree")
const branchName = splitArr.slice(idx + 1).join("/")
core.exportVariable(componentName.toUpperCase(), branchName);
})
}
})
console.log("Read release/tag from tracker issue successfully...")
}).catch(e => {
core.setFailed(`Action failed with error ${e}`);
})
}

38 changes: 38 additions & 0 deletions .github/scripts/update-manifests-tags.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

set -euo pipefail

update_tags(){
MANIFEST_STR=$(cat get_all_manifests.sh | grep $1 | sed 's/ //g')
readarray -d ":" -t STR_ARR <<< "$MANIFEST_STR"
RES=""
for i in "${!STR_ARR[@]}"; do
if [ $i == 2 ]; then
RES+=$2":"
else
RES+=${STR_ARR[$i]}":"
fi
done
echo "${RES::-2}"
sed -i -r "s|.*$1.*| ${RES::-2}|" get_all_manifests.sh
}

declare -A COMPONENT_VERSION_MAP=(
["\"codeflare\""]=$1
["\"ray\""]=$2
["\"kueue\""]=$3
["\"data-science-pipelines-operator\""]=$4
["\"odh-dashboard\""]=$5
["\"kf-notebook-controller\""]=$6
["\"odh-notebook-controller\""]=$7
["\"notebooks\""]=$8
["\"trustyai\""]=$9
["\"model-mesh\""]=$10
["\"odh-model-controller\""]=$11
["\"kserve\""]=$12
["\"modelregistry\""]=$13
)

for key in ${!COMPONENT_VERSION_MAP[@]}; do
update_tags ${key} ${COMPONENT_VERSION_MAP[${key}]}
done
31 changes: 31 additions & 0 deletions .github/scripts/update-variables.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = ({ github, context, core }) => {
const { VERSION, TRACKER_URL } = process.env
try {
console.log(`Variables to update are: VERSION: ${VERSION} and TRACKER_URL:${TRACKER_URL}`)
async function updateVariables() {
await github.request('PATCH /repos/{owner}/{repo}/actions/variables/{name}', {
owner: context.repo.owner,
repo: context.repo.repo,
name: 'VERSION',
value: VERSION,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
})

await github.request('PATCH /repos/{owner}/{repo}/actions/variables/{name}', {
owner: context.repo.owner,
repo: context.repo.repo,
name: 'TRACKER_URL',
value: TRACKER_URL,
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
})
}
updateVariables()
console.log("Updated variables successfully...")
} catch (e) {
core.setFailed(`Action failed with error ${e}`);
}
}
23 changes: 23 additions & 0 deletions .github/scripts/validate-semver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

set -euo pipefail

sem_ver_pattern="^[vV](0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"

die () {
echo >&2 "$@"
exit 1
}

validate_semantic_versioning() {
version=$1

if [[ ${version} == "" ]]; then
die "Undefined version. Please use semantic versioning https://semver.org/."
fi

# Ensure defined version matches semver rules
if [[ ! "${version}" =~ $sem_ver_pattern ]]; then
die "\`${version}\` you defined as a version does not match semantic versioning. Please make sure it conforms with https://semver.org/ and make sure it starts with v prefix."
fi
}
25 changes: 25 additions & 0 deletions .github/scripts/wait-for-checks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
#
# @param $1 - PR number or URL
# wait for a bit until pr is created, otherwise it throws an error "no checks reported on the 'odh-release/e2e-test' branch"
set -euo pipefail

sleep 10

while $(gh pr checks "$1" | grep -q -v 'tide' | grep -q 'pending'); do
printf ":stopwatch: PR checks still pending, retrying in 10 seconds...\n"
sleep 10
done

if $(gh pr checks "$1" | grep -q 'fail'); then
printf "!!PR checks failed!!\n"
exit 1
fi

if $(gh pr checks "$1" | grep -q 'pass'); then
printf "!!PR checks passed!!\n"
exit 0
fi

printf "!!An unknown error occurred!!\n"
exit 1
31 changes: 31 additions & 0 deletions .github/workflows/release-branch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: "Release: Create release branch"
on:
pull_request:
types:
- closed
jobs:
create-release-branch:
if: github.event.pull_request.merged && startsWith(github.event.pull_request.title, 'ODH Release') && endsWith(github.event.pull_request.title, 'Version Update')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: tibdex/github-app-token@v1
id: generate-token
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Set env variables
uses: ./.github/actions/set-shared-env
with:
pat-token: ${{ steps.generate-token.outputs.token }}
- name: Create release branch
run: |
git checkout -b odh-${{ env.VERSION }}
git push -f origin odh-${{ env.VERSION }}
- name: Create release pr to release branch
uses: ./.github/actions/create-release-pr
with:
pr-branch: "odh-release/branch-update"
title: "ODH ${{ env.VERSION }} Release"
commit-message: "ODH ${{ env.VERSION }} Release"
# reviewers: "VaishnaviHire,zdtsw,AjayJagan,ykaliuta" TODO
Loading

0 comments on commit 48d338e

Please sign in to comment.