コード例 #1
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_repo_add(config, plan_id, repo):
    api_client = ApiClient(config)

    # Look up the plan
    plan = get_plan(api_client, plan_id)

    # Filter by repository
    repo_data = lookup_repo(api_client, config, repo, required=True)

    # Check that we don't already have a matching PlanRepository
    params = {
        'plan': plan_id,
        'repo': repo_data['id'],
    }
    res = api_client('plan_repos', 'list', params=params)
    if res['count']:
        raise click.ClickException('Repo already added to plan')

    # Create the PlanRepository
    params = {
        'plan_id': plan_id,
        'repo_id': repo_data['id'],
    }
    res = api_client('plan_repos', 'create', params=params)
    click.echo()
    click.echo(
        'Added repo {repo[owner]}/{repo[name]} to plan {plan[name]}'.format(
            **res))
    render_recursive(res)
コード例 #2
0
def build_info(config, build_id, log, flow_log, flow):
    api_client = ApiClient(config)

    params = {
        'id': build_id,
    }

    # Look up the build
    try:
        build_res = api_client('builds', 'read', params=params)
    except coreapi.exceptions.ErrorMessage as e:
        raise click.ClickException(
            'Build with id {} not found.  Use metaci build list to see a list of latest builds and their ids'
            .format(build_id))

    if log:
        click.echo(build_res['log'])
    elif flow_log:
        params = {'build': build_id}
        if flow:
            params['flow'] = flow
        build_flow_res = api_client('build_flows', 'list', params=params)
        for build_flow in build_flow_res['results']:
            click.echo()
            click.echo(
                click.style('{}:'.format(build_flow['flow']),
                            bold=True,
                            fg='blue'))
            click.echo(build_flow['log'])

    else:
        click.echo(render_recursive(build_res))
コード例 #3
0
ファイル: org.py プロジェクト: Nickers3/MetaCI-CLI
def org_list(config, repo):
    api_client = ApiClient(config)

    params = {}

    # Filter by repository
    repo_data = lookup_repo(api_client, config, repo)
    if repo_data:
        params['repo'] = repo_data['id']

    res = api_client('orgs', 'list', params=params)

    org_list_fmt = '{id:<5} {name:24.24} {scratch:7} {repo[owner]}'
    headers = {
        'id': '#',
        'name': 'Name',
        'scratch': 'Scratch',
        'repo': {
            'owner': 'Repo'
        },
    }
    click.echo(org_list_fmt.format(**headers))
    #org_list_fmt += "/{repo[name]}"
    for org in res['results']:
        click.echo(org_list_fmt.format(**org))
コード例 #4
0
def build_list(config, repo, status):
    api_client = ApiClient(config)

    params = {}

    # Filter by repository
    repo_data = lookup_repo(api_client, config, repo)
    if repo_data:
        params['repo'] = repo_data['id']

    # Filter by status
    if status:
        params['status'] = status

    res = api_client('builds', 'list', params=params)

    build_list_fmt = '{id:<5} {status:8.8} {plan[name]:24.24} {branch[name]:24.24} {commit}'
    headers = {
        'id': '#',
        'status': 'Status',
        'plan': {
            'name': 'Plan'
        },
        'branch': {
            'name': 'Branch'
        },
        'commit': 'Commit',
    }
    click.echo(build_list_fmt.format(**headers))
    for build in res['results']:
        click.echo(
            color_status(
                status=build['status'],
                line=build_list_fmt.format(**build),
            ))
コード例 #5
0
ファイル: org.py プロジェクト: Nickers3/MetaCI-CLI
def org_add(config, name, org, repo):
    require_project_config(config)

    api_client = ApiClient(config)
    params = {}

    # Prompt for org name if not specified
    if not org:
        click.echo(
            'To create a MetaCI org, select one of your existing CumulusCI orgs.  The org information from your local CumulusCI keychain will be transferred to the MetaCI site.  You can use cci org scratch or cci org connect to create new CumulusCI orgs if needed.'
        )
        click.echo()
        default_org, org_config = config.keychain.get_default_org()
        click.echo('Available Orgs: ' + ', '.join(config.keychain.list_orgs()))
        org = click.prompt('Org', default=default_org)

    # Validate the org
    try:
        org_config = config.keychain.get_org(org)
    except OrgNotFound:
        raise click.ClickException(
            'The org {} is not configured in the local cci keychain'.format(
                org))

    org_name = name
    if not name:
        org_name = org

    # Filter by repository
    repo_data = lookup_repo(api_client, config, repo, required=True)

    name = prompt_org_name(repo_data['id'], org_name, api_client)

    params['repo_id'] = repo_data['id']
    params['name'] = name
    params['scratch'] = isinstance(org_config, ScratchOrgConfig)

    if params['scratch']:
        clean_org_config = {
            'config_file': org_config.config_file,
            'config_name': org_config.config_name,
            'namespaced': org_config.namespaced,
            'scratch': org_config.scratch,
        }
    else:
        clean_org_config = org_config.config

    params['json'] = json.dumps(clean_org_config)

    res = api_client('orgs', 'create', params=params)
    click.echo()
    click.echo(
        'Org {} was successfully created.  Use metaci org info {} to see the org details.'
        .format(name, name))
