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

Imporved the release process of training operator #2359

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
46 changes: 46 additions & 0 deletions .github/workflows/check-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Check Release

on:
pull_request:
branches:
- release-*
paths:
- VERSION

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
SEMVER_PATTERN: '^v([0-9]+)\.([0-9]+)\.([0-9]+)(-rc\.([0-9]+))?$'

jobs:
check-release:
runs-on: ubuntu-latest

steps:
- name: Chekcout source code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check whether version matches semver pattern
run: |
VERSION=$(cat VERSION)
if [[ ${VERSION} =~ ${{ env.SEMVER_PATTERN }} ]]; then
echo "Version '${VERSION}' matches semver pattern."
else
echo "Version '${VERSION}' does not match semver pattern."
exit 1
fi
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Check if tag exists
run: |
git fetch --tags
if git tag -l | grep -q "^${VERSION}$"; then
echo "Tag '${VERSION}' already exists."
exit 1
else
echo "Tag '${VERSION}' does not exist."
fi
227 changes: 227 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
name: Release

on:
push:
branches:
- release-*
paths:
- VERSION

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
SEMVER_PATTERN: '^v([0-9]+)\.([0-9]+)\.([0-9]+)(-rc\.([0-9]+))?$'
IMAGE_REGISTRY: docker.io
IMAGE_REPOSITORY: kubeflow/training-operator

jobs:
check-release:
runs-on: ubuntu-latest

steps:
- name: Chekcout source code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check whether version matches semver pattern
run: |
VERSION=$(cat VERSION)
if [[ ${VERSION} =~ ${{ env.SEMVER_PATTERN }} ]]; then
echo "Version '${VERSION}' matches semver pattern."
else
echo "Version '${VERSION}' does not match semver pattern."
exit 1
fi
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Check if tag exists
run: |
git fetch --tags
if git tag -l | grep -q "^${VERSION}$"; then
echo "Tag '${VERSION}' already exists."
exit 1
else
echo "Tag '${VERSION}' does not exist."
fi

build-images:
needs: check-release

runs-on: ubuntu-latest

strategy:
fail-fast: false # Need to confirm with maintainers
matrix:
platform:
- linux/amd64
- linux/arm64

steps:
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV

- name: Checkout source code
uses: actions/checkout@v4

- name: Read version from VERSION file
run: |
VERSION=$(cat VERSION)
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REPOSITORY }}
tags: |
type=semver,pattern={{version}},value=${{ env.VERSION }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to container registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: .
file: build/images/training-operator/Dockerfile
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REPOSITORY }},push-by-digest=true,name-canonical=true,push=true

- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

release-images:
needs: build-images

runs-on: ubuntu-latest

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Read version from VERSION file
run: |
VERSION=$(cat VERSION)
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REPOSITORY }}
tags: |
type=semver,pattern={{version}},value=${{ env.VERSION }}

- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

- name: Set up Docker buildx
uses: docker/setup-buildx-action@v3

- name: Login to container registry
uses: docker/login-action@v3
with:
registry: ${{ env.IMAGE_REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REPOSITORY }}@sha256:%s ' *)

- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_REPOSITORY }}:${{ steps.meta.outputs.version }}

push-tags:
needs: release-images

runs-on: ubuntu-latest

steps:
- name: Checkout source code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"

- name: Read version from VERSION file
run: |
VERSION=$(cat VERSION)
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Create and push tag
run: |
git tag -a "${VERSION}" -m "Training Operator Official Release ${VERSION}"
git push origin "${VERSION}"

draft-release:
needs: push-tags

permissions:
contents: write

runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"

- name: Read version from VERSION file
run: |
VERSION=$(cat VERSION)
echo "VERSION=${VERSION}" >> $GITHUB_ENV

- name: Create release
id: release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: "${{ env.VERSION }}"
tag_name: ${{ env.VERSION }}
prerelease: ${{ contains(env.VERSION, 'rc') }}
target_commitish: ${{ github.sha }}
draft: true
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v1.8.1
100 changes: 100 additions & 0 deletions docs/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Releasing the Training operator

## Prerequisites

- [Write](https://docs.github.com/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#permission-levels-for-repositories-owned-by-an-organization) permission for the Spark operator repository.

- Create a [GitHub Token](https://docs.github.com/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token).

- Install `PyGithub` to generate the [Changelog](../CHANGELOG.md):

```bash
pip install PyGithub==2.3.0
```

## Versioning policy

Training Operator version format follows [Semantic Versioning](https://semver.org/). Training Operator versions are in the format of `vX.Y.Z`, where `X` is the major version, `Y` is the minor version, and `Z` is the patch version. The patch version contains only bug fixes.

Additionally, Training Operator does pre-releases in this format: `vX.Y.Z-rc.N` where `N` is a number of the `Nth` release candidate (RC) before an upcoming public release named `vX.Y.Z`.

## Release branches and tags

Training Operator releases are tagged with tags like `vX.Y.Z`, for example `v1.7.2`.

Release branches are in the format of `release-X.Y`, where `X.Y` stands for the minor release.

`vX.Y.Z` releases are released from the `release-X.Y` branch. For example, `v1.7.2` release should be on `release-1.7` branch.

If you want to push changes to the `release-X.Y` release branch, you have to cherry pick your changes from the `master` branch and submit a PR.

## Create a new release

### Create release branch

1. Depends on what version you want to release,

- Major or Minor version - Use the GitHub UI to create a release branch from `master` and name the release branch `release-X.Y`.
- Patch version - You don't need to create a new release branch.

2. Fetch the upstream changes into your local directory:

```bash
git fetch upstream
```

3. Checkout into the release branch:

```bash
git checkout release-X.Y
git rebase upstream/release-X.Y
```

### Create GitHub tag

1. Modify `VERSION` file in the root directory of the project:

- For the RC tag as follows:

```bash
vX.Y.Z-rc.N
```

- For the official release tag as follows:

```bash
vX.Y.Z
```
2. Commit the changes:

```bash
git add VERSION
git commit -s -m "Training Operator Official Release v${VERSION}"
git push origin release-X.Y
```
3. Submit a PR to the release branch.

### Release Training Operator Image

After `VERSION` file is modified and pushed to the release branch, a release workflow will be triggered to build and push Training operator docker images to Docker Hub.


## Update Changelog

Update the `CHANGELOG.md` file by running:

```bash
python hack/generate-changelog.py \
--token=<github-token> \
--range=<previous-release>..<current-release>
```

If you are creating the **first minor pre-release** or the **minor** release (`X.Y`), your `previous-release` is equal to the latest release on the `release-X.Y` branch.
For example: `--range=v1.7.1..v1.8.0`.

Otherwise, your `previous-release` is equal to the latest release on the `release-X.Y` branch.
For example: `--range=v1.7.0..v1.8.0-rc.0`

Group PRs in the Changelog into Features, Bug fixes, Documentation, etc.

Finally, submit a PR with the updated Changelog.
Loading
Loading