Skip to main content
Publicamos actualizaciones para la documentación con frecuencia y es posible que aún se esté traduciendo esta página. Para obtener la información más reciente, consulta la documentación en inglés.

Automatización de Projects mediante acciones

Puedes usar GitHub Actions para automatizar los proyectos.

Flujos de trabajo de GitHub Actions

Este artículo 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 del que quieras que realice un seguimiento el proyecto. Para obtener más información sobre cómo crear archivos de flujo de trabajo, consulta "Guía de inicio rápido para GitHub Actions".

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

Para obtener más información sobre otros cambios que puedes realizar en el proyecto mediante la API, consulta "Uso de la API para administrar instancias de Projects".

También puedes usar el flujo de trabajo actions/add-to-project, que mantiene GitHub y agregará la incidencia o solicitud de incorporación de cambios actual al proyecto especificado. Para más información, consulta el repositorio actions/add-to-project y el archivo LÉAME.

Nota: GITHUB_TOKEN tiene como ámbito el nivel de repositorio y no puede acceder a projects. Para acceder a projects, puedes crear una GitHub App (recomendado para proyectos de la organización) o un personal access token (recomendado para 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

Para más información sobre la autenticación en un flujo de trabajo de GitHub Actions con una GitHub App, consulta "Realización de solicitudes de API autenticadas con una aplicación de GitHub en un flujo de trabajo de Acciones de GitHub".

  1. Crea una GitHub App o elige una GitHub App existente que le pertenezca a tu organización. Para obtener más información, vea «Registering a GitHub App».

  2. Dale a tu GitHub App permisos de lectura y escritura para los proyectos organizacionales. En este ejemplo concreto, tu GitHub App también necesitará permisos de lectura para las PR del repositorio y las incidencias del repositorio. Para obtener más información, vea «Modifying a GitHub App registration».

    Nota: Puede controlar el permiso de la aplicación para los proyectos de la organización y para los proyectos del 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, vea «Installing your own GitHub App».

  4. Almacena la ID de tu GitHub App como un secreto en tu repositorio u organización. En el flujo de trabajo siguiente, reemplace APP_ID por 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, vea «Aplicaciones».

  5. Generar una llave privada para tu app. Almacena el contenido del archivo resultante como secreto en tu repositorio u organización. (Almacene todo el contenido del archivo, incluido el contenido de -----BEGIN RSA PRIVATE KEY----- y -----END RSA PRIVATE KEY-----). En el flujo de trabajo siguiente, reemplace APP_PEM por el nombre del secreto. Para obtener más información, vea «Administración de claves privadas para aplicaciones de GitHub».

  6. En el flujo de trabajo siguiente, reemplace YOUR_ORGANIZATION por el nombre de la organización. Por ejemplo: octo-org. Reemplace YOUR_PROJECT_NUMBER por el número del proyecto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, https://github.com/orgs/octo-org/projects/5 tiene "5" como número de proyecto. Para que este ejemplo concreto funcione, el proyecto también debe tener un campo de fecha "Fecha de publicación".

YAML
# Este flujo de trabajo usa acciones que no GitHub no certifica.
# Estas las proporcionan entidades terceras y las gobiernan
# condiciones de servicio, políticas de privacidad y documentación de soporte
# en línea.

# GitHub recomienda anclar acciones a un SHA de confirmación.
# Para obtener una versión más reciente, debes actualizar el SHA.
# También puedes hacer referencia a una etiqueta o rama, pero la acción puede cambiar sin ninguna advertencia.

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@b62528385c34dbc9f38e5f4225ac829252d1ea92
        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){
                projectV2(number: $number) {
                  id
                  fields(first:20) {
                    nodes {
                      ... on ProjectV2Field {
                        id
                        name
                      }
                      ... on ProjectV2SingleSelectField {
                        id
                        name
                        options {
                          id
                          name
                        }
                      }
                    }
                  }
                }
              }
            }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json

          echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
          echo 'DATE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
          echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
          echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .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!) {
              addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
                item {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.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: Date!
            ) {
              set_status: updateProjectV2ItemFieldValue(input: {
                projectId: $project
                itemId: $item
                fieldId: $status_field
                value: {
                  singleSelectOptionId: $status_value
                  }
              }) {
                projectV2Item {
                  id
                  }
              }
              set_date_posted: updateProjectV2ItemFieldValue(input: {
                projectId: $project
                itemId: $item
                fieldId: $date_field
                value: {
                  date: $date_value
                }
              }) {
                projectV2Item {
                  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 de autenticación con una personal access token

  1. Crea una personal access token (classic) con los ámbitos project y repo. Para obtener más información, vea «Managing your personal access tokens».
  2. Guarda el personal access token como un secreto en el repositorio u organización.
  3. En el flujo de trabajo siguiente, reemplace YOUR_TOKEN por el nombre del secreto. Reemplace YOUR_ORGANIZATION por el nombre de la organización. Por ejemplo, octo-org. Reemplace YOUR_PROJECT_NUMBER por el número del proyecto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, 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){
                projectV2(number: $number) {
                  id
                  fields(first:20) {
                    nodes {
                      ... on ProjectV2Field {
                        id
                        name
                      }
                      ... on ProjectV2SingleSelectField {
                        id
                        name
                        options {
                          id
                          name
                        }
                      }
                    }
                  }
                }
              }
            }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json

          echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
          echo 'DATE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
          echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
          echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .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!) {
              addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
                item {
                  id
                }
              }
            }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.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: Date!
            ) {
              set_status: updateProjectV2ItemFieldValue(input: {
                projectId: $project
                itemId: $item
                fieldId: $status_field
                value: {
                  singleSelectOptionId: $status_value
                  }
              }) {
                projectV2Item {
                  id
                  }
              }
              set_date_posted: updateProjectV2ItemFieldValue(input: {
                projectId: $project
                itemId: $item
                fieldId: $date_field
                value: {
                  date: $date_value
                }
              }) {
                projectV2Item {
                  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.

Código Explicación
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 solo:

- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@c2055a00597a80f713b78b1650e8d3418f4d9a65
  with:
    app_id: ${{ secrets.APP_ID }}
    private_key: ${{ secrets.APP_PEM }}
Usa la acción tibdex/github-app-token para generar un token de acceso de instalación para la aplicación a partir del id. de la aplicación y la clave privada. Más adelante en el flujo de trabajo se accede al token de acceso de instalación como ${{ steps.generate_token.outputs.token }}.

Reemplace APP_ID por el nombre del secreto que contiene el id. de la aplicación.

Reemplace APP_PEM por el nombre del secreto que contiene la clave privada de la aplicación.

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 usas un personal access token, reemplaza YOUR_TOKEN por el nombre del secreto que contiene tu personal access token.

Reemplaza YOUR_ORGANIZATION por el nombre de la organización. Por ejemplo, octo-org.

Reemplace YOUR_PROJECT_NUMBER por el número del proyecto. Para encontrar un número de proyecto, revisa su URL. Por ejemplo, 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){
      projectV2(number: $number) {
        id
        fields(first:20) {
          nodes {
            ... on ProjectV2Field {
              id
              name
            }
            ... on ProjectV2SingleSelectField {
              id
              name
              options {
                id
                name
              }
            }
          }
        }
      }
    }
  }'  -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json

Usa GitHub CLI para consultar a la API el id.del proyecto y devolver el nombre y el id. de los primeros 20 campos del proyecto. fields devuelve una unión y la consulta usa fragmentos insertados (... on) para devolver información acerca de los campos ProjectV2Field y ProjectV2SingleSelectField.

La respuesta se almacena en un archivo denominado project_data.json.

echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
echo 'DATE_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Date posted") | .id' project_data.json) >> $GITHUB_ENV
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .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 el identificador de un campo denominado Team, agregue echo 'TEAM_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV.
  • Para obtener el id. de una opción denominada Octoteam para el campo de selección única Team, agrega echo 'OCTOTEAM_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") |.options[] | select(.name=="Octoteam") |.id' project_data.json) >> $GITHUB_ENV.
