GitHub Actions GitHub CLI
The GitHub CLI, called gh, is a command-line tool that manages issues, pull requests, releases, and workflow runs. GitHub-hosted runners include it already. Workflows use it to talk to GitHub with simple one-line commands instead of long scripts.
The CLI in Simple Words
Think of a TV remote. You press one button, and the television does a complex job. The gh tool is a remote for GitHub. One short command creates a release, posts a comment, or starts another workflow.
Authentication
The tool needs a token. Pass GITHUB_TOKEN through the GH_TOKEN environment variable.
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}Set the variable at step level to limit exposure, or at job level when several steps use the tool. The token follows the permissions you declared in the workflow.
How a Command Travels
+-----------------+ +----------+ +------------+ +--------------+
| Workflow step | --> | gh | --> | GitHub API | --> | Issue, PR or |
| run: gh ... | | command | | (HTTPS) | | release done |
+-----------------+ +----------+ +------------+ +--------------+Common Commands
| Task | Command |
|---|---|
| Create an issue | gh issue create --title "Bug" --body "Details" |
| Comment on a pull request | gh pr comment 12 --body "Checked" |
| Add a label | gh issue edit 5 --add-label bug |
| List recent runs | gh run list --limit 5 |
| Start a workflow | gh workflow run deploy.yml |
| Create a release | gh release create v1.0.0 --generate-notes |
Example: Comment on Every Pull Request
name: PR Comment
on:
pull_request:
types: [ opened ]
permissions:
pull-requests: write
jobs:
comment:
runs-on: ubuntu-latest
steps:
- name: Post checklist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
gh pr comment "$PR_NUMBER" \
--repo "${{ github.repository }}" \
--body "Please confirm tests pass and the changelog is updated."The --repo flag matters when the job does not check out the repository. Without a checkout, the tool cannot detect the repository on its own.
Example: Create an Issue When a Job Fails
- name: Open issue on failure
if: failure()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh issue create \
--repo "${{ github.repository }}" \
--title "Nightly build failed" \
--body "Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"The issue requires the issues: write permission at the workflow or job level.
Calling Any API Endpoint
The gh api command reaches any GitHub REST endpoint. The tool fills in the authentication header for you.
gh api repos/${{ github.repository }}/releases/latest --jq '.tag_name'The --jq flag filters the JSON response down to one value. The command above prints only the latest release tag.
Using Output in Later Steps
- name: Find latest tag
id: latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG=$(gh api repos/${{ github.repository }}/releases/latest --jq '.tag_name')
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
- run: echo "Latest is ${{ steps.latest.outputs.tag }}"CLI Versus Marketplace Actions
Marketplace actions package common tasks with inputs and tested behavior. The CLI offers flexibility for tasks without a ready-made action. Choose the CLI when one command solves the problem. Choose an action when the task needs many options.
Safety Tips
- Grant only the permissions that the command needs.
- Pass user-controlled text, such as issue titles, through environment variables instead of pasting them into the command line. The practice prevents script injection.
- Test commands on your own computer first with
gh auth login.
