Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add release workflow #166

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions .github/workflows/create-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: "Create release"

env:
IMAGE_REPO: europe-docker.pkg.dev/kyma-project/prod/runtime-watcher-skr
CODE_REPOSITORY: kyma-project/runtime-watcher
on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]-?*'
jobs:
validate-release:
name: Validate release
runs-on: ubuntu-latest
outputs:
current_release_tag: ${{ steps.get_current_release_tag.outputs.current_release_tag }}
last_release_tag: ${{ steps.get_last_release_tag.outputs.last_release_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find the release tag
id: get_current_release_tag
run: |
echo "Current release tag: ${GITHUB_REF#refs/*/}"
echo "current_release_tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
- name: Check if release doesn't exist yet
env:
CURRENT_RELEASE_TAG: ${{ steps.get_current_release_tag.outputs.current_release_tag }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./runtime-watcher/scripts/release/get_release_by_tag.sh $CURRENT_RELEASE_TAG
- name: Get last release version
id: get_last_release_tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set +e
SCRIPT_OUTPUT=$(./runtime-watcher/scripts/release/get_last_release.sh)
SCRIPT_EXIT_CODE=$?
if [[ $SCRIPT_EXIT_CODE != 0 ]]; then
echo "$SCRIPT_OUTPUT"
exit $SCRIPT_EXIT_CODE
fi
set -e
echo "Last Release version: $SCRIPT_OUTPUT"
echo "last_release_tag=$SCRIPT_OUTPUT" >> $GITHUB_OUTPUT
- name: Wait for the Docker image
timeout-minutes: 15
env:
ITERATIONS: 30
SLEEP_SECONDS: 30
run: ./runtime-watcher/scripts/release/wait_for_image.sh ${{ env.IMAGE_REPO }}:${{ steps.get_current_release_tag.outputs.current_release_tag }} $ITERATIONS $SLEEP_SECONDS
draft-release:
name: Create draft release
runs-on: ubuntu-latest
needs: validate-release
outputs:
release_id: ${{ steps.draft_release.outputs.release_id }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
id: generate_changelog
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURRENT_RELEASE_TAG: ${{ needs.validate-release.outputs.current_release_tag }}
LAST_RELEASE_TAG: ${{ needs.validate-release.outputs.last_release_tag }}
run: |
echo "Generating changelog for version: ${{ needs.validate-release.outputs.current_release_tag }}"
CHANGELOG_FILE_NAME=$(./runtime-watcher/scripts/release/create_changelog.sh $CURRENT_RELEASE_TAG $LAST_RELEASE_TAG)
echo "changelog_file_name=$CHANGELOG_FILE_NAME" >> $GITHUB_OUTPUT
- name: Create draft release
id: draft_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURRENT_RELEASE_TAG: ${{ needs.validate-release.outputs.current_release_tag }}
CHANGELOG_FILE_NAME: ${{ steps.generate_changelog.outputs.changelog_file_name }}
run: |
RELEASE_ID=$(./runtime-watcher/scripts/release/create_draft_release.sh $CURRENT_RELEASE_TAG $CHANGELOG_FILE_NAME)
echo "RELEASE_ID=$RELEASE_ID"
echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT
publish_release:
name: Publish release
runs-on: ubuntu-latest
needs: draft-release
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Publish release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_ID: ${{ needs.draft-release.outputs.release_id }}
run: |
echo "RELEASE_ID=$RELEASE_ID"
./runtime-watcher/scripts/release/publish_release.sh $RELEASE_ID
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ The [Listener package](https://github.com/kyma-project/runtime-watcher/tree/main

## Read more

The release process is described in the [How To Release](./docs/how_to_release.md) document.
For further details on Runtime Watcher's architecture, see the [Architecture](./docs/architecture.md) document.
15 changes: 15 additions & 0 deletions docs/how_to_release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Runtime Watcher Release Procedure

Use the steps described in this document to release a new version of Runtime Watcher.

## Steps

1. Checkout the main branch.
2. Create a new tag for the release in the main branch and push it to the repository. The tag should follow the [Semantic Versioning 2.0.0 format](https://semver.org/), for example, `1.2.3`.
The new tag will trigger a ProwJob that creates and publishes a Docker image with a Runtime Watcher executable.
The new tag will also trigger the release workflow.

> **NOTE:** The release workflow waits for a Docker image to be published. If the image is not available within the configured time (15 minutes), the workflow fails. In that case, you need to manually re-run it once the Docker image is ready. The expected image URL is: `europe-docker.pkg.dev/kyma-project/prod/runtime-watcher-skr:<NewTag>`

> **NOTE:** If you want to create a tag without triggering a release, just ensure the tag does not match the Semantic Versioning format.

25 changes: 25 additions & 0 deletions runtime-watcher/scripts/release/create_changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

CURRENT_RELEASE_TAG=$1
LAST_RELEASE_TAG=$2

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: token ${GITHUB_TOKEN}"
CHANGELOG_FILE="CHANGELOG.md"

echo "## What has changed" >> ${CHANGELOG_FILE}

git log ${LAST_RELEASE_TAG}..${CURRENT_RELEASE_TAG} --pretty=tformat:"%h" --reverse | while read -r commit
do
COMMIT_AUTHOR=$(curl -H "${GITHUB_AUTH_HEADER}" -sS "${GITHUB_URL}/commits/${commit}" | jq -r '.author.login')
git show -s ${commit} --format="* %s by @${COMMIT_AUTHOR}" >> ${CHANGELOG_FILE}
done

echo -e "\n**Full changelog**: $GITHUB_URL/compare/${LAST_RELEASE_TAG}...${CURRENT_RELEASE_TAG}" >> ${CHANGELOG_FILE}

echo ${CHANGELOG_FILE}
40 changes: 40 additions & 0 deletions runtime-watcher/scripts/release/create_draft_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

RELEASE_TAG=$1
CHANGELOG_FILE_NAME=$2
CHANGELOG_FILE=$(cat ${CHANGELOG_FILE_NAME})

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}"

#echo "RELEASE_TAG: ${RELEASE_TAG}"
#echo "CHANGELOG_FILE_NAME: ${CHANGELOG_FILE_NAME}"

JSON_PAYLOAD=$(jq -n \
--arg tag_name "$RELEASE_TAG" \
--arg name "$RELEASE_TAG" \
--arg body "$CHANGELOG_FILE" \
'{
"tag_name": $tag_name,
"name": $name,
"body": $body,
"draft": true
}')

CURL_RESPONSE=$(curl -L \
-s \
--fail-with-body \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "${GITHUB_AUTH_HEADER}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases \
-d "$JSON_PAYLOAD")

# return the id of the release draft
echo "$CURL_RESPONSE" | jq -r ".id"
23 changes: 23 additions & 0 deletions runtime-watcher/scripts/release/get_last_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

set -o nounset
set -o pipefail

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}

CURL_RESPONSE=$(curl -L \
-s \
--fail-with-body \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases/latest)

CURL_EXIT_CODE=$?

if [[ ${CURL_EXIT_CODE} == 0 ]]; then
echo "${CURL_RESPONSE}" | jq -r .tag_name
else
echo "Can't find any previous release - unable to generate changelog"
fi

exit ${CURL_EXIT_CODE}
26 changes: 26 additions & 0 deletions runtime-watcher/scripts/release/get_release_by_tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

set -o nounset
set -o pipefail

RELEASE_TAG=$1

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}"

CURL_RESPONSE=$(curl -L \
-s \
--fail-with-body \
-H "Accept: application/vnd.github+json" \
-H "${GITHUB_AUTH_HEADER}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases/tags/$RELEASE_TAG)

CURL_EXIT_CODE=$?

if [[ ${CURL_EXIT_CODE} == 0 ]]; then
echo "Release with tag: $RELEASE_TAG already exists!"
exit 1
fi

exit 0
23 changes: 23 additions & 0 deletions runtime-watcher/scripts/release/publish_release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

RELEASE_ID=$1

GITHUB_URL=https://api.github.com/repos/${CODE_REPOSITORY}
GITHUB_AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}"

CURL_RESPONSE=$(curl -L \
-s \
--fail-with-body \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "${GITHUB_AUTH_HEADER}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${GITHUB_URL}"/releases/"${RELEASE_ID}" \
-d '{"draft":false}')
echo "$CURL_RESPONSE"

25 changes: 25 additions & 0 deletions runtime-watcher/scripts/release/wait_for_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

set -o nounset
set -o errexit
set -E
set -o pipefail

DOCKER_IMAGE=$1
ITERATIONS="${2:-30}"
SLEEP_TIME="${3:-30}"

for (( c=1; c<=$ITERATIONS; c++ ))
do
if $(docker manifest inspect $1 > /dev/null 2>&1); then
exit 0
fi
echo "Attempt $c: Docker image: $DOCKER_IMAGE doesn't exist"
if [[ $c -lt $ITERATIONS ]]; then
sleep ${SLEEP_TIME}
fi
done

echo "Fail: Docker image: $DOCKER_IMAGE doesn't exist"
exit 1