Skip to main content

Esta versão do GitHub Enterprise será descontinuada em 2022-09-28. Nenhum lançamento de patch será feito, mesmo para questões críticas de segurança. Para obter melhor desempenho, melhorar a segurança e novos recursos, upgrade to the latest version of GitHub Enterprise. Para ajuda com a atualização, contact GitHub Enterprise support.

Usando o GitHub CLI em um executor

Como usar funcionalidades avançadas de GitHub Actions para integração contínua (IC).

Observação: Executores hospedados em GitHub não são atualmente compatíveis com GitHub Enterprise Server. Você pode ver mais informações sobre suporte futuro planejado no Itinerário público do GitHub.

Visão geral do exemplo

Este artigo usa um exemplo de fluxo de trabalho para demonstrar algumas das principais funcionalidades da CI de GitHub Actions. Quando esse fluxo de trabalho é acionado, ele executa automaticamente um script que verifica se o site Docs de GitHub tem algum link quebrado. Se algum link quebrado for encontrado, o fluxo de trabalho usará a CLI de GitHub para criar um problema de GitHub com os detalhes.

O diagrama a seguir mostra uma visão de alto nível das etapas do fluxo de trabalho e como elas são executadas dentro do trabalho:

Diagrama de visão geral das etapas do fluxo de trabalho

Características utilizadas neste exemplo

O exemplo de fluxo de trabalho demonstra os seguintes recursps de GitHub Actions:

FuncionalidadeImplementação
Executando um fluxo de trabalho em intervalos regulares:cronograma
Definindo permissões para o token:permissões
Impedindo que um trabalho seja executado a menos que condições específicas sejam atendidas:se
Fazendo referência a segredos em um fluxo de trabalho:Segredos
Clonando o repositório para o executor:actions/checkout
Instalando o no executor:actions/setup-node
Usando uma ação de terceiros:peter-evans/create-issue-from-file

Exemplo de fluxo de trabalho

O fluxo de trabalho a seguir foi criado pela equipe de Engenharia de GitHub Para revisar a versão mais recente deste arquivo no repositório github/docs, consulte check-all-english-links.yml.

Observação: Cada linha deste fluxo de trabalho é explicada na próxima seção em "Compreendendo o exemplo".

YAML
name: Check all English links

# **What it does**: This script once a day checks all English links and reports in issues.
# **Why we have it**: We want to know if any links break.
# **Who does it impact**: Docs content.

on:
  workflow_dispatch:
  schedule:
    - cron: '40 19 * * *' # once a day at 19:40 UTC / 11:40 PST

permissions:
  contents: read
  issues: write

jobs:
  check_all_english_links:
    name: Check all links
    if: github.repository == 'github/docs-internal'
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.DOCUBOT_READORG_REPO_WORKFLOW_SCOPES }}
      FIRST_RESPONDER_PROJECT: Docs content first responder
      REPORT_AUTHOR: docubot
      REPORT_LABEL: broken link report
      REPORT_REPOSITORY: github/docs-content
    steps:
      - name: Check out repo's default branch
        uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 16.13.x
          cache: npm
      - name: npm ci
        run: npm ci
      - name: npm run build
        run: npm run build
      - name: Run script
        run: |
          script/check-english-links.js > broken_links.md

      # check-english-links.js returns 0 if no links are broken, and 1 if any links
      # are broken. When an Actions step's exit code is 1, the action run's job status
      # is failure and the run ends. The following steps create an issue for the
      # broken link report only if any links are broken, so `if: ${{ failure() }}`
      # ensures the steps run despite the previous step's failure of the job.

      - if: ${{ failure() }}
        name: Get title for issue
        id: check
        run: echo "::set-output name=title::$(head -1 broken_links.md)"
      - if: ${{ failure() }}
        name: Create issue from file
        id: broken-link-report
        uses: peter-evans/create-issue-from-file@b4f9ee0a9d4abbfc6986601d9b1a4f8f8e74c77e
        with:
          token: ${{ env.GITHUB_TOKEN }}

          title: ${{ steps.check.outputs.title }}
          content-filepath: ./broken_links.md
          repository: ${{ env.REPORT_REPOSITORY }}
          labels: ${{ env.REPORT_LABEL }}
      - if: ${{ failure() }}
        name: Close and/or comment on old issues
        env:
          NEW_REPORT_URL: 'https://github.com/${{ env.REPORT_REPOSITORY }}/issues/${{ steps.broken-link-report.outputs.issue-number }}'
        run: |
          gh alias set list-reports "issue list \
                                       --repo ${{ env.REPORT_REPOSITORY }} \
                                       --author ${{ env.REPORT_AUTHOR }} \
                                       --label '${{ env.REPORT_LABEL }}'"

          # Link to the previous report from the new report that triggered this
          # workflow run.

          previous_report_url=$(gh list-reports \
                                  --state all \
                                  --limit 2 \
                                  --json url \
                                  --jq '.[].url' \
                                  | grep -v ${{ env.NEW_REPORT_URL }} | head -1)

          gh issue comment ${{ env.NEW_REPORT_URL }} --body "⬅️ [Previous report]($previous_report_url)"

          # If an old report is open and assigned to someone, link to the newer
          # report without closing the old report.

          for issue_url in $(gh list-reports \
                                  --json assignees,url \
                                  --jq '.[] | select (.assignees != []) | .url'); do
            if [ "$issue_url" != "${{ env.NEW_REPORT_URL }}" ]; then
              gh issue comment $issue_url --body "➡️ [Newer report](${{ env.NEW_REPORT_URL }})"
            fi
          done

          # Link to the newer report from any older report that is still open,
          # then close the older report and remove it from the first responder's
          # project board.

          for issue_url in $(gh list-reports \
                                  --search 'no:assignee' \
                                  --json url \
                                  --jq '.[].url'); do
            if [ "$issue_url" != "${{ env.NEW_REPORT_URL }}" ]; then
              gh issue comment $issue_url --body "➡️ [Newer report](${{ env.NEW_REPORT_URL }})"
              gh issue close $issue_url
              gh issue edit $issue_url --remove-project "${{ env.FIRST_RESPONDER_PROJECT }}"
            fi
          done

