Skip to content
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
157 changes: 157 additions & 0 deletions .github/scripts/bump-renovate-chart-version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/usr/bin/env python3
"""Bump chart version for Renovate Weblate image updates."""

from __future__ import annotations

import os
import re
import subprocess
import sys
from pathlib import Path

CHART_PATH = Path("charts/weblate/Chart.yaml")
README_PATH = Path("charts/weblate/README.md")
VALUES_PATH = Path("charts/weblate/values.yaml")

ALLOWED_PATHS = {
CHART_PATH.as_posix(),
README_PATH.as_posix(),
VALUES_PATH.as_posix(),
}
REQUIRED_PATHS = {
CHART_PATH.as_posix(),
VALUES_PATH.as_posix(),
}


def run_git(*args: str) -> str:
completed = subprocess.run(
("git", *args),
check=True,
capture_output=True,
text=True,
)
return completed.stdout


def git_show(base_ref: str, path: Path) -> str:
return run_git("show", f"origin/{base_ref}:{path.as_posix()}")


def root_scalar(chart: str, key: str) -> str:
match = re.search(
rf"^{re.escape(key)}:\s*([^\s#]+).*$",
chart,
flags=re.MULTILINE,
)
if match is None:
raise SystemExit(f"Unable to find top-level {key!r} in Chart.yaml")
return match.group(1).strip("'\"")


def bump_patch(version: str) -> str:
match = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)", version)
if match is None:
raise SystemExit(f"Unsupported chart version: {version}")
major, minor, patch = match.groups()
return f"{major}.{minor}.{int(patch) + 1}"


def changed_paths(base_ref: str) -> set[str]:
return set(
run_git(
"diff",
"--name-only",
"--diff-filter=ACMRT",
f"origin/{base_ref}...HEAD",
).splitlines()
)


def update_chart_version(chart: str, target_version: str) -> str:
new_chart, count = re.subn(
r"^(version:\s*)[^\s#]+(.*)$",
lambda match: f"{match.group(1)}{target_version}{match.group(2)}",
chart,
count=1,
flags=re.MULTILINE,
)
if count != 1:
raise SystemExit("Unable to update chart version in Chart.yaml")
return new_chart


def update_readme_badge(readme: str, target_version: str) -> str:
version_badge = (
f"![Version: {target_version}]"
f"(https://img.shields.io/badge/Version-{target_version}"
"-informational?style=flat-square)"
)
new_readme, count = re.subn(
r"!\[Version: [^\]]+\]\("
r"https://img\.shields\.io/badge/Version-[^-)]*"
r"-informational\?style=flat-square\)",
version_badge,
readme,
count=1,
)
if count != 1:
raise SystemExit("Unable to update chart version badge in README.md")
return new_readme


def main() -> int:
base_ref = os.environ["BASE_REF"]
changed = changed_paths(base_ref)
unexpected = changed - ALLOWED_PATHS

if unexpected:
print(
"Skipping chart version bump; unexpected changed paths: "
+ ", ".join(sorted(unexpected))
)
return 0

if not REQUIRED_PATHS.issubset(changed):
print(
"Skipping chart version bump; Weblate Chart.yaml and values.yaml "
"changes were not both detected."
)
return 0

base_chart = git_show(base_ref, CHART_PATH)
head_chart = CHART_PATH.read_text(encoding="utf-8")

base_app_version = root_scalar(base_chart, "appVersion")
head_app_version = root_scalar(head_chart, "appVersion")
if base_app_version == head_app_version:
print("Skipping chart version bump; appVersion did not change.")
return 0

base_chart_version = root_scalar(base_chart, "version")
head_chart_version = root_scalar(head_chart, "version")
target_chart_version = bump_patch(base_chart_version)
if head_chart_version not in {base_chart_version, target_chart_version}:
raise SystemExit(
f"Unexpected chart version {head_chart_version}; expected "
f"{base_chart_version} or {target_chart_version}."
)

new_chart = update_chart_version(head_chart, target_chart_version)
readme = README_PATH.read_text(encoding="utf-8")
new_readme = update_readme_badge(readme, target_chart_version)

CHART_PATH.write_text(new_chart, encoding="utf-8")
README_PATH.write_text(new_readme, encoding="utf-8")

if head_chart_version == target_chart_version:
print(f"Chart version already set to {target_chart_version}.")
else:
print(
f"Bumped chart version from {head_chart_version} to {target_chart_version}."
)
return 0


if __name__ == "__main__":
sys.exit(main())
55 changes: 55 additions & 0 deletions .github/workflows/renovate-chart-version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright © Michal Čihař <michal@weblate.org>
#
# SPDX-License-Identifier: CC0-1.0

name: Renovate chart version

on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- charts/weblate/Chart.yaml
- charts/weblate/README.md
- charts/weblate/values.yaml

permissions:
contents: read

jobs:
bump-version:
name: Bump chart version
runs-on: ubuntu-24.04
if: >-
github.event.pull_request.user.login == 'renovate[bot]' &&
github.event.pull_request.head.repo.full_name == github.repository &&
(
startsWith(github.event.pull_request.head.ref, 'renovate/weblate-weblate-') ||
contains(github.event.pull_request.title, 'weblate/weblate')
)
steps:
- name: Checkout pull request
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}

- name: Fetch base branch
env:
BASE_REF: ${{ github.base_ref }}
run: git fetch --no-tags --prune origin "+refs/heads/${BASE_REF}:refs/remotes/origin/${BASE_REF}"

- name: Bump chart version
env:
BASE_REF: ${{ github.base_ref }}
run: python3 .github/scripts/bump-renovate-chart-version.py

- name: diff
if: always()
run: git diff

- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: success()
with:
msg: 'chore: bump chart version for Weblate update'
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ repos:
rev: v1.38.0
hooks:
- id: yamllint
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.20
hooks:
- id: ruff-check
args:
- --fix
- --exit-non-zero-on-fix
- id: ruff-format
- repo: https://github.com/astral-sh/ty-pre-commit
rev: v0.0.56
hooks:
- id: ty
args: [--isolated]
- repo: https://github.com/norwoodj/helm-docs
rev: v1.14.2
hooks:
Expand Down Expand Up @@ -60,3 +73,4 @@ ci:
autoupdate_schedule: quarterly
skip:
- kingfisher-auto
- ty
Loading