首页 > 解决方案 > 为不同的 GitHub Actions 作业共享相同的步骤

问题描述

我有一个跨平台项目,将在 2 个平台上构建:mac 和 linux(ubuntu)。

我的管道包含 3 个作业:

  1. 准备好所有必要的 docker 镜像来构建项目。
  2. 在准备好的 docker 容器中构建 ubuntu,取决于步骤 1
  3. 建立在 MacOS 上,不需要任何东西

linux和macos的步骤肯定是一样的。但是矩阵有很大不同,Linux 构建是在容器内运行的。

有没有办法在两个不同的工作之间共享步骤?

我尝试了 YAML 锚点,但 GitHub 不支持它们。

完整的工作流程

on:
  push:
    branches: [ main, support/1.2.x ]
  pull_request:
    branches: [ main, support/1.2.x ]

jobs:
  Docker-iroha-builder:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Cache Docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-
      -
        name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        uses: docker/build-push-action@v2
        with:
          file: docker/develop/Dockerfile.builder
          # context: .
          push: true
          tags: ${{ secrets.DOCKERHUB_ORG }}/iroha:builder
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new
      -
        # Temp fix
        # https://github.com/docker/build-push-action/issues/252
        # https://github.com/moby/buildkit/issues/1896
        name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache


  build-iroha-ubuntu:
    needs: Docker-iroha-builder
    runs-on: ubuntu-latest
    container: ikyb/iroha:builder
    strategy:
      fail-fast: false
      matrix:
        cc: [ gcc-9, gcc-10, clang ]  ##todo g++-10
        USE_BURROW: [ -DUSE_BURROW=OFF ]
        debrel: [ Debug ] #,Release, RelWithDebInfo
    steps:
      - ## Takes 22 seconds with default github runner
        name: Homebrew
        run: brew install cmake ninja coreutils
        if: ${{ runner.os == 'MacOS' }}
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Cache vcpkg
        uses: actions/cache@v2
        with:
          path: |
            build-vcpkg
            build/vcpkg_installed
            $HOME/.cache/vcpkg
          key:          ${{ runner.os }}-vcpkg-${{ github.sha }}
          restore-keys: ${{ runner.os }}-vcpkg-
      - 
        name: Build Iroha vcpkg dependancies
        run: ./vcpkg/build_iroha_deps.sh $PWD/build-vcpkg
      - 
        name: CMake configure
        run: |
          export CC=${{ matrix.cc }} CXX=$(echo ${{ matrix.cc }} | sed -es,gcc,g++, -es,clang,clang++,)
          cmake -B build -DCMAKE_TOOLCHAIN_FILE=$PWD/build-vcpkg/scripts/buildsystems/vcpkg.cmake \
             ${{ matrix.USE_BURROW }} -GNinja #-DCMAKE_VERBOSE_MAKEFILE=ON
      -
        name: CMake build
        run: cmake --build build --config ${{ matrix.debrel }}

  build-iroha-macos:
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        USE_BURROW: [ -DUSE_BURROW=OFF ]
        debrel: [ Debug,Release ]
    steps:
      - ## Takes 22 seconds with default github runner
        name: Homebrew
        run: brew install cmake ninja coreutils
        if: ${{ runner.os == 'MacOS' }}
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Cache vcpkg
        uses: actions/cache@v2
        with:
          path: |
            build-vcpkg
            build/vcpkg_installed
            $HOME/.cache/vcpkg
          key:          ${{ runner.os }}-vcpkg-${{ github.sha }}
          restore-keys: ${{ runner.os }}-vcpkg-
      - 
        name: Build Iroha vcpkg dependancies
        run: ./vcpkg/build_iroha_deps.sh $PWD/build-vcpkg
      - 
        name: CMake configure
        run: |
          export CC=${{ matrix.cc }} CXX=$(echo ${{ matrix.cc }} | sed -es,gcc,g++, -es,clang,clang++,)
          cmake -B build -DCMAKE_TOOLCHAIN_FILE=$PWD/build-vcpkg/scripts/buildsystems/vcpkg.cmake \
             ${{ matrix.USE_BURROW }} -GNinja #-DCMAKE_VERBOSE_MAKEFILE=ON
      -
        name: CMake build
        run: cmake --build build --config ${{ matrix.debrel }}

标签: yamlgithub-actions

解决方案


TL;博士

我用 shell 工具解决了我的问题yq

yq eval 'explode(.)' file.yml

带有示例用法和详细描述的存储库 https://github.com/kuvaldini/make-workflows.sh可能有助于轻松启动。它是根据这个答案制作的。注意Actions 选项卡

长答案

YAML 中的 GitHub 工作流描述不支持锚点。有几种解决方法 => 无论如何,它们都是从源代码构建编辑工作流 yaml 的。所以我建议另一个make-workflows.sh基于 YAML 工具yq

用法

  1. 将您的工作流程移至.github/*.src.yml
  2. 放入make-workflows.sh目录.github/
  3. (可选)复制或链接pre-commit.sh.git/hooks/pre-commit 喜欢ln -s ../../.github/pre-commit.sh .git/hooks/pre-commit

文件make-workflows.sh

#!/usr/bin/env bash
set -euo pipefail

## The script expands '*.src.yml' from $1(default: script's directory) 
## to $2 (default:subdirectory 'workflows') with corresponding name '*.yml'
## Main goal is to dereference YAML anchors.
## Deals only with Git cached/indexed files
## Set -x to debug

script_dir=$(dirname $(realpath "$0"))
dir_from=${1:-${script_dir}}
dir_to=${2:-workflows}
cd $dir_from

edited=
for f in $(git status -s -- \*.src.yml | sed 's,^.. ,,') ;do
    readonly out=$(echo $f | sed s,.src.yml\$,.yml,)
    readonly wout=$dir_to/$out
    readonly tempout=$(mktemp)
    trap "rm -f $tempout" EXIT
    echo >>$tempout "## DO NOT EDIT"
    echo >>$tempout "## Generated from $f with $(basename $0)"
    echo >>$tempout ""
    yq eval 'explode(.)' $f >>$tempout
    if ! diff -q $wout $tempout &>/dev/null ;then
        mv $tempout $wout
        edited+="'$out' "
    fi
done

if [[ -n "$edited" ]] 
then echo >&2 "make-workflows: these files were edited: $edited"
else echo >&2 "make-workflows: everything is up to date"
fi

文件预提交.sh

#!/usr/bin/env bash
set -euo pipefail

gitroot=$(git rev-parse --show-toplevel)

cd $gitroot
./.github/make-workflows.sh
git add .github/workflows

链接

  1. 准备好使用详细描述的解决方案https://github.com/kuvaldini/make-workflows.sh
  2. 为不同的 GitHub Actions 作业共享相同的步骤
  3. https://github.community/t/support-for-yaml-anchors/16128/60
  4. https://github.com/mithro/actions-includes
  5. https://github.com/allejo/gha-workflows

推荐阅读