fix: Prerelease.yaml bug; #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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' }} |