Skip to main content

Automatisieren von Projects mithilfe von Aktionen

Du kannst deine Projekte mit GitHub Actions automatisieren.

GitHub Actions-Workflows

In diesem Abschnitt wird veranschaulicht, wie du die GraphQL-API und GitHub Actions verwenden kannst, um einen Pull Request zu einem Organisationsprojekt hinzuzufügen. Wenn der Pull Request in den Beispielworkflows als „Bereit zur Überprüfung“ gekennzeichnet ist, wird dem Projekt ein neuer Auftrag hinzugefügt. Bei diesem Auftrag wird das Feld „Status“ auf „Aufgaben“ festgelegt, und das aktuelle Datum wird einem benutzerdefinierten „Bereitstellungsdatum“-Feld hinzugefügt.

Du kannst einen der nachstehenden Workflows kopieren und wie in der folgenden Tabelle beschrieben so ändern, dass er deinen Anforderungen entspricht.

Ein Projekt kann mehrere Repositorys umfassen, ein Workflow ist jedoch für ein Repository spezifisch. Füge den Workflow zu allen Repositorys hinzu, die das Projekt nachverfolgen soll. Weitere Informationen zum Erstellen von Workflowdateien findest du unter Schnellstart für GitHub Actions.

In diesem Artikel wird ein grundlegendes Verständnis von GitHub Actions vorausgesetzt. Weitere Informationen zu GitHub Actions findest du unter GitHub Actions.

Weitere Informationen zu sonstigen Änderungen, die du an deinem Projekt über die API vornehmen kannst, findest du unter Verwenden der API zum Verwalten von Projekten.

Möglicherweise möchtest du auch den actions/add-to-project-Workflow verwenden, der von GitHub verwaltet wird und das aktuelle Issue bzw. den aktuellen Pull Request dem angegebenen Projekt hinzufügt. Weitere Informationen findest du im actions/add-to-project-Repository und der zugehörigen README.

Hinweis: GITHUB_TOKEN wird auf die Repositoryebene festgelegt und kann nicht auf projects zugreifen. Wenn du auf projects zugreifen möchtest, kannst du entweder eine GitHub App (für Organisationsprojekte empfohlen) oder ein personal access token (für Benutzerprojekte empfohlen) erstellen. Unten werden Workflowbeispiele für beide Ansätze gezeigt.

Beispielworkflow für die Authentifizierung mit einer GitHub App

  1. Erstelle eine GitHub App, oder wähle eine vorhandene GitHub App im Besitz deiner Organisation aus. Weitere Informationen findest du unter Erstellen einer GitHub App.

  2. Weise deiner GitHub App Lese- und Schreibberechtigungen für Organisationsprojekte zu. Weitere Informationen findest du unter Bearbeiten der Berechtigungen einer GitHub App.

    Hinweis: Du kannst die Berechtigung deiner App für Organisationsprojekte und Repositoryprojekte steuern. Du musst die Berechtigung zum Lesen und Schreiben von Organisationsprojekten erteilen. Die Lese- und Schreibberechtigung für Repositoryprojekte ist nicht ausreichend.

  3. Installiere die GitHub App in deiner Organisation. Installiere sie für alle Repositorys, auf die dein Projekt zugreifen muss. Weitere Informationen findest du unter Installieren von GitHub Apps.

  4. Speichere die ID der GitHub App als Geheimnis in deinem Repository oder deiner Organisation. Ersetze APP_ID im folgenden Workflow durch den Namen des Geheimnisses. Du kannst die App-ID auf der Einstellungsseite deiner App oder durch die App-API finden. Weitere Informationen findest du unter Apps.

  5. Generiere einen privaten Schlüssel für deine App. Speichere den Inhalt der resultierenden Datei als Geheimnis in deinem Repository oder deiner Organisation. (Speichere den gesamten Inhalt der Datei, einschließlich -----BEGIN RSA PRIVATE KEY----- und -----END RSA PRIVATE KEY-----.) Ersetze APP_PEM im folgenden Workflow durch den Namen des Geheimnisses. Weitere Informationen findest du unter Authentifizieren mit GitHub Apps.

  6. Ersetze YOUR_ORGANIZATION im folgenden Workflow durch den Namen deiner Organisation. Beispiel: octo-org. Ersetze YOUR_PROJECT_NUMBER durch deine Projektnummer. Sieh dir die URL des Projekts an, um die Projektnummer zu finden. https://github.com/orgs/octo-org/projects/5 hat beispielsweise die Projektnummer 5.

YAML
# <a name="this-workflow-uses-actions-that-are-not-certified-by-github"></a>Dieser Workflow verwendet Aktionen, die nicht von GitHub zertifiziert sind.
# <a name="they-are-provided-by-a-third-party-and-are-governed-by"></a>Sie werden von einem Drittanbieter bereitgestellt und unterliegen
# <a name="separate-terms-of-service-privacy-policy-and-support"></a>separaten Nutzungsbedingungen, Datenschutzbestimmungen und Support
# <a name="documentation"></a>Onlinedokumentation.

