Skip to content
Merged
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: 102 additions & 55 deletions scripts/gen-aqua-changelog.sh
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
Comment on lines +39 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The strip_quotes function 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.

Suggested change
def strip_quotes(v: str) -> str:
v = v.strip()
if len(v) >= 2 and v[0] == v[-1] and v[0] in ("'", '"'):
return v[1:-1]
return v
def strip_quotes(v: str) -> str:
v = v.split(' #')[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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regex used to extract YAML field values will capture trailing comments if they exist on the same line (e.g., name: foo # comment). This can lead to incorrect package IDs and false positives in the 'Updated Packages' section if comments are modified. Consider stripping comments from the value before processing.

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('')
Comment thread
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
Loading