Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
jdavcs committed Nov 22, 2024
1 parent 05ef95e commit 7b5eaaa
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 79 deletions.
188 changes: 124 additions & 64 deletions galaxy_release_util/bootstrap_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
import sys
import textwrap
from pathlib import Path
from typing import Optional
from typing import Optional, List

import click
from github.PullRequest import PullRequest
from packaging.version import Version

from .cli.options import (
ClickVersion,
#next_version_option,
freeze_date_option,
galaxy_root_option,
group_options,
)
Expand All @@ -34,6 +36,7 @@

RELEASE_DELTA_MONTHS = 4 # Number of months between releases.
MINOR_TO_MONTH = {0: 2, 1: 6, 2: 10}
FREEZE_TO_RELEASE_DELTA_DAYS = 21 # Default number of days from freeze to release


TEMPLATE = """
Expand Down Expand Up @@ -327,31 +330,47 @@

release_version_argument = click.argument("release-version", type=ClickVersion())

next_version_option = click.option(
"--next-version",
type=ClickVersion(),
help="Next release version.",
)

@click.group(help="Subcommands of this script can perform various tasks around creating Galaxy releases")
def cli():
pass


@cli.command(help="Create release checklist issue on GitHub")
@group_options(release_version_argument, galaxy_root_option)
def create_release_issue(release_version: Version, galaxy_root: Path):
previous_release = _previous_release(galaxy_root, release_version)
new_version_params = _next_version_params(release_version)
next_version = new_version_params["version"]
freeze_date, _ = _release_dates(release_version)
@group_options(release_version_argument, next_version_option, freeze_date_option, galaxy_root_option)
def create_release_issue(release_version: Version, next_version: Version, freeze_date, galaxy_root: Path):
"""
TODO
""" # TODO ADD COMMENT

previous_version = _get_previous_release_version(galaxy_root, release_version)
next_version = next_version or _get_next_release_version(release_version)
assert next_version > release_version, "Next release version should be greater than release version"

release_issue_template_params = dict(
version=release_version,
next_version=next_version,
previous_version=previous_release,
previous_version=previous_version,
freeze_date=freeze_date,
)

release_issue_contents = RELEASE_ISSUE_TEMPLATE.safe_substitute(**release_issue_template_params)
#print(release_issue_contents)

github = github_client()
repo = github.get_repo(f"{PROJECT_OWNER}/{PROJECT_NAME}")

# TODO error: must enable github tokern !!!!!
assert token?????

release_issue = repo.create_issue(
title=f"Publication of Galaxy Release v {release_version}",
body=release_issue_contents,
title=f"Publication of Galaxy Release v {release_version}",
body=release_issue_contents,
)
return release_issue

Expand Down Expand Up @@ -449,34 +468,55 @@ def _issue_to_str(pr):
return f"Issue #{pr.number} ({pr.title}) {pr.html_url}"


def _next_version_params(release_version: Version):
def _get_next_version_params(release_version: Version):
# we'll just hardcode this to 3 "minor" versions per year
if release_version.minor < 2:
next_major = release_version.major
next_minor = release_version.minor + 1
else:
next_major = release_version.major + 1
next_minor = 0
next_month_name = calendar.month_name[MINOR_TO_MONTH[next_minor]]
next_version = Version(f"{next_major}.{next_minor}")
freeze_date, release_date = _release_dates(next_version)
return dict(
version=next_version,
year=next_major,
month_name=next_month_name,
freeze_date=freeze_date,
release_date=release_date,
)


def _release_dates(version: Version):
# hardcoded to 3 releases a year, freeze dates kind of random
year = version.major
month = MINOR_TO_MONTH[version.minor]
first_of_month = datetime.date(year + 2000, month, 1)
freeze_date = next_weekday(first_of_month, 0)
release_date = next_weekday(first_of_month, 0) + datetime.timedelta(21)
return freeze_date, release_date
#if release_version.minor < 2:
# next_major = release_version.major
# next_minor = release_version.minor + 1
#else:
# next_major = release_version.major + 1
# next_minor = 0
#next_month_name = calendar.month_name[MINOR_TO_MONTH[next_minor]]
#next_version = Version(f"{next_major}.{next_minor}")
#freeze_date, release_date = _release_dates(next_version)
#return dict(
# version=next_version,
# year=next_major,
# month_name=next_month_name,
# freeze_date=freeze_date,
# release_date=release_date,
#)
return None


#def _next_version_params(release_version: Version):
# # we'll just hardcode this to 3 "minor" versions per year
# if release_version.minor < 2:
# next_major = release_version.major
# next_minor = release_version.minor + 1
# else:
# next_major = release_version.major + 1
# next_minor = 0
# next_month_name = calendar.month_name[MINOR_TO_MONTH[next_minor]]
# next_version = Version(f"{next_major}.{next_minor}")
# freeze_date, release_date = _release_dates(next_version)
# return dict(
# version=next_version,
# year=next_major,
# month_name=next_month_name,
# freeze_date=freeze_date,
# release_date=release_date,
# )


#def _release_dates(version: Version):
# # hardcoded to 3 releases a year, freeze dates kind of random
# year = version.major
# month = MINOR_TO_MONTH[version.minor]
# first_of_month = datetime.date(year + 2000, month, 1)
# freeze_date = next_weekday(first_of_month, 0)
# release_date = next_weekday(first_of_month, 0) + datetime.timedelta(21)
# return freeze_date, release_date


def _get_prs(release_version: str, state="closed"):
Expand Down Expand Up @@ -554,43 +594,67 @@ def _write_file(path, contents, skip_if_exists=False):
f.write(contents)


def _previous_release(galaxy_root, to: Version):
previous_release = None
for release in _releases(galaxy_root):
if release == str(to):
break

previous_release = release

return previous_release


def _releases(galaxy_root):
#def _get_release_date(freeze_date: click.DateTime): # TODO do we need this?
# """
# Return release date based on freeze date and FREEZE_TO_RELEASE_DELTA_DAYS.
# If the date falls on the weekend, return the next Monday.
# Do not account for holidays.
# """
# release_date = freeze_date + datetime.timedelta(FREEZE_TO_RELEASE_DELTA_DAYS)
# if release_date.weekday() > 4:
# release_date += datetime.timedelta(7 - release_date.weekday())
# return release_date



