Skip to content

Commit

Permalink
Add release next version command
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Sep 27, 2021
1 parent 7387623 commit 06174a3
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 8 deletions.
10 changes: 10 additions & 0 deletions docs/usage/cli_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ or
changelog_path=subfolder/CHANGELOG.md
```

It also provides two keywords `next` and `latest` instead of using a version number when creating a zip.

## Command help

```bash
Expand All @@ -39,6 +41,14 @@ The `CHANGELOG.md` file must follow the convention [Keep A Changelog](https://ke
- Extract the `CHANGELOG.md` content and copy it into the `changelog` section within plugin `metadata.txt`
- Extract the `n` latest versions from `CHANGELOG.md` into `metadata.txt`
- Get the latest version release note
- When packaging or releasing, you can use these keywords :
- `latest` will make a package of the latest tag described in the changelog file.
- `next` will make a package of the possible smallest higher tag :
- `3.4.0` -> `3.4.1-alpha`
- `3.4.0-alpha` -> `3.4.1-alpha.1`
- `3.4.0-alpha1` -> `3.4.1-alpha2`

Be careful when you use the `next` command. It is designed to make a package which is not based on a specific version (on CI mainly). You should be careful with the tag you are creating if you have some packages delivered as well with the `next` command otherwise QGIS Plugin manager might not warn users about possible new release.

## Examples

Expand Down
45 changes: 38 additions & 7 deletions qgispluginci/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@
)
from qgispluginci.parameters import Parameters
from qgispluginci.translation import Translation
from qgispluginci.utils import configure_file, parse_tag, replace_in_file
from qgispluginci.utils import (
append_to_file,
configure_file,
parse_tag,
replace_in_file,
)


def create_archive(
Expand Down Expand Up @@ -105,6 +110,18 @@ def create_archive(
"version={}".format(release_version),
)

# Git SHA1
append_to_file(
f"{parameters.plugin_path}/metadata.txt",
f"gitSha1={repo.head.object.hexsha}",
)

# Date/time in UTC
date_time = datetime.datetime.now(datetime.timezone.utc).strftime(
"%Y-%m-%dT%H:%M:%SZ"
)
append_to_file(f"{parameters.plugin_path}/metadata.txt", f"dateTime={date_time}")

# set the plugin as experimental on a pre-release
if is_prerelease:
replace_in_file(
Expand Down Expand Up @@ -379,6 +396,25 @@ def upload_plugin_to_osgeo(username: str, password: str, archive: str):
sys.exit(1)


def check_release_keywords(release_version: str) -> str:
""" Check if we are releasing some special version shortcut. """
if release_version not in ("latest", "next"):
return release_version

parser = ChangelogParser()
if not parser.has_changelog():
raise Exception(
"Not possible to determine the latest tag without a changelog file."
)

if release_version == "latest":
return parser.latest_version()

# Next tags
latest_version = parse_tag(parser.latest_version())
return latest_version.next_version().version


def release(
parameters: Parameters,
release_version: str,
Expand Down Expand Up @@ -422,12 +458,7 @@ def release(
If omitted, a git submodule is updated. If specified, git submodules will not be updated/initialized before packaging.
"""

if release_version == "latest":
parser = ChangelogParser(
parent_folder=Path(parameters.plugin_path).resolve().parent,
changelog_path=parameters.changelog_path,
)
release_version = parser.latest_version()
release_version = check_release_keywords(release_version)

if transifex_token is not None:
tr = Translation(
Expand Down
6 changes: 6 additions & 0 deletions qgispluginci/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ def replace_in_file(file_path: str, pattern, new: str, encoding: str = "utf8"):
f.write(content)


def append_to_file(file_path: str, new_line: str):
""" Append a line in a file. """
with open(file_path, "a", encoding="utf8") as f:
f.write("{}\n".format(new_line))


def configure_file(source_file: str, dest_file: str, replace: dict):
with open(source_file, "r", encoding="utf-8") as f:
content = f.read()
Expand Down
33 changes: 33 additions & 0 deletions qgispluginci/version_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,36 @@ def version(self) -> str:
return f"{self.major}.{self.minor}.{self.patch}-{self.prerelease}"
else:
return f"{self.major}.{self.minor}.{self.patch}"

def increment_pre_release(self) -> str:
""" Increment the pre-release string. """
items = self.prerelease.split(".")

numbers = "".join([i for i in self.prerelease if i.isdigit()])

if len(items) == 1:
if numbers:
return f"{self.prerelease[0:-len(numbers)]}{int(numbers) + 1}"
else:
return f"{self.prerelease}.1"

return f"{items[0]}.{int(numbers) + 1}"

def next_version(self) -> NamedTuple:
""" Increment the pre-release string or the patch. """
# "pre" is not supported by QGIS
# https://github.com/qgis/QGIS/blob/master/python/pyplugin_installer/version_compare.py
if not self.prerelease:
return VersionNote(
major=self.major,
minor=self.minor,
patch=str(int(self.patch) + 1),
prerelease="alpha",
)

return VersionNote(
major=self.major,
minor=self.minor,
patch=self.patch,
prerelease=self.increment_pre_release(),
)
21 changes: 20 additions & 1 deletion test/test_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from qgispluginci.changelog import ChangelogParser
from qgispluginci.exceptions import GithubReleaseNotFound
from qgispluginci.parameters import DASH_WARNING, Parameters
from qgispluginci.release import release
from qgispluginci.release import check_release_keywords, release
from qgispluginci.translation import Translation
from qgispluginci.utils import replace_in_file

Expand Down Expand Up @@ -179,6 +179,25 @@ def test_release_changelog(self):
f"changelog detection failed in release: {data}",
)

def test_release_latest_next(self):
""" Test releasing the latest and next versions. """
keywords = ("next", "latest")
for keyword in keywords:
with self.subTest(i=keyword):
release(self.parameters, keyword)
archive_name = self.parameters.archive_name(
self.parameters.plugin_path, check_release_keywords(keyword)
)

with ZipFile(archive_name, "r") as zip_file:
data = zip_file.read("qgis_plugin_CI_testing/metadata.txt")

self.assertEqual(
data.find(b"version=latest"), -1
) # Version is the one in __about__.py
self.assertGreater(data.find(b"gitSha1="), 0)
self.assertGreater(data.find(b"dateTime="), 0)


if __name__ == "__main__":
unittest.main()
16 changes: 16 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ def test_version_note_from_tag(self):
self.assertIsNone(version.prerelease)
self.assertFalse(version.is_prerelease)

def test_next_version(self):
""" Test to guess the next version. """
self.assertEqual(parse_tag("10.1.0").next_version().version, "10.1.1-alpha")
self.assertEqual(
parse_tag("10.1.0-beta").next_version().version, "10.1.0-beta.1"
)
self.assertEqual(
parse_tag("10.1.0-beta1").next_version().version, "10.1.0-beta2"
)
self.assertEqual(
parse_tag("10.1.0-beta.2").next_version().version, "10.1.0-beta.3"
)
self.assertEqual(
parse_tag("10.1.0-rc.10").next_version().version, "10.1.0-rc.11"
)


if __name__ == "__main__":
unittest.main()

0 comments on commit 06174a3

Please sign in to comment.