Github Actions, how to share a calculated value be

2020-02-05 04:27发布

问题:

Is there a DRY way to calculate and share a value in multiple job steps with Github Actions?

In the below workflow yml file, echo ${GITHUB_REF} | cut -d'/' -f3`-${GITHUB_SHA} is repeated in multiple steps.

name: Test, Build and Deploy
on:
  push:
    branches:
      - master
jobs:
  build_and_push:
    name: Build and Push
    runs-on: ubuntu-latest
    steps:
      - name: Docker Build
        uses: "actions/docker/cli@master"
        with:
          args: build . --file Dockerfile -t cflynnus/blog:`echo ${GITHUB_REF} | cut -d'/' -f3`-${GITHUB_SHA}
      - name: Docker Tag Latest
        uses: "actions/docker/cli@master"
        with:
          args: tag cflynnus/blog:`echo ${GITHUB_REF} | cut -d'/' -f3`-${GITHUB_SHA} cflynnus/blog:latest

回答1:

set-output can be used to define outputs for steps. The outputs can then be used in later steps and evaluated in with and env input sections.

The following is what that would look like for your example.

name: Test, Build and Deploy
on:
  push:
    branches:
      - master
jobs:
  build_and_push:
    name: Build and Push
    runs-on: ubuntu-latest
    steps:
      - name: Set tag var
        id: vars
        run: echo ::set-output name=docker_tag::$(echo ${GITHUB_REF} | cut -d'/' -f3)-${GITHUB_SHA}
      - name: Docker Build
        uses: "actions/docker/cli@master"
        with:
          args: build . --file Dockerfile -t cflynnus/blog:${{ steps.vars.outputs.docker_tag }}
      - name: Docker Tag Latest
        uses: "actions/docker/cli@master"
        with:
          args: tag cflynnus/blog:${{ steps.vars.outputs.docker_tag }} cflynnus/blog:latest

Here is another example showing how to dynamically set multiple variables to be used by an action.

      - name: Set output variables
        id: vars
        run: |
          echo ::set-output name=pr_title::"[Test] Add report file $(date +%d-%m-%Y)"
          echo ::set-output name=pr_body::"This PR was auto-generated on $(date +%d-%m-%Y) \
            by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v1.5.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PULL_REQUEST_TITLE: ${{ steps.vars.outputs.pr_title }}
          PULL_REQUEST_BODY: ${{ steps.vars.outputs.pr_body }}

Alternatively you can use set-env.

      - name: Set environment variables
        run: |
          echo ::set-env name=PR_TITLE::"[Test] Add report file $(date +%d-%m-%Y)"
          echo ::set-env name=PR_BODY::"This PR was auto-generated on $(date +%d-%m-%Y) \
            by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v1.5.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PULL_REQUEST_TITLE: ${{ env.PR_TITLE }}
          PULL_REQUEST_BODY: ${{ env.PR_BODY }}

Update: The docker actions in the first example are deprecated. Please see this answer for the latest way to work with docker in GitHub Actions.