How to Get Started with GitHub Actions
Create your first GitHub Actions workflow, run it on a push, and find its logs. Learn the YAML structure, triggers, secrets, and common fixes.
To get started with GitHub Actions, add a YAML workflow file under .github/workflows/, choose an event such as push, define a job and its steps, then commit and push the file. Open the repository’s Actions tab to inspect the run.
This guide walks through a first workflow, explains the YAML, and covers templates, triggers, runners, secrets, troubleshooting, and practical limits. It assumes you can navigate a GitHub repository; basic familiarity with repositories and pull requests is helpful. See GitHub’s Actions quickstart.
1. Create your first workflow
- Open or create a repository where GitHub Actions is available.
- At the repository root, create the directory
.github/workflows/. - Add a file named
learn-github-actions.ymlwith this workflow. - Commit and push the file to GitHub.
- Open the repository’s Actions tab, select the run, and inspect the job and step logs.
name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push]
jobs:
check-bats-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v7
with:
node-version: '24'
- run: npm install -g bats
- run: bats -v
This is the example shown in GitHub’s beginner workflow tutorial at the time of writing, not an independently tested workflow. Action versions and runtime support can change; check their official documentation before copying it into a long-lived project. The sample checks out the repository, installs Node.js 24, installs Bats, and prints its version.
What each part means
| YAML | Purpose |
|---|---|
name |
Names the workflow in GitHub’s interface. |
run-name |
Sets a descriptive name for an individual run; this expression includes the actor who triggered it. |
on |
Lists the event or events that start the workflow. Here, every matching push triggers it. |
jobs |
Contains one or more jobs. This file defines a job called check-bats-version. |
runs-on |
Selects the runner environment. ubuntu-latest uses a GitHub-hosted Ubuntu runner. |
steps |
Lists work performed in sequence inside the job. |
uses |
Invokes a reusable action. The example uses checkout and Node.js setup actions. |
with |
Passes inputs to the preceding action, here the Node.js version. |
run |
Runs a shell command on the runner. |
Use spaces for YAML indentation and keep child keys nested consistently. Workflow files must be in .github/workflows/ and use a .yml or .yaml extension. GitHub associates a workflow with the event’s commit SHA or ref, so a file in the wrong location or absent from the pushed commit will not run for that event.
2. Understand the workflow model
The basic path is event → workflow → job → runner → steps. A workflow is the repository-checked-in automation. An event triggers a run. Each job has steps, and a runner executes that job. A step can run a shell command or call an action, which packages a reusable task. Steps in one job run in order and can share files through the runner. Independent jobs can run in parallel; use job dependencies when one must wait for another. See GitHub’s workflow concepts.
GitHub provides hosted Linux, Windows, and macOS runners. You can also maintain self-hosted runners when you need control over the machine or an environment not covered by hosted runners. Hosted runners reduce machine maintenance; self-hosted runners make you responsible for keeping the machine available and secure. Choose based on your operating system, hardware, network, and maintenance needs.
3. Choose a trigger and decide when it should run
The on key controls when a workflow starts. For a first CI workflow, push is easy to understand: a push that includes the workflow file can trigger a run. Other common choices are pull-request activity, manual dispatch, and schedules.
- Push: run automation when commits are pushed. Use it when each update should receive checks.
- Pull request: run checks around proposed changes. This is useful when you want feedback before merging; choose the activity types and branches relevant to your process.
- Manual dispatch: let an authorized user start a run when needed, for example for an intentional maintenance task.
- Schedule: run on a recurring timetable. Account for the fact that scheduled work is time-based and may not need to run on every code change.
For the exact event syntax and available filters, consult the live workflow syntax reference. Add branch or path filters only when you have a clear reason: a filter that excludes the relevant change can make a workflow appear not to run.
4. Start from a template or write your own
GitHub can suggest templates based on repository contents. Its templates cover areas such as CI, deployments, automation, code scanning, and Pages. You can also browse the starter workflows repository.
| Approach | Good fit | What to check |
|---|---|---|
| Use a template | You want a quick starting point for a familiar language or task. | Read its comments, triggers, permissions, action references, and setup requirements. Replace assumptions that do not match your project. |
| Write a small workflow | You want to learn the pieces or automate a narrow task. | Start with one event, one job, and a few explicit steps; expand when the need is clear. |
A template is configuration to review, not a guarantee that it fits your repository. If it refers to a secret, create that secret deliberately and understand what access it grants before enabling the workflow.
5. Add secrets safely when a workflow needs credentials
Do not hard-code API keys, deployment tokens, or passwords in YAML. GitHub secrets are encrypted values scoped to an organization, repository, or environment. A workflow receives one only when it is explicitly passed to an action or exposed as an environment variable. Environment secrets can require reviewer approval. Avoid printing secret values to logs, and review GitHub’s secrets guidance and secure-use guidance before handling privileged deployments.
For example, after adding a repository secret named DEPLOY_TOKEN in repository settings, pass it only to the step that needs it:
steps:
- name: Deploy
run: ./scripts/deploy.sh
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
The command or deployment script should read the token from its environment and must not print it. Grant workflows only the permissions they need, especially when a workflow handles untrusted pull request content. The available secret counts and size limits are documented by GitHub and can change; check the live reference if you approach a limit.
6. Find and read a workflow run
- Push a commit containing the workflow file and matching the configured event.
- Open the repository’s Actions tab.
- Choose the workflow in the left list, then select the run associated with your commit.
- Open the job to see each step’s status and logs.
- After changing the YAML, push another matching commit and inspect the new run rather than assuming the earlier run updated.
If you cannot see the Actions tab, Actions may be disabled for the repository. Repository or organization policy can also constrain which actions may run. Check the repository’s Actions settings or ask an administrator who manages those settings.
7. Troubleshoot common first-run problems
| Symptom | Likely cause | Fix |
|---|---|---|
| No workflow appears in Actions | The file is outside .github/workflows/, has no YAML extension, or was not pushed to the relevant ref. |
Check the path, extension, commit, and branch. Confirm the event matches the ref containing the workflow. |
| The workflow exists but no run starts | The event or branch/path filters do not match, Actions is disabled, or repository policy blocks the workflow. | Review on and its filters, verify Actions settings, and inspect policy restrictions. |
| “Invalid workflow file” or a YAML parsing error | Indentation, quoting, or mapping syntax is invalid. | Use consistent spaces, inspect the line named by GitHub, and compare the nesting with the example. |
| An action is not allowed or cannot be found | Organization or repository policy restricts it, the reference is wrong, or the action version is unavailable. | Check the action’s official repository and version, then review allowed-action settings with the repository administrator. |
| A shell command reports “command not found” | The runner image does not include the tool, or the workflow did not install/setup it. | Add an explicit setup or install step and choose a runner compatible with the tool. |
| A step cannot find project files | The repository was not checked out, or the command assumes a different working directory. | Place actions/checkout before commands that need source files, and check the path used by the command. |
| A secret is empty or unavailable | The secret name or scope is wrong, it was not explicitly passed, or an environment approval is pending. | Check spelling and scope, pass it through env or the action’s expected input, and inspect environment protection. Do not print the value to debug it. |
| A pull-request workflow behaves differently for a fork | Secrets and write access are constrained for untrusted contributions. | Follow GitHub’s secure-use guidance; avoid granting privileged credentials to code you do not trust. |
8. Performance, reliability, and cost
For a first workflow, keep the job small and install only what the task needs. Put independent checks in separate jobs only when parallel execution helps; each job may need setup of its own. Avoid running expensive or slow work on every event unless that feedback is worth the additional runs. Caching and concurrency controls can help larger workflows, but configure them for the project’s actual dependencies and event patterns using the official syntax documentation.
A job depends on its runner and every action or external service it calls. Pin and review action references according to your organization’s security policy, keep tool versions intentional, and inspect logs when a dependency changes. Hosted and self-hosted execution have different maintenance responsibilities; choose one that suits your environment.
GitHub documents a maximum workflow-run duration of 35 days, a six-hour maximum for a GitHub-hosted job, and a 256-job matrix maximum in the limits reference. These are upper bounds, not targets, and GitHub notes limits can change. Most starter workflows need far less time. Check the current Actions limits and your plan’s billing details before scaling usage. Costs depend on GitHub’s current plan and runner usage; this guide does not assume a price.
Or skip the browser setup
If your workflow needs screenshots of a website for visual checks, reports, or documentation, ScreenshotNeo provides a website screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. It can accept cookie banners and remove known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture.
Here is a GitHub Actions step using the API. Add an SCREENSHOTNEO_API_KEY repository secret first, then use the key as an environment variable so it is not stored in the workflow file:
- name: Capture page screenshot
run: |
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key="$SCREENSHOTNEO_API_KEY" \
--data-urlencode url=https://stripe.com \
-o shot.webp
env:
SCREENSHOTNEO_API_KEY: ${{ secrets.SCREENSHOTNEO_API_KEY }}
See the ScreenshotNeo API documentation for request options. The same call in other clients:
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo has 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000. Every feature is available on every plan. Create a free account at ScreenshotNeo sign-up.
Frequently asked questions
Do I need to install GitHub Actions?
No. Workflows are YAML files in your repository, and GitHub runs them when their configured events occur, subject to repository settings and available runners.
Can a workflow have more than one job?
Yes. Independent jobs can run in parallel. Declare dependencies when a job must wait for another job to finish.
Can I start a workflow without pushing a commit?
Yes, if it is configured with a manual trigger such as workflow_dispatch and the repository’s settings permit it.
Where do I check the current action versions and limits?
Use the action’s official documentation or repository for its current usage and version guidance, and GitHub’s live workflow syntax and limits references for platform details.


