示例#1
0
    def push(self, force: bool = False):
        ''' Boolean return type states, whether to continue process or abort'''
        if (not force and not self.has_unpushed_commits()):
            log_info("Nothing to be pushed.")
            return

        if (self.__config.test_run or self.__config.debug) and not prompt_yesno_question(
                "[DEBUG] Changes will be pushed now. Continue?"):
            self.reset()
            sys.exit()
        if self.__config.dry_run:
            log_info_dry('Skipping pushing of changes.')
            return

        try:
            log_info(
                "Pushing to origin/" + self.__repo.active_branch.name + " in " + self.__repo.working_tree_dir + "  ...")
            self.__repo.git.execute("git push origin " + self.__repo.active_branch.name + " --tags")
        except Exception as e:
            if "no changes added to commit" in str(e):
                log_info("No file is changed, nothing to commit.")
            else:
                if not prompt_yesno_question(
                        "Something went wrong during pushing. Please check if you can perform pushing on your own. Resume the script?"):
                    self.reset()
示例#2
0
 def reset(self):
     if (self.__config.cleanup_silently or prompt_yesno_question(
             'Should the repository and file system to be reset automatically?\nThis will reset the entire repository inlcuding latest commits to comply to remote.\nThis will also delete untrackted files!')):
         # arbitrary 20, but extensive enough to reset all hopefully
         log_info("Executing reset (git reset --hard HEAD~20)")
         self.__repo.git.reset('--hard', 'HEAD~20')
         self.update_and_clean()
示例#3
0
    def merge(self, source: str, target: str) -> None:
        if self.__config.dry_run:
            log_info_dry("Would merge from " + source + " to " + target)
            return

        try:
            self.checkout(target)
            log_info("Executing git pull...")
            self.pull()
            log_info("Merging...")
            self.__repo.git.execute("git merge " + self.__config.branch_to_be_released)
            log_info("Adapting automatically generated merge commit message to include issue no.")
            automatic_commit_message = self.__repo.git.execute("git log -1 --pretty=%B")
            if "Merge" in automatic_commit_message and str(
                    self.__config.github_issue_no) not in automatic_commit_message:
                self.__repo.git.execute('git commit --amend -m"#' + str(
                    self.__config.github_issue_no) + ' ' + automatic_commit_message + '"')
        except Exception as ex:
            log_error("Something went wrong, please check if merge conflicts exist and solve them.")
            if self.__config.debug:
                print(ex)
            if not prompt_yesno_question(
                    "If there were conflicts you solved and committed, would you like to resume the script?"):
                self.__repo.git.execute("git merge --abort")
                self.reset()
                sys.exit()
示例#4
0
    def create_issue(self, title: str, milestone: Milestone, body: str) -> int:
        '''Function creates an issue in git hub with title,milestone,body,labels passed'''
        if self.__config.dry_run:
            log_info_dry('Skipping creation of issue with title ' + str(title))
            return 0
        if self.__config.debug and not prompt_yesno_question(
                '[DEBUG] Would now create GitHub issue with title="' + title +
                '", milestone=' + str(milestone) + '. Continue?'):
            sys.exit()

        log_info('Create GitHub issue with title "' + title + '"...')

        try:
            issue: Issue = self.__repo.create_issue(
                title=title,
                body=body,
                milestone=milestone,
                labels=[self.__config.issue_label_name, "CI/CD"],
                assignee=self.__github.get_user().login)
            self.__config.github_issue_no = issue.number
            self.__cache.issues.update({issue.number: issue})
            return self.__config.github_issue_no
        except GithubException as e:
            print(str(e))
            return 0
