【问题标题】:Paired values in github actions matrixgithub 动作矩阵中的配对值
【发布时间】:2021-05-07 13:10:30
【问题描述】:

我想针对 C 和 C++ 项目的三个编译器版本进行构建:gcc、gcc-8 和 clang(用于 C 编译器),对于 C++ 编译器应该分别使用 g++、g++-8 和 clang++。

总共有 3 种配置。我不想使用所有 C 和 C++ 编译器版本的 product 构建,即。没有gcc/g++-8等

如何指定具有这三个配置的矩阵,每个配置设置两个变量?

目前我正在使用这个(注意指定了 2 个操作系统,所以总共有 6 个配置):

    strategy:
      matrix:
        os: [ubuntu-16.04, ubuntu-latest]
        cpp_compiler: [g++, g++-8, clang++]
        include:
          - c_compiler: gcc
          - cpp_ompiler: g++-8
            c_compiler: gcc-8
          - cpp_compiler: clang++
            c_compiler: clang

本质上是用C++编译器(cpp_compiler)作为master版本,然后includecpp_compiler版本的基础上用hacky方式设置c_compiler,但肯定有更好的...

【问题讨论】:

标签: github-actions


【解决方案1】:

我刚刚尝试过,结果证明您可以在构建矩阵中嵌套数组,但它没有记录。因此,您可以在job.matrix 中创建一个编译器数组。我们称之为compiler-versioncompiler-version: [[g++, gcc], [g++-8, gcc-8], [clang++, clang]]。然后,您可以使用零索引访问 compiler-version 数组的每个元素中的每个值:matrix.compiler-version[0] 用于 C++ 编译器,matrix.compiler-version[1] 用于 C 对应物。

您的工作流程将变为:

    strategy:
      matrix:
        os: [ubuntu-16.04, ubuntu-latest]
        compiler-version: [[g++, gcc], [g++-8, gcc-8], [clang++, clang]]
    steps:
      # .... checkout steps
      - name: Compile file with C++ compiler
        env:
          COMPILER: ${{ matrix.compiler-version[0] }}
        run: |
          $COMPILER file.c
          ./a.out
      - name: Compile file with C compiler
        env:
          COMPILER: ${{ matrix.compiler-version[1] }}
        run: |
          $COMPILER file.c
          ./a.out

我创建了一个包含 2 个 Python 版本和 2 个 Ubuntu 版本的矩阵的最小示例,其中 3.7 与 Ubuntu-18.04 配对,3.8 与 Ubuntu-20.04 配对。您可以看到工作流文件here 及其对应的运行here

此解决方案解决了必须在工作流文件的 2 个位置定义 C++ 选项的尴尬。尽管它没有记录,但我认为它是稳定的,因为 GitHub Actions 上下文对象是(或至少被视为)JavaScript 对象,所以我们实际上只是将数组文字定义为矩阵对象属性并访问它们的值。

【讨论】:

  • 一些补充:matrix的值也可以存储map。示例:val: [ { x: 'str1' }, { y: 'str2' } ],用法:${{ matrix.val.x }}。这将使代码更具可读性。但是无论是array还是map,Actions的语法检查器都会用红色下划线标记,并报错Matrix options must only contain primitive values。它确实有效,只需忽略错误。但是,由于它目前没有记录,所有这些都可能在未来发生变化。
  • 有趣的是,它会将其标记为错误 - 我完全忘记了 Web 编辑器和 Actions 语法检查器。我完全同意这是一种冒险的方法,因为它没有记录在案并且将来可能会改变。
  • @Sprite - 我认为你的评论是正确的答案,这就是我目前正在使用的。想让它成为答案吗?
  • @Sprite - 目前语法检查器似乎并没有标记矩阵条目本身,但它们以后使用${{ matrix.mapping.value }} 会得到带有下划线的“未知上下文访问”错误。但是,此错误在其他情况下也很常见,例如,env. 上下文的许多用途。
【解决方案2】:

除了@jidicula's answermatrix 存储为array,您还可以将其存储为map,这将使工作流程更具可读性。

所以下面的工作流程应该更漂亮:

# simplified

strategy:
  matrix:
    os: [ubuntu-16.04, ubuntu-latest]
    compiler: [ {cpp: g++, c: gcc}, {cpp: g++-8, c: gcc-8}, {cpp: clang++, c: clang} ]
steps:
  - name: Compile with C++ compiler
    run: ${{ matrix.compiler.cpp }} source.cpp
  - name: Compile with C compiler
    run: ${{ matrix.compiler.c }} source.c

当这个工作流被触发时,它会以不同的matrix并行执行6次。

1: matrix.os == ubuntu-16.04, matrix.compiler.cpp == g++, matrix.compiler.c == gcc
2: matrix.os == ubuntu-16.04, matrix.compiler.cpp == g++-8, matrix.compiler.c == gcc-8
3: matrix.os == ubuntu-16.04, matrix.compiler.cpp == clang++, matrix.compiler.c == clang
4: matrix.os == ubuntu-latest, matrix.compiler.cpp == g++, matrix.compiler.c == gcc
5: matrix.os == ubuntu-latest, matrix.compiler.cpp == g++-8, matrix.compiler.c == gcc-8
6: matrix.os == ubuntu-latest, matrix.compiler.cpp == clang++, matrix.compiler.c == clang

但是,无论是array 还是map,语法目前都没有记录,尽管在某个时间点,语法检查器不再将其标记为错误。所以这一切都可能在未来发生变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-29
    • 2021-03-30
    • 1970-01-01
    • 2022-01-17
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    相关资源
    最近更新 更多