Coverage for heliumcli/actions/buildrelease.py: 84.88%
86 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-14 23:25 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-14 23:25 +0000
1import datetime
2import os
3import shutil
5import git
7from .. import utils
8from .prepcode import PrepCodeAction
10__author__ = "Alex Laird"
11__copyright__ = "Copyright 2018, Helium Edu"
12__version__ = "1.5.0"
15class BuildReleaseAction:
16 def __init__(self):
17 self.name = "build-release"
18 self.help = "Build a release version for all projects, tagging when complete"
20 def setup(self, subparsers):
21 parser = subparsers.add_parser(self.name, help=self.help)
22 parser.add_argument("version", help="The version number to be tagged")
23 parser.add_argument("--roles", action="store", type=str, nargs="*",
24 help="Limit the project roles to be built/tagged")
25 parser.set_defaults(action=self)
27 def run(self, args):
28 config = utils.get_config()
29 projects_dir = utils.get_projects_dir()
31 # First ensure all repos are in a clean state with all changes committed
32 dirty_repos = []
33 for project in utils.get_projects(config):
34 if args.roles and project not in args.roles:
35 continue
37 if config["projectsRelativeDir"] != ".":
38 project_path = os.path.join(projects_dir, project)
39 else:
40 project_path = os.path.join(projects_dir)
42 repo = git.Repo(project_path)
44 if repo.untracked_files or repo.is_dirty():
45 dirty_repos.append(project)
46 else:
47 repo.git.fetch(tags=True, prune=True)
48 repo.git.checkout("master")
50 if len(dirty_repos) > 0:
51 print("WARN: this operation cannot be performed when a repo is dirty. Commit all changes to the following "
52 "repos before proceeding: {}".format(dirty_repos))
54 return
56 version = args.version.lstrip("v")
58 self._update_version_file(version,
59 os.path.join(config["versionInfo"]["project"], config["versionInfo"]["path"]))
61 prepcodeaction = PrepCodeAction()
62 prepcodeaction.run(args)
64 print("Committing changes and creating release tags ...")
66 for project in utils.get_projects(config):
67 print(project)
69 if config["projectsRelativeDir"] != ".":
70 project_path = os.path.join(projects_dir, project)
71 else:
72 project_path = os.path.join(projects_dir)
74 self._commit_and_tag(project_path, version)
76 if config["projectsRelativeDir"] != ".":
77 root_dir = os.path.abspath(os.path.join(projects_dir, ".."))
78 if os.path.exists(os.path.join(root_dir, ".git")):
79 print(utils.get_repo_name(root_dir))
80 self._commit_and_tag(root_dir, version)
82 print("... release version {} built.".format(version))
84 def _commit_and_tag(self, path, version):
85 repo = git.Repo(path)
87 if version in repo.tags:
88 print("Version already exists, not doing anything.")
89 else:
90 if repo.is_dirty():
91 repo.git.add(u=True)
92 repo.git.commit(m="[heliumcli] Release {}".format(version))
93 repo.remotes["origin"].push("master")
94 tag = repo.create_tag(version, m="")
95 repo.remotes["origin"].push(tag)
97 def _update_version_file(self, version, path):
98 config = utils.get_config()
100 version_file_path = os.path.join(utils.get_projects_dir(), path)
102 version_file = open(version_file_path, "r")
103 new_version_file = open(version_file_path + ".tmp", "w")
105 for line in version_file:
106 if version_file_path.endswith(".py"):
107 if line.strip().startswith("__version__ ="):
108 line = "__version__ = \"{}\"\n".format(version)
109 elif line.strip().startswith("__copyright__ = "):
110 line = "__copyright__ = \"Copyright {}, {}\"\n".format(str(datetime.date.today().year),
111 utils.get_copyright_name())
112 elif version_file.name == "package.json":
113 if line.strip().startswith("\"version\":"):
114 line = " \"version\": \"{}\",\n".format(version)
115 # TODO: implement other known types
116 else:
117 print("WARN: helium-cli does not know how to process this type of file for version file: {}".format(
118 config["versionInfo"]["path"]))
120 new_version_file.close()
121 os.remove(version_file_path + ".tmp")
123 return
125 new_version_file.write(line)
127 version_file.close()
128 new_version_file.close()
130 shutil.copy(version_file_path + ".tmp", version_file_path)
131 os.remove(version_file_path + ".tmp")