Entendendo o exemplo

A tabela a seguir explica como cada um desses recursos são usados ao criar um fluxo de trabalho de GitHub Actions.

Código Explicação
YAML
name: Check all English links

O nome do fluxo de trabalho como ele aparecerá na aba "Ações" do repositório de GitHub.

YAML
on:
  workflow_dispatch:
  schedule:
    - cron: '40 20 * * *' # once a day at 20:40 UTC / 12:40 PST

Defines the workflow_dispatch and scheduled as triggers for the workflow:

  • The workflow_dispatch lets you manually run this workflow from the UI. Para obter mais informações, consulte workflow_dispatch.
  • The schedule event lets you use cron syntax to define a regular interval for automatically triggering the workflow. Para obter mais informações, consulte 'agendamento'.
YAML
permissions:
  contents: read
  issues: write

Modifica as permissões padrão concedidas a "GITHUB_TOKEN". Isso vai variar dependendo das necessidades do seu fluxo de trabalho. Para obter mais informações, consulte "Atribuindo permissões a trabalhos."

YAML
jobs:

Agrupa todos os trabalhos executados no arquivo do fluxo de trabalho.

YAML
  check_all_english_links:
    name: Check all links

Define um trabalho com o ID "check_all_english_links", e o nome 'Verificar todos os links', que é armazenado na chave "trabalhos".

YAML
if: github.repository == 'github/docs-internal'

Só execute o trabalho de "checkall_english_links" se o repositório for denominado "docs-internal" e estiver dentro da organização "github". Caso contrário, o trabalho é marcado como _skipped.

YAML
runs-on: ubuntu-latest

Configura o trabalho a ser executado em um executor do Ubuntu Linux. Isso significa que o trabalho será executado em uma nova máquina virtual hospedada por GitHub. Para obter exemplos de sintaxe usando outros executores, consulte "Sintaxe de fluxo de trabalho para GitHub Actions."

YAML
    env:
      GITHUB_TOKEN: ${{ secrets.DOCUBOT_READORG_REPO_WORKFLOW_SCOPES }}
      REPORT_AUTHOR: docubot
      REPORT_LABEL: broken link report
      REPORT_REPOSITORY: github/docs-content

Cria variáveis de ambiente personalizadas e redefine a variável "GITHUB_TOKEN" incorporada para usar um secret personalizado. Essas variáveis serão referenciadas posteriormente no fluxo de trabalho.

YAML
    steps:

Agrupa todos os passos que serão executados como parte do trabalho "check_all_english_links". Cada trabalho no fluxo de trabalho tem sua própria seção de "etapas".

YAML
      - name: Check out repo's default branch
        uses: actions/checkout@v2

