コード例 #1
0
async def closed(event: github.EventType):
    ref = event.payload[event.key]['html_url']
    logger.debug(
        f'Triggered {event.key}/{event.action} event handler from ref {ref}')

    token = event.app['token']
    card_data = await github.graphql_query(queries.GET_ALL_CARDS, token=token)
    cards_df = projects.build_cards_frame(card_data)

    matching_cards = cards_df[cards_df['ref'] == ref]
    if len(matching_cards) == 0:
        logger.debug(f'No cards found matching ref {ref}')
        return web.Response()

    df_column = 'in_progress_column_id' if event.action == 'reopened' else 'done_column_id'
    async with github.ProjectClientSession(token=token) as session:
        for _, card in matching_cards.iterrows():
            card_id = int(card['card_id'])
            column_id = int(card[df_column])
            logger.info(f'Moving card {card_id} to column {column_id}')
            response = await session.move_project_card(card_id=card_id,
                                                       column_id=column_id)
            if response.status != 201:
                logger.warning(f'Failed to move card [{response.status}]')
            await asyncio.sleep(0.1)

    await utils.log_rate_limits(token=token)

    return web.Response()
コード例 #2
0
async def moved(event: github.EventType):
    mover = event.payload['sender']['login']
    if mover == 'xdev-bot':
        return web.Response()

    moved_card_id = event.payload[event.key]['id']

    note = event.payload[event.key]['note']
    refs = utils.refs_from_note(note)
    if len(refs) != 1:
        logger.debug(f'No cards found matching note: {note}')
        return web.Response()
    ref = refs[0]
    logger.debug(
        f'Triggered {event.key}/{event.action} event handler from note "{note}"'
    )

    token = event.app['token']
    all_card_data = await github.graphql_query(queries.GET_ALL_CARDS,
                                               token=token)
    cards_df = projects.build_cards_frame(all_card_data)

    moved_card = cards_df[cards_df['card_id'] == moved_card_id]
    if len(moved_card) != 1:
        logger.debug(f'Could not find moved card {moved_card_id}')
        return web.Response()
    moved_column_name = moved_card['column_name'].to_list()[0]
    df_column = f'{moved_column_name.lower().replace(" ", "_")}_column_id'

    matching_cards = cards_df[cards_df['ref'] == ref]
    other_cards = matching_cards[matching_cards['card_id'] != moved_card_id]
    if len(other_cards) == 0:
        logger.debug(f'No other cards found matching ref {ref}')
        return web.Response()

    async with github.ProjectClientSession(token=token) as session:
        for _, card in other_cards.iterrows():
            card_id = int(card['card_id'])
            column_id = int(card[df_column])
            logger.info(f'Moving card {card_id} to column {column_id}')
            response = await session.move_project_card(card_id=card_id,
                                                       column_id=column_id)
            if response.status != 201:
                logger.warning(f'Failed to move card [{response.status}]')
            await asyncio.sleep(0.1)

    await utils.log_rate_limits(token=token)

    return web.Response()
コード例 #3
0
ファイル: test_github.py プロジェクト: NCAR/xdevbot
async def test_project_card_lifetime():
    note = 'https://github.com/NCAR/xdevbot-testing/issues/5'
    # content_id = 664727902
    # content_type = 'Issue'
    async with github.ProjectClientSession(token=TOKEN) as session:
        response = await session.create_project_card(note=note, column_id=NEW_COLUMN_ID)
        assert response.status == 201
        new_card = await response.json()

        response = await session.list_project_cards(column_id=NEW_COLUMN_ID)
        assert response.status == 200
        new_cards = await response.json()
        new_card_found = False
        for card in new_cards:
            if card['id'] == new_card['id']:
                new_card_found = True
        assert new_card_found

        response = await session.update_project_card(card_id=new_card['id'], archived=True)
        assert response.status == 200
        card = await response.json()
        assert card['archived']

        response = await session.update_project_card(card_id=new_card['id'], archived=False)
        assert response.status == 200
        card = await response.json()
        assert not card['archived']

        response = await session.get_project_card(card_id=new_card['id'])
        assert response.status == 200
        card = await response.json()
        assert card['id'] == new_card['id']
        assert card['note'] == new_card['note']

        response = await session.move_project_card(card_id=new_card['id'], column_id=OLD_COLUMN_ID)
        assert response.status == 201

        response = await session.delete_project_card(card_id=new_card['id'])
        assert response.status == 204
