Skip to main content

Automatizar proyectos (beta)

Puedes utiilzar flujos de trabajo integrados o la API y las GitHub Actions para administrar tus proyectos.

Nota: Los proyectos (beta) se encuentran en beta público y están sujetos a cambios.

Introducción

Puedes agregar automatización para ayudarte a administrar tu proyecto. Los proyectos (beta) incluyen flujos de trabajo integrados que puedes configurar a través de la IU. Adicionalmente, puedes escribir flujos personalizados con la API de GraphQL y las GitHub Actions.

Flujos de trabajo integrados

Los proyectos (beta) incluyen flujos de trabajo integrados que puedes utilizar para actualizar el Estado de los elementos con base en ciertos eventos. Por ejemplo, puedes configurar automáticamente el estado a Pendiente cuando se agrega un elemento a tu proyecto o configurarlo en Hecho cuando se cierre una propuesta.

Cuando inicializa tu proyecto, se habilitan dos flujos de trabajo predeterminadamente: Cuando se cierran las propuestas o solicitudes de cambio de tu proyecto, su estado se muestra como Done y cuando estas se fusionan, se muestra también como Done.

Puedes habilitar o inhabilitar los flujos de trabajo integrados de tu proyecto.

  1. Navegar a tu proyecto.
  2. En la parte superior derecha, haz clic en para abrir el menú.
  3. En el menú, haz clic en Flujos de trabajo.
  4. Debajo de Flujos de trabajo predeterminados, haz clic en el flujo de trabajo que quieres editar.
  5. Si el flujo de trabajo puede aplicarse a ambos resultados y solicitudes de cambio, junto a Dónde, verifica el(los) tipo(s) de elemento(s) sobre el(los) cuál(es) quieres actuar.
  6. Junto a Configurar, elige el valor en el cual quieres configurar al estado.
  7. Si el flujo de trabajo se inhabilita, haz clic en el alternador junto a Inhabilitado para habilitarlo.

Flujos de trabajo de GitHub Actions

Esta sección demuestra cómo utilizar la API de GraphQL y las GitHub Actions para agregar una solicitud de cambios a un proyecto organizacional. En los flujos de trabajo de ejemplo, cuando la solicitud de cambios se marca como "lista para revisión", se agrega una tarea nueva al proyecto con un campo de "Estado" configurado en "Pendiente" y se agrega la fecha actual a un campo personalizado de "Fecha en la que se publicó".

Puedes copiar uno de los siguientes flujos de trabajo y modificarlo de acuerdo con lo descrito en la siguiente tabla para que satisfaga tus necesidades.

Un proyecto puede abarcar repositorios múltiples, pero un flujo de trabajo es específico par aun repositorio. Agrega el flujo de trabajo a cada repositorio que quieras que rastree tu proyecto. Para obtener más información sobre cómo crear archivos de flujo de trabajo, consulta la sección "Inicio rápido para las GitHub Actions".

Este artículo asume que tienes un entendimiento básico de las GitHub Actions. Para obtener más información acerca de GitHub Actions, consulta la sección "GitHub Actions".

Para obtener más información sobre otros cambios que puedes hacer a tu proyecto a través de la API, consulta la sección "Utilizar la API para administrar proyectos".

Nota: GITHUB_TOKEN tiene el alcance del nivel de repositorio y no puede acceder a los proyectos (beta). Para acceder a los proyectos (beta), puedes ya sea crear una GitHub App (recomendado para los proyectos organizacionales) o un token de acceso personal (recomendado para los proyectos de usuario). A continuación se muestran los ejemplos de flujo de trabajo para ambos acercamientos.

Flujo de trabajo ejemplo autenticándose con una GitHub App

  1. Crea una GitHub App o elige una GitHub App existente que le pertenezca a tu organización. Para obtener más información, consulta la sección "Crear una GitHub App".

  2. Dale a tu GitHub App permisos de lectura y escritura para los proyectos organizacionales. Para obtener más información, consulta la sección "Editar los permisos de una GitHub App".

    Nota: Puedes controlar los permisos de tu app con respecto a los proyectos organizacionales y de repositorio. Debes otorgar permisos de lectura y escritura de proyectos organizacionales; los permisos de lectura y escritura en los proyectos de repositorio no serán suficientes.

  3. Instala la GitHub App en tu organización. Instálala para todos los repositorios a los cuales necesita acceso tu proyecto. Para obtener más información, consulta la sección "Instalar GitHub Apps".

  4. Almacena la ID de tu GitHub App como un secreto en tu repositorio u organización. En el siguiente flujo de trabajo, reemplaza APP_ID con el nombre del secreto. Puedes encontrar tu ID de app en la página de ajustes de tu app o mediante la API de la misma. Para obtener más información, consulta la sección "Apps".

  5. Generar una llave privada para tu app. Almacena el contenido del archivo resultante como secreto en tu repositorio u organización. (Almacena todo el contenido del archivo, incluyendo -----BEGIN RSA PRIVATE KEY----- y -----END RSA PRIVATE KEY-----.) En el siguiente flujo de trabajo, reemplaza a APP_PEM con el nombre del secreto. Para obtener más información, consulta la sección "Autenticarse con GitHub Apps".

  6. En el siguiente flujo de trabajo, reemplaza a YOUR_ORGANIZATION con el nombre de tu organización. Por ejemplo, octo-org. Reemplaza a YOUR_PROJECT_NUMBER con el número de tu proyecto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, la dirección https://github.com/orgs/octo-org/projects/5 tiene "5" como número de proyecto.

