Esempio n. 1
0
    def package_all(self, version=None):
        """Repackage files to be uploaded.

        'version': version to package; defaults to the current tag (without the
        'release-' prefix."""
        if not self.repo.is_nuxeoecm:
            log("Skip packaging step (not a main Nuxeo repository).")
            return
        self.archive_dir = os.path.abspath(os.path.join(self.repo.basedir,
                                                   os.pardir, "archives"))
        if os.path.isdir(self.archive_dir):
            shutil.rmtree(self.archive_dir)
        os.mkdir(self.archive_dir)
        self.tmpdir = tempfile.mkdtemp()

        if version is None:
            version = self.tag

        # Tomcat and JBoss packages
        for old, new in PKG_RENAMINGS.items():
            self.package(old % version, new % version)
        # Tomcat SDK packages
        for old, new in PKG_RENAMINGS_OPTIONALS.items():
            self.package(old % version, new % version, False)

        self.package_sources(version)
        shutil.rmtree(self.tmpdir)
Esempio n. 2
0
 def __init__(self, alias, restart_from, default_conf=None, marketplace_conf=None):
     self.alias = alias
     self.restart_from = restart_from
     if marketplace_conf == '':
         marketplace_conf = DEFAULT_MP_CONF_URL
     self.marketplace_conf = marketplace_conf
     cwd = os.getcwd()
     if os.path.isdir(os.path.join(cwd, "marketplace")):
         pass
     elif os.path.split(cwd)[1] == "marketplace":
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     else:
         if '__file__' not in locals():
             __file__ = inspect.getframeinfo(inspect.currentframe())[0]  # @ReservedAssignment
         cwd = os.path.dirname(os.path.abspath(__file__))
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     log("Nuxeo source location: %s" % cwd)
     self.repo = Repository(cwd, self.alias)
     self.defaults = {}
     if default_conf:
         default_info = ReleaseInfo()
         default_info.read_release_log(default_conf)
         prefix = default_info.module
         for key, value in vars(default_info).iteritems():
             self.defaults[prefix + "-" + key] = str(value)
     self.mp_config = self.repo.get_mp_config(self.marketplace_conf, self.defaults)
Esempio n. 3
0
 def __init__(self,
              alias,
              restart_from,
              default_conf=None,
              marketplace_conf=None):
     self.alias = alias
     self.restart_from = restart_from
     if marketplace_conf == '':
         marketplace_conf = DEFAULT_MP_CONF_URL
     self.marketplace_conf = marketplace_conf
     cwd = os.getcwd()
     if os.path.isdir(os.path.join(cwd, "marketplace")):
         pass
     elif os.path.split(cwd)[1] == "marketplace":
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     else:
         if '__file__' not in locals():
             __file__ = inspect.getframeinfo(
                 inspect.currentframe())[0]  # @ReservedAssignment
         cwd = os.path.dirname(os.path.abspath(__file__))
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     log("Nuxeo source location: %s" % cwd)
     self.repo = Repository(cwd, self.alias)
     self.defaults = {}
     if default_conf:
         default_info = ReleaseInfo()
         default_info.read_release_log(default_conf)
         prefix = default_info.module
         for key, value in vars(default_info).iteritems():
             self.defaults[prefix + "-" + key] = str(value)
     self.mp_config = self.repo.get_mp_config(self.marketplace_conf,
                                              self.defaults)
Esempio n. 4
0
def main():
    assert_git_config()

    try:
        usage = ("""usage: %prog <command> [options]
       %prog clone [-r alias] [-m URL]
       %prog branch [-r alias] [-m URL] [--rf package] [--dryrun]
       %prog prepare [-r alias] [-m URL] [--rf package] [--dryrun]
       %prog perform [-r alias] [-m URL] [--rf package] [--dryrun]""")
        description = """Release Nuxeo Packages.\n
The first call must provide an URL for the configuration. If set to '' (empty string), it defaults to '%s'. You can use
a local file URL ('file://').\n
Then, a 'release.ini' file is generated and will be reused for the next calls. For each package, a
'release-$PACKAGE_NAME.log' file is also generated and corresponds to the file generated by the release.py script.\n
The 'release.ini' file contains informations about the release process:\n
- 'prepared = True' if the prepare task succeeded,\n
- 'performed = True' if the perform task succeeded,\n
- 'uploaded = ...' if an upload successfully happened,\n
- 'skip = Failed!' followed by a stack trace in case of error.\n
The script can be re-called: it will skip the packages with a skip value and skip the prepare (or perform) if
'prepared = True' (or 'performed = True').\n
Failed uploads are not retried and must be manually done.""" % DEFAULT_MP_CONF_URL
        help_formatter = IndentedHelpFormatterWithNL(max_help_position=7, width=get_terminal_size()[0])
        parser = optparse.OptionParser(usage=usage, description=description, formatter=help_formatter)
        parser.add_option('-r', action="store", type="string", dest='remote_alias', default='origin',
                          help="""The Git alias of remote URL. Default: '%default'""")
        parser.add_option('-m', "--marketplace-conf", action="store", type="string", dest='marketplace_conf',
                          default=None, help="""The Marketplace configuration URL. Default: '%default'""")
        parser.add_option('-i', '--interactive', action="store_true", dest='interactive', default=False,
                          help="""Not implemented (TODO NXP-8573). Interactive mode. Default: '%default'""")
        parser.add_option('--rf', '--restart-from', action="store", dest='restart_from', default=None,
                          help="""Restart from a package. Default: '%default'""")
        parser.add_option('--dryrun', action="store_true", dest='dryrun', default=False,
                          help="""Dry run mode. Default: '%default'""")
        (options, args) = parser.parse_args()
        if len(args) == 1:
            command = args[0]
        elif len(args) > 1:
            raise ExitException(1, "'command' must be a single argument. See usage with '-h'.")
        full_release = ReleaseMP(options.remote_alias, options.restart_from, options.marketplace_conf)
        if "command" not in locals():
            raise ExitException(1, "Missing command. See usage with '-h'.")
        elif command == "clone":
            full_release.clone()
        elif command == "branch":
            full_release.release_branch(dryrun=options.dryrun)
        elif command == "prepare":
            full_release.prepare(dryrun=options.dryrun)
        elif command == "perform":
            full_release.perform(dryrun=options.dryrun)
        elif command == "test":
            full_release.test()
        else:
            raise ExitException(1, "Unknown command! See usage with '-h'.")
    except ExitException, e:
        if e.message is not None:
            log("[ERROR] %s" % e.message, sys.stderr)
        sys.exit(e.return_code)
