Skip to content
This repository has been archived by the owner on Jul 17, 2024. It is now read-only.

Commit

Permalink
fix: issues with the release script
Browse files Browse the repository at this point in the history
Signed-off-by: Mateusz Urbanek <mateusz.urbanek.98@gmail.com>
  • Loading branch information
shanduur committed May 29, 2024
1 parent d9bb0f6 commit 49890f2
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 52 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: changelog

on:
push:
tags:
- v*

permissions: write-all

jobs:
deploy:
name: Generate changelog and publish a release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: requarks/changelog-action@v1
id: changelog
with:
token: ${{ github.token }}
tag: ${{ github.ref_name }}
- uses: ncipollo/release-action@v1.13.0
with:
allowUpdates: true
draft: false
makeLatest: true
name: ${{ github.ref_name }}
body: ${{ steps.changelog.outputs.changes }}
token: ${{ github.token }}
2 changes: 1 addition & 1 deletion docs/.crd-ref-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ processor:

render:
# Version of Kubernetes to use when generating links to Kubernetes API documentation.
kubernetesVersion: 'v1.30'
kubernetesVersion: '1.30'
2 changes: 1 addition & 1 deletion docs/reference/out.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ LKEClusterConfig is the Schema for the lkeclusterconfigs API.
| --- | --- | --- | --- |
| `apiVersion` _string_ | `lke.anza-labs.dev/v1alpha1` | | |
| `kind` _string_ | `LKEClusterConfig` | | |
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/vv1.30/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
| `spec` _[LKEClusterConfigSpec](#lkeclusterconfigspec)_ | | | |


Expand Down
219 changes: 169 additions & 50 deletions hack/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,111 +13,228 @@
# limitations under the License.

import argparse
import os
import subprocess
import sys
import os
import requests
import yaml

import requests
import semver
import yaml

import hack.utils as utils

logger = utils.setup(__name__)


def make(args: list[str]) -> None:
rc = subprocess.run(
"""
Runs the 'make' command with the provided arguments.
Args:
args (list[str]): List of arguments to pass to the 'make' command.
"""
subprocess.run(
["make"] + args,
stdout=sys.stdout,
stderr=sys.stderr,
check=True,
)
if rc.returncode != 0:
raise Exception(rc.stderr)


def git(args: list[str]) -> None:
rc = subprocess.run(
"""
Runs the 'git' command with the provided arguments.
Args:
args (list[str]): List of arguments to pass to the 'git' command.
"""
subprocess.run(
["git"] + args,
stdout=sys.stdout,
stderr=sys.stderr,
check=True,
)
if rc.returncode != 0:
raise Exception(rc.stderr)

def _parse_version(version: str) -> tuple[str, bool]:

def _branch_prep(version: str, full_version: str):
"""
Prepares the branch for the release.
If the branch exists, switches to it; otherwise, creates a new branch.
Merges the main branch into the release branch and pushes the changes.
Args:
version (str): The short version string.
full_version (str): The full version string.
"""
branch = f"release-{version}"
if _branch_exists(branch):
_switch_to_branch(branch)
else:
_create_branch(branch)
git(
[
"merge",
"main",
"-m",
f"chore({version}): merge changes for {full_version}",
"--signoff",
]
)
git(["push", "origin", branch])


def _branch_exists(branch_name: str) -> bool:
"""
Checks if a Git branch exists.
Args:
branch_name (str): The name of the branch to check.
Returns:
bool: True if the branch exists, False otherwise.
"""
result = subprocess.run(
["git", "branch", "--list", branch_name], capture_output=True, text=True
)
return branch_name in result.stdout


def _switch_to_branch(branch_name: str) -> None:
"""
Switches to the specified Git branch.
Args:
branch_name (str): The name of the branch to switch to.
"""
git(["checkout", branch_name])


def _create_branch(branch_name: str) -> None:
"""
Parses the given version string and returns a short version string and a boolean indicating whether it's a prerelease.
Creates and switches to a new Git branch.
Args:
branch_name (str): The name of the branch to create.
"""
git(["checkout", "-b", branch_name])


def _parse_version(version: str) -> str:
"""
Parses the given version string and returns a short version string.
Args:
version (str): The version string to parse.
Returns:
Tuple[str, bool]: A tuple containing the short version string and a boolean indicating whether it's a prerelease.
str: The short version string.
"""
short_version = ""
is_prerelease = True

if version == "main":
short_version = version
else:
try:
sv = semver.Version.parse(version.removeprefix("v"))
short_version = f"v{sv.major}.{sv.minor}"
is_prerelease = sv.prerelease is not None
short_version = f"{sv.major}.{sv.minor}"
except ValueError as e:
logger.warn(e)

logger.info("%s (is_prerelease: %s)", short_version, is_prerelease)
return short_version, is_prerelease
logger.info("%s", short_version)
return short_version


def _get_latest_kubernetes_release() -> str:
"""
Fetches the latest Kubernetes release version from the GitHub API.
Returns:
str: The latest Kubernetes release version.
Raises:
Exception: If the API request fails.
"""
url = "https://api.github.com/repos/kubernetes/kubernetes/releases/latest"
response = requests.get(url)

if response.status_code == 200:
latest_release = response.json()['tag_name']
latest_release = response.json()["tag_name"]
return latest_release
else:
raise Exception(f"Failed to fetch the latest release. Status code: {response.status_code}")
raise Exception(
f"Failed to fetch the latest release. Status code: {response.status_code}"
)


def _replace_kubernetes_version(file_path: str, new_version: str) -> None:
# Temporary file path
temp_file_path = file_path + '.tmp'
"""
Replaces the Kubernetes version in the specified configuration file.
Args:
file_path (str): The path to the configuration file.
new_version (str): The new Kubernetes version to set.
"""
temp_file_path = file_path + ".tmp"

with open(file_path, 'r') as file, open(temp_file_path, 'w') as temp_file:
with open(file_path, "r") as file, open(temp_file_path, "w") as temp_file:
for line in file:
# Check if the line contains the kubernetesVersion key
if 'kubernetesVersion' in line:
# Split the line at the colon and replace the version
key, _ = line.split(':')
# Preserve the formatting by adding back the key and the new version
if "kubernetesVersion" in line:
key, _ = line.split(":")
temp_file.write(f"{key}: '{new_version}'\n")
else:
# Write the original line if it doesn't contain kubernetesVersion
temp_file.write(line)

# Replace the original file with the modified file
os.replace(temp_file_path, file_path)


def _create_kustomization(resources, image_name, new_tag):
"""
Creates a kustomization dictionary.
Args:
resources (list[str]): List of resource paths.
image_name (str): Name of the image to replace.
new_tag (str): New tag for the image.
Returns:
dict: Kustomization dictionary.
"""
kustomization = {
"apiVersion": "kustomize.config.k8s.io/v1beta1",
"kind": "Kustomization",
"resources": resources,
"images": [
{
"name": image_name,
"newTag": new_tag
}
]
"images": [{"name": image_name, "newTag": new_tag}],
}
return kustomization

def _write_kustomization(kustomization, filepath):
with open(filepath, 'w') as file:

def _release(version: str, full_version: str) -> None:
"""
Creates a release by committing changes, pushing to the remote branch, and tagging the release.
Args:
version (str): The short version string.
full_version (str): The full version string.
"""
git(["add", "."])
git(["commit", "-sm", f"chore({version}): create release commit {full_version}"])
git(["push", "origin", f"release-{version}"])
git(["tag", full_version])
git(["push", "--tags"])


def _write_kustomization(kustomization, filepath) -> None:
"""
Writes the kustomization dictionary to a file.
Args:
kustomization (dict): The kustomization dictionary.
filepath (str): The path to the file where the kustomization will be written.
"""
with open(filepath, "w") as file:
yaml.dump(kustomization, file)

def run(args=sys.argv):

def run(args=sys.argv) -> None:
"""
Runs the release script.
Expand Down Expand Up @@ -152,16 +269,18 @@ def run(args=sys.argv):

args = parser.parse_args(args=args[1:])

resources = [
"./config/crd",
"./config/manager",
"./config/rbac"
]
resources = ["./config/crd", "./config/manager", "./config/rbac"]

version, _ = _parse_version(version=args.version)
kube_version, _ = _parse_version(version=_get_latest_kubernetes_release())
version = _parse_version(version=args.version)
kube_version = _parse_version(version=_get_latest_kubernetes_release())
_replace_kubernetes_version(args.config, kube_version)
git(["checkout", "-b", f"release-{version}"])
make(["manifests", "api-docs"])
kustomization = _create_kustomization(resources=resources, image_name=args.image, new_tag=args.version)

_branch_prep(version, args.version)

kustomization = _create_kustomization(
resources=resources, image_name=args.image, new_tag=args.version
)
_write_kustomization(kustomization=kustomization, filepath="./kustomization.yaml")
make(["manifests", "apidocs"])

_release(version, args.version)

0 comments on commit 49890f2

Please sign in to comment.