示例#5
0
 def __authenticate_git_user(self):
     while True:
         if not hasattr(self.__config, "two_factor_authentication"):
             self.__config.two_factor_authentication = prompt_yesno_question(
                 "Are you using two-factor authentication on GitHub?")
         if self.__config.two_factor_authentication:
             self.__config.git_token = getpass.getpass(
                 "> Please enter your token: ")
             while not self.__config.git_token:
                 self.__config.git_token = getpass.getpass(
                     "> Please enter your token: ")
         else:
             if not hasattr(self.__config, "git_username"):
                 self.__config.git_username = prompt_enter_value(
                     "your git user name")
             else:
                 log_info("The stored Github username is {}".format(
                     self.__config.git_username))
             self.__config.git_password = getpass.getpass(
                 "> Please enter your password: "******"> Please enter your password: "******"Authenticated.")
             break
         except BadCredentialsException:
             log_info("Authentication error, please try again.")
             continue
示例#6
0
def __log_step(message: str):
    log_step(message)

    global git_repo
    global config
    if config.debug and not prompt_yesno_question("[DEBUG] Continue with next step '"+message+"'?"):
        if git_repo:
            git_repo.reset()
            sys.exit()
 def assure_clean_working_copy(self) -> None:
     if not self.is_working_copy_clean(True):
         log_error("Working copy is not clean!")
         if self.__config.cleanup_silently or prompt_yesno_question("Should I clean the repo for you? This will delete all untracked files and hardly reset the repository!"):
             self.reset()
         else:
             log_info("Please cleanup your working copy first. Then run the script again.")
             sys.exit()
     else:
         log_info("Working copy clean.")
示例#8
0
 def update_and_clean(self):
     log_info("Executing update and cleanup (git pull origin && git clean -fd)")
     self.pull()
     self.__repo.git.clean("-fd")
     if not self.is_working_copy_clean():
         log_error("Reset and cleanup did not work out. Other branches have local commits not yet pushed:")
         log_info("\n" + self.__list_unpushed_commits())
         if not prompt_yesno_question(
                 "Something went wrong during cleanup. Please check if you can perform the cleanup on your own. Resume the script?"):
             self.reset()
             sys.exit()
示例#9
0
def run_maven_process_and_handle_error(command: str, execpath: str=config.build_folder_abs):
    log_info("Execute command '" + command + "'")
    returncode = maven.run_maven_process(execpath, command)

    if returncode == 1:
        log_error("Maven execution failed, please see create_release.py.log for logs located at current directory.")
        if prompt_yesno_question("Maven execution failed. Script is not able to recover from it by its own.\nCan you fix the problem right now? If so, would you like to retry the last maven execution and resume the script?"):
            run_maven_process_and_handle_error(command, execpath)
        else:
            git_repo.reset()
            sys.exit()
示例#10
0
 def pull(self, branch_name: str = None):
     if not branch_name:
         branch = self.__repo.active_branch.name
     else:
         branch = branch_name
     try:
         log_info('Pull changes from origin ...')
         self.__repo.git.execute("git pull origin {}".format(branch).split(" "))
     except GitCommandError:
         log_error("Pull from origin/" + branch + " on " + self.__repo.working_tree_dir +
                   " is not possible as you might have uncommitted or untracked files. Fix the working tree, and then try again.")
         if not prompt_yesno_question("Did you fix the issue manually? Resume script?"):
             self.reset()
             sys.exit()
示例#11
0
    def __set_path(config: Config, attr: str):
        while True:
            if not hasattr(config, attr) or not getattr(config, attr):
                path = config.temp_root_path
                if not hasattr(config, "two_factor_authentication"):
                    config.two_factor_authentication = prompt_yesno_question(
                        "Are you using two-factor authentication on GitHub?")
                if config.two_factor_authentication:
                    repository_url = "[email protected]:" + config.github_repo + ".git"
                else:
                    repository_url = "https://github.com/" + config.github_repo + ".git"
                log_info("Cloning temporary repository from " +
                         repository_url + " to " + str(path) +
                         " for processing the release...")
                Repo.clone_from(repository_url,
                                path,
                                multi_options=["--config core.longpaths=true"])
            else:
                path = getattr(config, attr)  # set by script param

            if not __check_path(path):
                setattr(config, attr, "")
                continue

            if (attr == "root_path") & (os.path.realpath(__file__).startswith(
                    os.path.abspath(path))):
                log_error(
                    "Please copy and run the create release script in another place outside of the repository and execute again."
                )
                sys.exit()

            try:
                Git(path)
            except InvalidGitRepositoryError:
                log_error("Path " + path + " is not a git repository.")

            setattr(config, attr, path)

            info = {
                "root_path": "Executing release in path '",
            }
            log_info(info[attr] + str(getattr(config, attr)) + "'")
            break
