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.

Note

Невозможно добавить и обновить элемент в том же вызове. Необходимо использовать 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
      }
    }
  }'

Note

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

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

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

  • 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 веб-перехватчика см. в разделе "События и полезные данные веб-перехватчика".