В этой статье показано, как использовать 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
, поскольку эти поля являются свойствами запросов на вытягивание и проблем, а не элементов проекта. Вместо этого можно использовать следующие изменения:
Обновление поля одиночного выбора
В следующем примере будет обновлено значение поля одиночного выбора для элемента.
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
веб-перехватчика см. в разделе "События и полезные данные веб-перехватчика".