Skip to main content
This guide walks through creating a simple GitHub Actions workflow and troubleshooting a common failure: forgetting to check out the repository, which leaves the runner workspace empty. We’ll pause our Jenkins pipeline for the moment and explore GitHub Actions instead.
A screenshot of the Jenkins Blue Ocean pipeline activity page for the job "ci-pipeline-poll-scm", showing a list of recent pipeline runs with status icons, run numbers, messages and durations.
Example: a Jenkins pipeline (for context) that we are not running while migrating to Actions:
pipeline {
    agent {
        label 'us-west-1-ubuntu-22'
    }
    tools {
        nodejs 'nodejs-22-6-0'
    }

    environment {
        MONGO_URI = "mongodb+srv://supercluster.d83jj.mongodb.net/superData"
        MONGO_DB_CREDS = credentials('mongo-db-credentials')
        MONGO_USERNAME = credentials('mongo-db-username')
        MONGO_PASSWORD = credentials('mongo-db-password')
    }

    stages {
        stage('Installing Dependencies') {
            agent {
                docker {
                    image 'node:24'
                    args '-u root:root'
                }
            }
            steps {
                sh 'npm install --no-audit'
            }
        }

        stage('Dependency Scanning') {
            parallel {
                stage('NPM Dependency Audit') {
                    steps {
                        sh '''
                            npm audit --audit-level=critical
                        '''
                    }
                }
            }
        }
    }
}
Create a new repository on GitHub (for example actions-1) and add a README. Open the repository’s Actions tab and click Configure to create a starter workflow — GitHub will create .github/workflows/<your-file>.yml for you.
A dark-mode GitHub repository page for "actions-1" showing the main branch, an initial commit and a README.md file. The right sidebar displays repository metadata like stars, forks, releases, and package links.
GitHub often provides this starter workflow template:
# This is a basic workflow to help you get started with Actions
name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events (example)
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

# Allows manual runs from the Actions tab
workflow_dispatch:

jobs:
  # A single job called "build"
  build:
    runs-on: ubuntu-latest

    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v4

      # Example steps
      - name: Run a one-line script
        run: echo Hello, world!
You can simplify the triggers and rename the job. This example triggers on any push and allows manual runs:
name: CI

on:
  push:
  workflow_dispatch:

jobs:
  first_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Welcome Message
        run: echo "My first GitHub Action Job"

      - name: List files on repo
        run: ls

      - name: Read README
        run: cat README.md
A common mistake is omitting the checkout step. If you comment out or remove actions/checkout, the runner will not have your repository files by default — ls will show an empty workspace and cat README.md will fail. When a workflow runs, GitHub prints runner setup information (OS, image versions, and a long list of preinstalled tools). You can review the hosted runner images and available tools in the documentation.
A GitHub repository page showing the Ubuntu2404-Readme.md file in a dark theme, listing installed languages (Node.js, Python, Ruby, etc.) and package management tools with a file tree in the left sidebar.
If you remove checkout and push the workflow, the run will fail during the file-read step. Example failing run summary:
demo.yml
on: push

first_job
Process completed with exit code 1.
A failed “Read File” step appears like this in the Actions UI:
A GitHub Actions run page (dark theme) showing a failed workflow "Update README.md #2" for the repo, with the job "first_job" and a failed "Read File" step. Other steps like "Set up job" and "Welcome Message" are shown as completed.
Example job log when the repository wasn’t checked out:
Run echo "My first GitHub Action Job"
My first GitHub Action Job

Run ls
ls
shell: /usr/bin/bash -e {0}

Run cat README.md
cat: README.md: No such file or directory
Error: Process completed with exit code 1.
Why did this happen? By default the runner’s workspace does not include your repository files. To make your repository available to the job, include the checkout action: actions/checkout@v4. Key differences in workflow syntax:
KeywordUse caseExample
uses:Run a prebuilt action from the Marketplace or a repositoryactions/checkout@v4, docker/build-push-action@v6
run:Execute inline shell commands on the runnerecho, ls, cat, npm
Always include - uses: actions/checkout@v4 (or the appropriate version) as the first step if your job needs repository files. Note: hidden files (like .github) won’t appear with ls unless you run ls -a.
After adding (or uncommenting) the checkout step and rerunning the workflow, the job has access to repository files and cat README.md will succeed. Here is the final example workflow:
name: CI

on:
  push:
  workflow_dispatch:

jobs:
  first_job:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v4

      - name: Welcome Message
        run: echo "My first GitHub Action Job"

      - name: List files on repo
        run: ls

      - name: Read README
        run: cat README.md
When the workflow runs successfully you’ll see the checkout step complete, ls listing README.md, and the README content printed in the logs:
Run ls
README.md

Run cat README.md
# Exploring Actions
We will be learning GitHub Actions,
- a robust automation tool that empowers you to streamline repetitive tasks
- how to automate your software development workflows
- techniques to enhance productivity and code quality
Marketplace and useful community actions Example: a Docker build-and-push job using popular Marketplace actions:
name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: user/app:latest
You can also manually trigger workflows from the Actions tab (Run workflow) or rely on triggers such as pushes and pull requests. The basic flow is:
  1. Define triggers in your workflow YAML.
  2. Run jobs on runners (hosted or self-hosted).
  3. Use actions/checkout to access repository files.
  4. Combine Marketplace uses actions with run shell steps to build, test, and deploy.
If your job needs repository content, do not forget actions/checkout. Missing this step is the most common cause of “No such file or directory” errors when reading files in Actions.
That’s the basics of creating and troubleshooting your first GitHub Actions workflow. For deeper reference and runner images, see:

Watch Video