コード例 #6
0
def service_info(config, name):
    api_client = ApiClient(config)

    params = {'name': name}

    # Look up the service
    res = api_client('services', 'list', params=params)
    if res['count'] == 0:
        raise click.ClickError('Service named {} not found'.format(name))

    click.echo(render_recursive(res['results'][0]))
コード例 #7
0
def service_add(config, name):
    require_project_config(config)

    api_client = ApiClient(config)

    services = config.keychain.list_services()
    existing = []
    resp = api_client('services', 'list')
    for service in resp['results']:
        existing.append(service['name'])
        if service['name'] in services:
            services.remove(service['name'])

    # Prompt for service name if not specified
    if not name:
        click.echo(
            'To create a MetaCI service, select one of your existing CumulusCI services.  The service information from your local CumulusCI keychain will be transferred to the MetaCI site.  You can use cci service list to see available services and cci service connect <service_name> to connect a service to the local cci keychain.'
        )
        click.echo()
        click.echo('Available Services: ' + ', '.join(services))
        name = click.prompt('Service')

    # Validate the service name
    if name not in services:
        if name in existing:
            raise click.ClickException(
                'Service {} already exists.  Available services are: {}'.
                format(name, ', '.join(services)))
        raise click.ClickException(
            'Service {} is invalid.  Available services are: {}'.format(
                name, ', '.join(services)))

    # Validate the service exists in the cci keychain
    try:
        service_config = config.keychain.get_service(name)
    except ServiceNotConfigured:
        raise click.ClickException(
            'The service {} is not configured in the local cci keychain.  Use cci service connect {}'
            .format(service, service))
    except ServiceNotValid:
        raise click.ClickException(
            'The service {} is not a valid cci service name.  If this is a custom service for the project, you need to first configure the service in the project cumulusci.yml file.'
            .format(service))

    params = {}
    params['name'] = name
    params['json'] = json.dumps(service_config.config)
    res = api_client('services', 'create', params=params)
    click.echo()
    click.echo(
        'Service {} was successfully created.  Use metaci service info {} to see the service details.'
        .format(name, name))
コード例 #8
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_run(config, plan_id, branch, commit):
    api_client = ApiClient(config)
    plan = get_plan(api_client, plan_id)

    # Look up the repo
    repo_data = lookup_repo(api_client, config, None, required=True)

    # Look up the plan org
    org_params = {
        'repo': repo_data['id'],
        'name': plan['org'],
    }
    org_res = api_client('orgs', 'list', params=org_params)
    if org_res['count'] == 0:
        raise click.ClickException(
            'The plan org "{}" does not exist in MetaCI.  Use metaci org create to create the org.'
            .format(plan['org']))
    org_data = org_res['results'][0]

    # Look up the branch
    if not branch:
        branch = config.project_config.repo_branch
    branch_data = get_or_create_branch(api_client, branch, repo_data['id'])

    # Determine the commit
    if not commit:
        gh = config.project_config.get_github_api()
        gh_repo = gh.repository(
            config.project_config.repo_owner,
            config.project_config.repo_name,
        )
        branch = gh_repo.branch(branch)
        commit = branch.commit.sha

    # Create the build
    build_params = {
        'repo_id': repo_data['id'],
        'org_id': org_data['id'],
        'plan_id': plan_id,
        'branch_id': branch_data['id'],
        'commit': commit,
    }
    resp = api_client('builds', 'create', params=build_params)
    click.echo(
        click.style('Build {} created successfully'.format(resp['id']),
                    bold=True,
                    fg='green'))
    click.echo(
        'Use metaci build info {} to monitor the build or metaci build list to monitor multiple builds'
        .format(resp['id']))
