0

I referred many answers such as this and this, but none of them were satisfactory since they call another workflow directly.

on:
  workflow_run:
    workflows: ["Build"]
    types:
      - completed

Above workflow triggers when workflow is completed/succeeded.

So far, My code can handle errors better, so it'll always (I hope it to be) succeed.

Let's say:

  • workflow_1.yml
  • workflow_2.yml

I want to call workflow_2.yml from workflow_1.yml. This is simple and can be done with:

- name: Call another workflow
  uses: ./.github/workflows/workflow_2.yml

but, can I call workflow_2.yml like this?

jobs:
  update_fork:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Forked Repo
        uses: actions/checkout@v3
      # some other steps that makes condition to be true
      - name: Call another workflow
        run: |
          # some other code
          if [ $condition == "true" ]; then
            # call workflow_2.yml
          fi

Edit_1:
I added if statement as another step to the above code:

- if: ${{ steps.fetch.outputs.build_app == 'true' }}
  uses: ./.github/workflows/android_build.yml

I'm pretty much sure by now that this will not work and hence it kept throwing this below error:

Error: Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under '/home/runner/work/wftest/wftest/.github/workflows/android_build.yml'. Did you forget to run actions/checkout before running your local action?

This is because, I need to call it from another job i.e., it is illegal to call another workflow within a step as far as I remember.

theycallmepix
  • 474
  • 4
  • 13
  • Why not simply add an `if` for the step itself and mention the workflow in `uses`? Under `run` it's a shell now. The workflow should be meaningless there unless there's another runner there accepting jobs which I'm sure is not the case here. What exactly is your use case? – Azeem Jan 21 '23 at 10:41
  • I'm trying automate stuffs a bit. `workflow_1.yml` fetches updates from upstream. Only if update exists, it'll fetch commits. Else, prints "no commits to sync". Since it fetches commits, I want to call the workflow_2.yml that builds the app after syncing with upstream – theycallmepix Jan 21 '23 at 10:45
  • There could be multiple ways to achieve this. You can simply set an env var i.e. `GITHUB_ENV` and check that in the next step with `if`. The next step will only proceed if that env var is set. Another alternative would be to set the output i.e. `GITHUB_OUTPUT` instead and use that in the `if` condition. – Azeem Jan 21 '23 at 10:51
  • 1
    Relevant: https://stackoverflow.com/questions/75178201/outputs-for-github-actions-on-windows-hosted-runner – Azeem Jan 21 '23 at 10:53
  • Ok, so, on successful fetch, I'm supposed to store a variable, say 1, into `env` and check whether env has a one or not in a different if step. If yes, call `workflow_2.yml`. Is this what you meant? – theycallmepix Jan 21 '23 at 11:01
  • 1
    Yes, As this is part of the same job, using an env var seems to be a straightforward solution. See: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable. You may use the output as well. See: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter. IMO, using the output would be more expressive. – Azeem Jan 21 '23 at 11:03
  • Ah, I started this, I got confused, stopped and asked here! I think this will be my answer... I'm stopping for now since I need to study for tomorrow's (monday) exam. I'm thinking of using output so that I can see what's happening over there. – theycallmepix Jan 21 '23 at 11:05
  • 1
    Yes, that should solve this. Good luck! – Azeem Jan 21 '23 at 11:08
  • I was able to implement the thing, but builds are failing just because it cannot find the file. `Error: Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under '/home/runner/work/wftest/wftest/.github/workflows/android_build.yml'. Did you forget to run actions/checkout before running your local action?` – theycallmepix Jan 24 '23 at 10:23
  • Please update your question with all the details. From that message, it does look like the checkout is missing or it's a different branch with different content. – Azeem Jan 24 '23 at 10:39
  • I updated my question some more details. Please do check it out. – theycallmepix Jan 24 '23 at 12:09
  • Please include your complete workflow which is reproducible in isolation. – Azeem Jan 24 '23 at 13:00
  • Updated the code again – theycallmepix Jan 24 '23 at 13:05
  • According to docs (https://docs.github.com/en/actions/using-workflows/reusing-workflows#calling-a-reusable-workflow), "**You call a reusable workflow by using the `uses` keyword. Unlike when you are using actions within a workflow, you call reusable workflows directly within a job, and not from within job steps.**". – Azeem Jan 24 '23 at 13:35
  • You can configure this second workflow which should run when the first one finishes. See [workflow_run](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) for more details. – Azeem Jan 24 '23 at 13:45
  • FYI, I've been roaming on the pages that you shared now since morning today.. with no success so far. I'm aware that I need to call it via uses immediately after creating another job and that's I've mentioned in my question. I currently have no idea about how to implement them under condition statement. – theycallmepix Jan 24 '23 at 13:51
  • For your use case, you don't need a reusable workflow. You need one workflow that syncs your repo (that you already have shared) and another one that runs on its completion (one that builds it). With `workflow_run`, you can mention the condition in your second workflow that it should run on the successful completion of the first one. Even with a reusable workflow, you'll have to mention that somehow and that's why I mention `workflow_run` in my previous comment but that would add redundancy of creating "envelop" workflow which is not needed at all. Does that make sense? – Azeem Jan 24 '23 at 14:51
  • I've already played a bit with `workflow_run`. But the thing is, I don't want to trigger `build_workflow.yml` everytime runs since the first workflow doesn't fail. What happens if I don't add a condition is that, the build would be triggered everytime, the `wf1.yml` is triggered. I only want it to trigger only if upstream has got some commits to be merged.. My thinking currently is that, read output of `wf1.yml` in `wf2.yml` and only run if that variable has value. IDK how to achieve that as of now – theycallmepix Jan 24 '23 at 15:08
  • Right. I believe that's doable by setting output parameters for jobs. See this example: https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-outputs-from-a-reusable-workflow. You need to slightly change your current config. Move the second workflow from the step and put it under another job e.g. `build`, add a `needs: update_fork` section, and then use the output of the previous job i.e. `if: ${{ needs.update_fork.outputs.build_app }}`. I think that's pretty much it. That should do it. – Azeem Jan 24 '23 at 15:55
  • Here's a very similar example: https://github.com/iamazeem/test/blob/main/.github/workflows/ci-win-share-output-bw-jobs.yml but it's without a reusable workflow. – Azeem Jan 24 '23 at 15:57
  • please elaborate this a bit more – theycallmepix Jan 24 '23 at 16:00

1 Answers1

0

After digging in and out the documentation for about 11 hours by trying and testing few other methods, I learnt that, currently, there's no way to call another workflow within steps and it is not possible to share values between workflow.yml files.

I solved this by following my own traditional method which is described below.

Logic

I cannot call a workflow based on condition. However, that doesn't stop me from raising an error.
This answer of mine describes what I was trying to do in the first place.
Adding command: exit 1 in the else block in the foo.yml file immediately stops the execution by throwing an Error. However, if the below is added in the bar.yml, it doesn't stop the execution of it on failure.

on:
  workflow_run:
  workflow: ["Foo"]
    types: [completed]

A simple method to get around this is to call the workflow i.e., call bar.yml from foo.yml's new job as shown below.

jobs:
  job1:
    # some code 
    if [this]; then
      echo "Hi"
    else
      exit 1
    fi
  job2:
    needs: job1
    uses: ./.github/workflows/bar.yml

Since job2 is now dependent on job1, bar.yml isn't called for execution until foo.yml is succeeded which is possible only if statement is executed.

theycallmepix
  • 474
  • 4
  • 13