-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(release): list aqua package additions/updates in changelog #9471
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,73 +1,120 @@ | ||
| #!/usr/bin/env bash | ||
| # Generate aqua-registry changelog section | ||
| # Usage: gen-aqua-changelog.sh <old_tag> <new_tag> <heading_level> | ||
| # | ||
| # Lists packages added or modified in the upstream aqua-registry between | ||
| # OLD_TAG and NEW_TAG by diffing the merged registry.yaml at each tag. | ||
| set -euo pipefail | ||
|
|
||
| OLD_TAG="$1" | ||
| NEW_TAG="$2" | ||
| OLD_TAG="${1:-}" | ||
| NEW_TAG="${2:-}" | ||
| HEADING_LEVEL="${3:-###}" # Default to ### for CHANGELOG.md sections | ||
| REPO="aquaproj/aqua-registry" | ||
| NEW_REGISTRY="crates/aqua-registry/aqua-registry/registry.yaml" | ||
|
|
||
| if [[ -z $OLD_TAG ]] || [[ -z $NEW_TAG ]] || [[ $OLD_TAG == "$NEW_TAG" ]]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| if ! command -v gh >/dev/null 2>&1; then | ||
| echo "gh is required to generate aqua-registry changelog entries" >&2 | ||
| exit 1 | ||
| if [[ ! -f $NEW_REGISTRY ]]; then | ||
| echo "Expected $NEW_REGISTRY to exist" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| release_tags() { | ||
| local collecting=0 | ||
| local found_old=0 | ||
| local found_new=0 | ||
| local -a tags=() | ||
|
|
||
| while IFS= read -r tag; do | ||
| if [[ $tag == "$OLD_TAG" ]]; then | ||
| found_old=1 | ||
| break | ||
| fi | ||
| if [[ $tag == "$NEW_TAG" ]]; then | ||
| collecting=1 | ||
| found_new=1 | ||
| fi | ||
| if [[ $collecting -eq 1 ]]; then | ||
| tags+=("$tag") | ||
| fi | ||
| done < <(gh release list --repo "$REPO" --limit 1000 --json tagName --jq '.[].tagName') | ||
|
|
||
| if [[ $found_old -eq 0 ]]; then | ||
| return 0 | ||
| fi | ||
|
|
||
| if [[ $found_new -eq 0 ]]; then | ||
| echo "Unable to find aqua-registry release $NEW_TAG" >&2 | ||
| return 1 | ||
| fi | ||
|
|
||
| if [[ ${#tags[@]} -eq 0 ]]; then | ||
| echo "Unable to find aqua-registry releases from $OLD_TAG to $NEW_TAG" >&2 | ||
| return 1 | ||
| fi | ||
|
|
||
| for ((i = ${#tags[@]} - 1; i >= 0; i--)); do | ||
| printf '%s\n' "${tags[$i]}" | ||
| done | ||
| } | ||
|
|
||
| RELEASE_TAGS="$(release_tags)" | ||
| if [[ -z $RELEASE_TAGS ]]; then | ||
| OLD_REGISTRY="$(mktemp)" | ||
| trap 'rm -f "$OLD_REGISTRY"' EXIT | ||
|
|
||
| if ! curl -fsSL "https://raw.githubusercontent.com/$REPO/$OLD_TAG/registry.yaml" -o "$OLD_REGISTRY"; then | ||
| echo "Failed to fetch aqua-registry $OLD_TAG/registry.yaml" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "$HEADING_LEVEL 📦 Aqua Registry" | ||
| echo "" | ||
| echo "Updated [aqua-registry](https://github.com/$REPO): [$OLD_TAG](https://github.com/$REPO/releases/tag/$OLD_TAG) -> [$NEW_TAG](https://github.com/$REPO/releases/tag/$NEW_TAG)." | ||
| echo "" | ||
| echo "Included aqua-registry releases:" | ||
| echo "" | ||
| python3 - "$OLD_REGISTRY" "$NEW_REGISTRY" "$HEADING_LEVEL" <<'PYEOF' | ||
| import re | ||
| import sys | ||
|
|
||
| old_path, new_path, heading = sys.argv[1:4] | ||
|
|
||
|
|
||
| def strip_quotes(v: str) -> str: | ||
| # Strip an unquoted YAML inline comment (` #...`) before quote handling. | ||
| # A bare `#` with no leading space is part of the value (e.g. aqua names | ||
| # like `_go/sigsum.org/sigsum-go#cmd/sigsum-key`). | ||
| v = v.split(' #', 1)[0].strip() | ||
| if len(v) >= 2 and v[0] == v[-1] and v[0] in ("'", '"'): | ||
| return v[1:-1] | ||
| return v | ||
|
|
||
|
|
||
| def parse(path: str) -> dict[str, tuple[str, str]]: | ||
| """Return {canonical_id: (github_repo_or_empty, package_block_text)}. | ||
|
|
||
| github_repo is set when the package has repo_owner+repo_name (so the id | ||
| resolves to a github URL); empty for name-only or path-only packages. | ||
| """ | ||
| with open(path) as f: | ||
| text = f.read() | ||
| # Top-level packages start with ' - ' at column 0. Split on those boundaries. | ||
| parts = re.split(r'(?m)^ - ', text) | ||
| pkgs: dict[str, tuple[str, str]] = {} | ||
| for body in parts[1:]: | ||
| block = ' - ' + body | ||
| # Top-level package fields are at exactly 4-space indent. The first | ||
| # field also appears inline on the ' - ' line itself. | ||
| fields: dict[str, str] = {} | ||
| first_line, _, rest = body.partition('\n') | ||
| m = re.match(r'(name|repo_owner|repo_name|path|type):\s*(.*?)\s*$', first_line) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The regex used to extract YAML field values will capture trailing comments if they exist on the same line (e.g., |
||
| if m: | ||
| fields[m.group(1)] = strip_quotes(m.group(2)) | ||
| for ln in rest.splitlines(): | ||
| mm = re.match(r'^ (name|repo_owner|repo_name|path):\s*(.*?)\s*$', ln) | ||
| if mm: | ||
| fields.setdefault(mm.group(1), strip_quotes(mm.group(2))) | ||
| github_repo = '' | ||
| if fields.get('repo_owner') and fields.get('repo_name'): | ||
| github_repo = f"{fields['repo_owner']}/{fields['repo_name']}" | ||
| if fields.get('name'): | ||
| pkg_id = fields['name'] | ||
| elif github_repo: | ||
| pkg_id = github_repo | ||
| elif fields.get('path'): | ||
| pkg_id = fields['path'] | ||
| else: | ||
| continue | ||
| pkgs[pkg_id] = (github_repo, block) | ||
| return pkgs | ||
|
|
||
|
|
||
| old = parse(old_path) | ||
| new = parse(new_path) | ||
|
|
||
| added = sorted(set(new) - set(old)) | ||
| updated = sorted(k for k in (set(old) & set(new)) if old[k][1] != new[k][1]) | ||
|
|
||
| if not added and not updated: | ||
| sys.exit(0) | ||
|
|
||
|
|
||
| def link(pkg: str, github_repo: str) -> str: | ||
| if github_repo: | ||
| return f'[`{pkg}`](https://github.com/{github_repo})' | ||
| return f'`{pkg}`' | ||
|
|
||
|
|
||
| sub = heading + '#' | ||
| out: list[str] = [] | ||
| out.append(f'{heading} 📦 Aqua Registry Updates') | ||
| out.append('') | ||
| if added: | ||
| out.append(f'{sub} New Packages ({len(added)})') | ||
| out.append('') | ||
| out.extend(f'- {link(p, new[p][0])}' for p in added) | ||
| out.append('') | ||
| if updated: | ||
| out.append(f'{sub} Updated Packages ({len(updated)})') | ||
| out.append('') | ||
| out.extend(f'- {link(p, new[p][0])}' for p in updated) | ||
| out.append('') | ||
|
greptile-apps[bot] marked this conversation as resolved.
|
||
|
|
||
| while IFS= read -r tag; do | ||
| echo "- [$tag](https://github.com/$REPO/releases/tag/$tag)" | ||
| done <<<"$RELEASE_TAGS" | ||
| print('\n'.join(out)) | ||
| PYEOF | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
strip_quotesfunction is naive and will fail to strip quotes if there is a trailing comment on the line, as the last character won't be a quote. It's better to handle comment stripping first.