Nota: En este flujo de trabajo se da por hecho que tiene un proyecto con un único campo de selección denominado "Status" (Estado) que incluye una opción denominada "Todo" (Pendiente) y un campo de fecha denominado "Date posted" (Fecha de publicación). 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 ha descrito anteriormente. PR_ID es el identificador de la solicitud de incorporación de cambios que ha desencadenado este flujo de trabajo.
item_id="$( gh api graphql -f query='
  mutation($project:ID!, $pr:ID!) {
    addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
      item {
        id
      }
    }
  }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.id')"
Usa GitHub CLI y la API para agregar la solicitud de incorporación de cambios que ha desencadenado este flujo de trabajo al proyecto. La marca jq analiza la respuesta para obtener el identificador 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 una variable de entorno con 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 ha descrito anteriormente.
gh api graphql -f query='
  mutation (
    $project: ID!
    $item: ID!
    $status_field: ID!
    $status_value: String!
    $date_field: ID!
    $date_value: Date!
  ) {
    set_status: updateProjectV2ItemFieldValue(input: {
      projectId: $project
      itemId: $item
      fieldId: $status_field
      value: {
        singleSelectOptionId: $status_value
        }
    }) {
      projectV2Item {
        id
        }
    }
    set_date_posted: updateProjectV2ItemFieldValue(input: {
      projectId: $project
      itemId: $item
      fieldId: $date_field
      value: {
        date: $date_value
      }
    }) {
      projectV2Item {
        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
Establece el valor del campo Status en Todo. Establece el valor del campo Date posted.