-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatically manage pre-release branches
A k8s-snap PR automatically creates and cleans up git branches for upstream k8s pre-releases: canonical/k8s-snap#916 Here we're adding an almost identical job that picks up these git branches and prepares launchpad recipes. TODOs: * clean up obsolete pre-releases that were superseeded by a new pre-release or stable release * promote beta and rc pre-releases to the corresponding snap risk level
- Loading branch information
1 parent
a83cf81
commit 1d56a1c
Showing
6 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: Job prerequisites | ||
|
||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Harden Runner | ||
uses: step-security/harden-runner@v2 | ||
with: | ||
egress-policy: audit | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
with: | ||
ssh-key: ${{ secrets.BOT_SSH_KEY }} | ||
- name: Setup Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.12' | ||
cache: 'pip' | ||
- name: Install Python dependencies | ||
run: pip3 install -r ./scripts/requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
name: Auto-update pre-release branches | ||
|
||
on: | ||
pull_request: | ||
paths: | ||
- .github/workflows/update-pre-release-branches.yaml | ||
schedule: | ||
# Run 20 minutes after midnight, giving the k8s-snap nightly job | ||
# enough time to pick up new k8s releases and setup the git branches. | ||
- cron: "20 0 * * *" | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
determine: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
preRelease: ${{ steps.determine.outputs.preRelease }} | ||
gitBranch: ${{ steps.determine.outputs.gitBranch }} | ||
steps: | ||
- name: Prerequisites | ||
uses: ./.github/actions/job-prerequisites | ||
- name: Determine outstanding pre-release | ||
id: determine | ||
run: | | ||
preRelease=`python3 ./scripts/k8s_releases.py get_outstanding_prerelease` | ||
echo "preRelease=$preRelease" >> "$GITHUB_OUTPUT" | ||
if [[ -n "$preRelease" ]]; then | ||
gitBranch="autoupdate/$preRelease" | ||
fi | ||
echo "gitBranch=$gitBranch" >> "$GITHUB_OUTPUT" | ||
- name: Create pre-release branch ${{ steps.determine.outputs.gitBranch }} | ||
if: ${{ steps.determine.outputs.preRelease }} != '' | ||
uses: ./.github/workflows/create-release-branch.yaml | ||
with: | ||
branches: ${{ steps.determine.outputs.gitBranch }} | ||
- name: Clean obsolete branches | ||
run: | | ||
git fetch origin | ||
# Log the latest release for reference. | ||
latestRelease=`python3 ./scripts/k8s_releases.py get_latest_release` | ||
echo "Latest k8s release: $latestRelease" | ||
for outstandingPreRelease in `python3 ./scripts/k8s_releases.py get_obsolete_prereleases`; do | ||
gitBranch="autoupdate/${outstandingPreRelease}" | ||
echo "Cleaning up obsolete pre-release branch: $gitBranch" | ||
# TODO | ||
done | ||
handle-pre-release: | ||
name: Handle pre-release ${{ needs.determine.outputs.preRelease }} | ||
needs: [determine] | ||
uses: ./.github/workflows/create-release-branch.yaml | ||
if: ${{ needs.determine.outputs.preRelease }} != '' | ||
with: | ||
branches: ${{ steps.determine.outputs.gitBranch }} | ||
clean-obsolete: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
preRelease: ${{ steps.determine.outputs.preRelease }} | ||
gitBranch: ${{ steps.determine.outputs.gitBranch }} | ||
steps: | ||
- name: Prerequisites | ||
uses: ./.github/actions/job-prerequisites | ||
- name: Clean obsolete branches | ||
run: | | ||
git fetch origin | ||
# Log the latest release for reference. | ||
latestRelease=`python3 ./scripts/k8s_releases.py get_latest_release` | ||
echo "Latest k8s release: $latestRelease" | ||
for outstandingPreRelease in `python3 ./scripts/k8s_releases.py get_obsolete_prereleases`; do | ||
gitBranch="autoupdate/${outstandingPreRelease}" | ||
echo "Cleaning up obsolete pre-release branch: $gitBranch" | ||
# TODO | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import json | ||
import sys | ||
from typing import List, Optional | ||
|
||
import requests | ||
from packaging.version import Version | ||
|
||
K8S_TAGS_URL = "https://api.github.com/repos/kubernetes/kubernetes/tags" | ||
|
||
|
||
def _url_get(url: str) -> str: | ||
r = requests.get(url, timeout=5) | ||
r.raise_for_status() | ||
return r.text | ||
|
||
|
||
def get_k8s_tags() -> List[str]: | ||
"""Retrieve semantically ordered k8s releases, newest to oldest.""" | ||
response = _url_get(K8S_TAGS_URL) | ||
tags_json = json.loads(response) | ||
if len(tags_json) == 0: | ||
raise Exception("No k8s tags retrieved.") | ||
tag_names = [tag['name'] for tag in tags_json] | ||
# Github already sorts the tags semantically but let's not rely on that. | ||
tag_names.sort(key=lambda x: Version(x), reverse=True) | ||
return tag_names | ||
|
||
|
||
# k8s release naming: | ||
# * alpha: v{major}.{minor}.{patch}-alpha.{version} | ||
# * beta: v{major}.{minor}.{patch}-beta.{version} | ||
# * rc: v{major}.{minor}.{patch}-rc.{version} | ||
# * stable: v{major}.{minor}.{patch} | ||
def is_stable_release(release: str): | ||
return "-" not in release | ||
|
||
|
||
def get_latest_stable() -> str: | ||
k8s_tags = get_k8s_tags() | ||
for tag in k8s_tags: | ||
if is_stable_release(tag): | ||
return tag | ||
raise Exception( | ||
"Couldn't find stable release, received tags: %s" % k8s_tags) | ||
|
||
|
||
def get_latest_release() -> str: | ||
k8s_tags = get_k8s_tags() | ||
return k8s_tags[0] | ||
|
||
|
||
def get_outstanding_prerelease() -> Optional[str]: | ||
latest_release = get_latest_release() | ||
if not is_stable_release(latest_release): | ||
return latest_release | ||
# The latest release is a stable release, no outstanding pre-release. | ||
return None | ||
|
||
|
||
def get_obsolete_prereleases() -> List[str]: | ||
"""Return obsolete K8s pre-releases. | ||
We only keep the latest pre-release if there is no corresponding stable | ||
release. All previous pre-releases are discarded. | ||
""" | ||
k8s_tags = get_k8s_tags() | ||
if not is_stable_release(k8s_tags[0]): | ||
# Valid pre-release | ||
k8s_tags = k8s_tags[1:] | ||
# Discard all other pre-releases. | ||
return [tag for tag in k8s_tags if not is_stable_release(tag)] | ||
|
||
|
||
# Rudimentary CLI that exposes these functions to shell scripts or GH actions. | ||
if __name__ == "__main__": | ||
if len(sys.argv) != 2: | ||
sys.stderr.write(f"Usage: {sys.argv[0]} <function>\n") | ||
sys.exit(1) | ||
f = locals()[sys.argv[1]] | ||
out = f() | ||
if isinstance(out, (list, tuple)): | ||
for item in out: | ||
print(item) | ||
else: | ||
print(out or "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
freezegun | ||
pytest | ||
types-requests |