# <a name="github-recommends-pinning-actions-to-a-commit-sha"></a>GitHub empfiehlt, Aktionen an einen Commit-SHA anzuheften.
# <a name="to-get-a-newer-version-you-will-need-to-update-the-sha"></a>Um eine neuere Version zu erhalten, musst du den SHA aktualisieren.
# <a name="you-can-also-reference-a-tag-or-branch-but-the-action-may-change-without-warning"></a>Du kannst auch auf ein Tag oder einen Branch verweisen, aber die Aktion kann sich ohne Vorwarnung ändern.

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){
                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

Beispielworkflow für die Authentifizierung mit einem personal access token

  1. Erstelle ein personal access token (classic) mit den Bereichen project und repo. Weitere Informationen findest du unter Erstellen eines personal access token.
  2. Speichere das personal access token als geheimen Schlüssel in deinem Repository oder deiner Organisation.
  3. Ersetze YOUR_TOKEN im folgenden Workflow durch den Namen des Geheimnisses. Ersetze YOUR_ORGANIZATION durch den Namen deiner Organisation. Beispiel: octo-org. Ersetze YOUR_PROJECT_NUMBER durch deine Projektnummer. Sieh dir die URL des Projekts an, um die Projektnummer zu finden. https://github.com/orgs/octo-org/projects/5 hat beispielsweise die Projektnummer 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){
                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

Erklärung des Workflows

In der folgenden Tabelle werden Abschnitte der Beispielworkflows erklärt, und es wird veranschaulicht, wie du die Workflows zur eigenen Verwendung anpassen kannst.

on:
  pull_request:
    types:
      - ready_for_review
Dieser Workflow wird ausgeführt, wenn ein Pull Request im Repository als „Bereit zur Überprüfung“ gekennzeichnet ist.

Nur für GitHub App:

- name: Generate token
  id: generate_token
  uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
  with:
    app_id: ${{ secrets.APP_ID }}
    private_key: ${{ secrets.APP_PEM }}
Der Workflow verwendet tibdex/github-app-token action, um aus der App-ID und dem privaten Schlüssel ein Installationszugriffstoken für deine App zu generieren. Auf das Installationszugriffstoken wird später im Workflow als ${{ steps.generate_token.outputs.token }} zugegriffen.

Ersetze APP_ID durch den Namen des Geheimnisses, das deine App-ID enthält.

Ersetze APP_PEM durch den Namen des Geheimnisses, das deinen privaten App-Schlüssel enthält.

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
Der Workflow legt Umgebungsvariablen für diesen Schritt fest.

Wenn du ein personal access token verwendest, ersetze YOUR_TOKEN durch den Namen des Geheimnisses, das dein personal access token enthält.

Ersetze YOUR_ORGANIZATION durch den Namen deiner Organisation. Beispiel: octo-org.

Ersetze YOUR_PROJECT_NUMBER durch deine Projektnummer. Sieh dir die URL des Projekts an, um die Projektnummer zu finden. https://github.com/orgs/octo-org/projects/5 hat beispielsweise die Projektnummer 5.
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

Dieser Workflow verwendet die GitHub CLI, um die API für die ID des Projekts abzurufen und den Namen und die ID der ersten 20 Felder im Projekt zurückzugeben. fields gibt eine Vereinigung zurück, und die Abfrage verwendet Inlinefragmente (... on), um Informationen zu den beliebigen Feldern ProjectV2Field und ProjectV2SingleSelectField zurückzugeben.

Die Antwort wird in einer Datei mit dem Namen project_data.json gespeichert.

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
Der Workflow analysiert die Antwort der API-Abfrage und speichert die relevanten IDs als Umgebungsvariablen. Ändere dies, um die ID verschiedener Felder oder Optionen abzurufen. Beispiel:
  • Füge echo 'TEAM_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") | .id' project_data.json) >> $GITHUB_ENV hinzu, um die ID eines Felds namens Team abzurufen.
  • Füge echo 'OCTOTEAM_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Team") |.options[] | select(.name=="Octoteam") |.id' project_data.json) >> $GITHUB_ENV hinzu, um die ID einer Option namens Octoteam für das Einfachauswahlfeld Team abzurufen.
Hinweis: Bei diesem Workflow wird davon ausgegangen, dass du über ein Projekt mit einem einzelnen Auswahlfeld namens „Status“ verfügst, das die Option „Aufgaben“ und das Datumsfeld „Bereitstellungsdatum“ enthält. Du musst diesen Abschnitt ändern, um ihn den in der Tabelle vorhandenen Feldern anzupassen.

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 }}
Der Workflow legt Umgebungsvariablen für diesen Schritt fest. GITHUB_TOKEN wird oben beschrieben. PR_ID ist die ID des Pull Requests, der diesen Workflow ausgelöst hat.
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')"
Der Workflow verwendet GitHub CLI und die API, um den Pull Request hinzuzufügen, der den Workflow dieses Projekts ausgelöst hat. Das jq-Flag analysiert die Antwort, um die ID des erstellten Elements abzurufen.
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
Der Workflow speichert die ID des erstellten Elements als Umgebungsvariable.
echo "DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
Der Workflow speichert das aktuelle Datum als Umgebungsvariable im yyyy-mm-dd-Format.

GitHub App:

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

Personal access token:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_TOKEN }}
Der Workflow legt Umgebungsvariablen für diesen Schritt fest. GITHUB_TOKEN wird oben beschrieben.
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
Der Workflow legt den Wert des Felds Status auf Todo fest. Der Workflow legt den Wert des Felds Date posted fest.