def _get_next_release_version(version: Version):
return Version(f"{version.major}.{version.minor + 1}")


def _get_previous_release_version(galaxy_root: Path, version: Version):
""" Return previous release version if it exists. """
# NOTE: We convert strings to Version objects to compare apples to apples:
# str(Version(foo)) is not the same as the string foo: str(Version("22.05")) == "22.5"
prev = None
for release in _get_release_version_strings(galaxy_root):
release_version = Version(release)
if release_version >= version:
return prev
prev = release_version
return prev


def _get_release_version_strings(galaxy_root: Path) -> List[str]:
"""
Return sorted list of release version strings.
"""
all_files = _get_release_notes_filenames(galaxy_root)
release_notes_file_pattern = re.compile(r"\d+\.\d+.rst")
filenames = [f.rstrip(".rst") for f in all_files if release_notes_file_pattern.match(f)]
return sorted(filenames)


def _get_release_notes_filenames(galaxy_root):
releases_path = galaxy_root / "doc" / "source" / "releases"
if not os.path.exists(releases_path):
msg = f"Path to releases documentation not found: {releases_path}. If you are running this script outside of galaxy root directory, you should specify the '--galaxy-root' argument"
raise Exception(msg)

all_files = sorted(os.listdir(releases_path))
release_note_file_pattern = re.compile(r"\d+\.\d+.rst")
release_note_files = [f for f in all_files if release_note_file_pattern.match(f)]
return sorted(f.rstrip(".rst") for f in release_note_files)
return sorted(os.listdir(releases_path))


def _release_file(galaxy_root: Path, release: Optional[str]) -> str:
def _release_file(galaxy_root: Path, release: Optional[str]) -> str: # TODO: check this!
releases_path = galaxy_root / "doc" / "source" / "releases"
if release is None:
release = sorted(os.listdir(releases_path))[-1]
history_path = os.path.join(releases_path, release)
return history_path


def get_first_sentence(message: str) -> str:
first_line = message.split("\n")[0]
return first_line


def process_sentence(message):
def process_sentence(message): # TODO: check this!
# Strip tags like [15.07].
message = strip_release(message=message)
# Link issues and pull requests...
Expand All @@ -599,7 +663,7 @@ def process_sentence(message):
return message


def wrap(message):
def wrap(message): # TODO: check this!
message = process_sentence(message)
wrapper = textwrap.TextWrapper(initial_indent="* ")
wrapper.subsequent_indent = " "
Expand All @@ -611,9 +675,5 @@ def wrap(message):
return first_lines + ("\n" + rest_lines if rest_lines else "")


def next_weekday(d, weekday):
"""Return the next week day (0 for Monday, 6 for Sunday) starting from ``d``."""
days_ahead = weekday - d.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
return d + datetime.timedelta(days_ahead)
def next_weekday(d, weekday): # TODO remobve this
pass
13 changes: 13 additions & 0 deletions galaxy_release_util/cli/options.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import pathlib
from typing import (
Any,
Expand All @@ -19,6 +20,18 @@
)


