def test_changelog_last_items(self): """Test last items from changelog.""" # on fixture changelog parser = ChangelogParser(parent_folder="test/fixtures") last_items = parser.last_items(3) self.assertIsInstance(last_items, str) # on repository changelog parser = ChangelogParser() last_items = parser.last_items(3) self.assertIsInstance(last_items, str)
def test_changelog_parser(self): """ Test we can parse a changelog with a regex. """ self.assertTrue(ChangelogParser.has_changelog()) parser = ChangelogParser(CHANGELOG_REGEXP) self.assertIsNone(parser.content("0.0.0"), "") expected = ( "* Tag using a wrong format DD/MM/YYYY according to Keep A Changelog\n" '* Tag without "v" prefix\n' "* Add a CHANGELOG.md file for testing") self.assertEqual(parser.content("0.1.2"), expected) expected = ( "\n " "Version 0.1.2 :\n " "* Tag using a wrong format DD/MM/YYYY according to Keep A Changelog\n " '* Tag without "v" prefix\n ' "* Add a CHANGELOG.md file for testing\n" "\n") self.assertEqual(parser.last_items(1), expected) expected = """ Version 0.1.2 : * Tag using a wrong format DD/MM/YYYY according to Keep A Changelog * Tag without "v" prefix * Add a CHANGELOG.md file for testing Version v0.1.1 : * Tag using a correct format YYYY-MM-DD according to Keep A Changelog * Tag with a "v" prefix to check the regular expression * Previous version Version 0.1.0 : * Very old version """ self.assertEqual(parser.last_items(3), expected)
def test_release_changelog(self): """Test if changelog in metadata.txt inside zipped plugin after release command.""" # variables cli_config_changelog = Path( "test/fixtures/.qgis-plugin-ci-test-changelog.yaml") version_to_release = "0.1.2" # load specific parameters with cli_config_changelog.open() as in_cfg: arg_dict = yaml.safe_load(in_cfg) parameters = Parameters(arg_dict) self.assertIsInstance(parameters, Parameters) # get output zip path archive_name = parameters.archive_name( plugin_name=parameters.plugin_path, release_version=version_to_release) # extract last items from changelog parser = ChangelogParser() self.assertTrue(parser.has_changelog()) changelog_lastitems = parser.last_items( count=parameters.changelog_number_of_entries) # Include a changelog release( parameters=parameters, release_version=version_to_release, allow_uncommitted_changes=True, ) # open archive and compare with ZipFile(archive_name, "r") as zip_file: data = zip_file.read(f"{parameters.plugin_path}/metadata.txt") # Changelog self.assertGreater( data.find(bytes(changelog_lastitems, "utf8")), 0, f"changelog detection failed in release: {data}", ) # Commit number self.assertEqual(1, len(re.findall(r"commitNumber=\d+", str(data)))) # Commit sha1 not in the metadata.txt self.assertEqual(0, len(re.findall(r"commitSha1=\d+", str(data))))
def create_archive( parameters: Parameters, release_version: str, archive_name: str, add_translations: bool = False, allow_uncommitted_changes: bool = False, is_prerelease: bool = False, raise_min_version: str = None, disable_submodule_update: bool = False, ): repo = git.Repo() top_tar_handle, top_tar_file = mkstemp(suffix=".tar") # keep track of current state initial_stash = None diff = repo.index.diff(None) if diff: print("Uncommitted changes:") for diff in diff: print(diff) if not allow_uncommitted_changes: raise UncommitedChanges( "You have uncommitted changes. Stash or commit them or use --allow-uncommitted-changes." ) else: initial_stash = repo.git.stash("create") # changelog if parameters.changelog_include: parser = ChangelogParser(parameters.changelog_regexp) if parser.has_changelog(): try: content = parser.last_items( parameters.changelog_number_of_entries) if content: replace_in_file( "{}/metadata.txt".format(parameters.plugin_path), r"^changelog=.*$", "changelog={}".format(content), ) except Exception as e: # Do not fail the release process if something is wrong when parsing the changelog replace_in_file( "{}/metadata.txt".format(parameters.plugin_path), r"^changelog=.*$", "", ) print( "An exception occurred while parsing the changelog file : {}" .format(e)) else: # Remove the changelog line replace_in_file("{}/metadata.txt".format(parameters.plugin_path), r"^changelog=.*$", "") # set version in metadata replace_in_file( "{}/metadata.txt".format(parameters.plugin_path), r"^version=.*$", "version={}".format(release_version), ) # set the plugin as experimental on a pre-release if is_prerelease: replace_in_file( "{}/metadata.txt".format(parameters.plugin_path), r"^experimental=.*$", "experimental={}".format(True if is_prerelease else False), ) if raise_min_version: replace_in_file( "{}/metadata.txt".format(parameters.plugin_path), r"^qgisMinimumVersion=.*$", "qgisMinimumVersion={}".format(raise_min_version), ) # replace any DEBUG=False in all Python files if not is_prerelease: for file in glob("{}/**/*.py".format(parameters.plugin_path), recursive=True): replace_in_file(file, r"^DEBUG\s*=\s*True", "DEBUG = False") # keep track of current state try: stash = repo.git.stash("create") except git.exc.GitCommandError: stash = "HEAD" if stash == "" or stash is None: stash = "HEAD" # create TAR archive print("archive plugin with stash: {}".format(stash)) repo.git.archive(stash, "-o", top_tar_file, parameters.plugin_path) # adding submodules for submodule in repo.submodules: _, sub_tar_file = mkstemp(suffix=".tar") if submodule.path.split("/")[0] != parameters.plugin_path: print("skipping submodule not in plugin source directory ({})". format(submodule.name)) continue if not disable_submodule_update: submodule.update(init=True) sub_repo = submodule.module() print("archive submodule:", sub_repo) sub_repo.git.archive("HEAD", "--prefix", "{}/".format(submodule.path), "-o", sub_tar_file) with tarfile.open(top_tar_file, mode="a") as tt: with tarfile.open(sub_tar_file, mode="r:") as st: for m in st.getmembers(): # print('adding', m, m.type, m.isfile()) if not m.isfile(): continue tt.add(m.name) # add translation files if add_translations: with tarfile.open(top_tar_file, mode="a") as tt: print("adding translations") for file in glob("{}/i18n/*.qm".format(parameters.plugin_path)): print(" adding translation: {}".format( os.path.basename(file))) # https://stackoverflow.com/a/48462950/1548052 tt.add(file) # compile qrc files pyqt5ac.main(ioPaths=[[ "{}/*.qrc".format(parameters.plugin_path), "{}/%%FILENAME%%_rc.py".format(parameters.plugin_path), ]]) for file in glob("{}/*_rc.py".format(parameters.plugin_path)): with tarfile.open(top_tar_file, mode="a") as tt: print(" adding resource: {}".format(file)) # https://stackoverflow.com/a/48462950/1548052 tt.add(file) # converting to ZIP # why using TAR before? because it provides the prefix and makes things easier with zipfile.ZipFile(file=archive_name, mode="w", compression=zipfile.ZIP_DEFLATED) as zf: # adding the content of TAR archive with tarfile.open(top_tar_file, mode="r:") as tt: for m in tt.getmembers(): if m.isdir(): continue f = tt.extractfile(m) fl = f.read() fn = m.name zf.writestr(fn, fl) print("-------") print("files in ZIP archive ({}):".format(archive_name)) with zipfile.ZipFile(file=archive_name, mode="r") as zf: for f in zf.namelist(): print(f) print("-------") # checkout to reset changes if initial_stash: repo.git.reset("--hard", initial_stash) repo.git.reset("HEAD^") else: repo.git.checkout("--", ".")