385 words
2 minutes
Conditionally running a second job in a GitHub Actions workflow

Conditionally running a second job in a GitHub Actions workflow#

My simonwillisonblog-backup workflow periodically creates a JSON backup of my blog’s PostgreSQL database, using db-to-sqlite and sqlite-diffable. It then commits any changes back to the repo using this pattern:

- name: Commit any changes
run: |-
git config user.name "Automated"
git config user.email "actions@users.noreply.github.com"
git add simonwillisonblog
timestamp=$(date -u)
git commit -m "Latest data: ${timestamp}" || exit 0
git push

I decided to upgrade it to also build and deploy a SQLite database of the content to datasette.simonwillison.net - but only if a change had been detected.

I figured out the following pattern for doing that.

First, I added a line to the above block that set a change_detected output variable for that step if it made it past the || exit 0. I also added an id to the step so I could reference it later on:

- name: Commit any changes
id: commit_and_push
run: |-
git config user.name "Automated"
git config user.email "actions@users.noreply.github.com"
git add simonwillisonblog
timestamp=$(date -u)
git commit -m "Latest data: ${timestamp}" || exit 0
git push
echo "::set-output name=change_detected::1"

This next piece took me a while to figure out: I also had to declare that output variable at the top of the initial job, copying the result of the named step:

jobs:
backup:
runs-on: ubuntu-latest
outputs:
change_detected: ${{ steps.commit_and_push.outputs.change_detected }}

Without this, the output is not visible to the second job.

My second job started like this:

build_and_deploy:
runs-on: ubuntu-latest
needs: backup
if: ${{ inputs.force_deploy || needs.backup.outputs.change_detected }}
steps:

This second job is called build_and_deploy and specify that it needs: backup - so it should run directly after that backup job completes.

That new job has an if: expression which looks at needs.backup.outputs.change_detected to read the variable that was set by my echo "::set-output line.

I’m also checking inputs.force_deploy here. That’s a separate mechanism, which allows me to trigger the workflow with manually and specify that a deploy should happen even if no changes were detected - useful for when I alter the code that configures the deployed Datasette instance.

The force_deploy variable comes from this section at the start of the YAML:

on:
push:
branches:
- main
workflow_dispatch:
inputs:
force_deploy:
description: 'Deploy even if no changes detected'
required: false
type: boolean

This configuration adds the following UI which I can use to manually trigger the workflow:

Screenshot of the UI showing the force_deploy checkbox

Conditionally running a second job in a GitHub Actions workflow
https://mranv.pages.dev/posts/conditionally-running-a-second-job-in-a-github-actions-workflow/
Author
Anubhav Gain
Published at
2024-05-25
License
CC BY-NC-SA 4.0