コード例 #4
0
async def deleted(event: github.EventType):
    deleter = event.payload['sender']['login']
    if deleter == 'xdev-bot':
        return web.Response()

    deleted_card_id = event.payload[event.key]['id']

    note = event.payload[event.key]['note']
    refs = utils.refs_from_note(note)
    if len(refs) != 1:
        logger.debug(f'No cards found matching note: {note}')
        return web.Response()
    ref = refs[0]
    logger.debug(
        f'Triggered {event.key}/{event.action} event handler from note "{note}"'
    )

    token = event.app['token']
    all_card_data = await github.graphql_query(queries.GET_ALL_CARDS,
                                               token=token)
    cards_df = projects.build_cards_frame(all_card_data)
    matching_cards = cards_df[cards_df['ref'] == ref]
    other_cards = matching_cards[matching_cards['card_id'] != deleted_card_id]
    if len(other_cards) == 0:
        logger.debug(f'No other cards found matching ref {ref}')
        return web.Response()

    async with github.ProjectClientSession(token=token) as session:
        for _, card in other_cards.iterrows():
            card_id = int(card['card_id'])
            logger.info(f'Deleting card {card_id}')
            response = await session.delete_project_card(card_id=card_id)
            if response.status != 204:
                logger.warning(f'Failed to delete card [{response.status}]')
            await asyncio.sleep(0.1)

    await utils.log_rate_limits(token=token)

    return web.Response()
コード例 #5
0
async def opened(event: github.EventType):
    ref = event.payload[event.key]['html_url']
    logger.debug(
        f'Triggered {event.key}/{event.action} event handler from ref {ref}')

    repo = event.payload['repository']['full_name']

    cfg_data = await utils.read_remote_yaml(CONFIG_URL)
    df = projects.build_config_frame(cfg_data)
    project_urls = df[df['repo'] == repo]['project_url'].to_list()
    if len(project_urls) == 0:
        logger.debug(f'No projects associated with repo {repo}')
        return web.Response()

    token = event.app['token']
    column_data = await github.graphql_query(queries.GET_COLUMNS, token=token)
    columns_df = projects.build_columns_frame(column_data)
    column_name = 'In Progress' if event.key == 'pull_request' else 'New'

    async with github.ProjectClientSession(token=token) as session:
        for project_url in project_urls:
            logger.info(f'Creating new card on project {project_url}')
            df = columns_df[columns_df['project_url'] == project_url]
            column_id = int(df[df['column_name'] == column_name]['column_id'])
            response = await session.create_project_card(note=ref,
                                                         column_id=column_id)
            if response.status != 201:
                logger.warning(
                    f'Failed to create new card! [{response.status}]')
                body = json.dumps(await response.json(), indent=4)
                logger.debug(f'HTTP Response Body:\n{body}')
            await asyncio.sleep(0.1)

    await utils.log_rate_limits(token=token)

    return web.Response()