示例#12
0
def __load_config_file(config: Config):
    def load_file(path):
        with open(path, 'r') as file:
            try:
                return yaml.safe_load(file)
            except yaml.YAMLError as exc:
                log_error(exc)

    config_dir = "config"
    non_git_config_path = os.path.join(config_dir, "non_git_config.yml")
    git_config_path = os.path.join(config_dir, "git_config.yml")
    if os.path.isfile(git_config_path) and os.path.isfile(git_config_path):
        msg = "[INFO ] We have found a configuration file from your previous execution," \
              " would you like to load it?"
        load_file_flag = prompt_yesno_question(msg)
        if load_file_flag:
            data = {
                **load_file(non_git_config_path),
                **load_file(git_config_path)
            }
            for attr in data:
                setattr(config, attr, data[attr])
            return True
    return False
示例#13
0
    init_non_git_config(config)
    loaded_config_flag = __load_config_file(config)
    __store_config(config)

    with create_git_repo(config) as git_repo:
        git_repo.assure_clean_working_copy()

        github = GitHub(config)
        init_git_dependent_config(config, github, git_repo)
        __store_config(config)
        exit_if_origin_is_not_correct(config)

        if (config.debug):
            log_debug("Current config:")
            pprint(vars(config))
            if not prompt_yesno_question("[DEBUG] Continue?"):
                sys.exit()

        maven = Maven(config, github)

        input(
            "\nPlease close all eclipse instances as of potential race conditions on maven builds causing errors. Press return if done..."
        )
        input(
            "\nPlease close SourceTree for Git performance reasons. Press return if done...\n"
        )

        report_messages = []

        #####################################################################
示例#14
0
def init_non_git_config(config: Config):
    __process_params(config)

    def __check_path(path):
        if not os.path.exists(path):
            log_error("Path does not exist.")
        if not os.path.isdir(path):
            log_error("Path is not a directory.")
        return os.path.exists(path) & os.path.isdir(path)

    def __set_path(config: Config, attr: str):
        msg = {
            'root_path': "path of the repository to work on",
        }
        while True:
            if not hasattr(config, attr) or not getattr(config, attr):
                path = prompt_enter_value(msg[attr])
            else:
                path = getattr(config, attr)  # set by script param

            if not __check_path(path):
                setattr(config, attr, "")
                continue

            if (attr == "root_path") & (os.path.realpath(__file__).startswith(
                    os.path.abspath(path))):
                log_error(
                    "Please copy and run the create release script in another place outside of the repository and execute again."
                )
                sys.exit()

            try:
                Git(path)
            except InvalidGitRepositoryError:
                log_error("Path is not a git repository.")

            setattr(config, attr, path)

            info = {
                "root_path": "Executing release in path '",
            }
            log_info(info[attr] + str(getattr(config, attr)) + "'")
            break

    __set_path(config, "root_path")

    if not hasattr(config, 'github_repo'):
        config.github_repo = ""
    repo_pattern = re.compile(r'[a-zA-Z]+/[a-zA-Z]+')
    while (not repo_pattern.match(config.github_repo)):
        if config.github_repo:
            log_error("'" + config.github_repo +
                      "' is not a valid GitHub repository name.")
        config.github_repo = prompt_enter_value(
            "repository to be released (e.g. devonfw/tools-cobigen)")
    log_info("Releasing against GitHub repository '" + config.github_repo +
             "'")
    config.git_repo_name = config.github_repo.split(sep='/')[1]
    config.git_repo_org = config.github_repo.split(sep='/')[0]

    if not config.oss:
        config.oss = prompt_yesno_question(
            "Should the release been published to maven central as open source?"
        )
    if config.oss:
        if not hasattr(config, "gpg_keyname"):
            config.gpg_keyname = prompt_enter_value(
                """Please provide your gpg.keyname for build artifact signing.
If you are unsure about this, please stop here and clarify, whether
  * you created a pgp key and
  * published it!
gpg.keyname = """)

        if not config.gpg_loaded:
            config.gpg_loaded = prompt_yesno_question(
                "Make sure the gpg key '" + config.gpg_keyname +
                "' is loaded by tools like Kleopatra before continuing! Continue?"
            )
            if not config.gpg_loaded:
                sys.exit()

        #Check whether the user has gpg2 installed
        if is_tool("gpg2"):
            if not hasattr(config, "gpg_executable"):
                log_info("gpg2 installation found")
                config.gpg_executable = "gpg2"
        elif is_tool("gpg"):
            if not hasattr(config, "gpg_executable"):
                log_info("gpg installation found")
                config.gpg_executable = "gpg"
        else:
            log_error(
                "gpg2 nor gpg are installed. Please install them on your computer (system path) or either use command -Dgpg.executable='gpg2'"
            )