Esempio n. 5
0
def main():
    assert_git_config()

    try:
        usage = ("""usage: %prog <command> [options]
       %prog clone [-r alias] [-m URL]
       %prog branch [-r alias] [-m URL] [--rf package] [--dryrun]
       %prog prepare [-r alias] [-m URL] [--rf package] [--dryrun]
       %prog perform [-r alias] [-m URL] [--rf package] [--dryrun]""")
        description = """Release Nuxeo Packages.\n
The first call must provide an URL for the configuration. If set to '' (empty string), it defaults to '%s'. You can use
a local file URL ('file://').\n
Then, a 'release.ini' file is generated and will be reused for the next calls. For each package, a
'release-$PACKAGE_NAME.log' file is also generated and corresponds to the file generated by the release.py script.\n
The 'release.ini' file contains informations about the release process:\n
- 'prepared = True' if the prepare task succeeded,\n
- 'performed = True' if the perform task succeeded,\n
- 'uploaded = ...' if an upload successfully happened,\n
- 'skip = Failed!' followed by a stack trace in case of error.\n
The script can be re-called: it will skip the packages with a skip value and skip the prepare (or perform) if
'prepared = True' (or 'performed = True').\n
Failed uploads are not retried and must be manually done.""" % DEFAULT_MP_CONF_URL
        help_formatter = IndentedHelpFormatterWithNL(max_help_position=7, width=get_terminal_size()[0])
        parser = optparse.OptionParser(usage=usage, description=description, formatter=help_formatter)
        parser.add_option('-r', action="store", type="string", dest='remote_alias', default='origin',
                          help="""The Git alias of remote URL. Default: '%default'""")
        parser.add_option('-m', "--marketplace-conf", action="store", type="string", dest='marketplace_conf',
                          default=None, help="""The Marketplace configuration URL. Default: '%default'""")
        parser.add_option('-i', '--interactive', action="store_true", dest='interactive', default=False,
                          help="""Not implemented (TODO NXP-8573). Interactive mode. Default: '%default'""")
        parser.add_option('--rf', '--restart-from', action="store", dest='restart_from', default=None,
                          help="""Restart from a package. Default: '%default'""")
        parser.add_option('--dryrun', action="store_true", dest='dryrun', default=False,
                          help="""Dry run mode. Default: '%default'""")
        (options, args) = parser.parse_args()
        if len(args) == 1:
            command = args[0]
        elif len(args) > 1:
            raise ExitException(1, "'command' must be a single argument. See usage with '-h'.")
        full_release = ReleaseMP(options.remote_alias, options.restart_from, options.marketplace_conf)
        if "command" not in locals():
            raise ExitException(1, "Missing command. See usage with '-h'.")
        elif command == "clone":
            full_release.clone()
        elif command == "branch":
            full_release.release_branch(dryrun=options.dryrun)
        elif command == "prepare":
            full_release.prepare(dryrun=options.dryrun)
        elif command == "perform":
            full_release.perform(dryrun=options.dryrun)
        elif command == "test":
            full_release.test()
        else:
            raise ExitException(1, "Unknown command! See usage with '-h'.")
    except ExitException, e:
        if e.message is not None:
            log("[ERROR] %s" % e.message, sys.stderr)
        sys.exit(e.return_code)
Esempio n. 6
0
 def perform(self):
     """ Perform the release: push source, deploy artifacts and upload
     packages."""
     cwd = os.getcwd()
     marketplaces = self.mp_config.sections()
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace,
                                 self.mp_config.get(marketplace, "skip")))
             continue
         if not self.mp_config.getboolean(marketplace, "prepared"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, "Not prepared"))
             continue
         if self.mp_config.getboolean(marketplace, "performed"):
             log("Skipped '%s' (%s)" % (marketplace, "Already performed"))
             continue
         try:
             log("Perform %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Perform release
             (_, branch, tag, next_snapshot, maintenance_version, is_final,
              skipTests, _, other_versions,
              _, _) = Release.read_release_log(mp_repo.basedir)
             mp_release = Release(mp_repo, branch, tag, next_snapshot,
                                  maintenance_version, is_final=is_final,
                                  skipTests=skipTests,
                                  other_versions=other_versions)
             mp_release.perform()
             performed = True
         except:
             stack = traceback.format_exc()
             log("[ERROR] %s" % stack)
             performed = False
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "performed", performed)
         self.repo.save_mp_config(self.mp_config)
         if performed:
             # Upload on Connect
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and
                         fnmatch.fnmatch(path[len(mp_repo.basedir) + 1:],
                         self.mp_config.get(marketplace, "mp_to_upload"))):
                         self.upload(CONNECT_PROD_URL, path)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_PROD_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
     os.chdir(cwd)
Esempio n. 7
0
 def update_versions(self, old_version, new_version):
     """Update all occurrences of 'old_version' with 'new_version'."""
     log("Replacing occurrences of %s with %s" % (old_version, new_version))
     pattern = re.compile("^.*\\.(xml|properties|txt|defaults|sh|html|nxftl)$")
     for root, dirs, files in os.walk(os.getcwd(), True, None, True):
         for dir in set(dirs) & set([".git", "target"]):
             dirs.remove(dir)
         for name in files:
             replaced = False
             if fnmatch.fnmatch(name, "pom*.xml"):
                 tree = etree.parse(os.path.join(root, name))
                 # Parent POM version
                 parent = tree.getroot().find("pom:parent", namespaces)
                 if parent is not None:
                     elem = parent.find("pom:version", namespaces)
                     if elem is not None and elem.text == old_version:
                         elem.text = new_version
                         replaced = True
                 # POM version
                 elem = tree.getroot().find("pom:version", namespaces)
                 if elem is not None and elem.text == old_version:
                     elem.text = new_version
                     replaced = True
                 # Properties like nuxeo.*.version
                 prop_pattern = re.compile("{" + namespaces.get("pom") +
                                           "}nuxeo\..*version")
                 properties = tree.getroot().find("pom:properties",
                                                  namespaces)
                 if properties is not None:
                     for property in properties.getchildren():
                         if (not isinstance(property, etree._Comment)
                             and prop_pattern.match(property.tag)
                             and property.text == old_version):
                             property.text = new_version
                             replaced = True
                 tree.write_c14n(os.path.join(root, name))
             elif pattern.match(name):
                 with open(os.path.join(root, name), "rb") as f:
                     content = f.read()
                     if content.find(old_version) > -1:
                         replaced = True
                     content = content.replace(old_version, new_version)
                 with open(os.path.join(root, name), "wb") as f:
                     f.write(content)
             if replaced:
                 log(os.path.join(root, name))
Esempio n. 8
0
 def __init__(self, alias, restart_from, marketplace_conf=None):
     self.alias = alias
     self.restart_from = restart_from
     if marketplace_conf == '':
         marketplace_conf = DEFAULT_MP_CONF_URL
     self.marketplace_conf = marketplace_conf
     cwd = os.getcwd()
     if os.path.isdir(os.path.join(cwd, "marketplace")):
         pass
     elif os.path.split(cwd)[1] == "marketplace":
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     else:
         if '__file__' not in locals():
             __file__ = inspect.getframeinfo(inspect.currentframe())[0]  # @ReservedAssignment
         cwd = os.path.dirname(os.path.abspath(__file__))
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     log("Nuxeo source location: %s" % cwd)
     self.repo = Repository(cwd, self.alias)
     self.mp_config = self.repo.get_mp_config(self.marketplace_conf)
Esempio n. 9
0
 def __init__(self, alias, restart_from, marketplace_conf=None):
     self.alias = alias
     self.restart_from = restart_from
     if marketplace_conf == '':
         marketplace_conf = DEFAULT_MP_CONF_URL
     self.marketplace_conf = marketplace_conf
     cwd = os.getcwd()
     if os.path.isdir(os.path.join(cwd, "marketplace")):
         pass
     elif os.path.split(cwd)[1] == "marketplace":
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     else:
         if '__file__' not in locals():
             __file__ = inspect.getframeinfo(inspect.currentframe())[0]
         cwd = os.path.dirname(os.path.abspath(__file__))
         cwd = os.path.abspath(os.path.join(cwd, os.pardir))
     log("Nuxeo source location: %s" % cwd)
     self.repo = Repository(cwd, self.alias)
     self.mp_config = self.repo.get_mp_config(self.marketplace_conf)
Esempio n. 10
0
 def __init__(self, repo, branch, tag, next_snapshot, maintenance="auto",
              is_final=False, skipTests=False):
     self.repo = repo
     self.branch = branch
     self.is_final = is_final
     self.maintenance = maintenance
     self.skipTests = skipTests
     # Evaluate default values, if not provided
     self.set_snapshot()
     self.set_tag(tag)
     self.set_next_snapshot(next_snapshot)
     # Detect if working on Nuxeo main sources
     tree = etree.parse(os.path.join(self.repo.basedir, "pom.xml"))
     artifact_id = tree.getroot().find("pom:artifactId", namespaces)
     self.repo.is_nuxeoecm = "nuxeo-ecm" == artifact_id.text
     if self.repo.is_nuxeoecm:
         log("Releasing Nuxeo main repository...")
     else:
         log("Releasing custom repository...")
Esempio n. 11
0
 def prepare(self, dryrun=False):
     """ Prepare the release."""
     cwd = os.getcwd()
     marketplaces = self.mp_config.sections()
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace,
                                 self.mp_config.get(marketplace, "skip")))
             continue
         if self.mp_config.getboolean(marketplace, "prepared"):
             log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
             continue
         try:
             log("Prepare %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Prepare release
             mp_release = Release(mp_repo,
                     self.mp_config.get(marketplace, "branch"),
                     self.mp_config.get(marketplace, "tag"),
                     self.mp_config.get(marketplace, "next_snapshot"),
                     self.mp_config.get(marketplace, "maintenance_version"),
                     is_final=True, skipTests=False,
                     other_versions=self.mp_config.get(
                                             marketplace, "other_versions",
                                             None))
             mp_release.log_summary()
             mp_release.prepare(dryrun=dryrun)
             prepared = True
         except:
             stack = traceback.format_exc()
             log("[ERROR] %s" % stack)
             prepared = False
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "prepared", prepared)
         self.repo.save_mp_config(self.mp_config)
         if (prepared):
             # Upload on Connect test
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and
                         fnmatch.fnmatch(path[len(mp_repo.basedir) + 1:],
                         self.mp_config.get(marketplace, "mp_to_upload"))):
                         self.upload(CONNECT_TEST_URL, path)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_TEST_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
     os.chdir(cwd)
Esempio n. 12
0
    def package(self, old_archive, new_name, failonerror=True):
        """Repackage a ZIP following the rules:
            - have a parent directory with the same name as the archive name
            - set executable bit on scripts in bin/
            - activate the setup wizard

        If 'failonerror', raise an ExitException in case of missing file."""
        if not os.path.isfile(old_archive):
            if failonerror:
                raise ExitException(1, "Could not find %s" % old_archive)
            else:
                log("[WARN] Could not find %s" % old_archive, sys.stderr)
                return
        new_archive = os.path.join(self.archive_dir, new_name + ".zip")
        extract_zip(old_archive, os.path.join(self.tmpdir, new_name))
        log("Packaging %s ..." % new_archive)
        cwd = os.getcwd()
        os.chdir(os.path.join(self.tmpdir, new_name))
        ls = os.listdir(os.curdir)
        if len(ls) == 1:
            if ls[0] != new_name:
                shutil.move(ls[0], new_name)
        else:
            os.mkdir(new_name)
            for file in ls:
                shutil.move(file, os.path.join(new_name, file))

        files = os.listdir(os.path.join(new_name, "bin"))
        for filename in (fnmatch.filter(files, "*ctl") +
                        fnmatch.filter(files, "*.sh") +
                        fnmatch.filter(files, "*.command")):
            os.chmod(os.path.join(new_name, "bin", filename), 0744)
        with open(os.path.join(new_name, "bin", "nuxeo.conf"), "a") as f:
            f.write("nuxeo.wizard.done=false\n")
        make_zip(os.path.join(self.archive_dir, new_name + ".zip"),
                            os.getcwd(), new_name)
        os.chdir(cwd)
        # Cleanup temporary directory
        shutil.rmtree(os.path.join(self.tmpdir, new_name))
Esempio n. 13
0
    def prepare(self, dryrun=False):
        """ Prepare the release."""
        cwd = os.getcwd()
        if not os.path.isdir(self.repo.mp_dir):
            self.clone()
        os.chdir(self.repo.mp_dir)
        marketplaces_skipped = []
        for marketplace in self.get_packages_list():
            log("")
            if self.mp_config.has_option(marketplace, "skip"):
                log("[%s]" % marketplace)
                log("[WARN] Skipped '%s' (%s)" % (marketplace, self.mp_config.get(marketplace, "skip")))
                marketplaces_skipped.append(marketplace)
                upgrade_only = True
            else:
                upgrade_only = False
            if self.mp_config.getboolean(marketplace, "prepared"):
                log("[%s]" % marketplace)
                log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
                continue
            try:
                mp_dir = os.path.join(self.repo.mp_dir, marketplace)
                if not os.path.isdir(mp_dir):
                    os.chdir(self.repo.mp_dir)
                    self.repo.git_pull(marketplace, self.mp_config.get(marketplace, "branch"))
                else:
                    log("[%s]" % marketplace)
                os.chdir(mp_dir)
                mp_repo = Repository(os.getcwd(), self.alias)
                if upgrade_only:
                    log("Upgrade skipped %s..." % marketplace)
                else:
                    log("Prepare release of %s..." % marketplace)

                release_info = ReleaseInfo(module=marketplace, remote_alias=self.alias,
                                           branch=self.mp_config.get(marketplace, "branch"),
                                           tag=self.mp_config.get(marketplace, "tag"),
                                           next_snapshot=self.mp_config.get(marketplace, "next_snapshot"),
                                           maintenance_version=self.mp_config.get(marketplace, "maintenance_version"),
                                           is_final=self.mp_config.getboolean(marketplace, "is_final"),
                                           skip_tests=self.mp_config.getboolean(marketplace, "skipTests"),
                                           skip_its=self.mp_config.getboolean(marketplace, "skipITs"),
                                           profiles=self.mp_config.get(marketplace, "profiles"),
                                           other_versions=self.mp_config.get(marketplace, "other_versions"),
                                           #files_pattern, props_pattern, msg_commit, msg_tag,
                                           auto_increment_policy=self.mp_config.get(marketplace,
                                                                                    "auto_increment_policy"),
                                           dryrun=dryrun)
                mp_release = Release(mp_repo, release_info)
                release_log = mp_release.log_summary()
                release_info.read_release_log(release_log)
                if dryrun:
                    print "DEBUG -- init %s with:" % marketplace
                for key, value in vars(release_info).iteritems():
                    if dryrun:
                        print "DEBUG: %s-%s=%s" % (marketplace, key, value)
                    self.mp_config.set("DEFAULT", marketplace + "-" + key, str(value))
                if dryrun:
                    print

                mp_release.prepare(dryrun=dryrun, upgrade_only=upgrade_only, dodeploy=True)
                prepared = True
            except Exception, e:
                stack = traceback.format_exc()
                if hasattr(e, 'message') and e.message is not None:
                    stack = e.message + "\n" + stack
                log("[ERROR] %s" % stack)
                prepared = False
                stack = stack.replace("%", "%%")
                self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
            self.mp_config.set(marketplace, "prepared", str(prepared))
            self.repo.save_mp_config(self.mp_config)
            if prepared and not upgrade_only:
                owner = None
                if self.mp_config.has_option(marketplace, "owner"):
                    owner = self.mp_config.get(marketplace, "owner")
                self.upload(CONNECT_TEST_URL, marketplace, dryrun=dryrun, owner=owner)
Esempio n. 14
0
 def perform(self, dryrun=False):
     """ Perform the release: push source, deploy artifacts and upload
     packages."""
     cwd = os.getcwd()
     marketplaces = self.mp_config.sections()
     marketplaces_skipped = []
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace,
                                 self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if not self.mp_config.getboolean(marketplace, "prepared"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, "Not prepared"))
             continue
         if self.mp_config.getboolean(marketplace, "performed"):
             log("Skipped '%s' (%s)" % (marketplace, "Already performed"))
             continue
         try:
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Perform %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Perform release
             (_, branch, tag, next_snapshot, maintenance_version, is_final,
              skipTests, skipITs, _, other_versions,
              _, _) = Release.read_release_log(mp_repo.basedir)
             mp_release = Release(mp_repo, branch, tag, next_snapshot,
                                  maintenance_version, is_final=is_final,
                                  skipTests=skipTests, skipITs=skipITs,
                                  other_versions=other_versions)
             mp_release.perform(dryrun=dryrun, upgrade_only=upgrade_only)
             performed = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             performed = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "performed", str(performed))
         self.repo.save_mp_config(self.mp_config)
         if performed and not upgrade_only:
             # Upload on Connect
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and
                         fnmatch.fnmatch(path[len(mp_repo.basedir) + 1:],
                         self.mp_config.get(marketplace, "mp_to_upload"))):
                         self.upload(CONNECT_PROD_URL, path, dryrun=dryrun)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_PROD_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
Esempio n. 15
0
 def log_summary(self, store_params=True):
     """Log summary of configuration for current release."""
     log("Releasing from branch:".ljust(25) + self.branch)
     log("Current version:".ljust(25) + self.snapshot)
     log("Tag:".ljust(25) + "release-" + self.tag)
     log("Next version:".ljust(25) + self.next_snapshot)
     if self.maintenance == "auto":
         log("No maintenance branch".ljust(25))
     else:
         log("Maintenance version:".ljust(25) + self.maintenance)
     if self.skipTests:
         log("Tests execution is skipped")
     if store_params:
         release_log = os.path.abspath(os.path.join(self.repo.basedir,
                                                    os.pardir,
                                                    "release.log"))
         with open(release_log, "wb") as f:
             f.write("REMOTE=%s\nBRANCH=%s\nTAG=%s\nNEXT_SNAPSHOT=%s\n"
                     "MAINTENANCE=%s\nFINAL=%s\nSKIP_TESTS=%s" %
                     (self.repo.alias, self.branch, self.tag,
                      self.next_snapshot, self.maintenance, self.is_final,
                      self.skipTests))
         log("Parameters stored in %s" % release_log)
     log("")
Esempio n. 16
0
    def package_all(self, version=None):
        """Repackage files to be uploaded.

        'version': version to package; defaults to the current tag (without the
        'release-' prefix."""
        self.archive_dir = os.path.abspath(os.path.join(self.repo.basedir,
                                                   os.pardir, "archives"))
        if os.path.isdir(self.archive_dir):
            shutil.rmtree(self.archive_dir)
        os.mkdir(self.archive_dir)
        self.tmpdir = tempfile.mkdtemp()

        if version is None:
            version = self.tag

        # Tomcat and JBoss packages
        for old, new in PKG_RENAMINGS.items():
            self.package(old % version, new % version)
        # Tomcat SDK packages
        for old, new in PKG_RENAMINGS_OPTIONALS.items():
            self.package(old % version, new % version, False)

        # Online (aka light) Tomcat package
        offline_name = "nuxeo-cap-%s-tomcat" % version
        extract_zip(os.path.join(self.archive_dir, offline_name + ".zip"),
                    self.tmpdir)
        # Generate online package if packages.xml exists
        if os.path.isfile(os.path.join(self.tmpdir, offline_name,
                        "setupWizardDownloads", "packages.xml")):
            online_name = "nuxeo-cap-%s-tomcat-online" % version
            shutil.move(os.path.join(self.tmpdir, offline_name,
                                       "setupWizardDownloads", "packages.xml"),
                      os.path.join(self.archive_dir, "packages.xml"))
            # Remove Marketplace packages
            shutil.rmtree(os.path.join(self.tmpdir, offline_name,
                                       "setupWizardDownloads"))
            shutil.move(os.path.join(self.tmpdir, offline_name),
                      os.path.join(self.tmpdir, online_name))
            make_zip(os.path.join(self.archive_dir, online_name + ".zip"),
                                os.path.join(self.tmpdir, online_name),
                                online_name)

            # Marketplace packages
            archive_mp_dir = os.path.join(self.archive_dir, "mp")
            if not os.path.isdir(archive_mp_dir):
                os.mkdir(archive_mp_dir)
            # Copy and rename MP to archive directory
            for old, new in MP_RENAMINGS.items():
                shutil.copy2(old % version,
                             os.path.join(archive_mp_dir, new % version))
            log("Checking packages integrity...")
            for package in os.listdir(archive_mp_dir):
                m = hashlib.md5()
                with open(os.path.join(archive_mp_dir, package), "rb") as f:
                    m.update(f.read())
                package_md5 = m.hexdigest()
                found_package = False
                found_package_md5 = False
                for line in open(os.path.join(self.archive_dir, "packages.xml")):
                    if package in line:
                        found_package = True
                    if package_md5 in line:
                        found_package_md5 = True
                    if found_package and found_package_md5:
                        break
                if not found_package:
                    log("[ERROR] Could not find %s in packages.xml" % package,
                    sys.stderr)
                if not found_package_md5:
                    log("[ERROR] %s MD5 did not match packages.xml information"
                        % package, sys.stderr)
            log("Done.")
        self.package_sources(version)
        shutil.rmtree(self.tmpdir)
Esempio n. 17
0
 def perform(self, dryrun=False):
     """ Perform the release: push source, deploy artifacts and upload
     packages."""
     cwd = os.getcwd()
     marketplaces = self.mp_config.sections()
     marketplaces_skipped = []
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" %
                 (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if not self.mp_config.getboolean(marketplace, "prepared"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, "Not prepared"))
             continue
         if self.mp_config.getboolean(marketplace, "performed"):
             log("Skipped '%s' (%s)" % (marketplace, "Already performed"))
             continue
         try:
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Perform %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Perform release
             (_, branch, tag, next_snapshot, maintenance_version, is_final,
              skipTests, skipITs, _, other_versions, _,
              _) = Release.read_release_log(mp_repo.basedir)
             mp_release = Release(mp_repo,
                                  branch,
                                  tag,
                                  next_snapshot,
                                  maintenance_version,
                                  is_final=is_final,
                                  skipTests=skipTests,
                                  skipITs=skipITs,
                                  other_versions=other_versions)
             mp_release.perform(dryrun=dryrun, upgrade_only=upgrade_only)
             performed = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             performed = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "performed", str(performed))
         self.repo.save_mp_config(self.mp_config)
         if performed and not upgrade_only:
             # Upload on Connect
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and fnmatch.fnmatch(
                             path[len(mp_repo.basedir) + 1:],
                             self.mp_config.get(marketplace,
                                                "mp_to_upload"))):
                         self.upload(CONNECT_PROD_URL, path, dryrun=dryrun)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_PROD_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
Esempio n. 18
0
 def prepare(self, dryrun=False):
     """ Prepare the release."""
     cwd = os.getcwd()
     if not os.path.isdir(self.repo.mp_dir):
         self.clone()
     os.chdir(self.repo.mp_dir)
     marketplaces_skipped = []
     for marketplace in self.get_packages_list():
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[%s]" % marketplace)
             log("[WARN] Skipped '%s' (%s)" % (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if self.mp_config.getboolean(marketplace, "prepared"):
             log("[%s]" % marketplace)
             log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
             continue
         try:
             mp_dir = os.path.join(self.repo.mp_dir, marketplace)
             if not os.path.isdir(mp_dir):
                 os.chdir(self.repo.mp_dir)
                 self.repo.git_pull(marketplace, self.mp_config.get(marketplace, "branch"))
             else:
                 log("[%s]" % marketplace)
             os.chdir(mp_dir)
             mp_repo = Repository(os.getcwd(), self.alias)
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Prepare release of %s..." % marketplace)
             mp_release = Release(mp_repo,
                                  self.mp_config.get(marketplace, "branch"),
                                  self.mp_config.get(marketplace, "tag"),
                                  self.mp_config.get(marketplace, "next_snapshot"),
                                  self.mp_config.get(marketplace, "maintenance_version"),
                                  is_final=True,
                                  skipTests=self.mp_config.getboolean(marketplace, "skipTests"),
                                  skipITs=self.mp_config.getboolean(marketplace, "skipITs"),
                                  other_versions=self.mp_config.get(marketplace, "other_versions", None))
             mp_release.log_summary()
             mp_release.prepare(dryrun=dryrun, upgrade_only=upgrade_only, dodeploy=True)
             prepared = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             prepared = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "prepared", str(prepared))
         self.repo.save_mp_config(self.mp_config)
         if prepared and not upgrade_only:
             self.upload(CONNECT_TEST_URL, marketplace, dryrun=dryrun)
Esempio n. 19
0
 def prepare(self, dryrun=False):
     """ Prepare the release."""
     cwd = os.getcwd()
     if not os.path.isdir(self.repo.mp_dir):
         self.clone()
     os.chdir(self.repo.mp_dir)
     marketplaces = self.mp_config.sections()
     marketplaces_skipped = []
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[%s]" % marketplace)
             log("[WARN] Skipped '%s' (%s)" %
                 (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if self.mp_config.getboolean(marketplace, "prepared"):
             log("[%s]" % marketplace)
             log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
             continue
         try:
             mp_dir = os.path.join(self.repo.mp_dir, marketplace)
             if not os.path.isdir(mp_dir):
                 os.chdir(self.repo.mp_dir)
                 self.repo.git_pull(
                     marketplace, self.mp_config.get(marketplace, "branch"))
             else:
                 log("[%s]" % marketplace)
             os.chdir(mp_dir)
             mp_repo = Repository(os.getcwd(), self.alias)
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Prepare release of %s..." % marketplace)
             mp_release = Release(
                 mp_repo,
                 self.mp_config.get(marketplace, "branch"),
                 self.mp_config.get(marketplace, "tag"),
                 self.mp_config.get(marketplace, "next_snapshot"),
                 self.mp_config.get(marketplace, "maintenance_version"),
                 is_final=True,
                 skipTests=False,
                 skipITs=False,
                 other_versions=self.mp_config.get(marketplace,
                                                   "other_versions", None))
             mp_release.log_summary()
             mp_release.prepare(dryrun=dryrun,
                                upgrade_only=upgrade_only,
                                dodeploy=True)
             prepared = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             prepared = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "prepared", str(prepared))
         self.repo.save_mp_config(self.mp_config)
         if prepared and not upgrade_only:
             # Upload on Connect test
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and fnmatch.fnmatch(
                             path[len(mp_repo.basedir) + 1:],
                             self.mp_config.get(marketplace,
                                                "mp_to_upload"))):
                         self.upload(CONNECT_TEST_URL, path, dryrun=dryrun)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_TEST_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
Esempio n. 20
0
def main():
    global namespaces
    assert_git_config()
    namespaces = {"pom": "http://maven.apache.org/POM/4.0.0"}
    etree.register_namespace('pom', 'http://maven.apache.org/POM/4.0.0')

    try:
        if not os.path.isdir(".git"):
            raise ExitException(1, "That script must be ran from root of a Git"
                                + " repository")
        usage = ("usage: %prog [options] <command>\n\nCommands:\n"
                 "  prepare: Prepare the release (build, change versions, tag "
                 "and package source and distributions). The release "
                 "parameters are stored in a release.log file.\n"
                 "  perform: Perform the release (push sources, deploy "
                 "artifacts and upload packages). If no parameter is given, "
                 "they are read from the release.log file.\n"
                 "  package: Package distributions and source code in the "
                 "archives directory.")
        parser = optparse.OptionParser(usage=usage,
                                       description="""Release Nuxeo from
a given branch, tag the release, then set the next SNAPSHOT version.  If a
maintenance version was provided, then a maintenance branch is kept, else it is
deleted after release.""")
        parser.add_option('-r', action="store", type="string",
                          dest='remote_alias',
                          default='origin',
                          help="""the Git alias of remote URL
                          (default: %default)""")
        parser.add_option('-f', '--final', action="store_true",
                          dest='is_final', default=False,
                          help='is it a final release? (default: %default)')
        parser.add_option("-b", "--branch", action="store", type="string",
                          help='branch to release (default: current branch)',
                          dest="branch", default="auto")
        parser.add_option("-t", "--tag", action="store", type="string",
                          dest="tag", default="auto",
                          help="""if final option is True, then the default tag
is the current version minus '-SNAPSHOT', else the 'SNAPSHOT' keyword is
replaced with a date (aka 'date-based release')""")
        parser.add_option("-n", "--next", action="store", type="string",
                          dest="next_snapshot", default="auto",
                          help="""next snapshot. If final option is True, then
the next snapshot is the current one increased, else it is equal to the current
""")
        parser.add_option('-m', '--maintenance', action="store",
                          dest='maintenance', default="auto",
                          help="""maintenance version (by default, the
maintenance branch is deleted after release)""")
        parser.add_option('-i', '--interactive', action="store_true",
                          dest='interactive', default=False,
                          help="""Not implemented (TODO NXP-8573). Interactive
mode.""")
        parser.add_option('-d', '--deploy', action="store_true",
                          dest='deploy', default=False,
                          help="""deploy artifacts to nightly repository""")
        parser.add_option('--skipTests', action="store_true",
                          dest='skipTests', default=False,
                          help="""skip tests execution (but compile them)""")
        (options, args) = parser.parse_args()
        if len(args) == 1:
            command = args[0]
        elif len(args) > 1:
            raise ExitException(1, "'command' must be a single argument. "
                                "See usage with '-h'.")

        release_log = os.path.abspath(os.path.join(os.getcwd(), os.pardir,
                                               "release.log"))
        if ("command" in locals() and command == "perform"
            and os.path.isfile(release_log)
            and options == parser.get_default_values()):
            log("Reading parameters from %s ..." % release_log)
            with open(release_log, "rb") as f:
                options.remote_alias = f.readline().split("=")[1].strip()
                options.branch = f.readline().split("=")[1].strip()
                options.tag = f.readline().split("=")[1].strip()
                options.next_snapshot = f.readline().split("=")[1].strip()
                options.maintenance = f.readline().split("=")[1].strip()
                options.is_final = f.readline().split("=")[1].strip() == "True"
                options.skipTests = f.readline().split("=")[1].strip() == "True"

        repo = Repository(os.getcwd(), options.remote_alias)
        if options.branch == "auto":
            options.branch = repo.get_current_version()
        system("git fetch %s" % (options.remote_alias))
        repo.git_update(options.branch)
        release = Release(repo, options.branch, options.tag,
                          options.next_snapshot, options.maintenance,
                          options.is_final, options.skipTests)
        release.log_summary("command" in locals() and command != "perform")
        if "command" not in locals():
            raise ExitException(1, "Missing command. See usage with '-h'.")
        elif command == "prepare":
            release.prepare(options.deploy)
        elif command == "perform":
            release.perform()
        elif command == "package":
            repo.clone()
            # workaround for NXBT-121: use install instead of package
            repo.mvn("clean install", skip_tests=options.skipTests,
                     profiles="qa")
            release.package_all(release.snapshot)
        elif command == "test":
            release.test()
        else:
            raise ExitException(1, "Unknown command! See usage with '-h'.")
    except ExitException, e:
        if e.message is not None:
            log("[ERROR] %s" % e.message, sys.stderr)
        sys.exit(e.return_code)
Esempio n. 21
0
 def perform(self, dryrun=False):
     """ Perform the release: push source, deploy artifacts and upload
     packages."""
     cwd = os.getcwd()
     marketplaces_skipped = []
     for marketplace in self.get_packages_list():
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" %
                 (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if not self.mp_config.getboolean(marketplace, "prepared"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, "Not prepared"))
             continue
         if self.mp_config.getboolean(marketplace, "performed"):
             log("Skipped '%s' (%s)" % (marketplace, "Already performed"))
             continue
         try:
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Perform %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Perform release
             release_info = ReleaseInfo()
             release_info.read_release_log(
                 ReleaseInfo.get_release_log(mp_repo.basedir))
             mp_release = Release(mp_repo, release_info)
             mp_release.perform(dryrun=dryrun, upgrade_only=upgrade_only)
             performed = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             performed = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "performed", str(performed))
         self.repo.save_mp_config(self.mp_config)
         if performed and not upgrade_only:
             self.upload(CONNECT_PROD_URL, marketplace, dryrun=dryrun)
Esempio n. 22
0
 def prepare(self, dryrun=False):
     """ Prepare the release."""
     cwd = os.getcwd()
     if not os.path.isdir(self.repo.mp_dir):
         self.clone()
     os.chdir(self.repo.mp_dir)
     marketplaces_skipped = []
     for marketplace in self.get_packages_list():
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[%s]" % marketplace)
             log("[WARN] Skipped '%s' (%s)" %
                 (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if self.mp_config.getboolean(marketplace, "prepared"):
             log("[%s]" % marketplace)
             log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
             continue
         try:
             mp_dir = os.path.join(self.repo.mp_dir, marketplace)
             if not os.path.isdir(mp_dir):
                 os.chdir(self.repo.mp_dir)
                 self.repo.git_pull(
                     marketplace, self.mp_config.get(marketplace, "branch"))
             else:
                 log("[%s]" % marketplace)
             os.chdir(mp_dir)
             mp_repo = Repository(os.getcwd(), self.alias)
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Prepare release of %s..." % marketplace)
             mp_release = Release(
                 mp_repo,
                 self.mp_config.get(marketplace, "branch"),
                 self.mp_config.get(marketplace, "tag"),
                 self.mp_config.get(marketplace, "next_snapshot"),
                 self.mp_config.get(marketplace, "maintenance_version"),
                 is_final=True,
                 skipTests=self.mp_config.getboolean(
                     marketplace, "skipTests"),
                 skipITs=self.mp_config.getboolean(marketplace, "skipITs"),
                 other_versions=self.mp_config.get(marketplace,
                                                   "other_versions", None))
             mp_release.log_summary()
             mp_release.prepare(dryrun=dryrun,
                                upgrade_only=upgrade_only,
                                dodeploy=True)
             prepared = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             prepared = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "prepared", str(prepared))
         self.repo.save_mp_config(self.mp_config)
         if prepared and not upgrade_only:
             self.upload(CONNECT_TEST_URL, marketplace, dryrun=dryrun)
Esempio n. 23
0
 def prepare(self, dryrun=False):
     """ Prepare the release."""
     cwd = os.getcwd()
     if not os.path.isdir(self.repo.mp_dir):
         self.clone()
     os.chdir(self.repo.mp_dir)
     marketplaces = self.mp_config.sections()
     marketplaces_skipped = []
     if self.restart_from:
         idx = marketplaces.index(self.restart_from)
         marketplaces = marketplaces[idx:]
     for marketplace in marketplaces:
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[%s]" % marketplace)
             log("[WARN] Skipped '%s' (%s)" % (marketplace,
                                 self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if self.mp_config.getboolean(marketplace, "prepared"):
             log("[%s]" % marketplace)
             log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
             continue
         try:
             mp_dir = os.path.join(self.repo.mp_dir, marketplace)
             if not os.path.isdir(mp_dir):
                 os.chdir(self.repo.mp_dir)
                 self.repo.git_pull(marketplace,
                                 self.mp_config.get(marketplace, "branch"))
             else:
                 log("[%s]" % marketplace)
             os.chdir(mp_dir)
             mp_repo = Repository(os.getcwd(), self.alias)
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Prepare release of %s..." % marketplace)
             mp_release = Release(mp_repo,
                     self.mp_config.get(marketplace, "branch"),
                     self.mp_config.get(marketplace, "tag"),
                     self.mp_config.get(marketplace, "next_snapshot"),
                     self.mp_config.get(marketplace, "maintenance_version"),
                     is_final=True, skipTests=False, skipITs=False,
                     other_versions=self.mp_config.get(
                                             marketplace, "other_versions",
                                             None))
             mp_release.log_summary()
             mp_release.prepare(dryrun=dryrun, upgrade_only=upgrade_only,
                                dodeploy=True)
             prepared = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             prepared = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "prepared", str(prepared))
         self.repo.save_mp_config(self.mp_config)
         if prepared and not upgrade_only:
             # Upload on Connect test
             for dirpath, _, filenames in os.walk(mp_repo.basedir):
                 for name in filenames:
                     path = os.path.join(dirpath, name)
                     if (os.path.isfile(path) and
                         fnmatch.fnmatch(path[len(mp_repo.basedir) + 1:],
                         self.mp_config.get(marketplace, "mp_to_upload"))):
                         self.upload(CONNECT_TEST_URL, path, dryrun=dryrun)
                         self.mp_config.set(marketplace, "uploaded",
                                            CONNECT_TEST_URL + ": " + path)
                         self.repo.save_mp_config(self.mp_config)
Esempio n. 24
0
def main():
    assert_git_config()

    try:
        usage = ("""usage: %prog <command> [options]
       %prog clone [-r alias] [-m URL] [-d PATH]
       %prog branch [-r alias] [-m URL] [-d PATH] [--rf package] [--dryrun]
       %prog prepare [-r alias] [-m URL] [-d PATH] [--rf package] [--dryrun]
       %prog perform [-r alias] [-m URL] [-d PATH] [--rf package] [--dryrun]
\nCommands:
       clone: Clone or update Nuxeo Package repositories.
       branch: Create the release branch so that the branch to release is freed for ongoing development. Following \
'prepare' or 'perform' commands must use option '--next=done'. If kept, that branch will become the maintenance \
branch after release.
       prepare: Prepare the release (build, change versions, tag and package source and distributions). The release \
parameters are stored in release-<package name>.log files generated by the release.py script. \
The first call must provide a Nuxeo Packages configuration URL (option '-m') from which a 'release.ini' file is \
generated and will be reused for the next calls.
       perform: Perform the release (push sources, deploy artifacts and upload packages, tests are always skipped). \
If no parameter is given, they are read from the 'release.ini' file.""")
        description = """Release Nuxeo Packages.\n
You can initiate some parameters with a release log file (option '-d').\n
The 'release.ini' file contains informations about the release process:\n
- 'prepared = True' if the prepare task succeeded,\n
- 'performed = True' if the perform task succeeded,\n
- 'uploaded = ...' if an upload successfully happened,\n
- 'skip = Failed!' followed by a stack trace in case of error.\n
The script can be re-called: it will skip the packages with a skip value and skip the prepare (or perform) if
'prepared = True' (or 'performed = True').\n
Failed uploads are not retried and must be manually done."""
        help_formatter = IndentedHelpFormatterWithNL(
            max_help_position=7, width=get_terminal_size()[0])
        parser = optparse.OptionParser(usage=usage,
                                       description=description,
                                       formatter=help_formatter)
        parser.add_option(
            '-r',
            action="store",
            type="string",
            dest='remote_alias',
            default='origin',
            help="""The Git alias of remote URL. Default: '%default'""")
        parser.add_option(
            '-d',
            "--default",
            action="store",
            type="string",
            dest='default_conf',
            default=None,
            help=
            """The default configuration file (usually '/path/to/release-nuxeo.log').
Default: '%default'""")
        parser.add_option(
            '-m',
            "--marketplace-conf",
            action="store",
            type="string",
            dest='marketplace_conf',
            default=None,
            help=
            """The Nuxeo Packages configuration URL (usually named 'marketplace.ini').
You can use a local file URL ('file://').\n
If set to '' (empty string), then it will default to '""" +
            DEFAULT_MP_CONF_URL + """'. Default: '%default'""")
        parser.add_option(
            '-i',
            '--interactive',
            action="store_true",
            dest='interactive',
            default=False,
            help=
            """Not implemented (TODO NXP-8573). Interactive mode. Default: '%default'"""
        )
        parser.add_option(
            '--rf',
            '--restart-from',
            action="store",
            dest='restart_from',
            default=None,
            help="""Restart from a package. Default: '%default'""")
        parser.add_option('--dryrun',
                          action="store_true",
                          dest='dryrun',
                          default=False,
                          help="""Dry run mode. Default: '%default'""")
        (options, args) = parser.parse_args()
        if len(args) == 1:
            command = args[0]
        elif len(args) > 1:
            raise ExitException(
                1, "'command' must be a single argument. See usage with '-h'.")
        full_release = ReleaseMP(options.remote_alias, options.restart_from,
                                 options.default_conf,
                                 options.marketplace_conf)
        if "command" not in locals():
            raise ExitException(1, "Missing command. See usage with '-h'.")
        elif command == "clone":
            full_release.clone()
        elif command == "branch":
            full_release.release_branch(dryrun=options.dryrun)
        elif command == "prepare":
            full_release.prepare(dryrun=options.dryrun)
        elif command == "perform":
            full_release.perform(dryrun=options.dryrun)
        elif command == "test":
            full_release.test()
        else:
            raise ExitException(1, "Unknown command! See usage with '-h'.")
    except ExitException, e:
        if e.message is not None:
            log("[ERROR] %s" % e.message, sys.stderr)
        sys.exit(e.return_code)
Esempio n. 25
0
 def perform(self, dryrun=False):
     """ Perform the release: push source, deploy artifacts and upload
     packages."""
     cwd = os.getcwd()
     marketplaces_skipped = []
     for marketplace in self.get_packages_list():
         log("")
         if self.mp_config.has_option(marketplace, "skip"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, self.mp_config.get(marketplace, "skip")))
             marketplaces_skipped.append(marketplace)
             upgrade_only = True
         else:
             upgrade_only = False
         if not self.mp_config.getboolean(marketplace, "prepared"):
             log("[WARN] Skipped '%s' (%s)" % (marketplace, "Not prepared"))
             continue
         if self.mp_config.getboolean(marketplace, "performed"):
             log("Skipped '%s' (%s)" % (marketplace, "Already performed"))
             continue
         try:
             if upgrade_only:
                 log("Upgrade skipped %s..." % marketplace)
             else:
                 log("Perform %s" % marketplace)
             os.chdir(os.path.join(self.repo.mp_dir, marketplace))
             mp_repo = Repository(os.getcwd(), self.alias)
             # Perform release
             (_, branch, tag, next_snapshot, maintenance_version, is_final, skipTests, skipITs, _, other_versions,
              _, _) = Release.read_release_log(mp_repo.basedir)
             mp_release = Release(mp_repo, branch, tag, next_snapshot, maintenance_version, is_final=is_final,
                                  skipTests=skipTests, skipITs=skipITs, other_versions=other_versions)
             mp_release.perform(dryrun=dryrun, upgrade_only=upgrade_only)
             performed = True
         except Exception, e:
             stack = traceback.format_exc()
             if hasattr(e, 'message') and e.message is not None:
                 stack = e.message + "\n" + stack
             log("[ERROR] %s" % stack)
             performed = False
             stack = stack.replace("%", "%%")
             self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
         self.mp_config.set(marketplace, "performed", str(performed))
         self.repo.save_mp_config(self.mp_config)
         if performed and not upgrade_only:
             self.upload(CONNECT_PROD_URL, marketplace, dryrun=dryrun)
Esempio n. 26
0
    def prepare(self, dryrun=False):
        """ Prepare the release."""
        cwd = os.getcwd()
        if not os.path.isdir(self.repo.mp_dir):
            self.clone()
        os.chdir(self.repo.mp_dir)
        marketplaces_skipped = []
        for marketplace in self.get_packages_list():
            log("")
            if self.mp_config.has_option(marketplace, "skip"):
                log("[%s]" % marketplace)
                log("[WARN] Skipped '%s' (%s)" %
                    (marketplace, self.mp_config.get(marketplace, "skip")))
                marketplaces_skipped.append(marketplace)
                upgrade_only = True
            else:
                upgrade_only = False
            if self.mp_config.getboolean(marketplace, "prepared"):
                log("[%s]" % marketplace)
                log("Skipped '%s' (%s)" % (marketplace, "Already prepared"))
                continue
            try:
                mp_dir = os.path.join(self.repo.mp_dir, marketplace)
                if not os.path.isdir(mp_dir):
                    os.chdir(self.repo.mp_dir)
                    self.repo.git_pull(
                        marketplace, self.mp_config.get(marketplace, "branch"))
                else:
                    log("[%s]" % marketplace)
                os.chdir(mp_dir)
                mp_repo = Repository(os.getcwd(), self.alias)
                if upgrade_only:
                    log("Upgrade skipped %s..." % marketplace)
                else:
                    log("Prepare release of %s..." % marketplace)

                release_info = ReleaseInfo(
                    module=marketplace,
                    remote_alias=self.alias,
                    branch=self.mp_config.get(marketplace, "branch"),
                    tag=self.mp_config.get(marketplace, "tag"),
                    next_snapshot=self.mp_config.get(marketplace,
                                                     "next_snapshot"),
                    maintenance_version=self.mp_config.get(
                        marketplace, "maintenance_version"),
                    is_final=self.mp_config.getboolean(marketplace,
                                                       "is_final"),
                    skip_tests=self.mp_config.getboolean(
                        marketplace, "skipTests"),
                    skip_its=self.mp_config.getboolean(marketplace, "skipITs"),
                    profiles=self.mp_config.get(marketplace, "profiles"),
                    other_versions=self.mp_config.get(marketplace,
                                                      "other_versions"),
                    #files_pattern, props_pattern, msg_commit, msg_tag,
                    auto_increment_policy=self.mp_config.get(
                        marketplace, "auto_increment_policy"),
                    dryrun=dryrun)
                mp_release = Release(mp_repo, release_info)
                release_log = mp_release.log_summary()
                release_info.read_release_log(release_log)
                if dryrun:
                    print "DEBUG -- init %s with:" % marketplace
                for key, value in vars(release_info).iteritems():
                    if dryrun:
                        print "DEBUG: %s-%s=%s" % (marketplace, key, value)
                    self.mp_config.set("DEFAULT", marketplace + "-" + key,
                                       str(value))
                if dryrun:
                    print

                mp_release.prepare(dryrun=dryrun,
                                   upgrade_only=upgrade_only,
                                   dodeploy=True)
                prepared = True
            except Exception, e:
                stack = traceback.format_exc()
                if hasattr(e, 'message') and e.message is not None:
                    stack = e.message + "\n" + stack
                log("[ERROR] %s" % stack)
                prepared = False
                stack = stack.replace("%", "%%")
                self.mp_config.set(marketplace, "skip", "Failed! %s" % stack)
            self.mp_config.set(marketplace, "prepared", str(prepared))
            self.repo.save_mp_config(self.mp_config)
            if prepared and not upgrade_only:
                self.upload(CONNECT_TEST_URL, marketplace, dryrun=dryrun)
Esempio n. 27
0
def main():
    assert_git_config()

    try:
        usage = ("""usage: %prog <command> [options]
       %prog clone [-r alias] [-m URL] [-d PATH]
       %prog branch [-r alias] [-m URL] [-d PATH] [--rf package] [--dryrun]
       %prog prepare [-r alias] [-m URL] [-d PATH] [--rf package] [--dryrun]
       %prog perform [-r alias] [-m URL] [-d PATH] [-o owner] [--rf package] [--dryrun]
\nCommands:
       clone: Clone or update Nuxeo Package repositories.
       branch: Create the release branch so that the branch to release is freed for ongoing development. Following \
'prepare' or 'perform' commands must use option '--next=done'. If kept, that branch will become the maintenance \
branch after release.
       prepare: Prepare the release (build, change versions, tag and package source and distributions). The release \
parameters are stored in release-<package name>.log files generated by the release.py script. \
The first call must provide a Nuxeo Packages configuration URL (option '-m') from which a 'release.ini' file is \
generated and will be reused for the next calls.
       perform: Perform the release (push sources, deploy artifacts and upload packages, tests are always skipped). \
If no parameter is given, they are read from the 'release.ini' file.""")
        description = """Release Nuxeo Packages.\n
You can initiate some parameters with a release log file (option '-d').\n
The 'release.ini' file contains informations about the release process:\n
- 'prepared = True' if the prepare task succeeded,\n
- 'performed = True' if the perform task succeeded,\n
- 'uploaded = ...' if an upload successfully happened,\n
- 'skip = Failed!' followed by a stack trace in case of error.\n
The script can be re-called: it will skip the packages with a skip value and skip the prepare (or perform) if
'prepared = True' (or 'performed = True').\n
Failed uploads are not retried and must be manually done."""
        help_formatter = IndentedHelpFormatterWithNL(max_help_position=7, width=get_terminal_size()[0])
        parser = optparse.OptionParser(usage=usage, description=description, formatter=help_formatter)
        parser.add_option('-r', action="store", type="string", dest='remote_alias', default='origin',
                          help="""The Git alias of remote URL. Default: '%default'""")
        parser.add_option('-d', "--default", action="store", type="string", dest='default_conf',
                          default=None, help="""The default configuration file (usually '/path/to/release-nuxeo.log').
Default: '%default'""")
        parser.add_option('-m', "--marketplace-conf", action="store", type="string", dest='marketplace_conf',
                          default=None, help="""The Nuxeo Packages configuration URL (usually named 'marketplace.ini').
You can use a local file URL ('file://').\n
If set to '' (empty string), then it will default to '""" + DEFAULT_MP_CONF_URL + """'. Default: '%default'""")
        parser.add_option('-o', "--owner", action="store", type="string", dest='owner',
                          default=None, help="""The Nuxeo Package owner, if the package is private.
This is the id of the connect client document on Connect. Sample value: 45a78af-7f83-44b2-79e1-f102abf7e435.""")
        parser.add_option('-i', '--interactive', action="store_true", dest='interactive', default=False,
                          help="""Not implemented (TODO NXP-8573). Interactive mode. Default: '%default'""")
        parser.add_option('--rf', '--restart-from', action="store", dest='restart_from', default=None,
                          help="""Restart from a package. Default: '%default'""")
        parser.add_option('--dryrun', action="store_true", dest='dryrun', default=False,
                          help="""Dry run mode. Default: '%default'""")
        (options, args) = parser.parse_args()
        if len(args) == 1:
            command = args[0]
        elif len(args) > 1:
            raise ExitException(1, "'command' must be a single argument. See usage with '-h'.")
        full_release = ReleaseMP(options.remote_alias, options.restart_from, options.default_conf,
                                 options.marketplace_conf)
        if "command" not in locals():
            raise ExitException(1, "Missing command. See usage with '-h'.")
        elif command == "clone":
            full_release.clone()
        elif command == "branch":
            full_release.release_branch(dryrun=options.dryrun)
        elif command == "prepare":
            full_release.prepare(dryrun=options.dryrun)
        elif command == "perform":
            full_release.perform(dryrun=options.dryrun)
        elif command == "test":
            full_release.test()
        else:
            raise ExitException(1, "Unknown command! See usage with '-h'.")
    except ExitException, e:
        if e.message is not None:
            log("[ERROR] %s" % e.message, sys.stderr)
        sys.exit(e.return_code)