Skip to main content

Automatizando projetos (beta)

Você pode usar fluxos de trabalho integrados ou a API e GitHub Actions para gerenciar seus projetos.

Note: Projects (beta) is currently in public beta and subject to change.

Introdução

Você pode adicionar a automação para ajudar a gerenciar seu projeto. Os projetos (beta) incluem fluxos de trabalho internos que você pode configurar por meio da interface do usuário. Além disso, você pode escrever fluxos de trabalho personalizados com a API do GraphQL e GitHub Actions.

Fluxos de trabalho integrados

Projects (beta) includes built-in workflows that you can use to update the Status of items based on certain events. For example, you can automatically set the status to Todo when an item is added to your project or set the status to Done when an issue is closed.

When your project initializes, two workflows are enabled by default: When issues or pull requests in your project are closed, their status is set to Done, and when pull requests in your project are merged, their status is set to Done.

Você pode habilitar ou desabilitar os fluxos de trabalho internos para o seu projeto.

  1. Navigate to your project.
  2. In the top-right, click to open the menu.
  3. In the menu, click Workflows.
  4. Under Default workflows, click on the workflow that you want to edit.
  5. If the workflow can apply to both issues and pull requests, next to When, check the item type(s) that you want to act on.
  6. Next to Set, choose the value that you want to set the status to.
  7. If the workflow is disabled, click the toggle next to Disabled to enable the workflow.

Fluxos de trabalho GitHub Actions

Esta seção demonstra como usar a API do GraphQL e GitHub Actions para adicionar um pull request a um projeto da organização. No exemplo de fluxos de trabalho, quando o pull request é marcado como "pronto para revisão", uma nova tarefa é adicionada ao projeto com um campo "Status" definido como "Todo", e a data atual é adicionada a um campo personalizado "Data de postagem".

Você pode copiar um dos fluxos de trabalho abaixo e modificá-lo conforme descrito na tabela abaixo para atender às suas necessidades.

Um projeto pode incluir vários repositórios, mas um fluxo de trabalho é específico para um repositório. Adicione o fluxo de trabalho a cada repositório que você deseja que seu projeto monitore. Para obter mais informações sobre como criar arquivos de fluxo de trabalho, consulte "Início rápido para GitHub Actions".

Este artigo pressupõe que você tem um entendimento básico de GitHub Actions. Para obter mais informações sobre GitHub Actions, consulte "GitHub Actions.

Para obter mais informações sobre outras alterações que você pode fazer no seu projeto por meio da API, consulte "Usando a API para gerenciar projetos".

Observação: GITHUB_TOKEN tem o escopo para o nível de repositório e não pode acessar projetos (beta). Para acessar projetos (beta) você pode criar um aplicativo GitHub (recomendado para projetos organizacionais) ou um token de acesso pessoal (recomendado para projetos de usuários). Exemplos de fluxo de trabalho para ambas as abordagens são mostrados abaixo.

Exemplo de fluxo de trabalho que efetua a autenticação com um aplicativo GitHub

  1. Crie um aplicativo GitHub ou escolha um aplicativo GitHub existente pertencente à sua organização. Para obter mais informações, consulte "Criando um aplicativo GitHub."

  2. Dê as suas permissões de leitura e gravação de aplicativo GitHub para projetos de organização. Para obter mais informações, consulte "Editando as permissões de aplicativo GitHubde."

    Observação: Você pode controlar a permissão do seu aplicativo para projetos de organização e projetos de repositório. Você deve dar permissão de leitura e gravação de projetos de organização; a permissão de leitura e gravação para projetos de repositório não será suficiente.

  3. Instale o aplicativo GitHub na sua organização. Instale-o em todos os repositórios que o seu projeto precisa acessar. Para obter mais informações, consulte "Instalando Aplicativos do GitHub."

  4. Armazene o ID do seu aplicativo GitHub como um segredo no seu repositório ou organização. No fluxo de trabalho a seguir, substitua APP_ID pelo nome do segredo. Você pode encontrar o ID do seu aplicativo na página de configurações do seu aplicativo ou por meio da API do aplicativo. Para obter mais informações, consulte "Aplicativos".

  5. Gerar uma chave privada para o seu aplicativo. Armazene o conteúdo do arquivo resultante como um segredo no seu repositório ou organização. (Armazene todo o conteúdo do arquivo, incluindo -----BEGIN RSA PRIVATE KEY----- e -----END RSA PRIVATE KEY-----.) No fluxo de trabalho a seguir, substitua APP_PEM pelo nome do segredo. Para obter mais informações, consulte "Efetuando a autenticação com o Aplicativos do GitHub".

  6. No fluxo de trabalho a seguir, substitua YOUR_ORGANIZATION pelo nome da sua organização. Por exemplo, octo-org. Substitua YOUR_PROJECT_NUMBER pelo número do seu projeto. Para encontrar o número do projeto, consulte a URL do projeto. Por exemplo, https://github.com/orgs/octo-org/projects/5 tem um número de projeto de 5.