def init_non_git_config(config: Config):
    __process_params(config)

    while True:
        if not hasattr(config, 'root_path') or not config.root_path:
            root_path = prompt_enter_value("path of the repository to work on")
        else:
            root_path = config.root_path  # set by script param
        if not os.path.exists(root_path):
            log_error("Path does not exist.")
            config.root_path = ""
            continue
        if not os.path.isdir(root_path):
            log_error("Path is not a directory.")
            config.root_path = ""
            continue
        if os.path.realpath(__file__).startswith(os.path.abspath(root_path)):
            log_error(
                "Please copy and run the create release script in another place outside of the repository and execute again."
            )
            sys.exit()

        try:
            Git(root_path)
        except InvalidGitRepositoryError:
            log_error("Path is not a git repository.")

        config.root_path = root_path
        log_info("Executing release in path '" + str(config.root_path) + "'")
        break

    if not hasattr(config, 'github_repo'):
        config.github_repo = ""
    repo_pattern = re.compile(r'[a-zA-Z]+/[a-zA-Z]+')
    while (not repo_pattern.match(config.github_repo)):
        if config.github_repo:
            log_error("'" + config.github_repo +
                      "' is not a valid GitHub repository name.")
        config.github_repo = prompt_enter_value(
            "repository to be released (e.g. devonfw/tools-cobigen)")
    log_info("Releasing against GitHub repository '" + config.github_repo +
             "'")
    config.git_repo_name = config.github_repo.split(sep='/')[1]
    config.git_repo_org = config.github_repo.split(sep='/')[0]

    config.wiki_submodule_name = "cobigen-documentation/" + config.git_repo_name + ".wiki"
    config.wiki_submodule_path = os.path.abspath(
        os.path.join(config.root_path, "cobigen-documentation",
                     config.git_repo_name + ".wiki"))

    config.oss = prompt_yesno_question(
        "Should the release been published to maven central as open source?")
    if config.oss:
        if not hasattr(config, "gpg_keyname"):
            config.gpg_keyname = prompt_enter_value(
                """Please provide your gpg.keyname for build artifact signing. 
If you are unsure about this, please stop here and clarify, whether
  * you created a pgp key and
  * published it!
gpg.keyname = """)
        if not prompt_yesno_question(
                "Make sure the gpg key '" + config.gpg_keyname +
                "' is loaded by tools like Kleopatra before continuing! Continue?"
        ):
            sys.exit()
config = Config()
init_non_git_config(config)

git_repo = GitRepo(config)
git_repo.assure_clean_working_copy()

github = GitHub(config)
init_git_dependent_config(config, github, git_repo)

exit_if_origin_is_not_correct(config)

