Skip to main content
Мы публикуем частые обновления нашей документации, и перевод этой страницы может все еще выполняться. Актуальные сведения см. в документации на английском языке.
В настоящее время GitHub AE находится в ограниченном выпуске.

Использование интерфейса командной строки GitHub в средстве выполнения

Использование расширенных функций GitHub Actions для непрерывной интеграции (CI).

Обзор примера

В этой статье на примере рабочего процесса демонстрируется применение некоторых функций GitHub Actions для непрерывной интеграции. При активации этого рабочего процесса он автоматически запускает скрипт, который проверяет, есть ли на сайте Документов GitHub неработающие ссылки. Если обнаруживаются неработающие ссылки, рабочий процесс использует интерфейс командной строки GitHub для создания проблемы GitHub с подробными сведениями.

На следующей схеме показано общее представление этапов рабочего процесса и их выполнение в задании:

Схема события, запускающего рабочий процесс, который использует GitHub CLI для создания проблемы.

Функции, используемые в этом примере

Пример рабочего процесса демонстрирует следующие возможности GitHub Actions.

ВозможностьРеализация
Выполнение рабочего процесса через регулярные интервалыschedule

Пример рабочего процесса

Следующий рабочий процесс был создан командой разработчиков документации для GitHub. Чтобы получить последнюю версию этого файла из репозитория github/docs, перейдите по адресу: check-all-english-links.yml.

Примечание. Каждая строка этого рабочего процесса описана в следующем разделе Основные сведения о примере.

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@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        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@ceef9be92406ace67ab5421f66570acf213ec395
        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

Общие сведения о примере

В следующей таблице собраны сведения о том, как каждая из этих возможностей используется при создании рабочего процесса GitHub Actions.

Код Пояснение
YAML
name: Check all English links

Имя рабочего процесса в том виде, в котором оно появится на вкладке "Действия" репозитория GitHub.

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

Определяет workflow_dispatch и scheduled как триггеры рабочего процесса:

  • workflow_dispatch позволяет вам вручную запустить рабочий процесс из пользовательского интерфейса. Дополнительные сведения см. на веб-сайте workflow_dispatch.
  • Событие schedule позволяет использовать синтаксис cron, чтобы определить регулярный интервал для автоматического запуска рабочего процесса. Дополнительные сведения см. на веб-сайте schedule.
YAML
permissions:
  contents: read
  issues: write

Изменяет разрешения по умолчанию, предоставленные GITHUB_TOKEN. Зависит от потребностей рабочего процесса. Дополнительные сведения см. в разделе Назначение разрешений для заданий.

YAML
jobs:

Объединяет все задания, выполняемые в файле рабочего процесса.

YAML
  check_all_english_links:
    name: Check all links

Определяет задание с идентификатором check_all_english_links и именем Check all links, которое хранится в ключе jobs.

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

Задание check_all_english_links можно выполнять только в том случае, если репозиторий имеет имя docs-internal и находится в организации github. В противном случае задание будет отмечено как пропущенное.

YAML
runs-on: ubuntu-latest

Настраивает задание для выполнения в последней версии средства выполнения Ubuntu Linux. Это означает, что задание будет выполняться на новой виртуальной машине, размещенной в GitHub. Примеры синтаксиса с использованием других средств выполнения см. в разделе Синтаксис рабочего процесса для 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

Создает пользовательские переменные среды и переопределяет встроенную переменную GITHUB_TOKEN для использования пользовательского секрета. На эти переменные будут использоваться ссылки позже в рабочем процессе.

YAML
    steps:

Группируют все шаги, которые будут выполняться в рамках задания check_all_english_links. Каждое задание в рабочем процессе имеет собственный раздел steps.

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

Ключевое слово uses сообщает заданию, что нужно получить действие с именем actions/checkout. Это действие, которое извлекает репозиторий и загружает его в средство выполнения, позволяя выполнять действия в коде (например, средства тестирования). Действие оформления заказа необходимо использовать в любой момент, когда рабочий процесс будет выполняться в коде репозитория или если вы используете действие, определенное в репозитории.

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

На этом шаге используется действие actions/setup-node для установки указанной версии пакета программного обеспечения node в средстве выполнения, которое предоставляет доступ к команде npm.

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

Ключевое слово run указывает заданию выполнить команду в средстве выполнения. В этом случае команды npm ci и npm run build выполняются в виде отдельных шагов для установки и сборки приложения Node.js в репозитории.

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

Эта команда run выполняет скрипт, хранящийся в репозитории в script/check-english-links.js, и передает выходные данные в файл с именем broken_links.md.

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

Если скрипт check-english-links.js обнаруживает неработающие ссылки и возвращает состояние выхода, отличное от нуля (сбой), используйте команду рабочего процесса, чтобы задать выходные данные, имеющие значение первой строки файла broken_links.md (используется в следующем шаге).

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

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

Использует действие peter-evans/create-issue-from-file, чтобы создать новую проблему GitHub. Этот пример закреплен к определенной версии действия с помощью SHA ceef9be92406ace67ab5421f66570acf213ec395.

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

Использует gh issue list для поиска ранее созданной проблемы из предыдущих запусков. Используется псевдоним gh list-reports для более простой обработки на последующих шагах. Чтобы получить URL-адрес проблемы, выражение jq обрабатывает полученные выходные данные JSON.

Затем используется gh issue comment, чтобы добавить комментарий к новой проблеме, которая ссылается на предыдущую.

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

Если проблема из предыдущего запуска открыта и назначена кому-либо, используйте для gh issue comment, чтобы добавить комментарий со ссылкой на новую проблему.

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

Если проблема из предыдущего запуска открыта и не назначена, выполните указанные ниже действия.

  • Используйте gh issue comment, чтобы добавить комментарий со ссылкой на новую проблему.
  • Используйте gh issue close, чтобы закрыть старую проблему.
  • Используйте gh issue edit, чтобы изменить старую проблему и удалить ее из определенной доски проекта GitHub.

Дальнейшие действия