Reputation: 331
I am currently working my way into GitHub Actions as well as NUKE.build. My project consists of 2 jobs in GitHub Actions: The first job is responsible for reading the build configurations from a given .csproj file and setting it as a JSON array variable. The second job (which is spread across multiple runners) is then supposed to use this JSON array as the value for the matrix, executing my targets in NUKE, with the respective value as a parameter.
I have managed this so far with the following workflow (shortened):
name: Build Workflow
on:
...
jobs:
get-configurations:
runs-on: windows-latest
outputs:
configurations: ${{ steps.generate-matrix.outputs.configurations }}
steps:
...
- name: Get Build Configurations
id: generate-matrix
run: |
dotnet NukeComponents --root . --relative-project-file-path "PathToProjectFile" --dotnet --get-configurations
build:
needs: get-configurations
runs-on: windows-latest
strategy:
matrix:
configuration: ${{ fromJson(needs.get-configurations.outputs.configurations) }}
steps:
...
- name: Build and test
run: |
$configuration = "${{ matrix.configuration }}"
dotnet NukeComponents --root . --relative-project-file-path "PathToProjectFile" --configuration "$configuration"
And in my NUKE "GetConfigurations" target I have the following to set the variable:
var output = string.Join(',', configurations.Select(x => $"\"{x}\""));
Console.WriteLine($"::set-output name=configurations::[{output}]");
As I said, this also works so far. But now it is the case that "::set-output" is deprecated and should not be used anymore. It was said that you should use the following instead:
echo 'KEY=VALUE' >> $GITHUB_OUTPUT
I have tested this and it also works when I define it directly in the workflow:
- name: Set configurations
id: set-configurations
run: echo 'configurations=["20200-Release","20201-Release","20202-Release"]' >> "$env:GITHUB_OUTPUT"
- name: echo output of previous step for testing
run: echo ${{ steps.set-configurations.outputs.configurations }}
However, if I now go and try to adjust the line in my NUKE target:
var output = string.Join(',', configurations.Select(x => $"\"{x}\""));
Console.WriteLine($"echo 'configurations=[{output}]' >> '$env:GITHUB_OUTPUT'");
And the workflow file:
- name: Get Build Configurations
id: generate-matrix
run: |
dotnet NukeComponents --root . --relative-project-file-path "PathToProjectFile" --dotnet --get-configurations
- name: echo output of previous step for testing
run: echo ${{ steps.generate-matrix.outputs.configurations }}
Then apparently I have the problem that "configurations" remains empty (Get as error message that InputObject in echo command is empty).
I have also tried things like setting the configurations as an environment variable in the NUKE target.
But I can't get it to work. It looks like the echo command is not executed, but just output. But maybe I am wrong and the error is somewhere else.
Can someone help me here?
Upvotes: 1
Views: 430
Reputation: 331
Thanks to @Azeem's help, I was able to solve the problem.
My answer is probably not 100% accurate, however the solution works for me and so I am posting it here. If anyone finds an error in my answer, feel free to correct it!
I removed NUKE from the equation and used a simple console application written in .NET 7.
I think my guess about GitHub Runner not interpreting the output of my console program and executing commands present in it seems to be correct. In the console program, I ran the following command in the console:
Console.WriteLine("echo 'configurations=\"[\\\"20200-Release\\\",\\\"20201-Release\\\",\\\"20202-Release\\\"]\"' >> $env:GITHUB_OUTPUT");
However, it seems that the GitHub runner does not execute the echo command, but simply returns it as output, which probably makes sense.
So what I needed to do is run the echo command in a separate PowerShell:
static void Main(string[] args)
{
ExecuteCommand($"echo 'configurations=\"[\\\"20200-Release\\\",\\\"20201-Release\\\",\\\"20202-Release\\\"]\"' >> $env:GITHUB_OUTPUT");
}
private static void ExecuteCommand(string command)
{
var processInfo = new ProcessStartInfo
{
FileName = "C:\Windows\System32\\WindowsPowerShell\v1.0\\powershell.exe",
Arguments = $"/c {command}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
Process.Start(processInfo);
}
The additional "\" in, for example. \\\"20201-Release\\\", are necessary because the array is in quotes and the whole thing, in this case, is interpreted by PowerShell.
The GitHub workflow job looks like this:
jobs:
get-configurations:
runs-on: windows-latest
outputs:
configurations: ${{ steps.generate-matrix.outputs.configurations }}
steps:
...
- name: Get Build Configurations
id: generate-matrix
run: ./NukeComponents/GetConfigurations.exe
- name: echo env of previous step for testing
run: echo ${{ steps.generate-matrix.outputs.configurations }}
Upvotes: 1