Skip to main content

Использование API для управления Projects

API GraphQL можно использовать для автоматизации проектов.

Tool navigation

В этой статье показано, как использовать API GraphQL для управления проектами. Дополнительные сведения об использовании API в рабочем процессе GitHub Actions см. в разделе Автоматизация Projects с помощью Actions. Полный список доступных типов данных см. в разделе Справочные материалы.

Проверка подлинности

Во всех приведенных ниже curl примерах команд замените TOKEN маркер, имеющий read:project область (для запросов) или project области (для запросов и мутаций). Маркер может быть personal access token (classic) для пользователя или маркера доступа к установке для GitHub App. Дополнительные сведения о создании personal access tokenсм. в разделе Управление личными маркерами доступа. Дополнительные сведения о создании маркера доступа к установке для GitHub Appсм. в разделе Генерация токена доступа для установки приложения GitHub.

При использовании маркера доступа к установке для GitHub Appнекоторые изменения GraphQL требуют дополнительных разрешений. Например, при использовании createProjectV2 изменения при указании входного repositoryId параметра Contents разрешение для этого репозитория также требуется для связывания проекта с целевым репозиторием.

Примечание.

Дополнительные сведения о GitHub CLIсм. в разделе О GitHub CLI.

Перед выполнением команд GitHub CLI необходимо выполнить проверку подлинности с помощью команды gh auth login --scopes "project". Если требуется только чтение, без редактирования проектов, можно указать область read:project вместо project. Дополнительные сведения о проверке подлинности командной строки см. в разделе gh auth login.

Использование переменных

Во всех следующих примерах переменные можно использовать для упрощения сценариев. Используйте ключ -F для передачи переменной, которая является числом, логическим значением или NULL. Используйте ключ -f для других переменных. Например,

my_org="octo-org"
my_num=5
gh api graphql -f query='
  query($organization: String! $number: Int!){
    organization(login: $organization){
      projectV2(number: $number) {
        id
      }
    }
  }' -f organization=$my_org -F number=$my_num

Дополнительные сведения см. в разделе Формирование вызовов с помощью GraphQL.

Поиск сведений о проектах

Используйте запросы для получения данных о проектах. Дополнительные сведения см. в разделе Формирование вызовов с помощью GraphQL.

Поиск идентификатора узла для проекта организации

Чтобы обновить проект с помощью API, необходимо знать идентификатор узла проекта.

Идентификатор узла проекта организации можно найти, если вы знаете название организации и номер проекта. Замените ORGANIZATION названием организации. Например: octo-org. Замените NUMBER номером проекта. Чтобы найти номер проекта, просмотрите URL-адрес проекта. Например, у https://github.com/orgs/octo-org/projects/5 номер 5.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"query{organization(login: \"ORGANIZATION\") {projectV2(number: NUMBER){id}}}"}'
gh api graphql -f query='
  query{
    organization(login: "ORGANIZATION"){
      projectV2(number: NUMBER) {
        id
      }
    }
  }'

Можно также найти идентификаторы узлов для всех проектов в организации. В следующем примере возвращается идентификаторы узлов и заголовки первых 20 проектов в организации. Замените ORGANIZATION названием организации. Например: octo-org.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"{organization(login: \"ORGANIZATION\") {projectsV2(first: 20) {nodes {id title}}}}"}'
gh api graphql -f query='
  query{
    organization(login: "ORGANIZATION") {
      projectsV2(first: 20) {
        nodes {
          id
          title
        }
      }
    }
  }'

Поиск идентификатора узла для проекта пользователя

Чтобы обновить проект с помощью API, необходимо знать идентификатор узла проекта.

Идентификатор узла проекта пользователя можно найти, если вы знаете номер проекта. Замените USER именем пользователя. Например: octocat. Замените NUMBER номером проекта. Чтобы найти номер проекта, просмотрите URL-адрес проекта. Например, у https://github.com/users/octocat/projects/5 номер 5.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"query{user(login: \"USER\") {projectV2(number: NUMBER){id}}}"}'
gh api graphql -f query='
  query{
    user(login: "USER"){
      projectV2(number: NUMBER) {
        id
      }
    }
  }'

