Example overview
This article uses an example workflow to demonstrate some of the main CI features of GitHub Actions. When this workflow is triggered, it automatically runs a script that checks whether the GitHub Docs site has any broken links. If any broken links are found, the workflow uses the GitHub CLI to create a GitHub issue with the details.
The following diagram shows a high level view of the workflow's steps and how they run within the job:
Features used in this example
The example workflow demonstrates the following capabilities of GitHub Actions.
Feature | Implementation |
---|---|
Running a workflow at regular intervals | schedule |
Setting permissions for the token | permissions |
Preventing a job from running unless specific conditions are met | if |
Referencing secrets in a workflow | Secrets |
Cloning your repository to the runner | actions/checkout |
Installing node on the runner | actions/setup-node |
Using a third-party action | peter-evans/create-issue-from-file |
Running shell commands on the runner | run |
Running a script on the runner | Using script/check-english-links.js |
Generating an output file | Piping the output using the > operator |
Checking for existing issues using GitHub CLI | gh issue list |
Commenting on an issue using GitHub CLI | gh issue comment |
Example workflow
The following workflow was created by the GitHub Docs Engineering team. To review the latest version of this file in the github/docs
repository, see check-all-english-links.yml
.
Note: Each line of this workflow is explained in the next section at "Understanding the example."
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
Understanding the example
The following table explains how each of these features are used when creating a GitHub Actions workflow.
Code | Explanation |
---|---|
|
The name of the workflow as it will appear in the "Actions" tab of the GitHub repository. |
|
Defines the
|
|
Modifies the default permissions granted to |
|
Groups together all the jobs that run in the workflow file. |
|
Defines a job with the ID |
|
Only run the |
|
Configures the job to run on an Ubuntu Linux runner. This means that the job will execute on a fresh virtual machine hosted by GitHub. For syntax examples using other runners, see "Workflow syntax for GitHub Actions." |
|
Creates custom environment variables, and redefines the built-in |
|
Groups together all the steps that will run as part of the |
|
The |
|
This step uses the |
|
The |
|
This |
|
If the |
|
Uses the |
|
Uses
|
|
If an issue from a previous run is open and assigned to someone, then use |
|
If an issue from a previous run is open and is not assigned to anyone, then:
|
Next steps
- To learn about GitHub Actions concepts, see "Understanding GitHub Actions."
- For more step-by-step guide for creating a basic workflow, see "Quickstart for GitHub Actions."
- If you're comfortable with the basics of GitHub Actions, you can learn about workflows and their features at "About workflows."