Depend on another workflow

Is it possible for a workflow to depend on another workflow?

We currently have two workflows. test and deploy.

Currently, the test workflow is responsible for testing the code base. The deploy workflow is responsible for testing, building and deploying the code base.

The test workflow runs on any push to all branches.

The deploy workflow only runs from a push on the master branch.

The current setup has two negative side effects. 1) we have to duplicate the test steps in both the test and deploy workflow. 2) when pushing to master the test steps get run twice. Once in the test workflow and once in the deploy workflow.

If would be great if there was a way to only run the deploy workflow if the test workflow was successful. Eliminating the requirement of duplicating steps between workflows and testing the code base twice.

22 Likes

I believe the intent in GH Actions is to use _jobs_ for this purpose rather than workflows.

e.g., one ci.yml workflow that contains jobs for building, testing, deploying, etc.

To that end, it would be great if jobs could be factored out into stand-alone files as parameterized templates.

4 Likes

Yes, this is possible. Assuming that you have enabled protection settings on your master branch to only allow merging pull requests whenever your CI workflow has run successful, you can create a secondary workflow that only triggers when the pull request is merged (because by then you already know the tests succeeded).

So you could have a CI workflow like:

---
name: CI

on:
  pull_request:
    branches:
      - master

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - <YOUR TEST STEPS HERE>
...

Then, create a secondary workflow (let’s call it deploy) that only runs when the PR was merged. By default, actions are not run when a PR is closed, unless you specifically request this with the types condition in your on clause, so the CI workflow will not trigger, but this one will:

---
name: Deploy

on:
  pull_request:
    types: [closed]
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
if: github.event.pull_request.merged

    steps:
      - name: checkout
        if: github.event.pull_request.merged
        uses: actions/checkout@v1
with:
ref: master

- <YOUR DEPLOY LOGIC HERE>

The:

if: github.event.pull_request.merged

condition on the job makes sure that it is only run when the PR was actually merged (rather then being closed without merging).

16 Likes

Is the latter if (the one under steps) actually necessary?

Yes, because you can close a PR without merging it I guess

This would require the second workflow to re-run build + all tests. I’d need the artifacts generated by the previous workflow and only deploy there, not having to run the whole thing again

1 Like

I am also looking for this. Would be nice if we could use on in a specific *job* (as opposed to the whole workflow), so e.g. the deploy job could run after the build job, but only when it was a merge to master.

@ianaz I found this which seems to help: https://stackoverflow.com/questions/58139406/only-run-job-on-specific-branch-with-github-actions

tl;dr use if condition in job

if: github.ref == 'refs/heads/master'

Hi :wave:

We’re in a similar situation now. I was here to ask the same question, then found this thread.

We have 4 workflows:

  • commit-stage (sanity-check, lint, unit-tests, coverage): runs on every commit
  • build-stage (startup, build, preview-deployment, integration-tests, functional-tests, teardown): runs on new pull requests to master
  • deploy (build, deploy, smoke-test): runs on every new commit to master (basically after pr’s merged)
  • release (build, deploy): runs when there’s a new release/tag

As you can see, every step highly depends on the previous steps to be done completely, to move forward. But since we cant use needs to point to another workflow, we need to duplicate most of the jobs and steps in every file, we need to add unnecessary ifs here and there, and in the end, it’ll take a lot more effort to keep them maintained and sync.

We can put them all in one workflow, that listens to commit, pull_request, release events, and use needs to at least make them depend on each other, but again, we need to somehow limit their scopes with ifs and with maybe other checks.

What I was thinking was, in build-stage.build for example, it’d be great to use something like needs: [ 'commit-stage.unit-tests' ] so that it goes up to the workflows folder, finds commit-stage.yml (part comes before .) then goes in there and finds unit-tests. Not sure if logistically this is possible (considering action workspace and all) but that’d definitely make dependencies more powerful and help with a nicer/leaner workflows.

I hope this makes sense, thanks in advance!

12 Likes