Также можно найти идентификатор узла для всех своих проектов. В следующем примере возвращается идентификаторы узлов и заголовки первых 20 ваших проектов. Замените USER своим именем пользователя. Например: octocat.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"{user(login: \"USER\") {projectsV2(first: 20) {nodes {id title}}}}"}'
gh api graphql -f query='
  query{
    user(login: "USER") {
      projectsV2(first: 20) {
        nodes {
          id
          title
        }
      }
    }
  }'

Поиск идентификатора узла для поля

Чтобы обновить значение поля, необходимо знать идентификатор узла поля. Кроме того, необходимо знать идентификатор параметров для полей одиночного выбора и идентификатор итерации для полей итерации.

В следующем примере возвращаются идентификатор, имя, параметры и конфигурация для первых 20 полей в проекте. Замените PROJECT_ID идентификатором узла для проекта.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"query{ node(id: \"PROJECT_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 }}}}}}}"}'
gh api graphql -f query='
  query{
  node(id: "PROJECT_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
            }
          }
        }
      }
    }
  }
}'

Вы получите ответ следующего вида:

{
  "data": {
    "node": {
      "fields": {
        "nodes": [
          {
            "id": "PVTF_lADOANN5s84ACbL0zgBZrZY",
            "name": "Title"
          },
          {
            "id": "PVTF_lADOANN5s84ACbL0zgBZrZc",
            "name": "Assignees"
          },
          {
            "id": "PVTSSF_lADOANN5s84ACbL0zgBZrZg",
            "name": "Status",
            "options": [
              {
                "id": "f75ad846",
                "name": "Todo"
              },
              {
                "id": "47fc9ee4",
                "name": "In Progress"
              },
              {
                "id": "98236657",
                "name": "Done"
              }
            ]
          },
          {
            "id": "PVTIF_lADOANN5s84ACbL0zgBah28",
            "name": "Iteration",
            "configuration": {
              "iterations": [
                {
                  "startDate": "2022-05-29",
                  "id": "cfc16e4d"
                }
              ]
            }
          }
        ]
      }
    }
  }
}

У каждого поля есть идентификатор и имя. Отдельные поля выбора возвращаются в формате объекта ProjectV2SingleSelectField и имеют поле options, в котором содержится идентификатор каждого варианта для одиночного выбора. Поля итерации возвращаются в формате объекта ProjectV2IterationField и содержат поле configuration, в котором есть поле iterations с идентификатором каждой итерации и сведениями о ней.

Если вам нужны только имя и идентификатор поля, но не нужны сведения об итерациях и вариантах для поля с одиночным выбором, можно использовать объект ProjectV2FieldCommon.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"query{ node(id: \"PROJECT_ID\") { ... on ProjectV2 { fields(first: 20) { nodes { ... on ProjectV2FieldCommon { id name }}}}}}"}'
gh api graphql -f query='
  query{
  node(id: "PROJECT_ID") {
    ... on ProjectV2 {
      fields(first: 20) {
        nodes {
          ... on ProjectV2FieldCommon {
            id
            name
          }
        }
      }
    }
  }
}'

При использовании объекта ProjectV2FieldCommon вы получите ответ следующего вида:

{
  "data": {
    "node": {
      "fields": {
        "nodes": [
          {
            "__typename": "ProjectV2Field",
            "id": "PVTF_lADOANN5s84ACbL0zgBZrZY",
            "name": "Title"
          },
          {
            "__typename": "ProjectV2Field",
            "id": "PVTF_lADOANN5s84ACbL0zgBZrZc",
            "name": "Assignees"
          },
          {
            "__typename": "ProjectV2SingleSelectField",
            "id": "PVTSSF_lADOANN5s84ACbL0zgBZrZg",
            "name": "Status"
          },
          {
            "__typename": "ProjectV2IterationField",
            "id": "PVTIF_lADOANN5s84ACbL0zgBah28",
            "name": "Iteration"
          }
        ]
      }
    }
  }
}