コード例 #9
0
def service_list(config):
    api_client = ApiClient(config)

    params = {}
    res = api_client('services', 'list', params=params)

    service_list_fmt = '{id:<3} {name}'
    headers = {
        'id': '#',
        'name': 'Name',
    }
    click.echo(service_list_fmt.format(**headers))
    for service in res['results']:
        click.echo(service_list_fmt.format(**service))
コード例 #10
0
ファイル: org.py プロジェクト: Nickers3/MetaCI-CLI
def org_info(config, name, repo):
    api_client = ApiClient(config)

    params = {'name': name}

    # Filter by repository
    repo_data = lookup_repo(api_client, config, repo, required=True)
    params['repo'] = repo_data['id']

    # Look up the org
    res = api_client('orgs', 'list', params=params)
    if res['count'] == 0:
        raise click.ClickError('Org named {} not found'.format(name))

    click.echo(render_recursive(res['results'][0]))
コード例 #11
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_list(config):
    api_client = ApiClient(config)

    res = api_client('plans', 'list')

    plan_list_fmt = '{id:<5} {name:24.24} {org:12.12} {flows:24.24} {type:7.7} {regex}'
    headers = {
        'id': '#',
        'name': 'Status',
        'org': 'Org',
        'flows': 'Flows',
        'type': 'Trigger',
        'regex': 'Regex',
    }
    click.echo(plan_list_fmt.format(**headers))
    for plan in res['results']:
        click.echo(plan_list_fmt.format(**plan))
コード例 #12
0
ファイル: org.py プロジェクト: Nickers3/MetaCI-CLI
def org_browser(config, org_name):
    api_client = ApiClient(config)

    params = {
        'name': org_name,
    }

    # Look up the build
    res = api_client('orgs', 'list', params=params)
    if res['count'] == 0:
        raise click.ClickException(
            'Org named {} not found.  Use metaci org list to see a list of available org names'
            .format(org_name))

    service = check_current_site(config)
    url = '{}/orgs/{}'.format(service.url, res['results'][0]['id'])
    click.echo('Opening browser to {}'.format(url))
    webbrowser.open(url)
コード例 #13
0
def service_browser(config, name):
    api_client = ApiClient(config)

    params = {
        'name': name,
    }

    # Look up the build
    res = api_client('services', 'list', params=params)
    if res['count'] == 0:
        raise click.ClickException(
            'Service named {} not found.  Use metaci service list to see a list of available service names'
            .format(name))

    metaci_service = check_current_site(config)
    url = '{}/admin/cumulusci/service/{}'.format(metaci_service.url,
                                                 res['results'][0]['id'])
    click.echo('Opening browser to {}'.format(url))
    webbrowser.open(url)
コード例 #14
0
def build_browser(config, build_id):
    api_client = ApiClient(config)

    params = {
        'id': build_id,
    }

    # Look up the build
    try:
        res = api_client('builds', 'read', params=params)
    except coreapi.exceptions.ErrorMessage as e:
        raise click.ClickException(
            'Build with id {} not found.  Use metaci build list to see a list of latest builds and their ids'
            .format(build_id))

    service = check_current_site(config)
    url = '{}/builds/{}'.format(service.url, res['id'])
    click.echo('Opening browser to {}'.format(url))
    webbrowser.open(url)
コード例 #15
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_repo_list(config, plan_id):
    api_client = ApiClient(config)
    plan = get_plan(api_client, plan_id)
    params = {
        'plan': plan_id,
    }
    res = api_client('plan_repos', 'list', params=params)
    click.echo()
    click.echo('Repos associated with plan {}:')
    repo_list_fmt = '{id:<5} {repo[id]:<6} {repo[name]:32.32} {repo[owner]}'
    headers = {
        'id': '#',
        'repo': {
            'id': 'Repo #',
            'name': 'Name',
            'owner': 'Owner',
        },
    }
    click.echo(repo_list_fmt.format(**headers))
    for plan_repo in res['results']:
        click.echo(repo_list_fmt.format(**plan_repo))
