Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add release "next" version command #52

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`
Copy link
Member

@3nids 3nids Apr 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it 3.4.1 ?

- `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
26 changes: 20 additions & 6 deletions qgispluginci/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,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 @@ -455,12 +474,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)

release_tag = release_tag or release_version

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(),
)
19 changes: 18 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 @@ -190,6 +190,23 @@ def test_release_changelog(self):
# Commit sha1 not in the metadata.txt
self.assertEqual(0, len(re.findall(r"commitSha1=\d+", str(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")

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


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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this because next version is experimental by default?

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()