Поиск сведений о элементах в проекте

Вы можете создать запрос к API, чтобы найти сведения о элементах проекта.

В следующем примере будут возвращены первые 20 проблем, запросов на вытягивание и черновиков проблем в проекте. Для проблем и запросов на вытягивание он также вернет заголовок и первые 10 уполномоченных. Для черновика проблемы он вернет заголовок и текст. Также в этом примере возвращаются имя и значение для любого поля с текстом, датой или единичным выбором из первых 8 полей проекта. Замените PROJECT_ID идентификатором узла для проекта.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"query{ node(id: \"PROJECT_ID\") { ... on ProjectV2 { items(first: 20) { nodes{ id fieldValues(first: 8) { nodes{ ... on ProjectV2ItemFieldTextValue { text field { ... on ProjectV2FieldCommon { name }}} ... on ProjectV2ItemFieldDateValue { date field { ... on ProjectV2FieldCommon { name } } } ... on ProjectV2ItemFieldSingleSelectValue { name field { ... on ProjectV2FieldCommon { name }}}}} content{ ... on DraftIssue { title body } ...on Issue { title assignees(first: 10) { nodes{ login }}} ...on PullRequest { title assignees(first: 10) { nodes{ login }}}}}}}}}"}'
gh api graphql -f query='
  query{
    node(id: "PROJECT_ID") {
        ... on ProjectV2 {
          items(first: 20) {
            nodes{
              id
              fieldValues(first: 8) {
                nodes{
                  ... on ProjectV2ItemFieldTextValue {
                    text
                    field {
                      ... on ProjectV2FieldCommon {
                        name
                      }
                    }
                  }
                  ... on ProjectV2ItemFieldDateValue {
                    date
                    field {
                      ... on ProjectV2FieldCommon {
                        name
                      }
                    }
                  }
                  ... on ProjectV2ItemFieldSingleSelectValue {
                    name
                    field {
                      ... on ProjectV2FieldCommon {
                        name
                      }
                    }
                  }
                }
              }
              content{
                ... on DraftIssue {
                  title
                  body
                }
                ...on Issue {
                  title
                  assignees(first: 10) {
                    nodes{
                      login
                    }
                  }
                }
                ...on PullRequest {
                  title
                  assignees(first: 10) {
                    nodes{
                      login
                    }
                  }
                }
              }
            }
          }
        }
      }
    }'

Проект может содержать элементы, для которых у пользователя нет разрешения на просмотр. В этом случае возвращается тип элемента REDACTED.

Обновление проектов

Используйте изменения для обновления проектов. Дополнительные сведения см. в разделе Формирование вызовов с помощью GraphQL.

Примечание.

Невозможно добавить и обновить элемент в том же вызове. Необходимо использовать addProjectV2ItemById для добавления элемента, а затем использовать updateProjectV2ItemFieldValue для обновления элемента.

Добавление элемента в проект

