In GitHub Actions, can I return back a value to be

2020-07-16 09:05发布

问题:

I'm setting up GitHub Actions as a CI for one of my projects, and the entire build process is basically a PowerShell script, driven by environment variables.

This is both to minimize vendor lock in, and to make sure I can run a build locally with pretty much the same process.

Now, my build script determines some stuff and puts it into environment variables - specifically, I have an MH_IS_PROD_BUILD variable that's either True or False, and determines which nuget package repository I push to.

However, when the step that runs the shell is done, the environment variable ceases to exist, as further steps are run in a new environment it seems.

What I want to do is something like this (abbreviated):

  steps:
    - name: Run build script
      id: pwshbuild
      shell: pwsh
      run: |
        cd scripts
        ./build.ps1
        # The above sets $Env:MH_IS_PROD_BUILD to either True or False
    - name: Push Publish to GPR (Dev Package)
      if: steps.pwshbuild.outputs.MH_IS_PROD_BUILD == 'False'
      shell: pwsh
      run: |
        # omitted: determine $nupkgPath
        nuget push $nupkgPath -Source "GPR" -SkipDuplicate
    - name: Push Publish to Nuget.org (Release Package)
      if: steps.pwshbuild.outputs.MH_IS_PROD_BUILD == 'True' 
      shell: pwsh
      run: |
        # omitted: determine $nupkgPath
        nuget push $nupkgPath -Source "NugetOrg" -SkipDuplicate

It appears that outputs is what I'd need, but that seems to require creation of a custom action?

The above does not work, of course (hence asking). So I'm wondering, what is the best way forward?

  • Can I set the outputs of a step from PowerShell? (preferred)
  • Do I have to create a custom action to encapsulate my call to build.ps1 so that I can return stuff via outputs?

回答1:

I think you can set outputs from Powershell by just echoing them to the console. Powershell has an alias mapping echo to Write-Output.

jobs:
  windows-test:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set outputs
        id: vars
        shell: pwsh
        run: echo "::set-output name=production::true"
      - name: Check outputs
        shell: pwsh
        run: echo ${{ steps.vars.outputs.production }}

ref: https://help.github.com/en/github/automating-your-workflow-with-github-actions/development-tools-for-github-actions#set-an-output-parameter-set-output



回答2:

In addition to answer by peterevans, you still can use environment variables for conditions, as long they are set via ::set-env "command"

Example:

- run:   |
         if [ -f FileMightNotExists.txt ]; then
            echo ::set-env name=HAVE_FILE::true
         fi
  shell: bash

- run: echo "I have file!"
  if:  env.HAVE_FILE == 'true'

As mentioned, there is ::set-output already, so it's a matter of taste mostly.

What makes ::set-env easier to use (in my opinion) is that you don't need to set id for steps (less typing), referencing vars is much shorter (less typing again), all variables you added will be listed for each step (folded inside Run block, can be useful when trying to find bugs in workflow), and well... it's just regular variable in the end, it might be easier to work with, depends on shell.