A palavra-chave "uses" diz para o trabalho recuperar a ação denominada "actions/checkout". Esta é uma ação que verifica seu repositório e o faz o download do runner, permitindo que você execute ações contra seu código (como, por exemplo, ferramentas de teste). Você deve usar a ação de checkout sempre que o fluxo de trabalho for executado no código do repositório ou você estiver usando uma ação definida no repositório.

YAML
      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: 16.8.x
          cache: npm

Esta etapa usa a ação actions/setup-node para instalar a versão especificada do pacote do "node" de software no executor, que lhe dá acesso ao comando npm.

YAML
      - name: Run the "npm ci" command
        run: npm ci
      - name: Run the "npm run build" command
        run: npm run build

A palavra-chave executar diz ao trabalho para executar um comando no executor. Neste caso, os comandos "npm ci" e "npm run build" são executados como etapas separadas para instalar e construir o aplicativo Node.js no repositório.

YAML
      - name: Run script
        run: |
          script/check-english-links.js > broken_links.md

Este comando "executar" executa um script armazenado no repositório em "script/check-english-links.js" e canalizado a saída para um arquivo denominado 'broken_links.md'.

YAML
      - if: ${{ failure() }}
        name: Get title for issue
        id: check
        run: echo "::set-output name=title::$(head -1 broken_links.md)"

Se o script "check-english-links.js" detectar links quebrados e retornar um status de saída não zero (falha) e, em seguida, usar um comando de fluxo de trabalho para definir uma saída que tenha o valor da primeira linha do arquivo 'broken_links.md' (este será usado na próxima etapa).

YAML
      - if: ${{ failure() }}
        name: Create issue from file
        id: broken-link-report
        uses: peter-evans/create-issue-from-file@b4f9ee0a9d4abbfc6986601d9b1a4f8f8e74c77e
        with:
          token: ${{ env.GITHUB_TOKEN }}

          title: ${{ steps.check.outputs.title }}
          content-filepath: ./broken_links.md
          repository: ${{ env.REPORT_REPOSITORY }}
          labels: ${{ env.REPORT_LABEL }}

Usa a ação "peter-evans/create-issue-from-file" para criar um novo problema de GitHub. Este exemplo é fixado em uma versão específica da ação, usando o SHA de "b4f9ee0a9d4abbfc6986601d9b1a4f8f8e74c77e".

YAML
      - if: ${{ failure() }}
        name: Close and/or comment on old issues
        env:
          NEW_REPORT_URL: 'https://github.com/${{ env.REPORT_REPOSITORY }}/issues/${{ steps.broken-link-report.outputs.issue-number }}'
        run: |
          gh alias set list-reports "issue list \
                                       --repo ${{ env.REPORT_REPOSITORY }} \
                                       --author ${{ env.REPORT_AUTHOR }} \
                                       --label '${{ env.REPORT_LABEL }}'"
          previous_report_url=$(gh list-reports \
                                  --state all \
                                  --limit 2 \
                                  --json url \
                                  --jq '.[].url' \
                                  | grep -v ${{ env.NEW_REPORT_URL }} | head -1)

          gh issue comment ${{ env.NEW_REPORT_URL }} --body "⬅️ [Previous report]($previous_report_url)"

Usa gh issue list para localizar a emissão anteriormente criada a partir de execuções anteriores. Este é aliased para 'gh list-reports' para processamento mais simples em etapas posteriores. Para obter a URL do problema, a expressão "jq" processa a saída do JSON resultante.

gh issue comment é usado em seguida para adicionar um comentário ao novo problema que vincula com o anterior.

YAML
          for issue_url in $(gh list-reports \
                                  --json assignees,url \
                                  --jq '.[] | select (.assignees != []) | .url'); do
            if [ "$issue_url" != "$" ]; then
              gh issue comment $issue_url --body "➡️ [Newer report]($)"
            fi
          done

Se um problema de uma execução anterior estiver aberto e atribuído a alguém, use gh issue comment para adicionar um comentário com um link para a nova edição.

YAML
          for issue_url in $(gh list-reports \
                                  --search 'no:assignee' \
                                  --json url \
                                  --jq '.[].url'); do
            if [ "$issue_url" != "${{ env.NEW_REPORT_URL }}" ]; then
              gh issue comment $issue_url --body "➡️ [Newer report](${{ env.NEW_REPORT_URL }})"
              gh issue close $issue_url
              gh issue edit $issue_url --remove-project "${{ env.FIRST_RESPONDER_PROJECT }}"
            fi
          done

Se um problema de uma execução anterior estiver aberto e não for atribuído a ninguém, então:

Próximas etapas