Ejemplo n.º 1
0
def _check_repo(path):
    try:
        repo = Repo.discover(path)
    except NotGitRepository:
        return None, "No Git repository could be found using the specified path. (path: {0})".format(path)

    return repo, False
Ejemplo n.º 2
0
    def __init__(self, decision, plugin_module):
        """

        :param decision: Decision (db) object
        """
        self.decision = decision
        self.plugin_module = plugin_module
        self.type = None
        self.attachments = []
        self.actions = {}
        self.repo = Repo.discover(start=decision_utils.gen_full_path(self.decision))
        self.du = decision_utils.DecisionUtils(decision)
Ejemplo n.º 3
0
def submit(
    ctx,
    phabricator_url,
    phabricator_api_key,
    repo_callsign,
    update_revision,
    revs,
):
    """Submit a change to phabricator for review."""
    phabricator = Phabricator(phabricator_url, api_key=phabricator_api_key)
    if not phabricator.verify_auth():
        print 'Authentication failed, please provide a valid api key.'
        ctx.exit(1)

    try:
        repo = Repo.discover()
    except NotGitRepository:
        print 'A git repository could not be found.'
        ctx.exit(1)

    repo_path = repo.controldir()
    git = Git(repo.controldir())
    commits, parent, remote_base = git.parse_revs(revs)

    if not commits:
        print 'Nothing to review'
        ctx.exit(1)

    # Generate the diff for phabricator.
    diff = git.get('diff', '-U32767', '{}..{}'.format(parent, commits[0]))
    if not diff:
        print 'No difference, nothing to review'
        ctx.exit(1)

    repo = phabricator.get_repo(repo_callsign)
    if repo is None:
        print '{} repository cannot be found'.format(repo_callsign)
        ctx.exit(1)

    # Create/Update the phabricator revision.
    diff_result = phabricator.create_diff(diff, repo_phid=repo['phid'])
    phabricator.set_diff_properties(diff_result, remote_base, parent)
    revision_result = phabricator.create_revision(diff_result,
                                                  revision=update_revision)

    msg = UPDATED_REVISION if update_revision else CREATED_REVISION
    print msg.format(revision_id=revision_result['object']['id'],
                     revision_url=phabricator_url +
                     'D{}'.format(revision_result['object']['id']))
Ejemplo n.º 4
0
    def __init__(  # pylint:disable=W0231
        self, root_dir=os.curdir, search_parent_directories=True
    ):
        from dulwich.errors import NotGitRepository
        from dulwich.repo import Repo

        try:
            if search_parent_directories:
                self.repo = Repo.discover(start=root_dir)
            else:
                self.repo = Repo(root_dir)
        except NotGitRepository as exc:
            raise SCMError(f"{root_dir} is not a git repository") from exc

        self._stashes: dict = {}
Ejemplo n.º 5
0
    def initialise(self):
        if self.project_repo is None:
            self.project_repo = Repo.discover()
            self.project_folder = Path(self.project_repo.path)

            self.project = self.project_folder.name

            self.matador_project_folder = Path(
                Path.home(), '.matador', self.project)

            self.matador_repository_folder = Path(
                self.matador_project_folder, 'repository')

            self.environments = get_environments(self.project_folder)
        else:
            return
Ejemplo n.º 6
0
args = parser.parse_args()


def print_verbose(str, *argv, **kwargs):
    if (verbose):
        print("... {}".format(str),\
              file=sys.stderr, *argv, **kwargs)


u = config['main']['user']
s = config['main']['token']
verbose = args.verbose
unmerged = args.unmerged

sys.stderr.flush()
repo = Repo.discover()
print_verbose("Found Git repository {}".format(repo))
print_verbose("  control dir is {}".format(repo.controldir()))
try:
    repo.commondir
except AttributeError:
    print_verbose("dulwich does not know repo.commondir()")
else:
    print_verbose("   common dir is {}".format(repo.commondir()))

print_verbose("   index path is {}".format(repo.index_path()))
print_verbose("Getting commits in current branch", end='')
print_verbose(" {}".\
              format(str(repo.refs.read_ref('HEAD'), "ascii")), end='')
