GitHub Context Variables Not Evaluating for Reusable Workflow Reference - github

I'm currently trying to build a reusable workflow where the reusable workflow is correctly setup with an on: workflow_call trigger and so forth.
When I'm calling the workflow though, I need to be able to dynamically populate the shared workflow file reference with the current branch or commit. I'd also like to populate the organisation and repo dynamically as well if possible with the current org/repo, but that's less essential. My call to the other workflow therefore looks like this:
jobs:
call-build-and-test:
uses: ${{github.repository}}/.github/workflows/cicd-build-and-test.yml#${{github.sha}}
Unfortunately however the two context variables, github.repository, and github.sha don't get evaluated and the workflow fails at runtime stating that a valid organisation and repo are required at the start of the string, or, if the organisation and repo are hardcoded so that they're valid, then it states the commit couldn't be found because that's not evaluated correctly either.
Can anyone explain why the context variables aren't getting evaluated? If this is not possible how can I dynamically populate these values? It's not sufficient to hardcode them as they need to execute against the version on the current branch, as the main branch has not had workflow merged in yet, so can't simply be hardcoded to that as in the examples in the Github docs here:
https://docs.github.com/en/actions/learn-github-actions/reusing-workflows#calling-a-reusable-workflow
I believing using context variables such as github.* is the right approach, as environment variables are only available within the scope of a shell executing a job, however I have also tried environment syntax as well, i.e. GITHUB_REPOSITORY, and GITHUB_SHA with the same problem.

It can't be done at the moment as Github Actions doesn't support expressions with uses attributes.
There is no workaround (yet?) because the workflow interpreter (that also checks the workflow syntax when you push the workflow to the repository) can't get the value from the expression at that moment.
It could maybe work if the workflow was recognized by the interpreter, but it doesn't event appear on the Actions tab as it's considered invalid.
For the moment, you can only use tag, branch ref or commit hash after the # symbol, the same way you use any action. Therefore, this has to be hardcoded at the moment.

As GuiFalourd says:
It can't be done at the moment as Github Actions doesn't support expressions with uses attributes.
If you just want to use the ${{ github.sha }}, and you only need the workflow from your local repo, don't specify the ref. As shown here:
If you use the second syntax option (without {owner}/{repo} and #{ref}) the called workflow is from the same commit as the caller workflow.
call-workflow-2-in-local-repo:
uses: ./.github/workflows/workflow-2.yml
You can find more info here.
Unfortunately I can't find any information on whether they are planning to support this one day.
I am also facing this issue when calling a build workflow from a deployment workflow. I think the solution for me is to pass the branch as a param to the reusable build workflow and checkout that branch if it's specified. I am just going to have to accept that I'm not using the workflow file from the branch specified.
I appreciate I'm late with this and it's a very specific scenario, but hope it may help you in some way!

Related

How can I have Release variables with runtime substitution from other variables

I am trying to create a simple Runtime Variable in my Release Pipeline that carries the BuildNumber of the Triggering Artifact.
I tried adding a variable called alias and in the value column I wrote $(Release.TriggeringArtifact.Alias) And I set the Settable at Release Time to true.
Then I added another variable called BuildNumber and I wrote this in the value column: $(Release.Artifacts{alias}.BuildNumber} and set the Settable at Release Time to true.
I have a powershell task that Echoes the value of my variable BuildNumber. I was expecting the build number that was assigned to my artifact, but what I see is the git repository's name instead.
How can I have release time variables with pre-defined variables substituted in them?
What you are trying to do is to use nested variable which is not supported:
Thanks for your patience on this. I checked with the product team and there are places where variables will expand when nested, and the behavior will be slightly different if you specify variables with macro syntax (example: $(var)). However, this is not an officially supported feature and their recommendation is to not document macro variables as expanding recursively.
If you would like to reach out the product team directly, please post in the Azure DevOps Developer Community. The product team actively monitors that space.
You can also vote on this on developer community

Conditional Variables in Azure Classic Pipelines

I'm trying to set up a variable in the Azure Build Pipelines Classic Editor to use conditional functions to determine its value. YAML is not an option (unless there's some way to inject YAML as part of a Classic build...?).
In my current scenario, the idea is that the variable would return one of a few possible string values (or empty string) depending on the branch that triggered the build.
I want something along the lines of this:
I fear this may be a YAML-only thing, but hopefully someone can tell me I'm wrong about that.
Like Matt mentioned in the comment, the best approach for this would be to use a script (powershell or bash) that will have the logic to set the variable.
For more details about how to set a variable, have a look at this documentation.

Is it possible to use patterns as branch type restrictions when creating a ClearCase trigger?

I'd like to create a branch restriction for a ClearCase preop merge trigger.
However, it should fire based not on the exact branch type, but rather
based on whether the branch type follows a specific naming convention, like
.../my_special_branchname_prefix*
Can I do this, or do I have to list every branch separately?
I read in "cleartool man mktrtype" that a "branch-type-selector" can be used,
but unfortunately I was not able to find comprehensive information on what
it entails, i.e. if it can be a version selector pattern as used in a config spec (using e.g. the three-dot ellipsis), or even a globbing pattern, or if it
can only be an exact branch type name.
One way to check what you can do is to write a dummy preop trigger script which will simply output the "trigger environment variables (EV)"
That way, you can check if one of those CLEARCASE_xxx environment variable has the name of the branch you want (do you mean the source or destination branch of that merge?).
Once you see the right variable, you can enforce your policy, by making sure the preop trigger script exits with -1 when the name of that branch does not start with the expected prefix.

