Skip to content

fix: Prerelease.yaml bug; #5

fix: Prerelease.yaml bug;

fix: Prerelease.yaml bug; #5

Workflow file for this run

# Comments marked with *TODO* are the customization points where you should adjust the text of this workflow template to the
# needs of your your repo.
name: "CI: Build, Test, Benchmark, Pack"
on:
push:
branches:
- "**" # trigger on push for all branches
pull_request:
branches:
- "**" # trigger on PR for all branches.
workflow_dispatch:
inputs:
runners-os:
description: Comma-separated runners OS-es
type: string
# Note: there is a known GitHub actions issue: the workflow dispatch UI doesn't properly handle JSON strings with quotes -
# it removes the quotes. E.g. entering '["ubuntu-latest"]' in the UI prompt removes the inner quotes and it becomes the
# invalid JSON: '[ubuntu-latest]'.
# *TODO* Adjust the default runner OS or OS-es as needed.
default: ubuntu-latest
preprocessor-symbols:
description: Comma-separated preprocessor symbols
type: string
# *TODO* Adjust the default preprocessor symbols as needed.
default: "SHORT_RUN"
reset-benchmark-thresholds:
description: Set to "true" to reset Bencher thresholds if some degradation is expected.
type: boolean
default: false
# Concurrency: cancel in-progress runs for the same ref
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
env:
# The value of all *_PROJECTS variables must be specified as a string containing a JSON array of strings - path(s) to the project(s).
# Note the yaml folding indicator `>-`. It allows to enter single value (scalar, array, object, long string) values on multiple
# text lines with no need for escaping, which might be more readable, and writable.
# If not specified or empty, no actual building will be run (e.g. template projects).
# *TODO* The source code project(s) or solution(s) to build. Must be a JSON array of strings containing path(s) to the buildable project(s) or solution(s).
BUILD_PROJECTS: >
[
"src/Project/Project.slnx"
]
# If not specified or empty, no tests will be built or run. Not having tests is not typical and not desirable, but possible.
# For example projects that contain only the code of the deliverables, e.g. projects in early stages of development, or DevOps
# projects containing scripts and/or markup and/or metadata, template projects, prototype projects, experimentation, etc.
# *TODO* The test project(s) to build and run. Must be a JSON array of strings containing path(s) to the buildable and runnable test project(s).
TEST_PROJECTS: >
[
]
# If not specified or empty, no benchmarks will be built or run.
# *TODO* The benchmark project(s) to build and run. Must be a JSON array of strings containing path(s) to the buildable and runnable benchmark project(s).
BENCHMARK_PROJECTS: >
[
]
# If not specified or empty, no projects will be packed for NuGet validation during CI.
# *TODO* The project(s) to pack for NuGet validation during CI. Must be a JSON array of strings containing path(s) to the packable project(s).
PACKAGE_PROJECTS: >
[
]
# If not specified, the default is ["ubuntu-latest"].
# *TODO* The OS-es of the runner(s) to use for building and testing. Must be a JSON array of strings containing OS-es.
RUNNERS_OS: >
[
"ubuntu-latest"
]
# *TODO* Space or comma or semicolon-separated preprocessor symbols to pass to the compiler.
PREPROCESSOR_SYMBOLS: ""
DOTNET_VERSION: ${{ vars.DOTNET_VERSION || '10.0.x' }} # The .NET SDK version to use.
CONFIGURATION: ${{ vars.CONFIGURATION || 'Release' }} # The build configuration: Debug, Release, etc.
MIN_COVERAGE_PCT: ${{ vars.MIN_COVERAGE_PCT || 80 }} # The minimum code coverage percentage required to pass the tests.
MAX_REGRESSION_PCT: ${{ vars.MAX_REGRESSION_PCT || 20 }} # The maximum allowed performance regression percentage for benchmarks to pass.
MINVERTAGPREFIX: ${{ vars.MINVERTAGPREFIX || 'v' }} # The MinVer tag prefix.
MINVERDEFAULTPRERELEASEIDENTIFIERS: ${{ vars.MINVERDEFAULTPRERELEASEIDENTIFIERS || 'preview.0' }} # The MinVer default pre-release identifiers.
RESET_BENCHMARK_THRESHOLDS: ${{ vars.RESET_BENCHMARK_THRESHOLDS || 'false' }} # Set to "true" to reset Bencher thresholds if some degradation is expected.
VERBOSE: ${{ vars.VERBOSE || 'false' }} # Set to "true" to enable verbose logging in scripts.
jobs:
get-params:
name: Prepare input from env, vars, secrets, inputs, and defaults
runs-on: ubuntu-latest # in this workflow the runner doesn't matter - we're just preparing the inputs for the next workload(s).
permissions:
pull-requests: read
if: github.event_name != 'push' || !contains(github.event.head_commit.message, '[skip ci]')
outputs:
build-projects: ${{ steps.gather-params.outputs.build-projects }}
test-projects: ${{ steps.gather-params.outputs.test-projects }}
benchmark-projects: ${{ steps.gather-params.outputs.benchmark-projects }}
package-projects: ${{ steps.gather-params.outputs.package-projects }}
runners-os: ${{ steps.gather-params.outputs.runners-os }}
dotnet-version: ${{ steps.gather-params.outputs.dotnet-version }}
configuration: ${{ steps.gather-params.outputs.configuration }}
preprocessor-symbols: ${{ steps.gather-params.outputs.preprocessor-symbols }}
min-coverage-pct: ${{ steps.gather-params.outputs.min-coverage-pct }}
max-regression-pct: ${{ steps.gather-params.outputs.max-regression-pct }}
minver-tag-prefix: ${{ steps.gather-params.outputs.minver-tag-prefix }}
minver-prerelease-id: ${{ steps.gather-params.outputs.minver-prerelease-id }}
reset-benchmark-thresholds: ${{ steps.gather-params.outputs.reset-benchmark-thresholds }}
skip-push: ${{ steps.gather-params.outputs.skip-push }}
steps:
- name: Setup DevOps environment variables
id: setup-env
uses: vmelamed/vm2.DevOps/.github/actions/setup-env@main
- name: Gather argument values depending on the event
id: gather-params
shell: bash
run: |
source $DEVOPS_LIB_DIR/gh_core.sh
build_projects='${{ env.BUILD_PROJECTS }}'
test_projects='${{ env.TEST_PROJECTS }}'
benchmark_projects='${{ env.BENCHMARK_PROJECTS }}'
package_projects='${{ env.PACKAGE_PROJECTS }}'
runners_os='${{ env.RUNNERS_OS }}'
dotnet_version='${{ env.DOTNET_VERSION }}'
configuration='${{ env.CONFIGURATION }}'
preprocessor_symbols='${{ env.PREPROCESSOR_SYMBOLS }}'
min_coverage_pct='${{ env.MIN_COVERAGE_PCT }}'
max_regression_pct='${{ env.MAX_REGRESSION_PCT }}'
minver_tag_prefix='${{ env.MINVERTAGPREFIX }}'
minver_prerelease_id='${{ env.MINVERDEFAULTPRERELEASEIDENTIFIERS }}'
reset_benchmark_thresholds='${{ env.RESET_BENCHMARK_THRESHOLDS }}'
skip_push='false'
if [[ '${{ github.event_name }}' == 'pull_request' ]] ||
[[ '${{ github.event_name }}' == 'push' && '${{ github.ref_name }}' == 'main' ]]; then
# For pull requests and pushes to the main branch, use the arg. values from env: vars, secrets, defaults
info "Event: ${{ github.event_name }}. Using the argument values from the environment: vars, secrets, defaults." | to_stdout
elif [ '${{ github.event_name }}' == 'push' ] && [ '${{ github.ref_name }}' != 'main' ]; then
# For pushes to the non-main branch, use the argument values from the environment: vars, secrets, defaults.
# To avoid duplicate runs when:
# 1) push to main AND
# 2) there is an open PR to main, then
# => skip the push-triggered CI.
export GH_TOKEN='${{ github.token }}'
# how many open PRs exist for this branch?
if ! open_pr_count=$(gh pr list \
--repo "${{ github.repository }}" \
--state open \
--json headRefName \
--jq 'map(select(.headRefName == "${{ github.ref_name }}")) | length'); then
open_pr_count=0
warning "Failed to query open PR-s via gh. Running push-triggered CI with SHORT_RUN." | to_stdout
fi
info "Open PR count for '${{ github.ref_name }}': ${open_pr_count}" | to_stdout
# if there are open PRs, skip push-triggered CI - rely on the PR to trigger it
if [ "${open_pr_count}" -gt 0 ]; then
info "There are open PRs for this branch: skip the CI triggered by the push." | to_stdout
skip_push='true'
else
info "No open PRs for this branch. Running push-triggered CI with SHORT_RUN preprocessor symbol for faster benchmarks." | to_stdout
preprocessor_symbols="${preprocessor_symbols};SHORT_RUN"
fi
elif [ '${{ github.event_name }}' == "workflow_dispatch" ]; then
# Get the values from the UI inputs of workflow_dispatch event. Convert comma-separated runners' OS values to JSON array
# There is a known GitHub actions issue: the workflow dispatch UI doesn't properly handle JSON strings with quotes.
# E.g. for the input '["ubuntu-latest"]', the UI removes the inner quotes and it becomes the invalid JSON: '[ubuntu-latest]'.
# For UI manually triggered runs (workflow_dispatch event), use the arg. values from env: vars, secrets, defaults
# and override with the inputs from the UI.
runners_os=$(echo "${{ inputs.runners-os }}" | jq -Rc 'split(",") | map(select(length > 0) | gsub("^\\s+|\\s+$";""))')
preprocessor_symbols="${preprocessor_symbols};${{ inputs.preprocessor-symbols }}"
reset_benchmark_thresholds="${{ inputs.reset-benchmark-thresholds }}"
else
error "Unsupported event: ${{ github.event_name }}" | to_stderr
exit 5
fi
# Set the outputs:
args_to_github_output \
build_projects \
test_projects \
benchmark_projects \
package_projects \
runners_os \
dotnet_version \
configuration \
preprocessor_symbols \
min_coverage_pct \
max_regression_pct \
minver_tag_prefix \
minver_prerelease_id \
reset_benchmark_thresholds \
skip_push
call-ci:
name: "Run CI: Build, Test, Benchmark, Pack"
needs:
- get-params
if: ${{ needs.get-params.outputs.skip-push != 'true' }}
uses: vmelamed/vm2.DevOps/.github/workflows/_ci.yaml@main
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
REPORTGENERATOR_LICENSE: ${{ secrets.REPORTGENERATOR_LICENSE }}
permissions:
contents: read # Required to checkout the code
packages: read # Required to restore GitHub Packages NuGet packages
pull-requests: write # Required to comment on PRs
checks: write # Required to create GitHub Checks
with:
build-projects: ${{ needs.get-params.outputs.build-projects }}
test-projects: ${{ needs.get-params.outputs.test-projects }}
benchmark-projects: ${{ needs.get-params.outputs.benchmark-projects }}
package-projects: ${{ needs.get-params.outputs.package-projects }}
runners-os: ${{ needs.get-params.outputs.runners-os }}
dotnet-version: ${{ needs.get-params.outputs.dotnet-version }}
configuration: ${{ needs.get-params.outputs.configuration }}
preprocessor-symbols: ${{ needs.get-params.outputs.preprocessor-symbols }}
min-coverage-pct: ${{ fromJSON(needs.get-params.outputs.min-coverage-pct) }}
max-regression-pct: ${{ fromJSON(needs.get-params.outputs.max-regression-pct) }}
minver-tag-prefix: ${{ needs.get-params.outputs.minver-tag-prefix }}
minver-prerelease-id: ${{ needs.get-params.outputs.minver-prerelease-id }}
reset-benchmark-thresholds: ${{ needs.get-params.outputs.reset-benchmark-thresholds == 'true' }}