release_date_option = click.option(
"--release-date",
type=click.DateTime(),
)

freeze_date_option = click.option(
"--freeze-date",
type=click.DateTime(),
default=datetime.datetime.today(),
)


def group_options(*options):
def wrapper(function):
for option in reversed(options):
Expand Down
73 changes: 58 additions & 15 deletions tests/test_bootstrap_history.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,65 @@
import datetime
from packaging.version import Version

import pytest

from galaxy_release_util.bootstrap_history import get_release_date
from galaxy_release_util import bootstrap_history
from galaxy_release_util.bootstrap_history import (
#_get_release_date,
_get_next_release_version,
_get_previous_release_version,
_get_next_release_version,
_get_release_version_strings,
)

# test data tuples: freeze date, expected release date
# (assumption: FREEZE_TO_RELEASE_DELTA_DAYS = 21)
release_date_test_data = [
(datetime.datetime(2024, 11, 1), datetime.datetime(2024, 11, 22)), # expect Friday
(datetime.datetime(2024, 11, 2), datetime.datetime(2024, 11, 25)), # expect Monday (not Saturday)
(datetime.datetime(2024, 11, 3), datetime.datetime(2024, 11, 25)), # expect Monday (not Sunday)
(datetime.datetime(2024, 11, 4), datetime.datetime(2024, 11, 25)), # expect Monday
(datetime.datetime(2024, 11, 5), datetime.datetime(2024, 11, 26)), # expect Tuesday
(datetime.datetime(2024, 11, 6), datetime.datetime(2024, 11, 27)), # expect Wednesday
(datetime.datetime(2024, 11, 7), datetime.datetime(2024, 11, 28)), # expect Thursday
]
# TODO do we need this???
## test data tuples: freeze date, expected release date
## (assumption: FREEZE_TO_RELEASE_DELTA_DAYS = 21)
#release_date_test_data = [
# (datetime.datetime(2024, 11, 1), datetime.datetime(2024, 11, 22)), # expect Friday
# (datetime.datetime(2024, 11, 2), datetime.datetime(2024, 11, 25)), # expect Monday (not Saturday)
# (datetime.datetime(2024, 11, 3), datetime.datetime(2024, 11, 25)), # expect Monday (not Sunday)
# (datetime.datetime(2024, 11, 4), datetime.datetime(2024, 11, 25)), # expect Monday
# (datetime.datetime(2024, 11, 5), datetime.datetime(2024, 11, 26)), # expect Tuesday
# (datetime.datetime(2024, 11, 6), datetime.datetime(2024, 11, 27)), # expect Wednesday
# (datetime.datetime(2024, 11, 7), datetime.datetime(2024, 11, 28)), # expect Thursday
#]
#
#
#@pytest.mark.parametrize("freeze_date, expected_release_date", release_date_test_data)
#def test_get_release_date(freeze_date, expected_release_date):
# assert _get_release_date(freeze_date) == expected_release_date
#


def test_get_previous_release_version(monkeypatch):
monkeypatch.setattr(bootstrap_history, "_get_release_version_strings", lambda x: sorted(["22.01", "22.05", "23.0", "23.1"]))

assert _get_previous_release_version(None, Version("15.1")) == None
assert _get_previous_release_version(None, Version("22.01")) == None
assert _get_previous_release_version(None, Version("22.05")) == Version("22.01")
assert _get_previous_release_version(None, Version("23.0")) == Version("22.05")
assert _get_previous_release_version(None, Version("23.1")) == Version("23.0")
assert _get_previous_release_version(None, Version("23.2")) == Version("23.1")
assert _get_previous_release_version(None, Version("99.99")) == Version("23.1")


def test_get_next_release_version():
assert _get_next_release_version(Version("25.0")) == Version("25.1")
assert _get_next_release_version(Version("26.1")) == Version("26.2")


def test_get_release_version_strings(monkeypatch):
filenames = [
"15.0.not_rst",
"22.01.rst",
"22.05.rst",
"23.0.rst",
"23.1.rst",
"23.not_a_release.rst",
"not_a_release.23.rst",
]
monkeypatch.setattr(bootstrap_history, "_get_release_notes_filenames", lambda x: sorted(filenames))
assert _get_release_version_strings(None) == ["22.01", "22.05", "23.0", "23.1"]


@pytest.mark.parametrize("freeze_date, expected_release_date", release_date_test_data)
def test_get_release_date(freeze_date, expected_release_date):
assert get_release_date(freeze_date) == expected_release_date

0 comments on commit 7b5eaaa

Please sign in to comment.