YAML
# This workflow uses actions that are not certified by GitHub.
# Estas las proporcionan entidades terceras y las gobiernan
# condiciones de servicio, políticas de privacidad y documentación de soporte
# documentación.

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

Flujo de trabajo de ejemplo para autenticarse con un token de acceso personal

  1. Crear un token de acceso personal con el alcance org:write. Para obtener más información, consulta la sección "Crear un token de acceso personal".
  2. Guardar el token de acceso personal como secreto en tu organización o repositorio.
  3. En el siguiente flujo de trabajo, reemplaza a YOUR_TOKEN con el nombre del secreto. Reemplaza a YOUR_ORGANIZATION con el nombre de tu organización. Por ejemplo, octo-org. Reemplaza a YOUR_PROJECT_NUMBER con el número de tu proyecto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, la dirección https://github.com/orgs/octo-org/projects/5 tiene "5" como número de proyecto.
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

Explicación del flujo de trabajo

La siguiente tabla explica las secciones de los flujos de trabajo de ejemplo y te muestra cómo adaptar los flujos de trabajo para tu propio uso.

on:
  pull_request:
    types:
      - ready_for_review
Este flujo de trabajo se ejecuta cada que una solicitud de cambios en el repositorio se marca como "ready for review".

GitHub App only:

- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
  with:
    app_id: ${{ secrets.APP_ID }}
    private_key: ${{ secrets.APP_PEM }}
Utiliza la acción tibdex/github-app-token para generar un token de acceso a la instalación para tu app desde la ID y llave privada de la misma. Se puede acceder al token de acceso a la instalación más adelante en el flujo de trabajo como ${{ steps.generate_token.outputs.token }}.

Reemplaza APP_ID con el nombre del secreto que contiene la ID de tu app.

Reemplaza a APP_PEM con el nombre del secreto que contiene la llave privada de tu app.

GitHub App:

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
Configura las variables para este paso.

Si estás utilizando un token de acceso personal, reemplaza a YOUR_TOKEN con el nombre del secreto que contiene tu token de acceso personal.

Reemplaza YOUR_ORGANIZATION con el nombre de tu organización. Por ejemplo, octo-org.

reemplaza YOUR_PROJECT_NUMBER con el número de tu proeycto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, la dirección https://github.com/orgs/octo-org/projects/5 tiene "5" como número de proyecto.
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
Utiliza el CLI de GitHub para consultar la API para la ID del proyecto y para la ID, nombre y configuración de los primeros 20 campos en este. La respuesta se almacena en un archivo que se llama 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
Analiza la respuesta desde la consulta de la API y almacena las ID relevantes como variables de ambiente. Modifica esto para obtener la ID para los campos u opciones diferentes. Por ejemplo:
  • Para obtener la ID de un campo llamado Team, agrega echo 'TEAM_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV.
  • Para obtener la ID de una opción llamada Octoteam para el campo Team, agrega 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
Nota: Este flujo de trabajo asume que tienes un proyecto con un campo de selección simple llamado "Status" que incluye una opción llamada "Todo" y un campo de fecha llamado "Date Posted". Debes modificar esta sección para empatar con los campos que están presentes en tu tabla.

GitHub App:

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 }}
Configura las variables para este paso. GITHUB_TOKEN se describe anteriormente. PR_ID es la ID de la solicitud de cambios que activó este flujo de trabajo.
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')"
Utiliza el CLI de GitHub y la API para agrega la solicitud de cambios que activó este flujo de trabajo hacia el proyecto. La bandera jq analiza la respuesta para obtener la ID del elemento creado.
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
Almacena la ID del elemento creado como variable de ambiente.
echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
Guarda la fecha actual como variable de ambiente en el formato yyyy-mm-dd.

GitHub App:

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

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
Configura las variables para este paso. GITHUB_TOKEN se describe anteriormente.
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
Configura el valor del campo Status como Todo. Configura el valor del campo Date posted.