В следующем примере в проект будет добавлена проблема или запрос на вытягивание. Замените PROJECT_ID идентификатором узла для проекта. Замените CONTENT_ID идентификатором узла проблемы или запроса на вытягивание, который вы хотите добавить.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {addProjectV2ItemById(input: {projectId: \"PROJECT_ID\" contentId: \"CONTENT_ID\"}) {item {id}}}"}'
gh api graphql -f query='
  mutation {
    addProjectV2ItemById(input: {projectId: "PROJECT_ID" contentId: "CONTENT_ID"}) {
      item {
        id
      }
    }
  }'

Ответ будет содержать идентификатор узла только что созданного элемента.

{
  "data": {
    "addProjectV2ItemById": {
      "item": {
        "id": "PVTI_lADOANN5s84ACbL0zgBVd94"
      }
    }
  }
}

При попытке добавить существующий элемент будет возвращен идентификатор уже существующего элемента.

Добавление черновика проблемы в проект

В следующем примере в проект будет добавлен черновик проблемы. Замените PROJECT_ID идентификатором узла для проекта. Замените TITLE и BODY нужным содержимым для нового черновика проблемы.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {addProjectV2DraftIssue(input: {projectId: \"PROJECT_ID\" title: \"TITLE\" body: \"BODY\"}) {projectItem {id}}}"}'
gh api graphql -f query='
  mutation {
    addProjectV2DraftIssue(input: {projectId: "PROJECT_ID" title: "TITLE" body: "BODY"}) {
      projectItem {
        id
      }
    }
  }'

Ответ будет содержать идентификатор узла только что созданного черновика проблемы.

{
  "data": {
    "addProjectV2DraftIssue": {
      "projectItem": {
        "id": "PVTI_lADOANN5s84ACbL0zgBbxFc"
      }
    }
  }
}

Обновление параметров проекта

В следующем примере будут обновлены параметры проекта. Замените PROJECT_ID идентификатором узла для проекта. Установите для public``true общедоступного проекта GitHub. Измените параметр readme, чтобы внести изменения в файл README проекта.

curl --request POST \
--url https://api.github.com/graphql \
--header 'Authorization: Bearer TOKEN' \
--data '{"query":"mutation { updateProjectV2(input: { projectId: \"PROJECT_ID\", title: \"Project title\", public: false, readme: \"# Project README\n\nA long description\", shortDescription: \"A short description\"}) { projectV2 { id, title, readme, shortDescription }}}"}'
gh api graphql -f query='
  mutation {
    updateProjectV2(
      input: {
        projectId: "PROJECT_ID",
        title: "Project title",
        public: false,
        readme: "# Project README\n\nA long description",
        shortDescription: "A short description"
      }
    ) {
      projectV2 {
        id
        title
        readme
        shortDescription
      }
    }
  }'

Обновление настраиваемого поля текста, числа или даты

В следующем примере будет обновлено значение текстового поля для элемента. Замените PROJECT_ID идентификатором узла для проекта. Замените ITEM_ID идентификатором узла элемента, который нужно обновить. Замените FIELD_ID идентификатором поля, которое нужно обновить.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {updateProjectV2ItemFieldValue( input: { projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: { text: \"Updated text\" }}) { projectV2Item { id }}}"}'
gh api graphql -f query='
  mutation {
    updateProjectV2ItemFieldValue(
      input: {
        projectId: "PROJECT_ID"
        itemId: "ITEM_ID"
        fieldId: "FIELD_ID"
        value: {
          text: "Updated text"
        }
      }
    ) {
      projectV2Item {
        id
      }
    }
  }'

Примечание.

Нельзя использовать updateProjectV2ItemFieldValue для изменения Assignees, Labels``MilestoneилиRepository, так как эти поля являются свойствами запросов на вытягивание и проблем, а не элементов проекта. Вместо этого можно использовать следующие изменения:

          [addAssigneesToAssignable](/graphql/reference/mutations#addassigneestoassignable)
          [removeAssigneesFromAssignable](/graphql/reference/mutations#removeassigneesfromassignable)
          [addLabelsToLabelable](/graphql/reference/mutations#addlabelstolabelable)
          [removeLabelsFromLabelable](/graphql/reference/mutations#removelabelsfromlabelable)
          [updateIssue](/graphql/reference/mutations#updateissue)
          [updatePullRequest](/graphql/reference/mutations#updatepullrequest)
          [transferIssue](/graphql/reference/mutations#transferissue)

Обновление поля одиночного выбора

В следующем примере будет обновлено значение поля одиночного выбора для элемента.

  •         `PROJECT_ID` — замените идентификатором узла для проекта.
    
  •         `ITEM_ID` — замените идентификатором узла элемента, который нужно обновить.
    
  •         `FIELD_ID` — замените идентификатором поля одиночного выбора, которое нужно обновить.
    
  •         `OPTION_ID` — замените идентификатором нужного параметра одиночного выбора.
    
curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {updateProjectV2ItemFieldValue( input: { projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: { singleSelectOptionId: \"OPTION_ID\" }}) { projectV2Item { id }}}"}'
gh api graphql -f query='
  mutation {
    updateProjectV2ItemFieldValue(
      input: {
        projectId: "PROJECT_ID"
        itemId: "ITEM_ID"
        fieldId: "FIELD_ID"
        value: {
          singleSelectOptionId: "OPTION_ID"
        }
      }
    ) {
      projectV2Item {
        id
      }
    }
  }'

Обновление поля итерации

В следующем примере будет обновлено значение поля итерации для элемента.

  •         `PROJECT_ID` — замените идентификатором узла для проекта.
    
  •         `ITEM_ID` — замените идентификатором узла элемента, который нужно обновить.
    
  •         `FIELD_ID` — замените идентификатором поля итерации, которое нужно обновить.
    
  •         `ITERATION_ID` — замените идентификатором требуемой итерации. Это может быть активная или завершенная итерация.
    
curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {updateProjectV2ItemFieldValue( input: { projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\" fieldId: \"FIELD_ID\" value: { iterationId: \"ITERATION_ID\" }}) { projectV2Item { id }}}"}'
gh api graphql -f query='
  mutation {
    updateProjectV2ItemFieldValue(
      input: {
        projectId: "PROJECT_ID"
        itemId: "ITEM_ID"
        fieldId: "FIELD_ID"
        value: {
          iterationId: "ITERATION_ID"
        }
      }
    ) {
      projectV2Item {
        id
      }
    }
  }'

Удаление элемента из проекта

В следующем примере элемент удаляется из проекта. Замените PROJECT_ID идентификатором узла для проекта. Замените ITEM_ID идентификатором узла элемента, который нужно удалить.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: Bearer TOKEN' \
  --data '{"query":"mutation {deleteProjectV2Item(input: {projectId: \"PROJECT_ID\" itemId: \"ITEM_ID\"}) {deletedItemId}}"}'
gh api graphql -f query='
  mutation {
    deleteProjectV2Item(
      input: {
        projectId: "PROJECT_ID"
        itemId: "ITEM_ID"
      }
    ) {
      deletedItemId
    }
  }'

Управление проектами

Создание проектов

Для создания нового проекта можно использовать мутацию. Дополнительные сведения см. в разделе Формирование вызовов с помощью GraphQL.

Чтобы создать проект с помощью API, необходимо указать имя проекта и идентификатор узла пользователя GitHub пользователя или организации, которая станет владельцем проекта.

Идентификатор узла переменных данных GitHub можно найти, если вы знаете имя пользователя. Замените GITHUB_OWNER именем пользователя GitHub нового владельца проекта.

curl --request GET \
  --url https://api.github.com/users/GITHUB_OWNER \
  --header 'Authorization: token TOKEN' \
  --header 'Accept: application/vnd.github+json'
gh api -H "Accept: application/vnd.github+json" /users/GITHUB_OWNER

Чтобы создать проект, замените OWNER_ID идентификатор узла нового владельца проекта и замените PROJECT_NAME именем проекта.

curl --request POST \
  --url https://api.github.com/graphql \
  --header 'Authorization: token TOKEN' \
  --data '{"query":"mutation {createProjectV2(input: {ownerId: \"OWNER_ID\" title: \"PROJECT_NAME\"}) {projectV2 {id}}}"}'
gh api graphql -f query='
  mutation{
    createProjectV2(
      input: {
        ownerId: "OWNER_ID",
        title: "PROJECT_NAME"
      }
    ){
      projectV2 {
        id
      }
     }
  }'

Использование веб-перехватчиков

Вы можете использовать веб-перехватчики для подписки на события, происходящие в проекте. Например, когда элемент редактируется, GitHub может отправлять полезные данные HTTP POST на настроенный URL-адрес веб-перехватчика, который может активировать автоматизацию на сервере. Дополнительные сведения о веб-перехватчиках см. в разделе Сведения о веб-перехватчиках. Дополнительные сведения о событии projects_v2_item веб-перехватчика см. в разделе События и полезные данные веб-перехватчика.