Ignore build step when a keyword in commit message is detected

I have a VCS trigger which starts build each time a new commit in specific branch is detected. But sometimes I want one of steps to be skipped. I decided to add a specific keyword to such commits.
I tried to use template and two configurations (one with step enabled and another with disabled) but there is no possibility to modify VCS Trigger properties in derived configurations. Also I can't add a second VCS Trigger neither to the configuration nor to the template: when I click "Add" there is no VCS Trigger in list.
How can it be done?
If you have template then you can replace VCS trigger rules from hardcoded values with some parameter, e.g. %TRIGGER_RULES%. And in each build, that uses this template you could easily override this parameter for your needs. This should give you possibility to make something like
-:comment=.*do-not-trigger.*
But if you would like to skip only one step, then in this case you have to create some custom script for it and check commit message in it. The behaviour of build is simple: either build is executed and all steps are triggered, or build is not executed at all.

Find all unmerged files/elements in ClearCase

We use ClearCase where I work and I'm trying to figure out how to find any files that have been modified but not merged up. We have a main branch at the very top level in ClearCase, and this is where the final source code changes are merged to and where we do our formal release builds from. We then have an integration branch under main where integration issues are worked out. When we get everything working and tested in the integration branch, we merge the integration branch up to main. For individual feature implementations and bug fixes, we create a new branch (usually named after an action, feature, or bugfix) off of the integration branch and work the issue. When we are done with it, we merge that change up to the integration branch.
I was wondering if anybody knew of a command or a way to see what files are modified in the feature/bug fix branches but were not merged back up to the integration branch. I've been looking around but I can't seem to find a way to do it. I would like to be able to run the command and have it tell me all files that have been modified on all of the sub-branches but not merged up. Thanks.
Normally, you use ct findmerge to find files to merge from one branch or view into the current view (assuming ct is an alias for cleartool).
I think you would have to identify all the branches you are interested in and do a separate ct findmerge operation for each branch - for each destination branch. That's complex. You'd also want to be able to eliminate many branches which are known to be fully merged. You can annotate a branch to indicate that it is fully merged.
So, I don't think there is a simple, single command to do this job.
You need to decide which branches are targets that you're concerned about. These would be your integration branch(es). Presumably, you have a fairly small list of these.
For each of those target branches, you need to decide which work branches are relevant to that integration branch. This is the tricky part; there is no easy way to determine whether a particular bug fix or feature branch is relevant to that integration branch using information in the VOBs; it is really only known by the users.
You then need a script that does (in outline):
for int_branch in $(list_relevant_integration_branches)
do
...create view with tag $tag for $int_branch...
ct setcs -f $(cspec_for_integration_branch $int_branch) $tag
ct setview -exec "find_outstanding_merges_for_integration_branch $int_branch" $tag
done
where find_outstanding_merges_for_integration_branch looks a bit like:
vob_list=$(list_relevant_vobs)
for mrg_branch in $(list_relevant_merge_branches $int_branch)
do
echo
echo "Merges from $mrg_branch to $int_branch"
ct findmerge $vob_list -fversion .../$mrg_branch/LATEST -print
done
Note that this command assumes (a) the current view is appropriate for the target, and (b) the integration branch name is passed as an argument.
You can get fancy and decide how to handle automatic or graphical merges instead of -print. The hard part is still the unwritten commands such as list_relevant_integration_branches and list_relevant_vobs. These might be simple:
# list_relevant_integration_branches
cat <<EOF
integration_branch_version_3_0
integration_branch_version_3_1
integration_branch_version_4_0
EOF
# list_relevant_vobs
cat <<EOF
/vobs/mainproject
/vobs/altproject
/vobs/universal
EOF
Or they might be considerably more complex. (If you only have one VOB, then your life is much simpler; the systems we work with have 20-odd VOBs visible in the cspec.)
The other unwritten script is list_relevant_merge_branches. I don't know whether there's a simple way to write that. If you define and apply appropriate attribute types (ct mkattype, ct mkattr) when the development branches are created (perhaps a 'target integration branch' attribute type, an enumeration type), you could use that to guide you. That leaves you with a retrofit problem; how to get the correct attribute onto each existing working branch. You also need a separate attribute to identify branches that no longer need merge scrutiny, unless you decide that the absence of a 'target integration branch' attribute means 'no need to scrutinize any more'. That reduces the retrofit problem to adding the target integration branch to those branches that still need merging; by default, all existing branches will be deemed fully merged.
If you know the source and destination branches (topic detailed in Jonathan's answer, which I have upvoted), then don't forget the query primitive merge:
merge (from-location , to-location)
In all cases, TRUE if the element to which the object belongs has a merge hyperlink (default name: Merge) connecting the from-location and to-location.
You can specify either or both locations with a branch pathname or a version selector.
Specifying a branch produces TRUE if the merge hyperlink involves any version on that branch.
The branch pathname must be complete (for example, /main/rel2_bugfix, not rel2_bugfix).
This thread illustrates that query in action:
How is it possible to find all the elements on a specific branch that are checked in and not merged away?
cleartool find \\view\administration\ProjectVOB \
-branch "brtype(HNH-372452) && \
!merge(...\HNH-372452\LATEST,...\main-372452\LATEST)" -print
\\view\administration\ProjectVOB\Com-API\Dll\COMFrontendDll\Mmi.cpp##\main\HNH-372452
\\view\administration\ProjectVOB\geometry\geochain\geocutterloc.cpp##\main\HNH-372452
That "merge hyperlink" is the red arrow you see in version tree:
(see article "Versioning and parallel development of requirements")