diff --git a/doc/release.rst b/doc/release.rst index 87a28759..39573453 100644 --- a/doc/release.rst +++ b/doc/release.rst @@ -52,7 +52,7 @@ How to make a psycopg2 release - When the workflows have finished download the packages using the ``download_packages.py`` and ``download_packages_appveyor.py`` scripts from the ``scripts/build`` directory. They will be saved in a - ``psycopg2-${VERSION}`` directory. + ``packages/psycopg2-${VERSION}`` directory. - Remove the ``.exe`` from the dir, because we don't want to upload them on PyPI:: diff --git a/scripts/build/download_packages.py b/scripts/build/download_packages.py index 46ce149c..cd8003e5 100755 --- a/scripts/build/download_packages.py +++ b/scripts/build/download_packages.py @@ -6,15 +6,14 @@ import io import os import sys import logging +import datetime as dt from pathlib import Path from zipfile import ZipFile import requests logger = logging.getLogger() -logging.basicConfig( - level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s" -) +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") REPOS = "psycopg/psycopg2" WORKFLOW_NAME = "Build packages" @@ -43,7 +42,17 @@ def main(): else: raise ScriptError(f"couldn't find {WORKFLOW_NAME!r} in recent runs") - logger.info(f"looking for run {run['id']} artifacts") + if run["status"] != "completed": + raise ScriptError(f"run #{run['run_number']} is in status {run['status']}") + + updated_at = dt.datetime.fromisoformat(run["updated_at"].replace("Z", "+00:00")) + now = dt.datetime.now(dt.timezone.utc) + age = now - updated_at + logger.info(f"found run #{run['run_number']} updated {pretty_interval(age)} ago") + if age > dt.timedelta(hours=6): + logger.warning("maybe it's a bit old?") + + logger.info(f"looking for run #{run['run_number']} artifacts") resp = s.get(f"{run['url']}/artifacts") resp.raise_for_status() artifacts = resp.json()["artifacts"] @@ -64,6 +73,19 @@ def main(): logger.info(f"now you can run: 'twine upload -s {dest}/*'") +def pretty_interval(td): + secs = td.total_seconds() + mins, secs = divmod(secs, 60) + hours, mins = divmod(mins, 60) + days, hours = divmod(hours, 24) + if days: + return f"{int(days)} days, {int(hours)} hours, {int(mins)} minutes" + elif hours: + return f"{int(hours)} hours, {int(mins)} minutes" + else: + return f"{int(mins)} minutes" + + if __name__ == "__main__": try: sys.exit(main()) diff --git a/scripts/build/download_packages_appveyor.py b/scripts/build/download_packages_appveyor.py index 7ac55b41..afdae379 100755 --- a/scripts/build/download_packages_appveyor.py +++ b/scripts/build/download_packages_appveyor.py @@ -3,8 +3,10 @@ """ import os +import re import sys import logging +import datetime as dt from pathlib import Path import requests @@ -35,6 +37,18 @@ def main(): resp = s.get(f"{API_URL}/projects/{REPOS}/") resp.raise_for_status() data = resp.json() + + updated_at = dt.datetime.fromisoformat( + re.sub(r"\.\d+", "", data["build"]["finished"]) + ) + now = dt.datetime.now(dt.timezone.utc) + age = now - updated_at + logger.info( + f"found build {data['build']['version']} updated {pretty_interval(age)} ago" + ) + if age > dt.timedelta(hours=6): + logger.warning("maybe it's a bit old?") + jobs = data["build"]["jobs"] for job in jobs: if job["status"] != "success": @@ -63,6 +77,19 @@ def main(): logger.info("now you can run: 'twine upload -s packages/*'") +def pretty_interval(td): + secs = td.total_seconds() + mins, secs = divmod(secs, 60) + hours, mins = divmod(mins, 60) + days, hours = divmod(hours, 24) + if days: + return f"{int(days)} days, {int(hours)} hours, {int(mins)} minutes" + elif hours: + return f"{int(hours)} hours, {int(mins)} minutes" + else: + return f"{int(mins)} minutes" + + if __name__ == "__main__": try: sys.exit(main()) @@ -74,4 +101,3 @@ if __name__ == "__main__": except KeyboardInterrupt: logger.info("user interrupt") sys.exit(1) -