From fb354669e40551b2592ffe936c88b4b93783179b Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Wed, 28 Apr 2021 10:05:17 +0700 Subject: [PATCH] Add release next version command --- docs/usage/cli_changelog.md | 10 ++++++++++ qgispluginci/release.py | 26 ++++++++++++++++++++------ qgispluginci/version_note.py | 33 +++++++++++++++++++++++++++++++++ test/test_release.py | 19 ++++++++++++++++++- test/test_utils.py | 16 ++++++++++++++++ 5 files changed, 97 insertions(+), 7 deletions(-) diff --git a/docs/usage/cli_changelog.md b/docs/usage/cli_changelog.md index 59cf5852..5d5f4ec0 100644 --- a/docs/usage/cli_changelog.md +++ b/docs/usage/cli_changelog.md @@ -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 @@ -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 diff --git a/qgispluginci/release.py b/qgispluginci/release.py index e64ca71e..ee6a93af 100644 --- a/qgispluginci/release.py +++ b/qgispluginci/release.py @@ -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, @@ -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 diff --git a/qgispluginci/version_note.py b/qgispluginci/version_note.py index a9ebd73f..23f72923 100644 --- a/qgispluginci/version_note.py +++ b/qgispluginci/version_note.py @@ -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(), + ) diff --git a/test/test_release.py b/test/test_release.py index 75668980..f32dbe6b 100644 --- a/test/test_release.py +++ b/test/test_release.py @@ -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 @@ -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() diff --git a/test/test_utils.py b/test/test_utils.py index 95d444f1..7b9fb6a9 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -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()