sys.stderr.flush()
walk = repo.get_walker(include=repo.head(),\
Ejemplo n.º 7
0
 def test_discover_notrepo(self):
     with self.assertRaises(NotGitRepository):
         Repo.discover('/')
Ejemplo n.º 8
0
 def test_discover_isrepo(self):
     r = Repo.discover(self._repo_dir)
     self.assertEqual(r.head(), self._repo.head())
Ejemplo n.º 9
0
 def test_discover_intended(self):
     path = os.path.join(self._repo_dir, 'b/c')
     r = Repo.discover(path)
     self.assertEqual(r.head(), self._repo.head())
Ejemplo n.º 10
0
 def test_discover_notrepo(self):
     with self.assertRaises(NotGitRepository):
         Repo.discover('/')
Ejemplo n.º 11
0
 def test_discover_isrepo(self):
     r = Repo.discover(self._repo_dir)
     self.assertEqual(r.head(), self._repo.head())
Ejemplo n.º 12
0
 def test_discover_intended(self):
     path = os.path.join(self._repo_dir, 'b/c')
     r = Repo.discover(path)
     self.assertEqual(r.head(), self._repo.head())
Ejemplo n.º 13
0
parser.add_argument('--unmerged', action='store_const', const=True,
                    help='show only unmerged pull-requests')
args = parser.parse_args()

def print_verbose(str, *argv, **kwargs):
    if(verbose):
        print("... {}".format(str),\
              file=sys.stderr, *argv, **kwargs)

u=config['main']['user']
s=config['main']['token']
verbose=args.verbose
unmerged=args.unmerged

sys.stderr.flush()
repo = Repo.discover()
print_verbose("Found Git repository {}".format(repo))
print_verbose("  control dir is {}".format(repo.controldir()))
try:
    repo.commondir
except AttributeError:
    print_verbose("dulwich does not know repo.commondir()")
else:
    print_verbose("   common dir is {}".format(repo.commondir()))

print_verbose("   index path is {}".format(repo.index_path()))
print_verbose("Getting commits in current branch", end='')
print_verbose(" {}".\
              format(str(repo.refs.read_ref('HEAD'), "ascii")), end='')
sys.stderr.flush()
walk = repo.get_walker(include=repo.head(),\
Ejemplo n.º 14
0
def main(version, github_personal_access_token,
         kiln_automation_docker_access_token):
    no_verify = True

    kiln_repo = Repo.discover()
    working_copy_clean = check_for_expected_working_copy_changes(kiln_repo)
    if not working_copy_clean:
        raise click.ClickException(
            "Working copy contains uncomitted changes except for CHANGELOG.md")
    dulwich.porcelain.branch_create(kiln_repo.path, f"release/{version}")
    release_branch_ref = f"refs/heads/release/{version}".encode()
    kiln_repo.refs.set_symbolic_ref(b'HEAD', release_branch_ref)

    kiln_repo.stage(['CHANGELOG.md'])
    changelog_commit_hash = kiln_repo.do_commit(
        message=f"Docs: Update CHANGELOG.md for {version} release.".encode(),
        no_verify=no_verify)
    changelog_commit = kiln_repo.get_object(changelog_commit_hash)

    buf = io.BytesIO()
    dulwich.porcelain.diff_tree(
        kiln_repo,
        kiln_repo.get_object(changelog_commit.parents[0]).tree,
        changelog_commit.tree, buf)

    diffs = whatthepatch.parse_patch(buf.getvalue().decode("utf-8"))
    changelog_lines = []
    for diff in diffs:
        for change in diff.changes:
            if change.old is None and change.new is not None and change.line != "":
                changelog_lines.append(change.line)

    set_cargo_toml_version(kiln_repo, "kiln_lib", version)
    sh.cargo.check("--manifest-path",
                   os.path.join(kiln_repo.path, "kiln_lib", "Cargo.toml"),
                   "--all-features",
                   _err=sys.stderr)
    kiln_repo.stage(['kiln_lib/Cargo.toml', 'kiln_lib/Cargo.lock'])
    kiln_lib_version_commit = kiln_repo.do_commit(
        message=f"Kiln_lib: Update component version to {version}".encode(),
        no_verify=no_verify)
    origin = kiln_repo.get_config().get(('remote', 'origin'), 'url')
    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=release_branch_ref)

    for component in [
            "data-collector", "data-forwarder", "report-parser",
            "slack-connector"
    ]:
        set_kiln_lib_dependency(kiln_repo,
                                component,
                                sha=kiln_lib_version_commit)
        sh.cargo.check("--manifest-path",
                       os.path.join(kiln_repo.path, component, "Cargo.toml"),
                       "--all-features",
                       _err=sys.stderr)
        kiln_repo.stage([f'{component}/Cargo.toml', f'{component}/Cargo.lock'])
        kiln_repo.do_commit(
            message=
            f"{component.capitalize()}: Update kiln_lib dependency to {version}"
            .encode(),
            no_verify=no_verify)
        set_cargo_toml_version(kiln_repo, component, version)
        sh.cargo.check("--manifest-path",
                       os.path.join(kiln_repo.path, component, "Cargo.toml"),
                       "--all-features",
                       _err=sys.stderr)
        kiln_repo.stage([f'{component}/Cargo.toml', f'{component}/Cargo.lock'])
        kiln_repo.do_commit(
            message=
            f"{component.capitalize()}: Update component version to {version}".
            encode(),
            no_verify=no_verify)

    set_cargo_toml_version(kiln_repo, "cli", version)
    sh.cargo.check("--manifest-path",
                   os.path.join(kiln_repo.path, 'cli', "Cargo.toml"),
                   "--all-features",
                   _err=sys.stderr)
    kiln_repo.stage(['cli/Cargo.toml', 'cli/Cargo.lock'])
    kiln_repo.do_commit(
        message=f"CLI: Update component version to {version}".encode(),
        no_verify=no_verify)

    signing_key_id = kiln_repo.get_config()[(
        b'user', )][b'signingkey'].decode('utf-8')
    dulwich.porcelain.tag_create(kiln_repo,
                                 f"v{version}".encode(),
                                 message=f"v{version}".encode(),
                                 annotated=True,
                                 sign=signing_key_id)
    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=[release_branch_ref])
    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=[f"refs/tags/v{version}".encode()])

    sh.cargo.make("build-data-forwarder-musl",
                  _cwd=os.path.join(kiln_repo.path, "data-forwarder"),
                  _err=sys.stderr)
    shutil.copy2(
        os.path.join(kiln_repo.path, "bin", "data-forwarder"),
        os.path.join(kiln_repo.path, "tool-images", "ruby", "bundler-audit"))
    shutil.copy2(
        os.path.join(kiln_repo.path, "bin", "data-forwarder"),
        os.path.join(kiln_repo.path, "tool-images", "python", "safety"))
    docker_client = docker.from_env()
    docker_client.login(username="******",
                        password=kiln_automation_docker_access_token)

    image_tags = docker_image_tags(version)
    (bundler_audit_image, build_logs) = docker_client.images.build(
        path=os.path.join(kiln_repo.path, "tool-images", "ruby",
                          "bundler-audit"),
        tag=f"kiln/bundler-audit:{image_tags[0]}",
        rm=True)
    for line in build_logs:
        try:
            print(line['stream'], end='')
        except KeyError:
            pass

    push_logs = docker_client.images.push("kiln/bundler-audit",
                                          tag=image_tags[0])
    print(push_logs)
    for tag in image_tags[1:]:
        bundler_audit_image.tag("kiln/bundler-audit", tag=tag)
        push_logs = bundler_audit_image.push("kiln/bundler-audit", tag=tag)
        print(push_logs)

    (safety_image, build_logs) = docker_client.images.build(
        path=os.path.join(kiln_repo.path, "tool-images", "python", "safety"),
        tag=f"kiln/safety:{image_tags[0]}",
        rm=True)
    for line in build_logs:
        try:
            print(line['stream'], end='')
        except KeyError:
            pass
    push_logs = docker_client.images.push("kiln/safety", tag=image_tags[0])
    print(push_logs)

    for tag in image_tags[1:]:
        safety_image.tag("kiln/safety", tag=tag)
        push_logs = docker_client.images.push("kiln/safety", tag=tag)
        print(push_logs)

    for component in ["data-collector", "report-parser", "slack-connector"]:
        sh.cargo.make("musl-build",
                      _cwd=os.path.join(kiln_repo.path, component),
                      _err=sys.stderr)
        (docker_image, build_logs) = docker_client.images.build(
            path=os.path.join(kiln_repo.path, component),
            tag=f"kiln/{component}:{image_tags[0]}",
            rm=True)
        for line in build_logs:
            try:
                print(line['stream'], end='')
            except KeyError:
                pass
        push_logs = docker_image.push(f"kiln/{component}", tag=image_tags[0])
        print(push_logs)
        for tag in image_tags[1:]:
            docker_image.tag(f"kiln/{component}", tag=tag)
            push_logs = docker_client.images.push(f"kiln/{component}", tag=tag)
            print(push_logs)

    sh.cargo.make("musl-build",
                  _cwd=os.path.join(kiln_repo.path, "cli"),
                  _err=sys.stderr)
    base_path = os.path.join(kiln_repo.path, "cli", "target",
                             "x86_64-unknown-linux-musl", "release")
    src_path = os.path.join(base_path, "kiln-cli")
    base_name = f"kiln-cli-{version}.x86_64"
    dst_path = os.path.join(base_path, base_name)
    tarball_name = f"{base_name}.tar.xz"
    tarball_path = os.path.join(base_path, tarball_name)
    hashfile_name = f"{tarball_name}.sha256"
    hashfile_path = os.path.join(base_path, hashfile_name)
    sig_name = f"{hashfile_name}.sig"
    sig_path = os.path.join(base_path, sig_name)

    os.rename(src_path, dst_path)
    with tarfile.open(name=tarball_path, mode='w:xz') as tarball:
        tarball.add(dst_path, arcname=base_name)

    sha256sum = hashlib.sha256()
    b = bytearray(128 * 1024)
    mv = memoryview(b)
    with open(tarball_path, 'rb', buffering=0) as f:
        for n in iter(lambda: f.readinto(mv), 0):
            sha256sum.update(mv[:n])
    tarball_hash = sha256sum.hexdigest()
    with open(hashfile_path, 'w') as f:
        f.write(f"{tarball_hash} {tarball_name}")

    with gpg.Context() as default_ctx:
        signing_key = default_ctx.get_key(signing_key_id)
        with gpg.Context(signers=[signing_key], armor=True) as ctx:
            with open(hashfile_path, 'rb') as hashfile:
                with open(sig_path, 'wb') as sigfile:
                    hashdata = hashfile.read()
                    sig, metadata = ctx.sign(
                        hashdata, mode=gpg.constants.sig.mode.DETACH)
                    sigfile.write(sig)

    source_tarball_name = f"Kiln-{version}.tar.xz"
    source_tarball_path = os.path.join(kiln_repo.path, source_tarball_name)
    source_hashfile_name = f"{source_tarball_name}.sha256"
    source_hashfile_path = os.path.join(kiln_repo.path, source_hashfile_name)
    source_sig_name = f"{source_hashfile_name}.sig"
    source_sig_path = os.path.join(kiln_repo.path, source_sig_name)

    with io.BytesIO() as f:
        dulwich.porcelain.archive(kiln_repo, outstream=f)
        f.flush()
        compressed_bytes = lzma.compress(f.getvalue())
    with open(source_tarball_path, 'wb') as f:
        f.write(compressed_bytes)
    sha256sum = hashlib.sha256()
    sha256sum.update(compressed_bytes)
    tarball_hash = sha256sum.hexdigest()
    with open(source_hashfile_path, 'w') as f:
        f.write(f"{tarball_hash} {source_tarball_name}")

    with gpg.Context() as default_ctx:
        signing_key = default_ctx.get_key(signing_key_id)
        with gpg.Context(signers=[signing_key], armor=True) as ctx:
            with open(source_hashfile_path, 'rb') as hashfile:
                with open(source_sig_path, 'wb') as sigfile:
                    hashdata = hashfile.read()
                    sig, metadata = ctx.sign(
                        hashdata, mode=gpg.constants.sig.mode.DETACH)
                    sigfile.write(sig)

    g = Github(github_personal_access_token)
    repo = g.get_repo("simplybusiness/Kiln")
    release = repo.create_git_release(f"v{version}",
                                      f"Version {version}",
                                      '\n'.join(changelog_lines),
                                      draft=True)
    release.upload_asset(tarball_path)
    release.upload_asset(hashfile_path)
    release.upload_asset(sig_path)
    release.upload_asset(source_tarball_path)
    release.upload_asset(source_hashfile_path)
    release.upload_asset(source_sig_path)

    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=release_branch_ref)
    main_branch_ref = f"refs/heads/main".encode()
    kiln_repo.refs.set_symbolic_ref(b'HEAD', main_branch_ref)
    kiln_repo.reset_index()
    sh.git.merge("--no-edit", "--no-ff", f"release/{version}")
    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=main_branch_ref)

    for component in [
            "data-collector", "data-forwarder", "report-parser",
            "slack-connector"
    ]:
        set_kiln_lib_dependency(kiln_repo, component, branch="main")
        sh.cargo.check("--manifest-path",
                       os.path.join(kiln_repo.path, component, "Cargo.toml"),
                       "--all-features",
                       _err=sys.stderr)
        kiln_repo.stage([f'{component}/Cargo.toml', f'{component}/Cargo.lock'])
        kiln_repo.do_commit(
            message=
            f"{component.capitalize()}: Revert kiln_lib dependency to main branch"
            .encode(),
            no_verify=no_verify)

    dulwich.porcelain.push(kiln_repo,
                           remote_location=origin,
                           refspecs=main_branch_ref)

    print(
        "Release is complete, but requires that Github release is published manually"
    )