Comparison of GitHub Actions with competitors
Deep dive into workflow syntax, triggers, and job configuration
Explore matrices, reusable workflows, and composite actions
•Runner Types and Execution Environments
•Persisting Build Outputs with Artifacts
•Controlling GitHub Permissions
Discover and integrate community actions from the GitHub Marketplace
Build custom JavaScript and Docker actions from scratch
•JavaScript and TypeScript Actions
Optimize logs, secrets, environments, and permissions for teams
•Developer Experience (Actions)
Harden workflows with security, reliability, and cost-saving techniques
•Maintainable Workflow Patterns
Apply course concepts by automating a real-world deployment pipeline
The GITHUB_TOKEN
injected into every workflow starts with read access to repository contents and packages only. Tightening or widening those permissions protects your organization from unintended writes and helps enforce least privilege.
jobs:
read-only-pr:
runs-on: ubuntu-24.04
permissions:
pull-requests: read # Can read PR data only
continue-on-error: true # Avoids failing entire workflow
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: List the first 5 open PRs (allowed)
run: gh pr list --limit 5
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Attempt to add a label (expected to fail)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr edit 1 --add-label "documentation"
- name: Confirm the failure
if: failure()
run: echo "❌ Write operation was blocked as expected – token is read-only."
read-write-pr:
runs-on: ubuntu-24.04
permissions:
pull-requests: write
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
- name: Attempt to add a label (expected to succeed)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr edit 1 --add-label "documentation"
- name: Confirm the result
if: success()
run: echo "✅ Write operation succeeded!"
By scoping permissions at the job or workflow level you can grant just enough access for each automation task (and nothing more!).