if (config.debug):
    log_debug("Current config:")
    pprint(vars(config))
    if not prompt_yesno_question("[DEBUG] Continue?"):
        sys.exit()

maven = Maven(config, github)

input(
    "\nPlease close all eclipse instances as of potential race conditions on maven builds causing errors. Press return if done..."
)
input(
    "\nPlease close SourceTree for Git performance reasons. Press return if done...\n"
)

report_messages = []

#####################################################################
示例#17
0
def init_non_git_config(config: Config):
    __process_params(config)

    def __check_path(path):
        if not os.path.exists(path):
            log_error("Path does not exist.")
        if not os.path.isdir(path):
            log_error("Path is not a directory.")
        return os.path.exists(path) & os.path.isdir(path)

    def __set_path(config: Config, attr: str):
        while True:
            if not hasattr(config, attr) or not getattr(config, attr):
                path = config.temp_root_path
                if not hasattr(config, "two_factor_authentication"):
                    config.two_factor_authentication = prompt_yesno_question(
                        "Are you using two-factor authentication on GitHub?")
                if config.two_factor_authentication:
                    repository_url = "[email protected]:" + config.github_repo + ".git"
                else:
                    repository_url = "https://github.com/" + config.github_repo + ".git"
                log_info("Cloning temporary repository from " + repository_url + " to " + str(path) + " for processing the release...")
                Repo.clone_from(repository_url, path, multi_options=["--config core.longpaths=true"])
            else:
                path = getattr(config, attr)  # set by script param

            if not __check_path(path):
                setattr(config, attr, "")
                continue

            if (attr == "root_path") & (os.path.realpath(__file__).startswith(os.path.abspath(path))):
                log_error(
                    "Please copy and run the create release script in another place outside of the repository and execute again.")
                sys.exit()

            try:
                Git(path)
            except InvalidGitRepositoryError:
                log_error("Path " + path + " is not a git repository.")

            setattr(config, attr, path)

            info = {
                "root_path": "Executing release in path '",
            }
            log_info(info[attr] + str(getattr(config, attr)) + "'")
            break

    ###################################################################################################################################

    if not hasattr(config, 'github_repo'):
        config.github_repo = ""
    repo_pattern = re.compile(r'[a-zA-Z]+/[a-zA-Z]+')
    while(not repo_pattern.match(config.github_repo)):
        if config.github_repo:
            log_error("'" + config.github_repo + "' is not a valid GitHub repository name.")
        config.github_repo = prompt_enter_value("repository to be released (default on empty: devonfw/cobigen)", "devonfw/cobigen")
    log_info("Releasing against GitHub repository '"+config.github_repo+"'")
    config.git_repo_name = config.github_repo.split(sep='/')[1]
    config.git_repo_org = config.github_repo.split(sep='/')[0]

    __set_path(config, "root_path")

    if not config.oss:
        config.oss = prompt_yesno_question("Should the release been published to maven central as open source?")
    if config.oss:
        if not hasattr(config, "gpg_keyname"):
            config.gpg_keyname = prompt_enter_value("""Please provide your gpg.keyname for build artifact signing.
If you are unsure about this, please stop here and clarify, whether
  * you created a pgp key and
  * published it!
gpg.keyname = """)

        if not config.gpg_loaded:
            config.gpg_loaded = prompt_yesno_question("Make sure the gpg key '" + config.gpg_keyname +
                                                      "' is loaded by tools like Kleopatra before continuing! Continue?")
            if not config.gpg_loaded:
                sys.exit()

        # Check whether the user has gpg2 installed
        if is_tool("gpg2"):
            if not hasattr(config, "gpg_executable"):
                log_info("gpg2 installation found")
                config.gpg_executable = "gpg2"
        elif is_tool("gpg"):
            if not hasattr(config, "gpg_executable"):
                log_info("gpg installation found")
                config.gpg_executable = "gpg"
        else:
            log_error("gpg2 nor gpg are installed. Please install them on your computer (system path) or either use command -Dgpg.executable='gpg2'")