コード例 #16
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_browser(config, plan_id):
    api_client = ApiClient(config)

    params = {
        'id': plan_id,
    }

    # Look up the plan
    try:
        res = api_client('plans', 'read', params=params)
    except coreapi.exceptions.ErrorMessage as e:
        raise click.ClickException(
            'Plan with id {} not found.  Use metaci plan list to see a list of plans and their ids'
            .format(plan_id))

    service = check_current_site(config)
    url = '{}/plans/{}'.format(
        service.url,
        res['id'],
    )
    click.echo('Opening browser to {}'.format(url))
    webbrowser.open(url)
コード例 #17
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_add(config):
    if not config.project_config:
        raise click.UsageError(
            'You must be inside a local git repository configured for CumulusCI.  No CumulusCI configuration was detected in the local directory'
        )

    api_client = ApiClient(config)

    params = {}

    # Make sure the local repo exists
    repo_data = lookup_repo(api_client, config, None, required=True)

    click.echo('# Name and Description')
    click.echo(
        'Provide a name and description of the build plan you are creating')
    name = click.prompt('Name')
    description = click.prompt('Description')

    click.echo()
    click.echo('# Org')
    click.echo(
        'Select the MetaCI org this plan should run its builds against.  If the org does not yet exist, use metaci org create to create the org first.'
    )
    org = prompt_org(api_client, config, repo_data['id'])

    flows_list = config.project_config.flows.keys()
    flows_list.sort()
    click.echo()
    click.echo('# Flows')
    click.echo(
        'What CumulusCI flows should this plan run?  You can enter multiple flows using a comma as a separator'
    )
    click.echo('Available Flows: {}'.format(', '.join(flows_list)))
    flows = click.prompt('Flow(s)')

    click.echo()
    click.echo('# Trigger Type')
    click.echo('How should this plan be triggered?')
    click.echo(
        '  - commit: Trigger on branch commits matching a regex pattern')
    click.echo('  - tag: Trigger on new tags matching a regex pattern')
    click.echo(
        '  - manual: Do not auto-trigger any builds.  Can be manually triggered.'
    )
    trigger_type = click.prompt('Trigger Type (commit, tag, or manual)')
    if trigger_type == 'commit':
        regex = click.prompt('Branch Match RegEx (ex feature/.*)')
    elif trigger_type == 'tag':
        regex = click.prompt('Tag Match RegEx (ex beta/.*)')
    elif trigger_type != 'manual':
        raise click.UsageError(
            '{} is an invalid trigger type.  Valid choices are: commit, tag, manual'
        )
    else:
        regex = None

    click.echo()
    click.echo('# Github Commit Status')
    click.echo(
        'MetaCI can set the build status via the Github Commit Status API.  Commit statuses are grouped by a context field.  Setting a different context on different plans will cause multiple commit statuses to be created for each unique context in Github.'
    )
    context = None
    if click.confirm('Set commit status in Github for this plan?',
                     default=True):
        context = click.prompt('Github Commit Status Context', default=name)

    if trigger_type == 'manual':
        active = True
    else:
        click.echo()
        click.echo('# Activate Plan')
        match_str = 'matching regex {}'.format(regex) if regex else ''
        click.echo(
            'If active, this plan will automatically build on new {}s{}'.
            format(trigger_type, match_str))
        active = click.confirm('Active?', default=True)

    click.echo()
    click.echo('# Public or Private')
    click.echo(
        'Public plans and their builds are visible to anonymous users.  This is recommended for open source projects, instances on an internal network or VPN, or projects that want transparency of their build information.  Private plans are only visible to logged in users who have been granted the Is Staff role by an admin.'
    )
    public = click.confirm('Public?')

    params = {
        'name': name,
        'description': description,
        'org': org,
        'flows': flows,
        'type': trigger_type,
        'regex': regex,
        'context': context,
        'active': active,
        'public': public,
    }

    res = api_client('plans', 'create', params=params)

    click.echo()
    click.echo(
        click.style(
            'Created plan {} with the following configuration'.format(name),
            fg='green',
        ))
    render_recursive(res)

    click.echo()
    click.echo('Adding repository {owner}/{name} to plan'.format(**repo_data))

    params = {
        'repo_id': repo_data['id'],
        'plan_id': res['id'],
    }
    res = api_client('plan_repos', 'create', params=params)
コード例 #18
0
ファイル: plan.py プロジェクト: Nickers3/MetaCI-CLI
def plan_info(config, plan_id):
    api_client = ApiClient(config)
    plan = get_plan(api_client, plan_id)
    click.echo(render_recursive(plan))