diff --git a/docs/setup_graphql.md b/docs/setup_graphql.md new file mode 100644 index 0000000..80e6b50 --- /dev/null +++ b/docs/setup_graphql.md @@ -0,0 +1,44 @@ +## GraphQL get some ID's instriction +You can find this many of id's with only +with GraphQL requests ([use Explorer](https://docs.github.com/ru/graphql/overview/explorer)): + + +```graphql +# This query return scrum project's id's (PROJECT_NODE_ID). Bot only can add issue only to one project +{organization(login: "GH_ORGANIZATION_NICKNAME") { + projectsV2(first: 100) { + edges { + node { + title + id + public +}}}}} +``` +```graphql +# Use PROJECT_NODE_ID for next request. +{node(id: "PROJECT_NODE_ID") { + ... on ProjectV2 { + fields(first: 20) { + nodes { + ... on ProjectV2Field { + id + name + } + ... on ProjectV2IterationField { + id + name + configuration { + iterations { + startDate + id + } + } + } + ... on ProjectV2SingleSelectField { + id + name + options { + id + name +}}}}}}} +``` \ No newline at end of file diff --git a/migrations/env.py b/migrations/env.py index ad3e7ef..c1c8097 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,12 +1,12 @@ from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - from alembic import context +from sqlalchemy import engine_from_config, pool + from social.models.base import Base from social.settings import get_settings + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config diff --git a/migrations/versions/57c72962d2b4_webhook_storage.py b/migrations/versions/57c72962d2b4_webhook_storage.py index 0d18b4d..3e2be3a 100644 --- a/migrations/versions/57c72962d2b4_webhook_storage.py +++ b/migrations/versions/57c72962d2b4_webhook_storage.py @@ -5,8 +5,8 @@ Create Date: 2023-03-12 14:22:34.958257 """ -from alembic import op import sqlalchemy as sa +from alembic import op # revision identifiers, used by Alembic. diff --git a/social/handlers_github/profcomff_issues.graphql b/social/handlers_github/profcomff_issues.graphql index 4b8135f..2cbcd4d 100644 --- a/social/handlers_github/profcomff_issues.graphql +++ b/social/handlers_github/profcomff_issues.graphql @@ -1,7 +1,68 @@ mutation AddToScrum($projectId: ID!, $contentId: ID!) { - addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) { - item { - id + addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) { + item { + id + } } - } } + + +query GetIssueDeadlineField($issueId: ID!) { + node(id: $issueId) { + ... on Issue { + id + title + projectItems(first: 10) { + totalCount + nodes { + id + fieldValues(first: 15, orderBy: {field: POSITION, direction: DESC}) { + nodes { + ... on ProjectV2ItemFieldDateValue { + id + date + field { + ... on ProjectV2Field { + id + name + } + } + } + } + } + } + } + } + } +} + + +mutation SetFieldDateValue($projectId: ID!, $itemId: ID!, $fieldId: ID!, $newDate: Date!){ + updateProjectV2ItemFieldValue( + input: { + projectId: $projectId, + itemId: $itemId, + fieldId: $fieldId, + value: {date: $newDate} + } + ) { + projectV2Item { + createdAt + updatedAt + fieldValues(first: 15, orderBy: {field: POSITION, direction: DESC}) { + nodes { + ... on ProjectV2ItemFieldDateValue { + id + date + field { + ... on ProjectV2Field { + id + name + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/social/handlers_github/profcomff_issues.py b/social/handlers_github/profcomff_issues.py index cf04192..88dcc11 100644 --- a/social/handlers_github/profcomff_issues.py +++ b/social/handlers_github/profcomff_issues.py @@ -1,9 +1,9 @@ +import datetime import logging +from social.handlers_github.base import event from social.utils.github_api import get_github -from .base import event - logger = logging.getLogger(__name__) github = get_github('profcomff') @@ -16,7 +16,7 @@ @event(issue=..., action="opened") def issue_opened(event): - """При открытиии новой ишью добавляет ее на достку "Твой ФФ" """ + """При открытии новой issue добавляет ее на доску "Твой ФФ" """ logger.debug("Issue %s created (node_id=%s)", event["issue"].get("url"), event["issue"].get("node_id")) r = github.request_gql( 'social/handlers_github/profcomff_issues.graphql', @@ -25,3 +25,62 @@ def issue_opened(event): contentId=event["issue"].get("node_id"), ) logging.debug("Response %s", r) + + +@event(issue=..., action="assigned") +def issue_opened(event): + """ + При назначении исполнителя для issue, + если дедлайн не назначен, то назначить дедлайн +неделю от текущей даты + если дедлайн просрочен (то есть смена исполнителя), то назначает дедлайн +неделю от текущей даты + + так же при назначении исполнителя установить taken_date на текущий день + впоследствии не менять, даже при смене исполнителя + """ + + # Получение project_item_id, деделайна и даты взятия в работу для текущей issue + logger.debug("Issue %s assigned (node_id=%s)", event["issue"].get("url"), event["issue"].get("node_id")) + r = github.request_gql( + 'social/handlers_github/profcomff_issues.graphql', + 'GetIssueDeadlineField', + issueId=event["issue"].get("node_id"), + ) + logging.debug("Get Project Fields: %s", r) + + # Парсинг полей + project_item_id = r['node']['projectItems']['nodes'][0]['id'] + deadline_date = None + taken_date = None + for node in r['node']['projectItems']['nodes'][0]['fieldValues']['nodes']: + if len(node) != 0 and node['field']['name'] == 'Deadline': + deadline_date = datetime.datetime.strptime(node['date'], '%Y-%m-%d').date() + if len(node) != 0 and node['field']['name'] == 'Taken': + taken_date = datetime.datetime.strptime(node['date'], '%Y-%m-%d').date() + + # Изменение дедлайна если требуется + if deadline_date is None or deadline_date < datetime.date.today(): + new_deadline_date = str((datetime.date.today() + datetime.timedelta(days=7))) + logging.debug(f"Try to change DeadlineDate from {deadline_date} to {new_deadline_date}") + r = github.request_gql( + 'social/handlers_github/profcomff_issues.graphql', + 'SetFieldDateValue', + projectId=PROJECT_NODE_ID, + itemId=project_item_id, + fieldId=DEADLINE_FIELD_NODE_ID, + newDate=new_deadline_date + ) + logging.debug("Deadline change response: %s", r) + + # Изменение даты взятия в работу если не назначена + if taken_date is None: + new_taken_date = str(datetime.date.today()) + logging.debug(f"Try to change TakenDate from {taken_date} to {new_taken_date}") + r = github.request_gql( + 'social/handlers_github/profcomff_issues.graphql', + 'SetFieldDateValue', + projectId=PROJECT_NODE_ID, + itemId=project_item_id, + fieldId=TAKEN_FIELD_NODE_ID, + newDate=new_taken_date + ) + logging.debug("Taken change response: %s", r) diff --git a/tests/github_processor.py b/tests/github_processor.py index e3cbb29..918b463 100644 --- a/tests/github_processor.py +++ b/tests/github_processor.py @@ -1,5 +1,7 @@ -import pytest from datetime import datetime + +import pytest + from social.handlers_github.base import EventProcessor