#!/usr/bin/env python3 """Creates github release for tag """ import fileinput import os.path import os import sys from contextlib import contextmanager from typing import Generator from lib import re_ga, get_gh_repo, re_ea from lib.uiutil import Checker, CheckResult, run, run_txtcapture RELEASE_TITLE_FORMAT = "Emissary Ingress {release_version}" RELEASE_BODY_FORMAT= """ ## :tada: Emissary Ingress {release_version} :tada: #### Emissary Ingress is an open source, Kubernetes-native microservices API gateway built on the Envoy Proxy. Upgrade Emissary - https://www.getambassador.io/reference/upgrading.html View changelog - https://github.com/emissary-ingress/emissary/blob/{git_tag}/CHANGELOG.md Get started with Emissary on Kubernetes - https://www.getambassador.io/user-guide/getting-started {release_notes} """ def main(release_version: str) -> int: # This context manager and check function are pretty much just to produce # a nice list of steps... in_ci = os.getenv('CI') != '' checker = Checker() @contextmanager def check(name: str) -> Generator[CheckResult, None, None]: with checker.check(name) as subcheck: # time.sleep(1) # it's stupid, but honestly the delay makes the output more readable yield subcheck with check(f"Check that tag v{release_version} exists"): if not in_ci: run(['git', 'fetch', '--tags']) run(['git', 'rev-parse', '--verify', f"v{release_version}"]) if not checker.ok: return 1 buf = "" with check(f"Creating release notes for {release_version}"): # TODO: Rewrite this to use `docs/releaseNotes.yml` instead of # `CHANGELOG.md`. in_changelog = False for line in fileinput.FileInput("CHANGELOG.md"): if in_changelog: if line.startswith("## ") or line == "### Ambassador Edge Stack only\n": break if line.startswith(f"[{release_version}]: https://github.com/"): continue if line == "### Emissary-ingress and Ambassador Edge Stack\n": continue buf += line if line.startswith(f"## [{release_version}] "): in_changelog = True buf = buf.strip() if buf == "": raise Exception(f"Changelog entry for {release_version} not found. Are you sure you're trying to release that?") print(f"Generated release notes:") print(buf) if not in_ci: ok = input("Does this look correct? (y/n)") if ok != 'y': print('Ok, not generating release') return 1 with check(f"Creating release for {release_version}"): run([ "gh", "release", "create", f"v{release_version}", "--repo", get_gh_repo(), "--title", RELEASE_TITLE_FORMAT.format(release_version=release_version), "--notes", RELEASE_BODY_FORMAT.format( release_version=release_version, release_notes=buf, git_tag="v"+release_version, )]) if not checker.ok: return 1 url = run_txtcapture([ "gh", "release", "view", "--json=url", "--jq=.url", "--repo="+get_gh_repo(), "v"+release_version]) print(f'echo "url={url}" >> $GITHUB_OUTPUT') if os.getenv("AMBASSADOR_RELENG_NO_GUI") == '': print('Release info from github:') run(["gh", "release", "view", "--repo="+get_gh_repo(), f"v{release_version}"]) return 0 if __name__ == '__main__': args = sys.argv[1:] if len(args) < 1 or (not re_ga.match(args[0]) and not re_ea.match(args[0])): sys.stderr.write(f"Usage: {os.path.basename(sys.argv[0])} X.Y.Z(-ea)?\n") sys.exit(2) sys.exit(main( release_version=args[0], ))