У меня есть рабочий процесс, который использует 'strategy' = 'matrix'
вместе со списком конкретных конфигураций для сборки.
Вот мой рабочий файл:
#
# build-N-test-v2.1-Dev and build-N-test-v2.1-Release are neary
# identical, but a few tests are commented out (to not needlessly stress CI system)
# for v2.1-Dev builds
#
# NOTE: I've tried many tricks - none which seem to work - to get this working on one file with one
# workflow and tests
# https://github.community/t/what-is-the-correct-if-condition-syntax-for-checking-matrix-os-version/16221
# https://github.community/t/how-to-conditionally-include-exclude-items-in-matrix-eg-based-on-branch/16853
#
# but none seem to work
#
name: build-N-test-v2.1-Dev
on:
push:
branches:
- v2.1-Dev
#- v2.1-Release
workflow_dispatch:
inputs:
ignored:
description: "ignored"
required: false
default: ""
## NB: JOBS section IDENTICAL between v2.1-Dev and 2.1-Release files EXCEPT that on v2.1-Dev file
## comment out all entries marked with includeInDevBranchBuilds: false
jobs:
build-n-test-Linux:
runs-on: ${{ matrix.runs_on }}
strategy:
#
# Configuration notes
# o --debug-symbols false to reduce build disk size (and we aren't debugging anyhow) in many debug configurations
#
matrix:
include:
# ## SADLY: Container operations are only supported on Linux runners
# - displayTargetName: windows-DBG
# os: windows
# compiler: g++-8
# runs_on: windows-latest
# container_image: sophistsolutionsinc/stroika-buildvm-windows-cygwin-vs2k19
# cpp_version: c++17
# config_name: Debug
# extra_config_args: --apply-default-debug-flags --trace2file enable
## centos 8
- displayTargetName: centos-8
os: unix
compiler: g++
runs_on: ubuntu-latest
container_image: sophistsolutionsinc/stroika-buildvm-centos-8-small
cpp_version: c++17
config_name: Release
extra_config_args: --apply-default-release-flags --trace2file enable
includeInDevBranchBuilds: true
## ubuntu 18.04
- displayTargetName: ubuntu-18.04-g++-8 (Debug)
os: unix
compiler: g++-8
runs_on: ubuntu-latest
container_image: sophistsolutionsinc/stroika-buildvm-ubuntu1804-regression-tests
cpp_version: c++17
config_name: Debug
extra_config_args: --apply-default-debug-flags --trace2file enable --debug-symbols false
includeInDevBranchBuilds: true
- displayTargetName: ubuntu-18.04-cross-compile-raspberrypi (Debug)
os: unix
compiler: g++-8
runs_on: ubuntu-latest
container_image: sophistsolutionsinc/stroika-buildvm-ubuntu1804-regression-tests
cpp_version: c++17
config_name: Debug
extra_config_args: --apply-default-release-flags --trace2file enable --compiler-driver arm-linux-gnueabihf-g++-8 --cross-compiling true
includeInDevBranchBuilds: true
# ubuntu 20.04
# - displayTargetName: ubuntu-20.04-g++-9 (Debug)
# os: unix
# compiler: g++-9
# runs_on: ubuntu-latest
# container_image: sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests
# cpp_version: c++17
# config_name: Debug
# extra_config_args: --apply-default-debug-flags --trace2file enable --debug-symbols false
# includeInDevBranchBuilds: false
# - displayTargetName: ubuntu-20.04-g++-10 (Debug)
# os: unix
# compiler: g++-10
# runs_on: ubuntu-latest
# container_image: sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests
# cpp_version: c++17
# config_name: Debug
# extra_config_args: --apply-default-debug-flags --trace2file enable --debug-symbols false
# includeInDevBranchBuilds: false
- displayTargetName: ubuntu-20.04-g++-10
os: unix
compiler: g++-10
runs_on: ubuntu-latest
container_image: sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests
cpp_version: c++17
config_name: Release
extra_config_args: --apply-default-release-flags --trace2file enable
includeInDevBranchBuilds: true
# - displayTargetName: ubuntu-20.04-g++-10-c++2a
# os: unix
# compiler: g++-10
# runs_on: ubuntu-latest
# container_image: sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests
# cpp_version: c++2a
# config_name: Release
# extra_config_args: --apply-default-release-flags --trace2file enable
# includeInDevBranchBuilds: false
# - displayTargetName: ubuntu-20.04-clang++-10
# os: unix
# compiler: clang++-10
# runs_on: ubuntu-latest
# container_image: sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests
# cpp_version: c++17
# config_name: Release
# extra_config_args: --apply-default-release-flags --trace2file enable
# includeInDevBranchBuilds: false
### ATTEMPT TO COMPRESS 2 workflow files into one, but so far not working
### SEE
### https://stackoverflow.com/questions/65384420/how-to-make-a-github-action-matrix-element-conditional/65385385#65385385
###
#if: github.ref == 'refs/heads/v2.1-Release' || matrix.includeInDevBranchBuilds
env:
# vm has 2 virtual CPUs, but 8GB ram, so jobs=5 (empirical), and QUICK_BUILD avoids some internal testing
MAKEFLAGS: "--jobs=3 QUICK_BUILD=1"
container: ${{ matrix.container_image }}
steps:
- uses: actions/checkout@v2
- name: Build System Info
if: ${{ matrix.os=='unix' }}
run: |
lsb_release -d 2>/dev/null || true
echo "CWD = " `pwd`
echo "nproc = " `nproc`
grep "model name" /proc/cpuinfo | head -1
grep processor /proc/cpuinfo | wc -l
grep MemTotal /proc/meminfo
df -h
- name: Build System Info (Windows)
if: ${{ matrix.os=='windows' }}
run: |
echo "CWD = " `pwd`
df -h
- name: Configure ${{ matrix.config_name }}
run: |
./configure ${{ matrix.config_name }} --compiler-driver ${{ matrix.compiler }} ${{ matrix.extra_config_args }} --cppstd-version ${{ matrix.cpp_version }}
cat ConfigurationFiles/${{ matrix.config_name }}.xml
# Break out third-party-components to do clean so we dont run out of disk space, and break out TPC AND library
# to show the summary time for each part
- name: Make third-party-components
run: |
make third-party-components
make clean
- name: Make libraries
run: make libraries
- name: Make all
run: make all
- name: Run Tests
run: make run-tests
- name: Archive Samples Results
uses: actions/upload-artifact@v2
with:
name: Sample apps (${{ matrix.displayTargetName }})
path: |
Builds/${{ matrix.config_name }}/Samples-*
- name: Archive Log Results
uses: actions/upload-artifact@v2
with:
name: Log Data (${{ matrix.displayTargetName }})
path: |
Builds/${{ matrix.config_name }}/PerformanceDump.txt
/tmp/Trace*.txt
build-n-test-MacOS:
runs-on: ${{ matrix.runs_on }}
strategy:
matrix:
# Add to extra_config_args for build speed: --Xerces no --OpenSSL no --lzma no --boost no
include:
- displayTargetName: MacOS-Debug
os: macos-10.15
runs_on: macos-10.15
config_name: Debug
extra_config_args: --apply-default-debug-flags --trace2file enable
includeInDevBranchBuilds: true
# - displayTargetName: MacOS
# os: macos-10.15
# runs_on: macos-10.15
# config_name: Release
# extra_config_args: --apply-default-release-flags --trace2file enable
# includeInDevBranchBuilds: false
env:
# vm has 2 virtual CPUs, but 8GB ram, so jobs=5 (empirical), and QUICK_BUILD avoids some internal testing
MAKEFLAGS: "--jobs=3 QUICK_BUILD=1"
steps:
- uses: actions/checkout@v2
- name: Build System Info
run: |
echo "CWD: `pwd`"
df -h
system_profiler SPSoftwareDataType
sw_vers
# If we had docker ability, most of these would be built into a docker file
- name: Install Basic Build requirements
run: |
brew install gnu-sed
brew install p7zip
brew install automake
make install-realpath
- name: Configure
run: |
./configure ${{ matrix.config_name }} ${{ matrix.extra_config_args }}
cat ConfigurationFiles/${{ matrix.config_name }}.xml
- name: Build third-party-components
run: |
make third-party-components
make clean
- name: Build Library
run: |
make libraries
- name: Build All
run: |
make all
- name: Run-Tests
run: |
make run-tests
- name: Workaround GitHub-Actions-MacOS Issue with env.TMPDIR
run: |
mkdir /tmp/LOGS-ARCHIVE
cp $TMPDIR/Trace*.txt /tmp/LOGS-ARCHIVE
- name: DEBUG Workaround GitHub-Actions-MacOS Issue with env.TMPDIR
run: |
echo "TMPDIR=$TMPDIR"
echo "TMPDIR using ENV.TMPDIR=${{ env.TMPDIR }}"
# Just the echo line above shows empty, and then the ls line causes exit 1/failure
#ls -l ${{ env.TMPDIR }}/Trace*.txt
#if this gets fixed, then lose Workaround GitHub-Actions-MacOS, and directly reference ${{ env.TMPDIR }}/Trace*.txt in Archive Log Results
- name: Build System Info
run: |
df -h
- name: Archive Log Results
uses: actions/upload-artifact@v2
with:
name: Log Results (${{ matrix.displayTargetName }})
path: |
Builds/${{ matrix.config_name }}/PerformanceDump.txt
/tmp/LOGS-ARCHIVE
#${{ env.TMPDIR }}/Trace*.txt
- name: Archive Sample Results
uses: actions/upload-artifact@v2
with:
name: Samples (${{ matrix.displayTargetName }})
path: |
Builds/${{ matrix.config_name }}/Samples-*
build-n-test-Windows:
runs-on: ${{ matrix.runs_on }}
strategy:
matrix:
# Add to extra_config_args for build speed: --Xerces no --OpenSSL no --lzma no --boost no
include:
- displayTargetName: windows-x86-Debug
os: windows
runs_on: windows-latest
container_image: sophistsolutionsinc/stroika-buildvm-windows-cygwin-vs2k19
config_name: Debug
extra_config_args: --arch x86 --apply-default-debug-flags --trace2file enable
includeInDevBranchBuilds: true
# - displayTargetName: windows-x86-Release
# os: windows
# runs_on: windows-latest
# container_image: sophistsolutionsinc/stroika-buildvm-windows-cygwin-vs2k19
# config_name: Release
# extra_config_args: --arch x86 --apply-default-release-flags --trace2file enable
# includeInDevBranchBuilds: false
# - displayTargetName: windows-x86_64-Debug
# os: windows
# runs_on: windows-latest
# container_image: sophistsolutionsinc/stroika-buildvm-windows-cygwin-vs2k19
# config_name: Debug
# extra_config_args: --arch x86_64 --apply-default-debug-flags --trace2file enable
# includeInDevBranchBuilds: false
# - displayTargetName: windows-x86_64-Release
# os: windows
# runs_on: windows-latest
# container_image: sophistsolutionsinc/stroika-buildvm-windows-cygwin-vs2k19
# config_name: Release
# extra_config_args: --arch x86 --apply-default-release-flags --trace2file enable
# includeInDevBranchBuilds: false
env:
# vm has 2 virtual CPUs, but 8GB ram, so jobs=5 (empirical), and QUICK_BUILD avoids some internal testing
MAKEFLAGS: "--jobs=3 QUICK_BUILD=1"
ARTIFACTS_DIR: "c:/Artifacts/"
steps:
- uses: actions/checkout@v2
# https://stackoverflow.com/questions/58033366/how-to-get-current-branch-within-github-actions
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- name: Build System Info
shell: "bash"
run: |
echo "CWD: `pwd`"
df -h
systeminfo
echo NUMBER_OF_PROCESSORS=$NUMBER_OF_PROCESSORS
- name: docker pull ${{ matrix.container_image }}
run: docker pull ${{ matrix.container_image }}
- name: Start docker build environment
run: |
docker run --tty --memory 5G --cpus 2 --storage-opt 'size=50GB' --detach --name buildContainer ${{ matrix.container_image }}
- name: Print Info about docker system
shell: "bash"
run: |
docker ps -a
docker exec buildContainer systeminfo
docker exec buildContainer df -h
- name: Git Checkout
shell: "bash"
run: |
docker exec buildContainer sh -c "git clone https://github.com/SophistSolutions/Stroika.git && cd Stroika && git checkout ${{ steps.extract_branch.outputs.branch }}"
- name: Configure
shell: "bash"
run: |
docker exec --workdir c:/Stroika buildContainer sh -c "./configure ${{ matrix.config_name }} ${{ matrix.extra_config_args }}"
docker exec --workdir c:/Stroika buildContainer cat ConfigurationFiles/${{ matrix.config_name }}.xml
- name: Build
shell: "bash"
run: |
docker exec --workdir c:/Stroika --env MAKEFLAGS = "$MAKEFLAGS" buildContainer make all
- name: Run-Tests
shell: "bash"
run: |
docker exec --workdir c:/Stroika --env MAKEFLAGS = "$MAKEFLAGS" buildContainer make run-tests
- name: Build System Info
shell: "bash"
run: |
df -h
docker exec buildContainer df -h
- name: Copy Build Artifacts
shell: "bash"
# due to flaws in docker (windows must stop) - and cp no wildcards
run: |
docker exec --workdir c:/Stroika buildContainer bash -c 'mkdir TRACE_LOGS && cp $TEMP/Trace*.txt TRACE_LOGS/'
docker stop buildContainer
docker cp buildContainer:Stroika/Builds/${{ matrix.config_name }}/ $ARTIFACTS_DIR 2> /dev/null
docker cp buildContainer:Stroika/TRACE_LOGS $ARTIFACTS_DIR 2> /dev/null
rm -rf $ARTIFACTS_DIR/{ThirdPartyComponents,Tests,*.lib}
- name: Archive Log Results
uses: actions/upload-artifact@v2
with:
name: Log Results (${{ matrix.displayTargetName }})
path: |
${{ env.ARTIFACTS_DIR }}PerformanceDump.txt
${{ env.ARTIFACTS_DIR }}TRACE_LOGS
- name: Archive Sample Results
uses: actions/upload-artifact@v2
with:
name: Samples (${{ matrix.displayTargetName }})
path: |
${{ env.ARTIFACTS_DIR }}Samples-*
Однако я хотел бы создавать некоторые конфигурации только тогда, когда ветка v2.1-Release
. То есть, по большей части, просто создайте одну или две конфигурации, но при выпуске создайте еще кучу.
Я добился этого, клонировав сценарий (рабочий процесс), переименовав несколько вещей и закомментировав их, но было бы неплохо, если бы этот механизм работал с матричными элементами.
Я понимаю, что есть функция if
, которую можно добавить к каждому шагу, но это создаст массу рабочих мест с отключенными шагами. Чего я хочу, так это вообще не запускать эти задания для каждого матричного элемента, в котором часть if
оценивается как ложная.
TLDR: вы можете делать то, что хотите, с помощью одного рабочего процесса, фильтруя конфигурации, которые вы хотите использовать в предыдущем задании/этапе сборки, и используя результат этой фильтрации в качестве значения матрицы в своем задании build-n-test
.
Более длинная версия:
Вы можете создать job
(т. е. build-n-test), где значение strategy.matrix
отличается в зависимости от некоторых критериев, установив значение strategy.matrix
на десериализованное output
предыдущего задания (т. е. matrix_prep). Эта предыдущая работа будет нести ответственность за построение значения matrix
в соответствии с вашими пользовательскими критериями. Следующий yaml демонстрирует это (копия была включена позже с добавленными комментариями для объяснения):
name: Configurable Build Matrix
on: push
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- id: set-matrix
run: |
branchName=$(echo '${{ github.ref }}' | sed 's,refs/heads/,,g')
matrix=$(jq --arg branchName "$branchName" 'map(
. | select((.runOn==$branchName) or (.runOn= = "always"))
)' matrix_includes.json)
echo "matrix = {\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
build-n-test:
needs: matrix_prep
runs-on: ${{ matrix.runs_on }}
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
steps:
- run: echo "Hello ${{ matrix.someValue }}"
Содержимое файла matrix_includes.json
, используемого в задаче set-matrix, можно найти после этого абзаца. Чтобы увидеть, как будет выглядеть конфигурация матрицы из вопроса в формате JSON, посмотрите внизу этого ответа. Я пошел по пути создания файла JSON отдельно от самого определения рабочего процесса, потому что обнаружил, что включение необработанного JSON в сам рабочий процесс было очень запутанным (особенно если файл JSON был большим).
[
{
"runs_on":"ubuntu-16.04",
"someValue":"Foo",
"runOn":"always"
},
{
"runs_on":"ubuntu-18.04",
"someValue":"Bar",
"runOn":"v2.1-Release"
},
{
"runs_on":"ubuntu-20.04",
"someValue":"Hello again",
"runOn":"v2.1-Release"
}
]
Используя приведенную выше настройку, одна конфигурация будет включена для всех сборок, а две будут включены только в том случае, если имя ветки соответствует v2.1-Release. С некоторыми изменениями в параметрах sed
и jq
в файле рабочего процесса ограничения на имена ветвей могут быть ослаблены, чтобы вы могли запускать конфигурации для всех ветвей, включающих -Release
(а не только для одной ветви). Я могу включить это в этот ответ, если есть интерес (поскольку это не обязательно соответствует вашему текущему вопросу).
set-matrix
Объяснение работыЧто касается задачи set-matrix
, пожалуйста, обратитесь к следующим примечаниям:
# ${{ github.ref }} returns the full git ref. As such, 'refs/heads/`
# should be stripped for easier future use.
branchName=$(echo '${{ github.ref }}' | sed 's,refs/heads/,,g')
# Use jq to read in a json file that represents the matrix configuration. Each
# block has a 'runOn' property. The jq filter is setup to only output items that
# are set to 'always' or that have a branch name that matches the current branch.
matrix=$(jq --arg branchName "$branchName" 'map(
. | select((.runOn==$branchName) or (.runOn= = "always"))
)' matrix_includes.json)
# This 'echo' uses a special syntax so that the output of this job
# is set correctly.
echo "matrix = {\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
Следующее содержимое yaml должно быть таким же, как и выше, с некоторыми дополнительными комментариями, которые помогут объяснить ситуацию:
name: Configurable Build Matrix
on: push
jobs:
matrix_prep:
# Using a separate job and agent so as to be able to use tools
# like 'sed' and 'jq'.
runs-on: ubuntu-latest
# Defining outputs of a job allows for easier consumption and use.
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# Checking out code as the set-matrix step utilizes a
# file named matrix_includes.json.
- name: Check out code into the Go module directory
uses: actions/checkout@v2
# This step is explained more in a following section
- id: set-matrix
run: |
branchName=$(echo '${{ github.ref }}' | sed 's,refs/heads/,,g')
matrix=$(jq --arg branchName "$branchName" 'map(
. | select((.runOn==$branchName) or (.runOn= = "always"))
)' matrix_includes.json)
echo "matrix = {\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
build-n-test:
# By stating 'needs' here, the output of 'matrix_prep' is
# available to this job.
needs: matrix_prep
runs-on: ${{ matrix.runs_on }}
strategy:
# We need to convert the json string output into an object that the
# GitHub Workflow expects. Thankfully, the json-schema for Workflows
# allows 'matrix' to be set to an expression.
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
steps:
# Output a configuration specific value as proof and as a sanity check
- run: echo "Hello ${{ matrix.someValue }}"
Я собрал два файла для этой демонстрации:
Следующие два снимка экрана относятся к запускам в разных ветвях с использованием одного и того же определения рабочего процесса. Обратите внимание, что количество заданий build-n-test различается между двумя:
Сборка для основной ветки Сборка для ветки v2.1-Release
Это связано с тем, что первая сборка происходит на ветке main
, а вторая — на ветке v2.1-Release
. Как видно из включенного файла matrix_includes.json
выше, этого следовало ожидать, поскольку две конфигурации настроены на запуск только тогда, когда ветка v2.1-Release
, и только одна конфигурация настроена на постоянное выполнение.
Фильтрация осуществляется с помощью jq для выбора объектов из массива json, у которых либо значение runOn
установлено на always
, либо которые соответствуют текущему branchName
. Это небольшая поправка к вашей логике, о которой я упоминал ранее: вместо того, чтобы говорить includeInDevBranchBuilds
, я использую runOn
, поскольку в этом конкретном примере это работает лучше.
Шаг set-matrix
использует набор значений из предыдущей строки: branchName=$(echo '${{ github.ref }}' | sed 's,refs/heads/.*-,,g')
. Эта строка удалит refs/heads/
из ссылки на ветку и сохранит результат в значении branchName
. Например, если ваша ветвь 2.1-Release
, branchName
будет установлена на 2.1-Release
, а фильтр из более раннего будет соответствовать всем объектам, которые имеют "runOn":"2.1-Release"
или "runOn":"always"
.
Файл JSON был создан для имитации содержимого оператора includes
из рабочего процесса, который вы связали. JSON используется, поскольку действия GitHub имеют встроенные функции JSON. В качестве примера ниже приведен мой вариант преобразования вашего раздела matrix:include
в JSON. Обратите внимание, что я изменил includeInDevBranchBuilds
на runOn
со значениями, установленными либо на always
, либо на v2.1-Release
.
[
{
"displayTargetName": "centos-8",
"os": "unix",
"compiler": "g++",
"runs_on": "ubuntu-latest",
"container_image": "sophistsolutionsinc/stroika-buildvm-centos-8-small",
"cpp_version": "c++17",
"config_name": "Release",
"extra_config_args": "--apply-default-release-flags --trace2file enable",
"runOn": "always"
},
{
"displayTargetName": "ubuntu-18.04-g++-8 (Debug)",
"os": "unix",
"compiler": "g++-8",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu1804-regression-tests",
"cpp_version": "c++17",
"config_name": "Debug",
"extra_config_args": "--apply-default-debug-flags --trace2file enable",
"runOn": "always"
},
{
"displayTargetName": "ubuntu-20.04-g++-9 (Debug)",
"os": "unix",
"compiler": "g++-9",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests",
"cpp_version": "c++17",
"config_name": "Debug",
"extra_config_args": "--apply-default-debug-flags --trace2file enable",
"runOn": "v2.1-Release"
},
{
"displayTargetName": "ubuntu-20.04-g++-10 (Debug)",
"os": "unix",
"compiler": "g++-10",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests",
"cpp_version": "c++17",
"config_name": "Debug",
"extra_config_args": "--apply-default-debug-flags --trace2file enable",
"runOn": "v2.1-Release"
},
{
"displayTargetName": "ubuntu-20.04-g++-10",
"os": "unix",
"compiler": "g++-10",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests",
"cpp_version": "c++17",
"config_name": "Release",
"extra_config_args": "--apply-default-release-flags --trace2file enable",
"runOn": "always"
},
{
"displayTargetName": "ubuntu-20.04-g++-10-c++2a",
"os": "unix",
"compiler": "g++-10",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests",
"cpp_version": "c++2a",
"config_name": "Release",
"extra_config_args": "--apply-default-release-flags --trace2file enable",
"runOn": "v2.1-Release"
},
{
"displayTargetName": "ubuntu-20.04-clang++-10",
"os": "unix",
"compiler": "clang++-10",
"runs_on": "ubuntu-latest",
"container_image":
"sophistsolutionsinc/stroika-buildvm-ubuntu2004-regression-tests",
"cpp_version": "c++17",
"config_name": "Release",
"extra_config_args": "--apply-default-release-flags --trace2file enable",
"runOn": "v2.1-Release"
}
]
это было НЕВЕРОЯТНО здорово! ответ (в том смысле, что вы были очень ясно о том, почему и как). К сожалению, ответ ужасно сложен. Я все еще не уверен, что стоит изменить мой текущий процесс (дублировать отладку в файл конфигурации выпуска и раскомментировать строки). Но возможно. ПОЖАЛУЙСТА, дайте мне знать, если github когда-либо решит это более прямолинейно (например, переключатель включения / выключения в каждом элементе матрицы).
Может быть, последний \" здесь не нужен? echo ::set-output name=matrix::{\"include\":$(echo $matrix)}\"
ооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооо Я даже не думал, что смогу использовать fromJson
и передать динамическое значение в матрицу. Это просто изменило все.
@AntonioGamizDelgado Вы правы, последнее \n
неверно (выяснилось после использования этих примеров для моего собственного рабочего процесса). Я отредактировал ответ и удалил его.
Добавление еще одного ответа, так как в этом используются настраиваемые действия вместо встроенных сценариев оболочки. Отказ от ответственности: я являюсь сопровождающим одного из действий (спасибо за вдохновение).
Используя два дополнительных действия,
Вы можете добиться того же эффекта, что и пользовательский сценарий оболочки в моем другом ответе, но, возможно, более чистым способом:
.github/рабочие процессы/sample.yml
name: Configurable Build Matrix
on: push
jobs:
matrix_prep:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- uses: nelonoel/[email protected]
- id: set-matrix
uses: JoshuaTheMiller/[email protected]
with:
filter: '[?runOn==`${{ env.BRANCH_NAME }}` || runOn==`always`]'
build-n-test:
needs: matrix_prep
runs-on: ${{ matrix.runs_on }}
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
steps:
- run: echo "Hello ${{ matrix.someValue }}"
.github/рабочие процессы/matrix_includes.json
[
{
"runs_on":"ubuntu-16.04",
"someValue":"Foo",
"runOn":"always"
},
{
"runs_on":"ubuntu-18.04",
"someValue":"Bar",
"runOn":"v2.1-Release"
},
{
"runs_on":"ubuntu-20.04",
"someValue":"Hello again",
"runOn":"v2.1-Release"
}
]
оба файла можно найти в репозитории Action
filter
также использует другой синтаксис фильтрации: вместо jq используется JMESPATH . Я обнаружил, что JMESPATH очень хорошо документирован и поддерживается. Чтобы узнать больше о том, как работает синтаксис, вы можете посетить их страницу с интерактивными примерами.conditional-build-matrix
ищет файл с именем matrix_includes.json
в папке .github/workflows/
(тот же файл, включенный в другой ответ). Это местоположение можно настроить, и оно задокументировано на странице акции.Я получаю эту ошибку из вашего решения: рабочий процесс недействителен. .github/workflows/release.yml (строка: 22, столбец: 15): ожидаемый формат {org}/{repo}[/path]@ref. Фактическая входная строка «JoshuaTheMiller/conditional-build-matrix» имеет неверный формат.
@FernandoRojo, не могли бы вы предоставить ссылку на свой репозиторий и/или открыть проблему в GitHub Action, если считаете, что проблема существует? В качестве быстрой проверки работоспособности я повторно запустил образец сборки, демонстрирующий этот ответ, и он работал правильно: github.com/JoshuaTheMiller/conditional-build-matrix/actions/…
Я думаю, это потому, что вы использовали локальное действие, а не импортировали его из отдельного репо. Попробуйте создать отдельный репозиторий, который импортирует ваши действия, и вы поймете, что я имею в виду.
@FernandoRojo Я запустил это из другого репо в качестве проверки работоспособности, и сборка завершилась успешно. Не могли бы вы поделиться ссылкой на вашу сборку, которая терпит неудачу?
Я только что обновил этот ответ, включив в него версию моего действия (@0.0.1
), поскольку раньше оно отсутствовало в этом ответе. Может ли это быть корнем проблемы, которую вы видите?
Я нашел этот пост, и он был очень полезным. Хотя это гораздо сложнее, чем вариант использования, который у меня был.
Это побудило меня изучить другие решения, и я придумал альтернативный ответ, который работает для более простых случаев использования, когда вы просто хотите исключить одно измерение матрицы для определенных условий.
Примеры будут:
apple
, если текущее действие выполняется на ветке main
banana
в сборки без PR ИЛИ в сборки PR, когда метка BUILD-BANANA
применяется к PRstrategy:
matrix:
fruits:
- apple
- banana
exclude:
- fruits: ${{ github.ref == 'refs/heads/main' && 'dummy' || 'apple' }}
- fruits: ${{ (github.event_name != 'pull_request' || (github.event_name == 'pull_request' && contains( github.event.pull_request.labels.*.name, 'BUILD-BANANA'))) && 'dummy' || 'banana' }}
Строка 'dummy'
назначается исключенным фруктам, когда фрукты не следует исключать.
Это сработало для меня... но мне пришлось изменить && '' || 'apple'
на && 'dummy' || 'apple'
. Поскольку ''
является «ложным», это приводит к тому, что apple
всегда исключается.
Я ПОНИМАЮ, что есть функция «если», которую можно добавить к каждому шагу, но это создаст массу заданий с отключенными шагами. Что я хочу, так это просто не запускать эти задания для каждого матричного элемента, в котором часть if оценивается как false.
С многоразовыми рабочими процессами мы можем полностью пропустить (повторно используемые) задания (по сравнению с каждым шагом), просто добавив одно условие к (повторно используемому) заданию/передав флаг в качестве входных данных. Не идеальный вариант, поскольку мы по-прежнему получаем пропущенные задания в отчетах, но довольно серьезный недостаток по сравнению с обусловливанием каждого шага задания.
матрица-workflow.yml:
jobs:
build:
strategy:
matrix:
build-config:
- foo: 'bar'
if: ${{ xxx }}
- foo: 'baz'
if: ${{ yyy }}
uses: ./.github/workflows/reusable-workflow.yml
with:
if: ${{ matrix.build-config.if }}
foo: ${{ matrix.build-config.foo }}
многоразовый-workflow.yml:
on:
workflow_call:
inputs:
if:
description: 'Whether to run this job'
required: false
default: true
type: boolean
foo:
required: true
type: string
jobs:
reusable-build:
if: ${{ inputs.if }}
...
Пример пропущенного задания в отчетах:
Это фантастика! Ну, это не необходимость «еще одного уровня косвенности», но это проблема GitHub Actions в целом. Я нашел это, потому что искал способ иметь матрицу заданий, которые все «пропускают», если знают, что им ничего не нужно делать, но которые также могут быть перечислены как «обязательные проверки» в защите ветвей. Если вы установите пропуск на уровне матрицы, проверки защиты ветвления никогда не будут выполнены. Выполнение этого в отдельных работах работает нормально. Небольшое улучшение: 'if' в задании повторно используемого рабочего процесса не нуждается в "${{ }}", так как это контекст выражения.
Чего большинство людей не понимают, так это того, что матрицы, например. матричные конфигурации с включением гораздо более удобны и сложны, чем обычные матрицы. Например, в Terraform это важно,
Добавление задания № 0 только для динамического создания «включаемых» матриц является хромым и будет портить внешний вид — это разумно только в том случае, если у вас есть 1 канал, который выполняет все окружения, и 1000 различных виртуальных машин / K8S на основе хромого ввода.
Что нам нужно, так это автоматически исключить включение матричной конфигурации, если есть только один корреспондент env: dev, если у нас есть только «dev» в списке envs, мы, очевидно, хотим пропустить все остальные, но все же github имеет лучшие функции канала.
@lewis, нет простого встроенного переключателя включения / выключения, подобного тому, что вы описываете для матричных сборок сегодня (29 декабря 2020 г.). Однако вы можете добиться результата, который вы описываете, как показано выше. Если встроенная опция станет доступной, я свяжусь с этим ответом при добавлении.