YAML
# This workflow uses actions that are not certified by GitHub.
# São fornecidas por terceiros e regidas por
# termos de serviço, política de privacidade e suporte separados
# documentação.

name: Add PR to project
on:
  pull_request:
    types:
      - ready_for_review
jobs:
  track_pr:
    runs-on: ubuntu-latest
    steps:
      - name: Generate token
        id: generate_token
        uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PEM }}

      - name: Get project data
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          ORGANIZATION: YOUR_ORGANIZATION
          PROJECT_NUMBER: YOUR_PROJECT_NUMBER
        run: |
          gh api graphql -f query='
            query($org: String!, $number: Int!) {
              organization(login: $org){
                projectNext(number: $number) {
                  id
                  fields(first:20) {
                    nodes {
                      id
                      name
                      settings
                    }
                  }
                }
              }
            }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json

          echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
          echo 'DATE_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
          echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
          echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV

      - name: Add PR to project
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
          PR_ID: ${{ github.event.pull_request.node_id }}
        run: |
          item_id="$( gh api graphql -f query='
            mutation($project:ID!, $pr:ID!) {
              addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
                projectNextItem {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"

          echo 'ITEM_ID='$item_id >> $GITHUB_ENV

      - name: Get date
        run: echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV

      - name: Set fields
        env:
          GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
        run: |
          gh api graphql -f query='
            mutation (
              $project: ID!
              $item: ID!
              $status_field: ID!
              $status_value: String!
              $date_field: ID!
              $date_value: String!
            ) {
              set_status: updateProjectNextItemField(input: {
                projectId: $project
                itemId: $item
                fieldId: $status_field
                value: $status_value
              }) {
                projectNextItem {
                  id
                  }
              }
              set_date_posted: updateProjectNextItemField(input: {
                projectId: $project
                itemId: $item
                fieldId: $date_field
                value: $date_value
              }) {
                projectNextItem {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.TODO_OPTION_ID }} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent

Exemplo de fluxo de trabalho que efetua a autenticação com um token de acesso pessoal

  1. Crie um token de acesso pessoal com escopo org:write. Para obter mais informações, consulte "Criando um token de acesso pessoal."
  2. Salve o token de acesso pessoal como um segredo no seu repositório ou organização.
  3. No fluxo de trabalho a seguir, substitua YOUR_TOKEN pelo nome do segredo. Substitua YOUR_ORGANIZATION pelo nome da sua organização. Por exemplo, octo-org. Substitua YOUR_PROJECT_NUMBER pelo número do seu projeto. Para encontrar o número do projeto, consulte a URL do projeto. Por exemplo, https://github.com/orgs/octo-org/projects/5 tem um número de projeto de 5.
YAML
name: Add PR to project
on:
  pull_request:
    types:
      - ready_for_review
jobs:
  track_pr:
    runs-on: ubuntu-latest
    steps:
      - name: Get project data
        env:
          GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
          ORGANIZATION: YOUR_ORGANIZATION
          PROJECT_NUMBER: YOUR_PROJECT_NUMBER
        run: |
          gh api graphql -f query='
            query($org: String!, $number: Int!) {
              organization(login: $org){
                projectNext(number: $number) {
                  id
                  fields(first:20) {
                    nodes {
                      id
                      name
                      settings
                    }
                  }
                }
              }
            }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json

          echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
          echo 'DATE_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
          echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
          echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV

      - name: Add PR to project
        env:
          GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
          PR_ID: ${{ github.event.pull_request.node_id }}
        run: |
          item_id="$( gh api graphql -f query='
            mutation($project:ID!, $pr:ID!) {
              addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
                projectNextItem {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"

          echo 'ITEM_ID='$item_id >> $GITHUB_ENV

      - name: Get date
        run: echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV

      - name: Set fields
        env:
          GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
        run: |
          gh api graphql -f query='
            mutation (
              $project: ID!
              $item: ID!
              $status_field: ID!
              $status_value: String!
              $date_field: ID!
              $date_value: String!
            ) {
              set_status: updateProjectNextItemField(input: {
                projectId: $project
                itemId: $item
                fieldId: $status_field
                value: $status_value
              }) {
                projectNextItem {
                  id
                  }
              }
              set_date_posted: updateProjectNextItemField(input: {
                projectId: $project
                itemId: $item
                fieldId: $date_field
                value: $date_value
              }) {
                projectNextItem {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.TODO_OPTION_ID }} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent

Explicação do fluxo de trabalho

A tabela a seguir explica as seções dos fluxos de trabalho de exemplo e mostra como adaptar os fluxos de trabalho para seu próprio uso.

on:
  pull_request:
    types:
      - ready_for_review
Este fluxo de trabalho é executado sempre que um pull request no repositório for marcado como "pronto para revisão".

aplicativo GitHub only:

- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
  with:
    app_id: ${{ secrets.APP_ID }}
    private_key: ${{ secrets.APP_PEM }}
Usa a ação tibdex/github-app-token para gerar um token de acesso da instalação para o seu aplicativo no ID do aplicativo e chave privada. O token de acesso da instalação é acessado mais adiante no fluxo de trabalho como ${{ steps.generate_token.outputs.token }}.

Substitua APP_ID pelo nome do segredo que contém o ID do seu aplicativo.

Substita APP_PEM pelo nome do segredo que contém a chave privada do seu aplicativo.

aplicativo GitHub:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
  ORGANIZATION: YOUR_ORGANIZATION
  PROJECT_NUMBER: YOUR_PROJECT_NUMBER

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
  ORGANIZATION: YOUR_ORGANIZATION
  PROJECT_NUMBER: YOUR_PROJECT_NUMBER
Define variáveis de ambiente para esta etapa.

Se você estiver usando um token de acesso pessoal, substitua YOUR_TOKEN pelo nome do segredo que contém o seu token de acesso pessoal.

Substitua YOUR_ORGANIZATION pelo nome da sua organização. Por exemplo, octo-org.

Substitua YOUR_PROJECT_NUMBER pelo número do seu projeto. Para encontrar o número do projeto, consulte a URL do projeto. Por exemplo, https://github.com/orgs/octo-org/projects/5 tem um número de projeto de 5.
gh api graphql -f query='
  query($org: String!, $number: Int!) {
    organization(login: $org){
      projectNext(number: $number) {
        id
        fields(first:20) {
          nodes {
            id
            name
            settings
          }
        }
      }
    }
  }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
Usa GitHub CLI para consultar a API para o ID do projeto e para o ID, nome e configurações para os primeiros 20 campos do projeto. A resposta é armazenada em um arquivo denominado project_data.json.
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
Analisa a resposta da consulta da API e armazena os IDs relevantes como variáveis de ambiente. Modifique este ID para obter o ID para diferentes campos ou opções. Por exemplo:
  • Para obter o ID de um campo denominado Team, adicione echo 'TEAM_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV.
  • Para obter o ID de uma opção denominada Octoteam para o campo Team, adicione echo 'OCTOTEAM_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Team") |.settings | fromjson.options[] | select(.name=="Octoteam") |.id' project_data.json) >> $GITHUB_ENV
Observação: Este fluxo de trabalho pressupõe que você tem um projeto com um único campo selecionado denominado "Status" que inclui uma opção denominada "Todo" e um campo de data denominado "Date posted". Você deve modificar esta seção para corresponder aos campos presentes na sua tabela.

aplicativo GitHub:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
  PR_ID: ${{ github.event.pull_request.node_id }}

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
  PR_ID: ${{ github.event.pull_request.node_id }}
Define variáveis de ambiente para esta etapa. GITHUB_TOKEN está descrito acima. PR_ID é o ID do pull request que acionou este fluxo de trabalho.
item_id="$( gh api graphql -f query='
  mutation($project:ID!, $pr:ID!) {
    addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
      projectNextItem {
        id
      }
    }
  }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
Usa GitHub CLI e a API para adicionar o pull request que acionou este fluxo de trabalho ao projeto. O jq analisa a resposta para obter o ID do item criado.
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
Armazena o ID do item criado como uma variável de ambiente.
echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
Salva a data atual como uma variável de ambiente no formato yyyy-mm-dd.

aplicativo GitHub:

env:
  GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
Define variáveis de ambiente para esta etapa. GITHUB_TOKEN está descrito acima.
gh api graphql -f query='
  mutation (
    $project: ID!
    $item: ID!
    $status_field: ID!
    $status_value: String!
    $date_field: ID!
    $date_value: String!
  ) {
    set_status: updateProjectNextItemField(input: {
      projectId: $project
      itemId: $item
      fieldId: $status_field
      value: $status_value
    }) {
      projectNextItem {
        id
        }
    }
    set_date_posted: updateProjectNextItemField(input: {
      projectId: $project
      itemId: $item
      fieldId: $date_field
      value: $date_value
    }) {
      projectNextItem {
        id
      }
    }
  }' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.TODO_OPTION_ID }} -f date_field=$DATE_FIELD_ID -f date_value=$DATE --silent
Define o valor do campo Status como Todo. Define o valor do campo Date posted.