diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 83dff98..8a46ddb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,16 +25,23 @@ jobs: curl -fsSL -o "/tmp/${archive}" "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/${archive}" tar -xzf "/tmp/${archive}" -C /tmp install "/tmp/git-cliff-${GIT_CLIFF_VERSION}/git-cliff" /usr/local/bin/git-cliff + - name: Check for unreleased changes + id: changes + run: | + echo "has_changes=$(python3 scripts/release.py has-unreleased-changes)" >> "${GITHUB_OUTPUT}" - name: Compute release version id: version + if: steps.changes.outputs.has_changes == 'true' run: echo "release_version=$(python3 scripts/release.py next-version)" >> "${GITHUB_OUTPUT}" - name: Generate changelog + if: steps.changes.outputs.has_changes == 'true' env: GITHUB_REPO: ${{ github.repository }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_VERSION: ${{ steps.version.outputs.release_version }} run: git-cliff --config cliff.toml --tag "${RELEASE_VERSION}" --output CHANGELOG.md - name: Create release PR + if: steps.changes.outputs.has_changes == 'true' uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: commit-message: "chore(release): ${{ steps.version.outputs.release_version }}" diff --git a/scripts/release.py b/scripts/release.py index 71c8eeb..c0ba3a4 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -46,6 +46,28 @@ def git_tags() -> list[str]: return [line.strip() for line in output.splitlines() if line.strip()] +def latest_release_tag(dockerfile: pathlib.Path, upstream: pathlib.Path) -> str | None: + upstream_version = read_upstream_version(dockerfile, upstream) + pattern = re.compile(rf"^{re.escape(upstream_version)}-aio\.(\d+)$") + matches: list[tuple[int, str]] = [] + for tag in git_tags(): + match = pattern.match(tag) + if match: + matches.append((int(match.group(1)), tag)) + if not matches: + return None + matches.sort(key=lambda item: item[0]) + return matches[-1][1] + + +def has_unreleased_changes(dockerfile: pathlib.Path, upstream: pathlib.Path) -> bool: + latest_tag = latest_release_tag(dockerfile, upstream) + if latest_tag is None: + return True + output = subprocess.check_output(["git", "log", "--format=%s", f"{latest_tag}..HEAD"], cwd=ROOT, text=True) + return any(line.strip() for line in output.splitlines()) + + def next_release_version(dockerfile: pathlib.Path, upstream: pathlib.Path) -> str: upstream_version = read_upstream_version(dockerfile, upstream) pattern = re.compile(rf"^{re.escape(upstream_version)}-aio\.(\d+)$") @@ -98,6 +120,9 @@ def main() -> None: next_parser = subparsers.add_parser("next-version") next_parser.add_argument("--dockerfile", type=pathlib.Path, default=DEFAULT_DOCKERFILE) next_parser.add_argument("--upstream-config", type=pathlib.Path, default=DEFAULT_UPSTREAM) + changes_parser = subparsers.add_parser("has-unreleased-changes") + changes_parser.add_argument("--dockerfile", type=pathlib.Path, default=DEFAULT_DOCKERFILE) + changes_parser.add_argument("--upstream-config", type=pathlib.Path, default=DEFAULT_UPSTREAM) latest_parser = subparsers.add_parser("latest-changelog-version") latest_parser.add_argument("--changelog", type=pathlib.Path, default=DEFAULT_CHANGELOG) notes_parser = subparsers.add_parser("extract-release-notes") @@ -108,6 +133,8 @@ def main() -> None: print(read_upstream_version(args.dockerfile, args.upstream_config)) elif args.command == "next-version": print(next_release_version(args.dockerfile, args.upstream_config)) + elif args.command == "has-unreleased-changes": + print("true" if has_unreleased_changes(args.dockerfile, args.upstream_config) else "false") elif args.command == "latest-changelog-version": print(latest_changelog_version(args.changelog)) else: