def bump_and_tag(repo, attempt, config, relbranch, revision, tags, defaultBranch): relbranchChangesets = len(tags) defaultBranchChangesets = 0 if relbranch in get_branches(reponame): update(reponame, revision=relbranch) else: update(reponame, revision=revision) run_cmd(['hg', 'branch', relbranch], cwd=reponame) if len(bumpFiles) > 0: # Bump files on the relbranch, if necessary bump(reponame, bumpFiles, 'version') run_cmd(['hg', 'diff'], cwd=repo) try: get_output(['hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version'])], cwd=reponame) relbranchChangesets += 1 revision = get_revision(reponame) except subprocess.CalledProcessError, e: # We only want to ignore exceptions caused by having nothing to # commit, which are OK. We still want to raise exceptions caused # by any other thing. if e.returncode != 1 or "nothing changed" not in e.output: raise
def tagRepo(config, repo, reponame, revision, tags, bumpFiles, relbranch, pushAttempts, defaultBranch='default'): remote = make_hg_url(HG, repo) mercurial(remote, reponame) def bump_and_tag(repo, attempt, config, relbranch, revision, tags, defaultBranch): # set relbranchChangesets=1 because tag() generates exactly 1 commit relbranchChangesets = 1 defaultBranchChangesets = 0 if relbranch in get_branches(reponame): update(reponame, revision=relbranch) else: update(reponame, revision=revision) run_cmd(['hg', 'branch', relbranch], cwd=reponame) if len(bumpFiles) > 0: # Bump files on the relbranch, if necessary bump(reponame, bumpFiles, 'version') run_cmd(['hg', 'diff'], cwd=repo) try: get_output(['hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version'])], cwd=reponame) relbranchChangesets += 1 except subprocess.CalledProcessError, e: # We only want to ignore exceptions caused by having nothing to # commit, which are OK. We still want to raise exceptions caused # by any other thing. if e.returncode != 1 or "nothing changed" not in e.output: raise # We always want our tags pointing at the tip of the relbranch # so we need to grab the current revision after we've switched # branches and bumped versions. revision = get_revision(reponame) # Create the desired tags on the relbranch tag(repo, revision, tags, config['hgUsername']) # This is the bump of the version on the default branch # We do it after the other one in order to get the tip of the # repository back on default, thus avoiding confusion. if len(bumpFiles) > 0: update(reponame, revision=defaultBranch) bump(reponame, bumpFiles, 'nextVersion') run_cmd(['hg', 'diff'], cwd=repo) try: get_output(['hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version'])], cwd=reponame) defaultBranchChangesets += 1 except subprocess.CalledProcessError, e: if e.returncode != 1 or "nothing changed" not in e.output: raise
def tagRepo(config, repo, reponame, revision, tags, bumpFiles, relbranch, pushAttempts): remote = make_hg_url(HG, repo) mercurial(remote, reponame) def bump_and_tag(repo, attempt, config, relbranch, revision, tags): # set relbranchChangesets=1 because tag() generates exactly 1 commit relbranchChangesets = 1 if relbranch in get_branches(reponame): update(reponame, revision=relbranch) else: update(reponame, revision=revision) run_cmd(['hg', 'branch', relbranch], cwd=reponame) if len(bumpFiles) > 0: # Bump files on the relbranch, if necessary bump(reponame, bumpFiles, 'version') run_cmd(['hg', 'diff'], cwd=repo) try: get_output([ 'hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version']) ], cwd=reponame) relbranchChangesets += 1 except subprocess.CalledProcessError, e: # We only want to ignore exceptions caused by having nothing to # commit, which are OK. We still want to raise exceptions caused # by any other thing. if e.returncode != 1 or "nothing changed" not in e.output: raise # We always want our tags pointing at the tip of the relbranch # so we need to grab the current revision after we've switched # branches and bumped versions. revision = get_revision(reponame) # Create the desired tags on the relbranch tag(repo, revision, tags, config['hgUsername']) # Validate that the repository is only different from the remote in # ways we expect. outgoingRevs = out(src=reponame, remote=remote, ssh_username=config['hgUsername'], ssh_key=config['hgSshKey']) if len([r for r in outgoingRevs if r[BRANCH] == relbranch ]) != relbranchChangesets: raise Exception("Incorrect number of revisions on %s" % relbranch) if len(outgoingRevs) != relbranchChangesets: raise Exception("Wrong number of outgoing revisions")
def process(self): """ Process this patchset, doing the following: 1. Check permissions on patchset 2. Clone the repository 3. Apply patches, with 3 attempts """ # 1. Check permissions on each patch outgoing = self.branch if not self.try_run else 'try' if not has_sufficient_permissions(self.user, outgoing): log.error('Insufficient permissions to push to %s.' % (outgoing)) self.add_comment('Insufficient permissions to push to %s.' % (outgoing)) return (False, '\n'.join(self.comments)) # 2. Clone the repository cloned_rev = None try: cloned_rev = clone_branch(self.branch, self.branch_url) except RetryException: log.error('[Branch %s] Could not clone from %s.' % (self.branch, self.branch_url)) self.add_comment('An error occurred while cloning %s.' % (self.branch_url)) return (False, '\n'.join(self.comments)) # 3. Apply patches, with 3 attempts try: # make 3 attempts so that # 1st is on current clone, # 2nd attempt is after an update -C, # 3rd attempt is a fresh clone retry(apply_and_push, attempts=3, retry_exceptions=(RetryException, ), cleanup=RepoCleanup(self.branch, self.branch_url), args=(self.active_repo, self.push_url, self.apply_patches, 1), kwargs=dict(ssh_username=config['hg_username'], ssh_key=config['hg_ssh_key'], force=self.try_run)) # force only on try revision = get_revision(self.active_repo) shutil.rmtree(self.active_repo) for patch in self.patches: patch.delete() except (HgUtilError, RetryException, FailException), err: # Failed log.error('[PatchSet] Could not be applied and pushed.\n%s' % (err)) self.add_comment('Patchset could not be applied and pushed.' '\n%s' % (err)) return (False, '\n'.join(self.comments))
def process(self): """ Process this patchset, doing the following: 1. Check permissions on patchset 2. Clone the repository 3. Apply patches, with 3 attempts """ # 1. Check permissions on each patch outgoing = self.branch if not self.try_run else 'try' if not has_sufficient_permissions(self.user, outgoing): log.error('Insufficient permissions to push to %s.' % (outgoing)) self.add_comment('Insufficient permissions to push to %s.' % (outgoing)) return (False, '\n'.join(self.comments)) # 2. Clone the repository cloned_rev = None try: cloned_rev = clone_branch(self.branch, self.branch_url) except RetryException: log.error('[Branch %s] Could not clone from %s.' % (self.branch, self.branch_url)) self.add_comment('An error occurred while cloning %s.' % (self.branch_url)) return (False, '\n'.join(self.comments)) # 3. Apply patches, with 3 attempts try: # make 3 attempts so that # 1st is on current clone, # 2nd attempt is after an update -C, # 3rd attempt is a fresh clone retry(apply_and_push, attempts=3, retry_exceptions=(RetryException,), cleanup=RepoCleanup(self.branch, self.branch_url), args=(self.active_repo, self.push_url, self.apply_patches, 1), kwargs=dict(ssh_username=config['hg_username'], ssh_key=config['hg_ssh_key'], force=self.try_run)) # force only on try revision = get_revision(self.active_repo) shutil.rmtree(self.active_repo) for patch in self.patches: patch.delete() except (HgUtilError, RetryException, FailException), err: # Failed log.error('[PatchSet] Could not be applied and pushed.\n%s' % (err)) self.add_comment('Patchset could not be applied and pushed.' '\n%s' % (err)) return (False, '\n'.join(self.comments))
def tagRepo(config, repo, reponame, revision, tags, bumpFiles, relbranch, pushAttempts): remote = make_hg_url(HG, repo) mercurial(remote, reponame) def bump_and_tag(repo, attempt, config, relbranch, revision, tags): # set relbranchChangesets=1 because tag() generates exactly 1 commit relbranchChangesets = 1 if relbranch in get_branches(reponame): update(reponame, revision=relbranch) else: update(reponame, revision=revision) run_cmd(['hg', 'branch', relbranch], cwd=reponame) if len(bumpFiles) > 0: # Bump files on the relbranch, if necessary bump(reponame, bumpFiles, 'version') run_cmd(['hg', 'diff'], cwd=repo) try: get_output(['hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version'])], cwd=reponame) relbranchChangesets += 1 except subprocess.CalledProcessError, e: # We only want to ignore exceptions caused by having nothing to # commit, which are OK. We still want to raise exceptions caused # by any other thing. if e.returncode != 1 or "nothing changed" not in e.output: raise # We always want our tags pointing at the tip of the relbranch # so we need to grab the current revision after we've switched # branches and bumped versions. revision = get_revision(reponame) # Create the desired tags on the relbranch tag(repo, revision, tags, config['hgUsername']) # Validate that the repository is only different from the remote in # ways we expect. outgoingRevs = out(src=reponame, remote=remote, ssh_username=config['hgUsername'], ssh_key=config['hgSshKey']) if len([r for r in outgoingRevs if r[BRANCH] == relbranch]) != relbranchChangesets: raise Exception("Incorrect number of revisions on %s" % relbranch) if len(outgoingRevs) != relbranchChangesets: raise Exception("Wrong number of outgoing revisions")
def import_and_push(repo, bug, branch_name, patch_ids, patches_dir, add_try_commit, try_syntax, pull_repo, push_repo, ssh_username, ssh_key): def changer(repo, attempt): log.debug("Importing patches, attemp #%s", attempt) import_patches(bug=bug, branch_name=branch_name, patch_ids=patch_ids, patches_dir=patches_dir, repo=repo, add_try_commit=add_try_commit, pull_repo=pull_repo, try_syntax=try_syntax) setup_repo(repo=repo, pull_repo=pull_repo) apply_and_push(localrepo=repo, remote=push_repo, changer=changer, max_attempts=10, ssh_username=ssh_username, ssh_key=ssh_key, force=False) return get_revision(repo)
def process_patchset(data): """ Process, apply, and push the patchset to the correct location. If try_run is specified, it will be pushed to try, and otherwise will be pushed to branch if the credentials are correct. process_patchset returns a 2-tuple, (return_code, comment). Comment will be none in the case of an error, as the message is sent out by process_patchset. There should always be a comment posted. """ active_repo = os.path.join('active/%s' % (data['branch'])) try_run = (data['try_run'] == True) if 'push_url' in data: push_url = data['push_url'] else: push_url = data['branch_url'] push_url = push_url.replace('https', 'ssh', 1) # The comment header. The comment is constructed incrementally at any possible # failure/success point. comment_hdr = ['Autoland Patchset:\n\tPatches: %s\n\tBranch: %s%s\n\tDestination: %s' % (', '.join(map(lambda x: str(x['id']), data['patches'])), data['branch'], (' => try' if try_run else ''), push_url )] comment = comment_hdr class RETRY(Exception): pass def cleanup_wrapper(): # use an attribute full_clean in order to keep track of # whether or not a full cleanup is required. # This is done since cleanup_wrapper's scope doesn't let us # access process_patchset globals, given the way it is used. if not hasattr(cleanup_wrapper, 'full_clean'): cleanup_wrapper.full_clean = False if not hasattr(cleanup_wrapper, 'branch'): cleanup_wrapper.branch = data['branch'] if cleanup_wrapper.branch != data['branch']: cleanup_wrapper.full_clean = False cleanup_wrapper.branch = data['branch'] # only wipe the repositories every second cleanup if cleanup_wrapper.full_clean: clear_branch(data['branch']) log_msg('Wiped repositories for: %s' % data['branch']) else: active_repo = os.path.join('active', data['branch']) update(active_repo) log_msg('Update -C on active repo for: %s' % data['branch']) cleanup_wrapper.full_clean = not cleanup_wrapper.full_clean clone_revision = clone_branch(data['branch'], data['branch_url']) if clone_revision == None: # TODO: Handle clone error log_msg('[HgPusher] Clone error...') return def apply_patchset(dir, attempt): if not clone_branch(data['branch'], data['branch_url']): msg = 'Branch %s could not be cloned.' log_msg('[Branch %s] Could not clone from %s.' \ % (data['branch'], data['branch_url'])) comment.append(msg) raise RETRY for patch in data['patches']: log_msg("Getting patch %s" % (patch['id']), None) # store patches in 'patches/' below work_dir patch_file = bz.get_patch(patch['id'], os.path.join('patches'),create_path=True) if not patch_file: msg = 'Patch %s could not be fetched.' % (patch['id']) log_msg(msg) if msg not in comment: comment.append(msg) raise RETRY valid_header = has_valid_header(patch_file) if not try_run and not valid_header: log_msg('[Patch %s] Invalid header.' % (patch['id'])) # append comment to comment msg = 'Patch %s does not have a properly formatted header.' \ % (patch['id']) if msg not in comment: comment.append(msg) raise RETRY user = None if not valid_header: # This is a try run, since we haven't exited # so author header not needed. Place in the author information # from bugzilla as committer. user='******' % (patch['author']['name'], patch['author']['email']) (patch_success,err) = import_patch(active_repo, patch_file, try_run, bug_id=data.get('bug_id', None), user=user, try_syntax=data.get('try_syntax', None)) if patch_success != 0: log_msg('[Patch %s] %s' % (patch['id'], err)) msg = 'Error applying patch %s to %s.\n%s' \ % (patch['id'], data['branch'], err) if msg not in comment: comment.append(msg) raise RETRY return True if not has_sufficient_permissions(data['patches'], data['branch'] if not try_run else 'try'): msg = 'Insufficient permissions to push to %s' \ % ((data['branch'] if not try_run else 'try')) log_msg(msg) comment.append(msg) log_msg('Comment "%s" to bug %s' % ('\n'.join(comment), data['bug_id']), log.DEBUG) return (False, '\n'.join(comment)) try: retry(apply_and_push, cleanup=cleanup_wrapper, retry_exceptions=(RETRY,), args=(active_repo, push_url, apply_patchset, 1), kwargs=dict(ssh_username=config['hg_username'], ssh_key=config['hg_ssh_key'], force=try_run)) # Force only on try pushes revision = get_revision(active_repo) shutil.rmtree(active_repo) except (HgUtilError, RETRY) as error: msg = 'Could not apply and push patchset:\n%s' % (error) log_msg('[PatchSet] %s' % (msg)) comment.append(msg) log_msg('Comment "%s" to bug %s' % ('\n'.join(comment), data['bug_id']), log.DEBUG) # TODO need to remove whiteboard tag here or in autoland_queue? return (False, '\n'.join(comment)) # Successful push. Clear any errors that might be in the comments comment = comment_hdr if try_run: # comment to bug with link to the try run on self-serve comment.append('Try run started, revision %s. To cancel or monitor the job, see: %s' % (revision, os.path.join(config['self_serve_url'], 'try/rev/%s' % (revision))) ) else: comment.append('Successfully applied and pushed patchset.\n\tRevision: %s' % (revision, data['branch'], ', '.join(map(lambda x: x['id'], data['patches'])))) comment.append('To monitor the commit, see: %s' % (os.path.join(config['self_serve_url'], '%s/rev/%s' % (data['branch'], revision)))) log_msg('Comment %s to bug %s' % ('\n'.join(comment), data['bug_id']), log.DEBUG) return (revision, '\n'.join(comment))
def main(): logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument("--from-dir", default="mozilla-beta", help="Working directory of repo to be merged from") parser.add_argument("--from-repo", default="ssh://hg.mozilla.org/releases/mozilla-beta", help="Repo to be merged from") parser.add_argument("--to-dir", default="mozilla-release", help="Working directory of repo to be merged to") parser.add_argument( "--to-repo", default="ssh://hg.mozilla.org/releases/mozilla-release", help="Repo to be merged to") parser.add_argument("--hg-user", default="ffxbld <*****@*****.**>", help="Mercurial username to be passed to hg -u") parser.add_argument("--remove-locale", dest="remove_locales", action="append", required=True, help="Locales to be removed from release shipped-locales") args = parser.parse_args() from_dir = args.from_dir to_dir = args.to_dir from_repo = args.from_repo to_repo = args.to_repo hg_user = args.hg_user with retrying(mercurial) as clone: for (d, repo) in ((from_dir, from_repo), (to_dir, to_repo)): clone(repo, d) log.info("Cleaning up %s...", d) strip_outgoing(d) update(d, branch="default") beta_rev = get_revision(from_dir) release_rev = get_revision(to_dir) now = datetime.datetime.now() date = now.strftime("%Y%m%d") # TODO: make this tag consistent with other branches release_base_tag = "RELEASE_BASE_" + date log.info("Tagging %s beta with %s", beta_rev, release_base_tag) tag(from_dir, tags=[release_base_tag], rev=beta_rev, user=hg_user, msg="Added %s tag for changeset %s. DONTBUILD CLOSED TREE a=release" % (release_base_tag, beta_rev)) new_beta_rev = get_revision(from_dir) raw_input("Push mozilla-beta and hit Return") pull(from_dir, dest=to_dir) merge_via_debugsetparents( to_dir, old_head=release_rev, new_head=new_beta_rev, user=hg_user, msg="Merge old head via |hg debugsetparents %s %s|. " "CLOSED TREE DONTBUILD a=release" % (new_beta_rev, release_rev)) replace( path.join(to_dir, "browser/confvars.sh"), "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release", "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release") replace(path.join(to_dir, "browser/confvars.sh"), "MAR_CHANNEL_ID=firefox-mozilla-beta", "MAR_CHANNEL_ID=firefox-mozilla-release") for d in branding_dirs: for f in branding_files: replace( path.join(to_dir, d, f), "ac_add_options --with-branding=mobile/android/branding/beta", "ac_add_options --with-branding=mobile/android/branding/official") if args.remove_locales: log.info("Removing locales: %s", args.remove_locales) remove_locales(path.join(to_dir, "browser/locales/shipped-locales"), args.remove_locales) log.warn("Apply any manual changes, such as disabling features.") raw_input("Hit 'return' to display channel, branding, and feature diffs onscreen") run_cmd(["hg", "diff"], cwd=to_dir) raw_input("If the diff looks good hit return to commit those changes") commit(to_dir, user=hg_user, msg="Update configs. CLOSED TREE a=release ba=release") raw_input("Go ahead and push mozilla-release changes.")
def tagRepo(config, repo, reponame, revision, tags, bumpFiles, relbranch, pushAttempts, defaultBranch='default'): remote = make_hg_url(HG, repo) retry(mercurial, args=(remote, reponame)) def bump_and_tag(repo, attempt, config, relbranch, revision, tags, defaultBranch): # set relbranchChangesets=1 because tag() generates exactly 1 commit relbranchChangesets = 1 defaultBranchChangesets = 0 if relbranch in get_branches(reponame): update(reponame, revision=relbranch) else: update(reponame, revision=revision) run_cmd(['hg', 'branch', relbranch], cwd=reponame) if len(bumpFiles) > 0: # Bump files on the relbranch, if necessary bump(reponame, bumpFiles, 'version') run_cmd(['hg', 'diff'], cwd=repo) try: get_output([ 'hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version']) ], cwd=reponame) relbranchChangesets += 1 except subprocess.CalledProcessError, e: # We only want to ignore exceptions caused by having nothing to # commit, which are OK. We still want to raise exceptions caused # by any other thing. if e.returncode != 1 or "nothing changed" not in e.output: raise # We always want our tags pointing at the tip of the relbranch # so we need to grab the current revision after we've switched # branches and bumped versions. revision = get_revision(reponame) # Create the desired tags on the relbranch tag(repo, revision, tags, config['hgUsername']) # This is the bump of the version on the default branch # We do it after the other one in order to get the tip of the # repository back on default, thus avoiding confusion. if len(bumpFiles) > 0: update(reponame, revision=defaultBranch) bump(reponame, bumpFiles, 'nextVersion') run_cmd(['hg', 'diff'], cwd=repo) try: get_output([ 'hg', 'commit', '-u', config['hgUsername'], '-m', getBumpCommitMessage(config['productName'], config['version']) ], cwd=reponame) defaultBranchChangesets += 1 except subprocess.CalledProcessError, e: if e.returncode != 1 or "nothing changed" not in e.output: raise
def main(): logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument("--hg-user", default="ffxbld <*****@*****.**>", help="Mercurial username to be passed to hg -u") args = parser.parse_args() hg_user = args.hg_user # prep the repos for d, repo in ((mc_dir, mc_repo), (ma_dir, ma_repo), (mb_dir, mb_repo)): mercurial(repo, d) log.info("Cleaning up %s...", d) strip_outgoing(d) update(d, branch="default") curr_mc_version = get_major_version(mc_dir) curr_ma_version = get_major_version(ma_dir) curr_mb_version = get_major_version(mb_dir) next_mc_version = str(int(curr_mc_version) + 1) next_ma_version = str(int(curr_ma_version) + 1) next_mb_version = str(int(curr_mb_version) + 1) # mozilla-central mc_revision = get_revision(mc_dir) mc_tag = "FIREFOX_AURORA_%s_BASE" % curr_mc_version tag(mc_dir, tags=[mc_tag], rev=mc_revision, user=hg_user, msg="Added %s tag for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (mc_tag, mc_revision)) new_mc_revision = get_revision(mc_dir) bump_version(mc_dir, curr_mc_version, next_mc_version, "a1", "a1", bump_major=True) raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mc_dir) raw_input("If the diff looks good hit return to commit those changes") commit(mc_dir, user=hg_user, msg="Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") raw_input("Go ahead and push mozilla-central...and continue to " "mozilla-aurora to mozilla-beta uplift ") # mozilla-aurora ma_revision = get_revision(ma_dir) ma_tag = "FIREFOX_BETA_%s_BASE" % curr_ma_version ma_end_tag = "FIREFOX_AURORA_%s_END" % curr_ma_version # pull must use revision not tag pull(mc_dir, dest=ma_dir, revision=new_mc_revision) merge_via_debugsetparents( ma_dir, old_head=ma_revision, new_head=new_mc_revision, user=hg_user, msg="Merge old head via |hg debugsetparents %s %s|. " "CLOSED TREE DONTBUILD a=release" % (new_mc_revision, ma_revision)) tag(ma_dir, tags=[ma_tag, ma_end_tag], rev=ma_revision, user=hg_user, msg="Added %s %s tags for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (ma_tag, ma_end_tag, ma_revision)) log.info("Reverting locales") for f in locale_files: run_cmd(["hg", "revert", "-r", ma_end_tag, f], cwd=ma_dir) bump_version(ma_dir, next_ma_version, next_ma_version, "a1", "a2") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=ma_dir) raw_input("If the diff looks good hit return to commit those changes") commit(ma_dir, user=hg_user, msg="Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") replace(path.join(ma_dir, "browser/confvars.sh"), "MOZ_BRANDING_DIRECTORY=browser/branding/nightly", "MOZ_BRANDING_DIRECTORY=browser/branding/aurora") replace(path.join(ma_dir, "browser/confvars.sh"), "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central", "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora") replace(path.join(ma_dir, "browser/confvars.sh"), "MAR_CHANNEL_ID=firefox-mozilla-central", "MAR_CHANNEL_ID=firefox-mozilla-aurora") for d in branding_dirs: for f in branding_files: replace(path.join(ma_dir, d, f), "ac_add_options --with-branding=mobile/android/branding/nightly", "ac_add_options --with-branding=mobile/android/branding/aurora") if f == "l10n-nightly": replace(path.join(ma_dir, d, f), "ac_add_options --with-l10n-base=../../l10n-central", "ac_add_options --with-l10n-base=..") for f in profiling_files: replace(path.join(ma_dir, f), "ac_add_options --enable-profiling", "") for f in elf_hack_files: replace(path.join(ma_dir, f), "ac_add_options --disable-elf-hack # --enable-elf-hack conflicts with --enable-profiling", "") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=ma_dir) raw_input("If the diff looks good hit return to commit those changes") commit(ma_dir, user=hg_user, msg="Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release") raw_input("Go ahead and push mozilla-aurora changes.") # mozilla-beta mb_revision = get_revision(mb_dir) mb_tag = "FIREFOX_BETA_%s_END" % curr_mb_version # pull must use revision not tag pull(ma_dir, dest=mb_dir, revision=ma_revision) merge_via_debugsetparents( mb_dir, old_head=mb_revision, new_head=ma_revision, user=hg_user, msg="Merge old head via |hg debugsetparents %s %s|. " "CLOSED TREE DONTBUILD a=release" % (ma_revision, mb_revision)) tag(mb_dir, tags=[mb_tag], rev=mb_revision, user=hg_user, msg="Added %s tag for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (mb_tag, mb_revision)) bump_version(mb_dir, next_mb_version, next_mb_version, "a2", "") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mb_dir) raw_input("If the diff looks good hit return to commit those changes") commit(mb_dir, user=hg_user, msg="Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") replace(path.join(mb_dir, "browser/confvars.sh"), "MOZ_BRANDING_DIRECTORY=browser/branding/aurora", "MOZ_BRANDING_DIRECTORY=browser/branding/nightly") replace(path.join(mb_dir, "browser/confvars.sh"), "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora", "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release") replace(path.join(mb_dir, "browser/confvars.sh"), "MAR_CHANNEL_ID=firefox-mozilla-aurora", "MAR_CHANNEL_ID=firefox-mozilla-beta") for d in branding_dirs: for f in branding_files: replace(path.join(mb_dir, d, f), "ac_add_options --with-branding=mobile/android/branding/aurora", "ac_add_options --with-branding=mobile/android/branding/beta") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mb_dir) raw_input("If the diff looks good hit return to commit those changes") commit(mb_dir, user=hg_user, msg="Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release") raw_input("Go ahead and push mozilla-beta changes.")
def process_patchset(data): """ Apply patches and push to branch repository. """ remote = '%s%s' % (config['hg_base_url'], data['branch']) active_repo = 'active/%s' % (data['branch']) fail_messages = [] def cleanup_wrapper(): try: shutil.rmtree(active_repo) clone_branch(data['branch']) except subprocess.CalledProcessError: # something useful needs to be done here log_msg('Error while cleaning/replacing repository.') def apply_patchset(dir, attempt): for patch in data['patches']: log_msg("Getting patch %s" % (patch['id']), None) # store patches in 'patches/' below work_dir patch_file = bz.get_patch(patch['id'], 'patches', create_path=True) if not has_valid_header(patch_file, data['branch'] == 'try'): log_msg('[Patch %s] invalid header.' % (patch['id'])) msg = { 'type' : 'error', 'action' : 'patch.header', 'bugid' : data['bugid'], 'branch' : data['branch'], 'patchid' : patch['id'], 'patchsetid' : data['patchsetid'], } if msg not in fail_messages: fail_messages.append(msg) return False # using import to patch, this will pull required header information # and automatically perform commit for each import. (out, err, rc) = run_hg(['import', '-R', active_repo, patch_file]) if rc != 0: log_msg('[Patch %s] %s' % (patch['id'], err)) msg = { 'type' : 'error', 'action' : 'patch.import', 'bugid' : data['bugid'], 'branch' : data['branch'], 'patchid' : patch['id'], 'patchsetid' : data['patchsetid'] } if msg not in fail_messages: fail_messages.append(msg) return False return True try: retry(apply_and_push, cleanup=cleanup_wrapper, retry_exceptions=Exception('E_RETRY'), args=(active_repo, remote, apply_patchset, 1), kwargs=dict(ssh_username=config['hg_username'],ssh_key=config['hg_ssh_key'])) except HgUtilError as error: log_msg('[PatchSet] Could not apply and push patchset:\n%s' % (error)) mq.send_message(fail_messages, config['mq_queue'], routing_keys=[config['mq_comment_topic'], config['mq_db_topic']]) return False except Exception('E_RETRY'): log_msg('[PatchSet] Could not apply and push patchset.') mq.send_message(fail_messages, config['mq_queue'], routing_keys=[config['mq_comment_topic'], config['mq_db_topic']]) return False revision = get_revision(active_repo) shutil.rmtree(active_repo) return revision
def main(): logging.basicConfig(format="%(asctime)s - %(message)s", level=logging.INFO) parser = argparse.ArgumentParser() parser.add_argument("--hg-user", default="ffxbld <*****@*****.**>", help="Mercurial username to be passed to hg -u") args = parser.parse_args() hg_user = args.hg_user # prep the repos for d, repo in ((mc_dir, mc_repo), (ma_dir, ma_repo), (mb_dir, mb_repo)): mercurial(repo, d) log.info("Cleaning up %s...", d) strip_outgoing(d) update(d, branch="default") curr_mc_version = get_major_version(mc_dir) curr_ma_version = get_major_version(ma_dir) curr_mb_version = get_major_version(mb_dir) next_mc_version = str(int(curr_mc_version) + 1) next_ma_version = str(int(curr_ma_version) + 1) next_mb_version = str(int(curr_mb_version) + 1) # mozilla-central mc_revision = get_revision(mc_dir) mc_tag = "FIREFOX_AURORA_%s_BASE" % curr_mc_version tag(mc_dir, tags=[mc_tag], rev=mc_revision, user=hg_user, msg= "Added %s tag for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (mc_tag, mc_revision)) new_mc_revision = get_revision(mc_dir) bump_version(mc_dir, curr_mc_version, next_mc_version, "a1", "a1", bump_major=True) raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mc_dir) raw_input("If the diff looks good hit return to commit those changes") commit( mc_dir, user=hg_user, msg= "Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") raw_input("Go ahead and push mozilla-central...and continue to " "mozilla-aurora to mozilla-beta uplift ") # mozilla-aurora ma_revision = get_revision(ma_dir) ma_tag = "FIREFOX_BETA_%s_BASE" % curr_ma_version ma_end_tag = "FIREFOX_AURORA_%s_END" % curr_ma_version # pull must use revision not tag pull(mc_dir, dest=ma_dir, revision=new_mc_revision) merge_via_debugsetparents( ma_dir, old_head=ma_revision, new_head=new_mc_revision, user=hg_user, msg="Merge old head via |hg debugsetparents %s %s|. " "CLOSED TREE DONTBUILD a=release" % (new_mc_revision, ma_revision)) tag(ma_dir, tags=[ma_tag, ma_end_tag], rev=ma_revision, user=hg_user, msg= "Added %s %s tags for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (ma_tag, ma_end_tag, ma_revision)) log.info("Reverting locales") for f in locale_files: run_cmd(["hg", "revert", "-r", ma_end_tag, f], cwd=ma_dir) bump_version(ma_dir, next_ma_version, next_ma_version, "a1", "a2") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=ma_dir) raw_input("If the diff looks good hit return to commit those changes") commit( ma_dir, user=hg_user, msg= "Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") replace(path.join(ma_dir, "browser/confvars.sh"), "MOZ_BRANDING_DIRECTORY=browser/branding/nightly", "MOZ_BRANDING_DIRECTORY=browser/branding/aurora") replace(path.join(ma_dir, "browser/confvars.sh"), "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central", "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora") replace(path.join(ma_dir, "browser/confvars.sh"), "MAR_CHANNEL_ID=firefox-mozilla-central", "MAR_CHANNEL_ID=firefox-mozilla-aurora") for d in branding_dirs: for f in branding_files: replace( path.join(ma_dir, d, f), "ac_add_options --with-branding=mobile/android/branding/nightly", "ac_add_options --with-branding=mobile/android/branding/aurora" ) if f == "l10n-nightly": replace(path.join(ma_dir, d, f), "ac_add_options --with-l10n-base=../../l10n-central", "ac_add_options --with-l10n-base=..") for f in profiling_files: replace(path.join(ma_dir, f), "ac_add_options --enable-profiling", "") for f in elf_hack_files: replace( path.join(ma_dir, f), "ac_add_options --disable-elf-hack # --enable-elf-hack conflicts with --enable-profiling", "") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=ma_dir) raw_input("If the diff looks good hit return to commit those changes") commit( ma_dir, user=hg_user, msg= "Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release" ) raw_input("Go ahead and push mozilla-aurora changes.") # mozilla-beta mb_revision = get_revision(mb_dir) mb_tag = "FIREFOX_BETA_%s_END" % curr_mb_version # pull must use revision not tag pull(ma_dir, dest=mb_dir, revision=ma_revision) merge_via_debugsetparents( mb_dir, old_head=mb_revision, new_head=ma_revision, user=hg_user, msg="Merge old head via |hg debugsetparents %s %s|. " "CLOSED TREE DONTBUILD a=release" % (ma_revision, mb_revision)) tag(mb_dir, tags=[mb_tag], rev=mb_revision, user=hg_user, msg= "Added %s tag for changeset %s. IGNORE BROKEN CHANGESETS DONTBUILD CLOSED TREE NO BUG a=release" % (mb_tag, mb_revision)) bump_version(mb_dir, next_mb_version, next_mb_version, "a2", "") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mb_dir) raw_input("If the diff looks good hit return to commit those changes") commit( mb_dir, user=hg_user, msg= "Version bump. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release") replace(path.join(mb_dir, "browser/confvars.sh"), "MOZ_BRANDING_DIRECTORY=browser/branding/aurora", "MOZ_BRANDING_DIRECTORY=browser/branding/nightly") replace( path.join(mb_dir, "browser/confvars.sh"), "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-aurora", "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release" ) replace(path.join(mb_dir, "browser/confvars.sh"), "MAR_CHANNEL_ID=firefox-mozilla-aurora", "MAR_CHANNEL_ID=firefox-mozilla-beta") for d in branding_dirs: for f in branding_files: replace( path.join(mb_dir, d, f), "ac_add_options --with-branding=mobile/android/branding/aurora", "ac_add_options --with-branding=mobile/android/branding/beta") raw_input("Hit 'return' to display diffs onscreen") run_cmd(["hg", "diff"], cwd=mb_dir) raw_input("If the diff looks good hit return to commit those changes") commit( mb_dir, user=hg_user, msg= "Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release" ) raw_input("Go ahead and push mozilla-beta changes.")