GitHub Actions Tutorial — Using Actions
Using Actions
Actions are reusable units of code that you reference with the uses: keyword. Instead of writing everything from scratch, you pull in pre-built functionality from the GitHub Marketplace or your own repositories.
The uses: Keyword
steps:
- uses: actions/checkout@v4 # official GitHub action
- uses: actions/setup-node@v4 # official setup action
- uses: docker/build-push-action@v6 # third-party action
Action Reference Formats
| Format | Example | Source |
|---|---|---|
owner/repo@ref |
actions/checkout@v4 |
Public GitHub repo |
owner/repo/path@ref |
actions/aws/ec2@main |
Subdirectory of a repo |
docker://image:tag |
docker://alpine:3.18 |
Docker Hub image |
./.github/actions/my-action |
Local action | Same repository |
Version Pinning
Always pin actions to a specific version:
# ✅ Good — pinned to major version tag
- uses: actions/checkout@v4
# ✅ Better — pinned to exact commit SHA
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
# ⚠️ Risky — using branch name (can change)
- uses: actions/checkout@main
# ❌ Bad — no version
- uses: actions/checkout
Why Pin to SHA?
Tags can be moved (an attacker could push malicious code to a tag). SHA pinning is the most secure option:
# Pin to SHA with a comment for readability
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Use Dependabot to keep SHA-pinned actions up to date automatically.
Finding Actions on the Marketplace
The GitHub Marketplace has thousands of pre-built actions:
| Category | Popular Actions |
|---|---|
| CI/CD | actions/checkout, actions/setup-node, actions/setup-python |
| Docker | docker/build-push-action, docker/login-action |
| Cloud | aws-actions/configure-aws-credentials, azure/login |
| Code Quality | github/codeql-action, sonarsource/sonarqube-scan-action |
| Notifications | slackapi/slack-github-action, 8398a7/action-slack |
Evaluating Third-Party Actions
Before using a third-party action, check:
- Stars and usage — popular actions are better tested
- Verified creator badge — indicates GitHub verification
- Source code — review the action’s repository
- Permissions — what access does it need?
- Maintenance — is it actively maintained?
run vs uses
run: |
uses: |
|---|---|
| Executes shell commands | Runs a pre-built action |
| Full control over commands | Abstraction over complex tasks |
| No external dependencies | Depends on action author |
| Good for simple tasks | Good for complex, reusable tasks |
General rule: Use run: for simple commands. Use uses: when the action saves you significant code or handles complexity.
Actions with Docker Images
You can use Docker images directly as actions:
steps:
- name: Run in Alpine
uses: docker://alpine:3.18
with:
args: echo "Hello from Alpine"
- name: Run custom image
uses: docker://ghcr.io/my-org/my-tool:latest
Local Actions
Reference actions from the same repository:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/my-custom-action
with:
input1: "value"
The local action must have an action.yml file in its directory. This is covered in depth in Custom Actions.
Common Mistakes
| Mistake | Fix |
|---|---|
| Action not found | Check the exact owner/repo name and version tag |
Using @main in production |
Pin to a version tag (@v4) or SHA for stability |
Missing with: for required inputs |
Check the action’s README for required inputs |
| Trusting unknown actions | Review source code and check marketplace ratings |
Quick Reference
| Concept | Syntax |
|---|---|
| Use action | uses: owner/repo@version |
| Pin to SHA | uses: owner/repo@abc123... |
| Local action | uses: ./.github/actions/name |
| Docker action | uses: docker://image:tag |
| Pass inputs | with: key: value |
← Previous: Run Commands
Next: Checkout & Setup →