コード例 #6
0
async def main():
    token = os.environ.get('XDEVBOT_TOKEN', None)

    cfg_data = await utils.read_remote_yaml(routes.CONFIG_URL)
    cfg_df = projects.build_config_frame(cfg_data)

    all_card_data = await github.graphql_query(GET_ALL_CARDS, token=token)
    all_cards_df = projects.build_cards_frame(all_card_data)
    columns_df = projects.build_columns_frame(all_card_data)

    new_cards_df = all_cards_df[all_cards_df['project_url'].isin(cfg_df['project_url'])]
    old_cards_df = all_cards_df[all_cards_df['project_url'] == BACKLOG_URL]

    unwatched = set()
    existing = set()
    missing = set()
    nonbot = set()

    for _, old_card in old_cards_df.iterrows():
        ref = old_card['ref']
        new_cards = new_cards_df[new_cards_df['ref'] == ref]
        if len(new_cards) > 0:
            existing.add(ref)
            continue

        creator = old_card['creator']
        if creator != 'xdev-bot':
            nonbot.add(ref)
            continue

        org, user, _ = utils.split_issue_ref(ref)
        repo = f'{org}/{user}'
        project_urls = cfg_df[cfg_df['repo'] == repo]['project_url'].to_list()
        if len(project_urls) == 0:
            unwatched.add(repo)
            continue

        missing.add(ref)
        print()
        print(f'--- Need to copy card: {ref}')

        old_column = old_card['column_name']
        new_column = BACKLOG_COLUMN_MAP[old_column]
        print(f'    From column "{old_column}"')

        async with github.ProjectClientSession(token=token) as session:
            for project_url in project_urls:
                df = columns_df[columns_df['project_url'] == project_url]
                column_id = int(df[df['column_name'] == new_column]['column_id'])
                print(f'    To project {project_url} column "{new_column}" [id: {column_id}]')

                response = await session.create_project_card(note=ref, column_id=column_id)
                if response.status != 201:
                    print(f'    *** Failed to transfer card! [{response.status}]')

    if unwatched:
        print()
        print('=== Unwatched Repositories:')
        for repo in sorted(unwatched):
            print(f'    - {repo}')

    if nonbot:
        print()
        print('=== Non-bot cards that were skipped:')
        for ref in sorted(nonbot):
            print(f'    - {ref}')

    if existing:
        print()
        print(f'Found {len(existing)} existing cards that were skipped.')

    if missing:
        print()
        print(f'Will copy {len(missing)} cards to new boards.')
コード例 #7
0
ファイル: polling.py プロジェクト: NCAR/xdevbot
async def update_nonbot_cards(token=None):
    card_data = await github.graphql_query(queries.GET_ALL_CARDS, token=token)
    columns = projects.build_columns_frame(card_data)
    cards = projects.build_cards_frame(card_data)
    nonbot_cards = cards[cards['creator'] != 'xdev-bot']
    logger.debug(f'Found {len(nonbot_cards)} non-bot cards on project boards')
    num_cards_moved = 0
    num_failures = 0
    for _, card in nonbot_cards.iterrows():
        card_id = card['card_id']
        project_url = card['project_url']
        column_id = card['column_id']

        df = columns[columns['project_url'] == project_url]
        column_name = df[df['column_id'] == column_id]['column_name'].item()

        ref = card['ref']
        content_id = card['content_id']

        if not pd.isna(content_id):
            state = card['content_state'].lower()
        elif not pd.isna(ref):
            owner, repo, number = utils.split_issue_ref(ref)
            async with github.IssueClientSession(token=token) as session:
                response = await session.get_issue(owner=owner,
                                                   repo=repo,
                                                   number=number)
                if response.status != 200:
                    logger.warning(
                        f'Failed to retrieve state of reference: {owner}/{repo}#{number}'
                    )
                    continue
            issue = await response.json()
            state = issue['state']
        else:
            logger.warning(
                f'Non-bot card {card_id} has no content_id or reference. Skipping.'
            )
            continue

        if state == 'open' and column_name == 'Done':
            logger.debug(
                f'Non-bot card {card_id} is open but was found in the "Done" column'
            )
            column_id = card['in_progress_column_id']
        elif state != 'open' and column_name != 'Done':
            logger.debug(
                f'Non-bot card {card_id} is closed but wasn\'t found in the "Done" column'
            )
            column_id = card['done_column_id']
        else:
            logger.debug(
                f'Non-bot card {card_id} appears to be in a consistent column')
            column_id = None

        if column_id:
            async with github.ProjectClientSession(token=token) as session:
                logger.debug(
                    f'Moving non-bot card {card_id} to column {column_id}')
                response = await session.move_project_card(card_id=card_id,
                                                           column_id=column_id)
                if response.status == 201:
                    num_cards_moved += 1
                else:
                    num_failures += 1
                    logger.warning(
                        f'Failed to move non-bot card [{response.status}]')

    if num_cards_moved > 0:
        logger.info(
            f'Updated {num_cards_moved} non-bot cards on project boards ({num_failures} failures)'
        )