Skip to content

Commit

Permalink
Add prepare-release task
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicoretti committed Mar 11, 2024
1 parent d29cf66 commit 9087f40
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 19 deletions.
32 changes: 32 additions & 0 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
# Unreleased

## ✨ Added
* **Added Nox Task `prepare-release`**

**Overview:**

A new Nox task, `prepare-release`, has been introduced to streamline the release preparation process. This task automates several crucial steps:

- Updates the version number to the next release.
- Transfers changes from the "Unreleased" section to the appropriate versioned changelog section.
- Creates a dedicated branch for the release changes.
- Initiates a Pull Request (PR) for review and integration into the main branch.

**Usage:**

To prepare a release, simply execute the following command in your terminal:

```shell
nox -s prepare-release -- 1.10.1
```

Add the changes for releasing ontop of the current branch:

```shell
nox -s prepare-release -- 1.10.1 --no-pr --no-branch
```

For additional options and help regarding the prepare-release task, execute:

```shell
nox -s prepare-release -- -h
```
99 changes: 86 additions & 13 deletions exasol/toolbox/nox/tasks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

from exasol.toolbox.cli import version

__all__ = [
"Mode",
"fix",
Expand Down Expand Up @@ -39,6 +41,13 @@
format_report,
)
from exasol.toolbox.project import python_files as _python_files
from exasol.toolbox.release import (
Version,
_content_from,
new_changelog,
new_changes,
new_unreleased,
)
from noxconfig import (
PROJECT_CONFIG,
Config,
Expand Down Expand Up @@ -336,8 +345,6 @@ def prepare_release(session: Session, python=False) -> None:
"""

def _parser():
from exasol.toolbox.cli import version

parser = argparse.ArgumentParser(
prog=f"nox -s prepare-release",
usage="nox -s prepare-release -- [-h] version",
Expand All @@ -346,36 +353,102 @@ def _parser():
parser.add_argument(
"version",
type=version,
help=(
"A version string of the following format:"
'"NUMBER.NUMBER.NUMBER"'
),
help=("A version string of the following format:" '"NUMBER.NUMBER.NUMBER"'),
)
parser.add_argument(
"--no-add",
default=False,
action="store_true",
help=("Neither add nor commit the changes"),
)
parser.add_argument(
"--no-branch",
default=False,
action="store_true",
help=("Do not create a branch to commit the changes on"),
)
parser.add_argument(
"--no-pr",
default=False,
action="store_true",
help=("Do not create a pull request for the changes"),
)
return parser

parser = _parser()
args = parser.parse_args(session.posargs)
version = args.version
# 0. check release version number
# 1. update version numbers in the project
# 2. update changelog (version + date)
new_version = args.version
old_version = Version.from_poetry()
if not new_version > old_version:
error_msg = (
"Invalid version, new version ({new}) "
"must be higher than old version ({old})."
)
session.error(error_msg.format(new=new_version, old=old_version))

if not args.no_branch and not args.no_add:
# prepare branch
session.run("git", "switch", "-c", f"release/prepare-{new_version}")

# bump project version and sync version file
session.run("poetry", "version", f"{new_version}")
_version(session, Mode.Fix, PROJECT_CONFIG.version_file)

# create a changelog file for the release and also create a new empty unrleased file
unreleased = Path(PROJECT_CONFIG.root) / "doc" / "changes" / "unreleased.md"
changelog = (
Path(PROJECT_CONFIG.root) / "doc" / "changes" / f"changes_{new_version}.md"
)
changes = Path(PROJECT_CONFIG.root) / "doc" / "changes" / f"changelog.md"

changelog_content = _content_from(unreleased)
changelog.write_text(new_changelog(new_version, changelog_content))

unreleased.write_text(new_unreleased())

changes_content = new_changes(changes, new_version)
changes.write_text(changes_content)

if args.no_add:
return

# 3. commit changes
session.run("git", "add", f"{changelog}")
session.run("git", "add", f"{unreleased}")
session.run("git", "add", f"{changes}")
session.run("git", "add", f"{PROJECT_CONFIG.root / 'pyproject.toml'}")
session.run("git", "add", f"{PROJECT_CONFIG.version_file}")
session.run("git", "commit", "-m", f"Prepare release {new_version}")

# 4. create pr
pass
if not args.no_pr:
session.run(
"gh",
"pr",
"create",
"--title",
f"Prepare release {new_version}",
"--body",
'""',
)


@nox.session(name="release", python=False)
def release(session: Session, python=False) -> None:
"""
Creates a new release and publishing it to GitHub and pypi.
"""
session.error("Not implemented yet")
# test are run on pr and on merge no so we assume we should be good
# can be changed in the future if that does not work well

# 0. check if tag does not exist (origin)
# 0.1. update git information
# 0.2. check if origin does not have the tag yet
# 2. check if current branch is main/master
# 3. build wheel/package
# 1. create release tag
# 2. push release tag to origin
# 3. build wheel/package
# 4. publish on gh
# 5. publish on pypi
# 6. output relase message/information
pass
41 changes: 35 additions & 6 deletions exasol/toolbox/release/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from datetime import datetime
import subprocess
from inspect import cleandoc
from dataclasses import dataclass
from datetime import datetime
from functools import total_ordering
from inspect import cleandoc
from pathlib import Path
from shutil import which

from exasol.toolbox.error import ToolboxError
Expand Down Expand Up @@ -66,7 +67,37 @@ def from_poetry():
return Version.from_string(version)


def changelog(version : Version, content: str, date: datetime | None = None) -> str:
def _content_from(unreleased: str | Path) -> str:
with open(unreleased) as f:
lines = f.readlines()[1:]
content = "".join(lines)
content = cleandoc(content)
return content


def new_changes(file: str | Path, version: str) -> str:
file = Path(file)
content = []

with open(file) as f:
for line in f:
content.append(line)
if line.startswith("* [unreleased]"):
content.append(f"* [{version}](changes_{version}.md)\n")
if line.startswith("unreleased"):
content.append(f"changes_{version}\n")

return "".join(content)


def new_unreleased() -> str:
"""
Creates the content of a new "empty" unreleased.md file.
"""
return "# Unreleased\n"


def new_changelog(version: Version, content: str, date: datetime | None = None) -> str:
"""
Create a changelog entry for a specific version.
Expand All @@ -87,7 +118,5 @@ def changelog(version : Version, content: str, date: datetime | None = None) ->
"""
)
return template.format(
version=version,
date=date.strftime('%Y-%m-%d'),
content=content
version=version, date=date.strftime("%Y-%m-%d"), content=content
)

0 comments on commit 9087f40

Please sign in to comment.