GitHub Actions Job Dependencies

GitBeginner
Practice Now

Introduction

In real-world CI/CD pipelines, workflows are rarely just a single list of steps. They are often composed of multiple distinct "jobs" that need to run in a specific order.

For example, you might have a Build job that compiles your code, and a Deploy job that pushes it to a server. You definitely don't want the Deploy job to run if the Build job fails, and you can't run them at the same time because the deployment needs the built artifacts.

In this lab, you will split your workflow into two separate jobs and use the needs keyword to enforce a dependency, ensuring the deploy job waits for the build job to complete successfully.

This lab builds on the repository you created in the previous labs. You will work with the github-actions-demo repository.

Define a build job

First, we will clean up our existing workflow to have a focused build job. We'll simplify the matrix strategy from the previous lab for clarity, going back to a single version to keep the focus on job dependencies.

  1. On your GitHub repository page for github-actions-demo, click the green Code button.
  2. Ensure the HTTPS tab is selected and copy the URL. It should look like https://github.com/your-username/github-actions-demo.git.
  3. Open the terminal in the LabEx environment. The default path is ~/project.
  4. Use the git clone command to download the repository. Replace your-username with your actual GitHub username.
cd ~/project
git clone https://github.com/your-username/github-actions-demo.git

Example Output:

Cloning into 'github-actions-demo'...
remote: Enumerating objects: X, done.
remote: Counting objects: 100% (X/X), done.
remote: Total X (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (X/X), done.
  1. Navigate into the cloned repository:
cd ~/project/github-actions-demo
  1. Create a new workflow file .github/workflows/job-dependencies.yml using the WebIDE editor. You can find the file in the file explorer on the left side under project/github-actions-demo/.github/workflows/.

  2. Start by creating the basic workflow structure. Add the workflow name and trigger:

name: Job Dependencies

on: [push]
  1. Add the jobs section and define the build job with its runner:
jobs:
  build:
    runs-on: ubuntu-latest
  1. Add the steps section. First, add the checkout step to get the repository code:
steps:
  - uses: actions/checkout@v4
  1. Add the Node.js setup step:
- name: Use Node.js
  uses: actions/setup-node@v4
  with:
    node-version: "20"
  1. Add the step to install dependencies:
- name: Install dependencies
  run: npm install
  1. Add the step to run tests:
- name: Run tests
  run: npm test
  1. Add the build step that creates the artifact directory and file:
- name: Build project
  run: |
    mkdir dist
    echo "Build artifact created at $(date)" > dist/build.txt
  1. Finally, add the upload artifact step. This step is crucial because it saves the build output so the next job can use it:
- name: Upload build artifact
  uses: actions/upload-artifact@v4
  with:
    name: dist-files
    path: dist

Your complete file should now look like this:

name: Job Dependencies

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build project
        run: |
          mkdir dist
          echo "Build artifact created at $(date)" > dist/build.txt
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist-files
          path: dist

Explanation

  • We removed the matrix strategy for simplicity.
  • We kept the Upload build artifact step. This is crucial because the next job will need these files!

Save the file (Ctrl+S or Cmd+S) after making changes.

Define a deploy job that needs build

Now we will add a second job named deploy. This job should only run if build succeeds. We achieve this using needs: build.

  1. Append the following deploy job to your .github/workflows/job-dependencies.yml file. Make sure it is at the same indentation level as build.

  2. Start by adding the deploy job definition with its runner and dependency:

deploy:
  runs-on: ubuntu-latest
  needs: build

The needs: build line is crucial - it tells GitHub Actions that this job depends on the successful completion of the build job.

  1. Add the steps section. First, add the step to download the artifact:
steps:
  - name: Download artifact
    uses: actions/download-artifact@v4
    with:
      name: dist-files
      path: dist

This downloads the artifact that was uploaded in the build job. The name must match the name used in the upload step.

  1. Add the deploy step:
- name: Deploy project
  run: |
    echo "Deploying project..."
    ls -R dist
    echo "Deployment successful!"

This step simulates a deployment by listing the downloaded files.

  1. Your full file structure should look like this:
name: Job Dependencies

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build project
        run: |
          mkdir dist
          echo "Build artifact created at $(date)" > dist/build.txt
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist-files
          path: dist

  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: dist-files
          path: dist
      - name: Deploy project
        run: |
          echo "Deploying project..."
          ls -R dist
          echo "Deployment successful!"

Explanation

  • needs: build: This is the key line. It tells GitHub Actions that this job depends on the successful completion of the build job.
  • uses: actions/download-artifact@v4: Since jobs run on different virtual machines, they don't share filesystems. To get the dist folder created in the build job, we must download the artifact we uploaded earlier.
  • name: dist-files: Must match the name used in the upload step.

Save the file (Ctrl+S or Cmd+S).

Commit, push, and verify sequential execution

Now let's verify that the jobs run in the correct order.

  1. Ensure you are in the repository directory:
cd ~/project/github-actions-demo
  1. Stage the changes:
git add .
  1. Commit the changes:
git commit -m "Add deploy job with dependency on build"
  1. Push the changes to the remote repository on GitHub:
git push

Note on Authentication:
When you run git push, the WebIDE will automatically prompt you to authenticate. Follow these detailed steps:

  1. A popup will appear with the message: "The extension 'GitHub' wants to sign in using GitHub." Click Allow.
  2. A new notification will appear. Click "Copy&Continue to GitHub", then click "Open" in the next prompt.
  3. Log in to your GitHub account in the browser window that opens, and enter the authorization code that was copied. After confirming the authorization, the page will automatically close.
  4. Wait a few seconds, and you will see the terminal successfully complete the push operation.

Privacy Note: The WebIDE will request full access to your GitHub account for authentication purposes. You don't need to worry about privacy concerns - the LabEx VM will be immediately destroyed after you complete the current lab, and your credentials and authorization information will not be retained.

This authentication process does not require manual configuration of username or Personal Access Token.

Verify on GitHub

  1. Visit your repository on GitHub in a web browser.
  2. Click on the Actions tab.
  3. Click on the latest workflow run.
  4. Look at the visualization graph. You should see two circles (jobs) connected by a line.
    • The build job will be on the left.
    • The deploy job will be on the right.
  5. Watch the progress. You will notice that deploy stays in a "Pending" or "Waiting" state until build turns green (Success).
  6. Once build finishes, deploy will start.
  7. Click on the deploy job logs to see the "Deploying project..." message and the file listing of the downloaded artifact.
GitHub Actions job dependencies

Summary

In this lab, you learned how to orchestrate multi-job workflows in GitHub Actions. You:

  1. Created separate build and deploy jobs.
  2. Used the needs keyword to define a dependency, ensuring deploy runs only after build.
  3. Used upload-artifact and download-artifact to pass data (files) between these separate jobs.

This pattern is fundamental for building robust CI/CD pipelines where you want to build once and then deploy to multiple environments (staging, production) only if previous steps succeed.