How to modularize actions?

There are multiple questions created long back and no response on them later.
The recent one is in 2019 last reply without any solution.
There is no use to resurrect them, so creating a new one.

I have a github action workflow job steps containing 10 to 15 windows batch commands, which I am running in my self-hosted windows server.

The same steps need to be repeated multiple times for different input files.

Is there anyway to create a module of this and call this with the parameters changed?

Please suggest.

2 Likes

Hi @ukreddy-erwin
There are a few ways to reduce duplication: composite actions and reusable workflows.
They can’t solve all aspects but could help.
Please, take a look at a few articles:

or

1 Like

I tried the steps in the second link composite action as is but.
I created a repo in my account ukreddy-erwin, GitHub - ukreddy-erwin/testactions

So, the workflow yaml changed as


on: [push]

jobs:
  hello_world_job:
    runs-on: ubuntu-latest
    name: A job to say hello
    steps:
      - uses: actions/checkout@v3
      - id: foo
        uses: ukreddy-erwin/testactions@v1
        with:
          who-to-greet: 'Mona the Octocat'
      - run: echo random-number ${{ steps.foo.outputs.random-number }}
        shell: bash

But, it is failing as below error.

Error: Unable to resolve action ukreddy-erwin/testactions@v1, repository not found

So, I changed the repo to public and tried and got below error.

How to keep them working in private repo?

/home/runner/work/_temp/80546fcd-4e8c-4b37-8201-dfd471a8cd93.sh: line 1: /home/runner/work/_actions/ukreddy-erwin/testactions/v1/goodbye.sh: Permission denied

[18](https://github.com/ukreddy-erwin/testworkflow/runs/6653946764?check_suite_focus=true#step:3:23)Error: Process completed with exit code 126.

Even I added chmod +x command as one step in action but getting this,
Run echo “/home/runner/work/_actions/ukreddy-erwin/testactions/ffbd787a4b9f0752347c5f62f2137460961e5a83” >> $GITHUB_PATH

12 echo “/home/runner/work/_actions/ukreddy-erwin/testactions/ffbd787a4b9f0752347c5f62f2137460961e5a83” >> $GITHUB_PATH

13 shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}

14Run chmod +x goodbye.sh

15 chmod +x goodbye.sh


[16](https://github.com/ukreddy-erwin/testworkflow/runs/6654053815?check_suite_focus=true#step:4:20) shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}

[17](https://github.com/ukreddy-erwin/testworkflow/runs/6654053815?check_suite_focus=true#step:4:22)chmod: cannot access 'goodbye.sh': No such file or directory

[18](https://github.com/ukreddy-erwin/testworkflow/runs/6654053815?check_suite_focus=true#step:4:23)Error: Process completed with exit code 1.
1 Like

Actions can be in internal repo (you need Enterprise GitHub org), but not private.
You can checkout your action repo as any other private repo to specific subfolder and use it as “local” action.

So, unfortunately it is no easy way to have actions in private repo:s.

1 Like

how to keep in the same repo as a sub folder and refer them?

1 Like

You can take a look at this thread Path to action in the same repository as workflow - #2 by yanjingzhu

1 Like

Also this one is good example Multiple github composite actions in one repo - #2 by mcaskill
only token is needed to checkout private repository

Thanks @ViacheslavKudinov , I tried the steps but not working.

Below is the steps I tried.

I kept an action.yml in the root folder of repo and tried to reference it in the github workflow.
But it is not able to find the yml file.
I kept ls -la top to it and it shows the file but the workflow not picking it up.
Can you see this once

@ukreddy-erwin, please, change step to

      - name: external step
        uses: ./

Thank you it works, so we it would pick from the folder directly.
So, we can’t keep multiple yaml files in the same folder right?
If can, how to refer in the users: ./

Also, i tried referring the input variable in the bash file of the action, but it is not expanding.Can you guide that also.

Also, is there anyway to keep these main workflow, actions, everything in a separate repository? so that these changes won’t add new commits to main codebase.

You can use subfolders if you wish and then it will be:

uses: subfolder

and it will pick up action.yaml from that subfolder.
Moreover you can have several subfolders, depends on your use case.

Yes, if you wish you can have one repo per one GitHub action and also utilise reusable workflow if you want to have workflow as separate code/repo.
Repo for GHA has to be public for the simplest usage, or internal if you have Enterprise GH account/organisation.
Please, read few articles Reusing workflows - GitHub Docs
Sharing workflows, secrets, and runners with your organization - GitHub Docs

In jenkins, say I have my source code in repoA. I can keep my pipeline file in repoB and in a separate branch say testB.
Then, in jenkins project, I can simply refer this repoB/testB branch pipeline file and it will run for repoA.

Can we set similarly here?

It really depends what you want to achieve.
But technically you can use GHA from any repo and branch/tag, just use
uses: my-org/my-action-repo@branch(or tag).
Same for reusable workflow:
uses: my-org/my-gha-repo/.github/workflows/reusable-workflow.yml@branch

If you don’t have Enterprise account/org it will be more complex (or maybe even not everything is possible) if you want to use private repositories for GHA:s and reusable workflows.

can we set something like.

Current repoA:

.github/workflows/main.yml

reference: myorg/repoB/branch1/workflow.yml

this workflow.yml is complete workflow, not an action.

You have to use syntax eg:
uses: myorg/repoB/.github/workflows/workflow.yml@branch1
part .github/workflows is mandatory as I know and it is where reusable workflow has to be in your repoB, branch name comes after @.

1 Like

Can you answer the input variables part also.

It is not getting expanded in bash file.

tried referring the input variable in the bash file of the action, but it is not expanding.Can you guide that also.

ukreddy-erwin/testactions/blob/8a9c78356cf770ba32016d03b56e4d3b2fd46ab6/goodbye.sh

If I remember correctly inputs not available by default as environment variables.
You need to use env section for job, eg

env:
variable: ${{ inputs.name }}

PS IT WAS THE WRONG SUGGESTION, SORRY!!!

I tried and got below error.

Let me double-check and I will be back soon.