Replies: 11 comments 9 replies
-
You can hack around this limitation by writing an local action to disk and tell the runner to execute it. I made this action to solve an different limitation, but this works too https://github.com/ChristopherHX/conditional/blob/main/action.yml. on:
workflow_call:
inputs:
ref: 'v1'
jobs:
job1:
runs-on: ubuntu-latest
steps:
- uses: ChristopherHX/conditional@b4a9649204f81002ec9a4ef7d4bf7d6b2ab7fa55
with:
step: |
uses: repo/action@${{ inputs.ref }}
with:
arg: ${{ tojson(inputs.ref) }} The whole step property is a string, therefore no error is reported. It is easy to create bugs with step inputs Feel free to copy this little action to your own repo or modify it.
Yes it is possible to get the repository, ref and name of the reusable workflow, see job_workflow_ref claim https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect. However you need to grant the reusable workflow the oidc permission and parse the claims of the jwt. I can try to lookup my sample if you are interested. It would be so much easier if github exposes job_workflow_ref as |
Beta Was this translation helpful? Give feedback.
-
Thanks @ChristopherHX ! This is one ugly hack!!! It does solves the reusable action with the ability to "dynamically" generate the action based on a template. Do you have an idea how to do so with callable workflow? Do you recommend a job which creates a workflow file and job that needs that job in order to call to the locally generated workflow? This will add another step of a runner which takes time and resources. Do you have any other idea? Thank you very much! |
Beta Was this translation helpful? Give feedback.
-
Not everything is possible in a usable way, but Good Luck if you still want to continue.
No, GitHub seems to parse the whole workflow incl. all referenced reusable / callable workflow before any job runs. So you can't generate any callable workflow within the same workflow run.
You probably don't want to do that... I wrote an GitHub Actions Emulator, which can execute your generated workflow on an GitHub Runner or locally. But this would be only an ugly composite action with multiple jobs on one machine without GitHub Support |
Beta Was this translation helpful? Give feedback.
-
Alternatively use oidc, clone your local actions and use Examplecaller workflow name: Test reusable
on:
push:
jobs:
_:
uses: ChristopherHX/newcomposite-sample/.github/workflows/main.yml@local-actions-with-reusable ChristopherHX/newcomposite-sample/.github/workflows/main.yml@local-actions-with-reusable: on:
workflow_call:
jobs:
test:
runs-on: ubuntu-latest
permissions:
id-token: write # required to get an oidc token
contents: read # optional permission to allow cloning the caller repository, not shure what happens if the reusable is in an internal repo
# permissions: write-all # if you don't want to restrict permissions
steps:
- uses: ChristopherHX/oidc@45e798774435c73c1bbf62e2df0ba60f95cdb457
id: oidc
- uses: actions/checkout@v3 # checks out caller workflow
- uses: actions/checkout@v3 # checks out called workflow
with:
path: .github/actions
repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner }}
ref: ${{ steps.oidc.outputs.job_workflow_repo_ref }}
- run: ls
- uses: ./.github/actions/dowork
# nested_workflow:
# uses: ./.github/workflows/second.yml # This is resoved in the same repository and version as the current reusable, I tested this, but couldn't find any documentation about this.
const core = require("@actions/core");
const jwt = require("jsonwebtoken");
(async function() {
try {
var id_token = await core.getIDToken();
var decoded = jwt.decode(id_token , {complete: true});
for(var key in decoded.payload) {
core.setOutput(key, decoded.payload[key]);
}
if(decoded.payload.job_workflow_ref) {
var nameAndRef = decoded.payload.job_workflow_ref.split("@", 2);
if(nameAndRef.length === 2) {
var nameAndPath = nameAndRef[0].split("/");
if(nameAndPath.length >= 3) {
core.setOutput("job_workflow_repo_owner", nameAndPath[0]);
core.setOutput("job_workflow_repo_name", nameAndPath[1]);
core.setOutput("job_workflow_repo_name_and_owner", nameAndPath[0] + "/" + nameAndPath[1]);
core.setOutput("job_workflow_repo_path", nameAndPath.splice(2).join("/"));
}
core.setOutput("job_workflow_repo_ref", nameAndRef[1]);
}
}
} catch(ex) {
core.error("Failed to get odic token, did you forget the `permissions: { id-token: write }` permission in your caller workflow, alternatively `permissions: write-all` works too: " + ex.toString());
process.exit(1);
}
})() dowork is a folder in the called workflow https://github.com/ChristopherHX/newcomposite-sample/tree/local-actions-with-reusable and contains an action next to the reusable workflow See https://github.com/ChristopherHX/Buildbot/runs/8060745717?check_suite_focus=true for an example workflow run. If this solves your problem then please mark as an answer Edit You don't have to specify id-token permission on the calling job / workflow, this simplifies usage a lot. I thought this would be permission elevation, but I guess this a weird default handling. |
Beta Was this translation helpful? Give feedback.
-
on:
workflow_call:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3 # checks out caller workflow
- uses: actions/github-script@v6 # Extract nameAndOwner of github.workflow_ref
id: parseData
with:
script: |
var nameAndRef = process.env.WORKFLOW_REF.split("@", 2);
if(nameAndRef.length === 2) {
var nameAndPath = nameAndRef[0].split("/");
if(nameAndPath.length >= 2) {
core.setOutput("nameAndOwner", nameAndPath[0] + "/" + nameAndPath[1]);
core.setOutput("path", nameAndPath.splice(2).join("/"));
}
core.setOutput("ref", nameAndRef[1]);
}
env:
WORKFLOW_REF: ${{ github.workflow_ref }}
- uses: actions/checkout@v3 # checks out called workflow
with:
path: .github/actions
repository: ${{ steps.parseData.outputs.nameAndOwner }}
ref: ${{ github.workflow_sha }}
- uses: ./.github/actions/dowork # dowork is a folder in the workflow repo We need |
Beta Was this translation helpful? Give feedback.
-
Despite the docs at https://docs.github.com/en/actions/learn-github-actions/contexts#github-context, the property |
Beta Was this translation helpful? Give feedback.
-
Even if the I hope GitHub adds the dynamic - uses: org/repo/path@commitish # no expression support
- uses:
name: org/repo # it's fine if this field does not support expression for security reasons
path: path-to-directory-containing-actions-yaml # but this should support expression
ref: commitish # so should this I don't want to write additional logic for cloning and definitely don't want to use PAT to clone internal repositories. My current workaround is to have placeholders in reusable workflow. The placeholders are replaced at the time of tagging
- uses: org/repo/path-to-action@{reusable_workflow_version}
- uses: org/repo/path-to-other-action@{reusable_workflow_version} I've a workflow that replaces these placeholders with simple sed command and creates, pushes commit then creates a tag from that commit sed -i 's/{reusable_workflow_version}/${{ inputs.version }}/g' reusable-*
git tag -a -m "Release from ${{ github.sha }}" ${{ inputs.version }} The drawback is tagging needs additional steps, and this only works for reusable workflows that have actions from same repository. There is issue of tags from detached HEAD. I hope GitHub provides solution for this problem soon |
Beta Was this translation helpful? Give feedback.
-
Just to confirm, these I'm working on a workflow that needs to gather a file that it's in the same branch/tag/commit that the called workflow. I couldn't find a context value that holds that reference. Is it possible? |
Beta Was this translation helpful? Give feedback.
-
Any chance having |
Beta Was this translation helpful? Give feedback.
-
Any news on this topic ? |
Beta Was this translation helpful? Give feedback.
-
look like action is stuck in 1999 .... |
Beta Was this translation helpful? Give feedback.
-
Hello,
Via trail and error I found out that the workflow engine does not resolve expression in
uses
statement.I expected the following to work:
What I would like to achieve is for production to use the formal tag, while debugging, testing and CI the workflow itself I can use a pre-release reference.
I would like to have a single repository that contains my reusable workflows and reusable actions for use of my repositories. I need somehow for the reusable workflows to know what reference used to fetch them in order to call the actions and nested workflows. I found no way to do that, so I tried to explicitly the reference this as parameter, but this does not work either.
The setup:
I thought of solving this by using git submodules, however, it is impossible to mix local and reusable as github does not support nested paths for workflows:
Any ideas how to implement nested reusable in separate repository correctly?
Thanks,
Alon
Beta Was this translation helpful? Give feedback.
All reactions