From 4352505321548168f95904702fffcce18262bc8f Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Wed, 21 Feb 2024 11:33:14 +0100 Subject: [PATCH 01/42] Split composite action into linux/macos/windows --- composite/action.yml | 170 ++----------------- composite/linux/action.yml | 315 +++++++++++++++++++++++++++++++++++ composite/macos/action.yml | 1 + composite/windows/action.yml | 315 +++++++++++++++++++++++++++++++++++ 4 files changed, 644 insertions(+), 157 deletions(-) create mode 100644 composite/linux/action.yml create mode 120000 composite/macos/action.yml create mode 100644 composite/windows/action.yml diff --git a/composite/action.yml b/composite/action.yml index cda1fed0..243a7d74 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -146,169 +146,25 @@ inputs: outputs: json: description: "Test results as JSON" - value: ${{ steps.test-results.outputs.json }} + value: ${{ steps.linux.outputs.json || steps.macos.outputs.json || steps.windows.outputs.json }} runs: using: 'composite' steps: - - name: Check for Python3 - id: python - run: | - echo '::group::Check for Python3' - # we check version here just to execute `python3` with an argument - # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store - # command `which python3` finds that, but `python3 -V` does not return the version on stdout - if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] - then - if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] - then - echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." - exit 1 - fi + - name: Run on Linux + id: linux + if: startsWith(env.RUNNER_OS, 'Linux') + uses: $GITHUB_ACTION_PATH/linux - PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" - else - PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" - fi + - name: Run on macOS + id: macos + if: startsWith(env.RUNNER_OS, 'macOS') + uses: $GITHUB_ACTION_PATH/macos - echo "Python that creates venv: $PYTHON_BIN" - echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" - echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '::endgroup::' - shell: bash - - - name: Detect OS - id: os - run: | - case "$RUNNER_OS" in - Linux*) - echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" - ;; - macOS*) - echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" - ;; - Windows*) - echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" - echo "pip-options=--user" >> "$GITHUB_OUTPUT" - ;; - esac - shell: bash - - - name: Restore PIP packages cache - uses: actions/cache/restore@v4 - id: cache - continue-on-error: true - with: - path: ${{ steps.os.outputs.pip-cache }} - key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - - - name: Create virtualenv - id: venv - continue-on-error: true - env: - PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} - run: | - echo '::group::Create virtualenv' - echo "Python that creates venv: $PYTHON_BIN" - - echo "Creating virtual environment" - if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv - then - echo "Looks like there is neither virtualenv nor venv package installed" - if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] - then - echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" - "$PYTHON_BIN" -m pip install virtualenv - fi - - if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv - then - echo "Still cannot create venv after installing virtualenv package" - exit 1 - fi - fi - - echo "Finding Python interpreter in venv" - case "$RUNNER_OS" in - Linux*|macOS*) - PYTHON_VENV="enricomi-publish-action-venv/bin/python";; - Windows*) - PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; - esac - PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" - echo "Python in venv: $PYTHON_VENV" - echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '::endgroup::' - shell: bash - - - name: Install Python dependencies - run: | - echo '::group::Install Python dependencies' - # make sure wheel is installed, which improves installing our dependencies - "$PYTHON_VENV" -m pip install wheel - "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '::endgroup::' - shell: bash - - - name: Publish Test Results - id: test-results - run: | - echo '::group::Publish Test Results' - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '::endgroup::' - env: - GITHUB_TOKEN: ${{ inputs.github_token }} - GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} - GITHUB_RETRIES: ${{ inputs.github_retries }} - COMMIT: ${{ inputs.commit }} - CHECK_NAME: ${{ inputs.check_name }} - COMMENT_TITLE: ${{ inputs.comment_title }} - COMMENT_MODE: ${{ inputs.comment_mode }} - FAIL_ON: ${{ inputs.fail_on }} - ACTION_FAIL: ${{ inputs.action_fail }} - ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} - FILES: ${{ inputs.files }} - JUNIT_FILES: ${{ inputs.junit_files }} - NUNIT_FILES: ${{ inputs.nunit_files }} - XUNIT_FILES: ${{ inputs.xunit_files }} - TRX_FILES: ${{ inputs.trx_files }} - TIME_UNIT: ${{ inputs.time_unit }} - TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} - REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} - REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} - DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} - LARGE_FILES: ${{ inputs.large_files }} - IGNORE_RUNS: ${{ inputs.ignore_runs }} - COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} - PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} - EVENT_FILE: ${{ inputs.event_file }} - EVENT_NAME: ${{ inputs.event_name }} - TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} - CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} - CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} - SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} - SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} - SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} - JSON_FILE: ${{ inputs.json_file }} - JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} - JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} - JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} - CHECK_RUN: ${{ inputs.check_run }} - JOB_SUMMARY: ${{ inputs.job_summary }} - SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented - ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented - LOG_LEVEL: ${{ inputs.log_level }} - shell: bash - - - name: Save PIP packages cache - uses: actions/cache/save@v4 - if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit - continue-on-error: true - with: - path: ${{ steps.os.outputs.pip-cache }} - key: ${{ steps.cache.outputs.cache-primary-key }} + - name: Run on Windows + id: windows + if: startsWith(env.RUNNER_OS, 'Windows') + uses: $GITHUB_ACTION_PATH/windows branding: icon: 'check-circle' diff --git a/composite/linux/action.yml b/composite/linux/action.yml new file mode 100644 index 00000000..9d45dda9 --- /dev/null +++ b/composite/linux/action.yml @@ -0,0 +1,315 @@ +name: 'Publish Test Results' +author: 'EnricoMi' +description: 'Publishes JUnit, NUnit, XUnit, TRX, JSON test results on GitHub for .NET, Dart, Java, JS, Jest, Mocha, Python, Scala, …' + +inputs: + github_token: + description: 'GitHub API Access Token.' + default: ${{ github.token }} + required: false + github_token_actor: + description: 'The name of the GitHub app that owns the GitHub API Access Token (see github_token). Used to identify pull request comments created by this action during earlier runs. Has to be set when `github_token` is set to a GitHub app installation token (other than GitHub actions). Otherwise, existing comments will not be updated, but new comments created. Note: this does not change the bot name of the pull request comments. Defaults to "github-actions".' + default: 'github-actions' + required: false + github_retries: + description: 'Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.' + default: '10' + required: false + commit: + description: 'Commit SHA to which test results are published. Only needed if the value of GITHUB_SHA does not work for you.' + required: false + check_name: + description: 'Name of the created check run.' + default: 'Test Results' + required: false + comment_title: + description: 'An alternative title for the pull request comment. Defaults to value of check_name input.' + required: false + comment_mode: + description: 'The action posts comments to pull requests that are associated with the commit. Set to "always" - always comment, "changes" - comment when changes w.r.t. the target branch exist, "changes in failures" - when changes in the number of failures and errors exist, "changes in errors" - when changes in the number of (only) errors exist, "failures" - when failures or errors exist, "errors" - when (only) errors exist, "off" - to not create pull request comments.' + default: 'always' + required: false + fail_on: + description: 'The created test result check run has failure state if any test fails or test errors occur. Never fails when set to "nothing", fails only on errors when set to "errors". Default is "test failures".' + default: 'test failures' + required: false + action_fail: + description: 'When set "true", the action itself fails when tests have failed (see option fail_on).' + default: 'false' + required: false + action_fail_on_inconclusive: + description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' + default: 'false' + required: false + files: + description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + required: false + junit_files: + description: 'Deprecated, use "files" option instead.' + required: false + nunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + xunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + trx_files: + description: 'Deprecated, use "files" option instead.' + required: false + time_unit: + description: 'Time values in the test result files have this unit. Supports "seconds" and "milliseconds".' + default: 'seconds' + required: false + test_file_prefix: + description: 'Paths in the test result files should be relative to the git repository for annotations to work best. This prefix is added to (if starting with "+"), or remove from (if starting with "-") test file paths. Examples: "+src/" or "-/opt/actions-runner".' + required: false + report_individual_runs: + description: 'Individual runs of the same test may see different failures. Reports all individual failures when set "true" or the first only otherwise.' + required: false + report_suite_logs: + description: 'In addition to reporting regular test logs, also report test suite logs. These are logs provided on suite level, not individual test level. Set to "info" for normal output, "error" for error output, "any" for both, or "none" for no suite logs at all. Defaults to "none".' + default: 'none' + required: false + deduplicate_classes_by_file_name: + description: 'De-duplicates classes with same name by their file name when set "true", combines test results for those classes otherwise.' + required: false + large_files: + description: 'Support for large files is enabled when set to "true". Defaults to "false", unless ignore_runs is "true".' + required: false + ignore_runs: + description: 'Does not collect test run information from the test result files, which is useful for very large files. This disables any check run annotations.' + default: 'false' + required: false + check_run: + description: 'Set to "true", the results are published as a check run, but it may not be associated with the workflow that ran this action.' + default: 'true' + required: false + job_summary: + description: 'Set to "true", the results are published as part of the job summary page of the workflow run.' + default: 'true' + required: false + compare_to_earlier_commit: + description: 'Test results are compared to results of earlier commits to highlight changes: "false" - disable comparison, "true" - compare across commits.' + default: 'true' + required: false + pull_request_build: + description: 'As part of pull requests, GitHub builds a merge commit, which combines the commit and the target branch. If tests ran on the actual pushed commit, then set this to "commit". Defaults to "merge".' + default: 'merge' + required: false + event_file: + description: 'An alternative event file to use. Useful to replace a "workflow_run" event file with the actual source event file.' + required: false + event_name: + description: 'An alternative event name to use. Useful to replace a "workflow_run" event name with the actual source event name: github.event.workflow_run.event.' + required: false + test_changes_limit: + description: 'Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of 0. The default is 10.' + required: false + check_run_annotations: + description: 'Adds additional information to the check run. This is a comma-separated list of any of the following values: "all tests" - list all found tests, "skipped tests" - list all skipped tests. Set to "none" to add no extra annotations at all.' + default: 'all tests, skipped tests' + required: false + check_run_annotations_branch: + description: 'Adds check run annotations only on given branches. Comma-separated list of branch names allowed, asterisk "*" matches all branches. Defaults to event.repository.default_branch or "main, master".' + required: false + seconds_between_github_reads: + description: 'Sets the number of seconds the action waits between concurrent read requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '0.25' + required: false + seconds_between_github_writes: + description: 'Sets the number of seconds the action waits between concurrent write requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '2.0' + required: false + secondary_rate_limit_wait_seconds: + description: 'Sets the number of seconds to wait before retrying secondary rate limit errors. If not set, the default defined in the PyGithub library is used (currently 60 seconds).' + required: false + json_file: + description: 'Results are written to this JSON file.' + required: false + json_thousands_separator: + description: 'Formatted numbers in JSON use this character to separate groups of thousands. Common values are "," or ".". Defaults to punctuation space (\u2008).' + default: ' ' + required: false + json_suite_details: + description: 'Write out all suite details to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + json_test_case_results: + description: 'Write out all individual test case results to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + search_pull_requests: + description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' + default: 'false' + required: false + +outputs: + json: + description: "Test results as JSON" + value: ${{ steps.test-results.outputs.json }} + +runs: + using: 'composite' + steps: + - name: Check for Python3 + id: python + run: | + echo '##[group]Check for Python3' + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] + then + if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] + then + echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + exit 1 + fi + + PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" + else + PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" + fi + + echo "Python that creates venv: $PYTHON_BIN" + echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" + echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + echo '##[endgroup]' + shell: bash + + - name: Detect OS + id: os + run: | + case "$RUNNER_OS" in + Linux*) + echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" + ;; + macOS*) + echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" + ;; + Windows*) + echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" + echo "pip-options=--user" >> "$GITHUB_OUTPUT" + ;; + esac + shell: bash + + - name: Restore PIP packages cache + uses: actions/cache/restore@v4 + id: cache + continue-on-error: true + with: + path: ${{ steps.os.outputs.pip-cache }} + key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 + + - name: Create virtualenv + id: venv + continue-on-error: true + env: + PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} + run: | + echo '##[group]Create virtualenv' + echo "Python that creates venv: $PYTHON_BIN" + + echo "Creating virtual environment" + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv + then + echo "Looks like there is neither virtualenv nor venv package installed" + if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] + then + echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" + "$PYTHON_BIN" -m pip install virtualenv + fi + + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv + then + echo "Still cannot create venv after installing virtualenv package" + exit 1 + fi + fi + + echo "Finding Python interpreter in venv" + case "$RUNNER_OS" in + Linux*|macOS*) + PYTHON_VENV="enricomi-publish-action-venv/bin/python";; + Windows*) + PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; + esac + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" + echo "Python in venv: $PYTHON_VENV" + echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + echo '##[endgroup]' + shell: bash + + - name: Install Python dependencies + run: | + echo '##[group]Install Python dependencies' + # make sure wheel is installed, which improves installing our dependencies + "$PYTHON_VENV" -m pip install wheel + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + echo '##[endgroup]' + shell: bash + + - name: Publish Test Results + id: test-results + run: | + echo '##[group]Publish Test Results' + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '##[endgroup]' + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} + shell: bash + + - name: Save PIP packages cache + uses: actions/cache/save@v4 + if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit + continue-on-error: true + with: + path: ${{ steps.os.outputs.pip-cache }} + key: ${{ steps.cache.outputs.cache-primary-key }} + +branding: + icon: 'check-circle' + color: 'green' diff --git a/composite/macos/action.yml b/composite/macos/action.yml new file mode 120000 index 00000000..10bf9204 --- /dev/null +++ b/composite/macos/action.yml @@ -0,0 +1 @@ +../linux/action.yml \ No newline at end of file diff --git a/composite/windows/action.yml b/composite/windows/action.yml new file mode 100644 index 00000000..9d45dda9 --- /dev/null +++ b/composite/windows/action.yml @@ -0,0 +1,315 @@ +name: 'Publish Test Results' +author: 'EnricoMi' +description: 'Publishes JUnit, NUnit, XUnit, TRX, JSON test results on GitHub for .NET, Dart, Java, JS, Jest, Mocha, Python, Scala, …' + +inputs: + github_token: + description: 'GitHub API Access Token.' + default: ${{ github.token }} + required: false + github_token_actor: + description: 'The name of the GitHub app that owns the GitHub API Access Token (see github_token). Used to identify pull request comments created by this action during earlier runs. Has to be set when `github_token` is set to a GitHub app installation token (other than GitHub actions). Otherwise, existing comments will not be updated, but new comments created. Note: this does not change the bot name of the pull request comments. Defaults to "github-actions".' + default: 'github-actions' + required: false + github_retries: + description: 'Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.' + default: '10' + required: false + commit: + description: 'Commit SHA to which test results are published. Only needed if the value of GITHUB_SHA does not work for you.' + required: false + check_name: + description: 'Name of the created check run.' + default: 'Test Results' + required: false + comment_title: + description: 'An alternative title for the pull request comment. Defaults to value of check_name input.' + required: false + comment_mode: + description: 'The action posts comments to pull requests that are associated with the commit. Set to "always" - always comment, "changes" - comment when changes w.r.t. the target branch exist, "changes in failures" - when changes in the number of failures and errors exist, "changes in errors" - when changes in the number of (only) errors exist, "failures" - when failures or errors exist, "errors" - when (only) errors exist, "off" - to not create pull request comments.' + default: 'always' + required: false + fail_on: + description: 'The created test result check run has failure state if any test fails or test errors occur. Never fails when set to "nothing", fails only on errors when set to "errors". Default is "test failures".' + default: 'test failures' + required: false + action_fail: + description: 'When set "true", the action itself fails when tests have failed (see option fail_on).' + default: 'false' + required: false + action_fail_on_inconclusive: + description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' + default: 'false' + required: false + files: + description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + required: false + junit_files: + description: 'Deprecated, use "files" option instead.' + required: false + nunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + xunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + trx_files: + description: 'Deprecated, use "files" option instead.' + required: false + time_unit: + description: 'Time values in the test result files have this unit. Supports "seconds" and "milliseconds".' + default: 'seconds' + required: false + test_file_prefix: + description: 'Paths in the test result files should be relative to the git repository for annotations to work best. This prefix is added to (if starting with "+"), or remove from (if starting with "-") test file paths. Examples: "+src/" or "-/opt/actions-runner".' + required: false + report_individual_runs: + description: 'Individual runs of the same test may see different failures. Reports all individual failures when set "true" or the first only otherwise.' + required: false + report_suite_logs: + description: 'In addition to reporting regular test logs, also report test suite logs. These are logs provided on suite level, not individual test level. Set to "info" for normal output, "error" for error output, "any" for both, or "none" for no suite logs at all. Defaults to "none".' + default: 'none' + required: false + deduplicate_classes_by_file_name: + description: 'De-duplicates classes with same name by their file name when set "true", combines test results for those classes otherwise.' + required: false + large_files: + description: 'Support for large files is enabled when set to "true". Defaults to "false", unless ignore_runs is "true".' + required: false + ignore_runs: + description: 'Does not collect test run information from the test result files, which is useful for very large files. This disables any check run annotations.' + default: 'false' + required: false + check_run: + description: 'Set to "true", the results are published as a check run, but it may not be associated with the workflow that ran this action.' + default: 'true' + required: false + job_summary: + description: 'Set to "true", the results are published as part of the job summary page of the workflow run.' + default: 'true' + required: false + compare_to_earlier_commit: + description: 'Test results are compared to results of earlier commits to highlight changes: "false" - disable comparison, "true" - compare across commits.' + default: 'true' + required: false + pull_request_build: + description: 'As part of pull requests, GitHub builds a merge commit, which combines the commit and the target branch. If tests ran on the actual pushed commit, then set this to "commit". Defaults to "merge".' + default: 'merge' + required: false + event_file: + description: 'An alternative event file to use. Useful to replace a "workflow_run" event file with the actual source event file.' + required: false + event_name: + description: 'An alternative event name to use. Useful to replace a "workflow_run" event name with the actual source event name: github.event.workflow_run.event.' + required: false + test_changes_limit: + description: 'Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of 0. The default is 10.' + required: false + check_run_annotations: + description: 'Adds additional information to the check run. This is a comma-separated list of any of the following values: "all tests" - list all found tests, "skipped tests" - list all skipped tests. Set to "none" to add no extra annotations at all.' + default: 'all tests, skipped tests' + required: false + check_run_annotations_branch: + description: 'Adds check run annotations only on given branches. Comma-separated list of branch names allowed, asterisk "*" matches all branches. Defaults to event.repository.default_branch or "main, master".' + required: false + seconds_between_github_reads: + description: 'Sets the number of seconds the action waits between concurrent read requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '0.25' + required: false + seconds_between_github_writes: + description: 'Sets the number of seconds the action waits between concurrent write requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '2.0' + required: false + secondary_rate_limit_wait_seconds: + description: 'Sets the number of seconds to wait before retrying secondary rate limit errors. If not set, the default defined in the PyGithub library is used (currently 60 seconds).' + required: false + json_file: + description: 'Results are written to this JSON file.' + required: false + json_thousands_separator: + description: 'Formatted numbers in JSON use this character to separate groups of thousands. Common values are "," or ".". Defaults to punctuation space (\u2008).' + default: ' ' + required: false + json_suite_details: + description: 'Write out all suite details to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + json_test_case_results: + description: 'Write out all individual test case results to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + search_pull_requests: + description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' + default: 'false' + required: false + +outputs: + json: + description: "Test results as JSON" + value: ${{ steps.test-results.outputs.json }} + +runs: + using: 'composite' + steps: + - name: Check for Python3 + id: python + run: | + echo '##[group]Check for Python3' + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] + then + if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] + then + echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + exit 1 + fi + + PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" + else + PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" + fi + + echo "Python that creates venv: $PYTHON_BIN" + echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" + echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + echo '##[endgroup]' + shell: bash + + - name: Detect OS + id: os + run: | + case "$RUNNER_OS" in + Linux*) + echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" + ;; + macOS*) + echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" + ;; + Windows*) + echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" + echo "pip-options=--user" >> "$GITHUB_OUTPUT" + ;; + esac + shell: bash + + - name: Restore PIP packages cache + uses: actions/cache/restore@v4 + id: cache + continue-on-error: true + with: + path: ${{ steps.os.outputs.pip-cache }} + key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 + + - name: Create virtualenv + id: venv + continue-on-error: true + env: + PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} + run: | + echo '##[group]Create virtualenv' + echo "Python that creates venv: $PYTHON_BIN" + + echo "Creating virtual environment" + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv + then + echo "Looks like there is neither virtualenv nor venv package installed" + if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] + then + echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" + "$PYTHON_BIN" -m pip install virtualenv + fi + + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv + then + echo "Still cannot create venv after installing virtualenv package" + exit 1 + fi + fi + + echo "Finding Python interpreter in venv" + case "$RUNNER_OS" in + Linux*|macOS*) + PYTHON_VENV="enricomi-publish-action-venv/bin/python";; + Windows*) + PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; + esac + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" + echo "Python in venv: $PYTHON_VENV" + echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + echo '##[endgroup]' + shell: bash + + - name: Install Python dependencies + run: | + echo '##[group]Install Python dependencies' + # make sure wheel is installed, which improves installing our dependencies + "$PYTHON_VENV" -m pip install wheel + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + echo '##[endgroup]' + shell: bash + + - name: Publish Test Results + id: test-results + run: | + echo '##[group]Publish Test Results' + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '##[endgroup]' + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} + shell: bash + + - name: Save PIP packages cache + uses: actions/cache/save@v4 + if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit + continue-on-error: true + with: + path: ${{ steps.os.outputs.pip-cache }} + key: ${{ steps.cache.outputs.cache-primary-key }} + +branding: + icon: 'check-circle' + color: 'green' From 3e1a5d340819de8b57dd2f162541174e944145d8 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 11:21:39 +0100 Subject: [PATCH 02/42] Rework echoing endgroup --- composite/linux/action.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/composite/linux/action.yml b/composite/linux/action.yml index 9d45dda9..df204561 100644 --- a/composite/linux/action.yml +++ b/composite/linux/action.yml @@ -155,6 +155,8 @@ runs: id: python run: | echo '##[group]Check for Python3' + trap "echo '##[endgroup]'" EXIT + # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store # command `which python3` finds that, but `python3 -V` does not return the version on stdout @@ -174,7 +176,6 @@ runs: echo "Python that creates venv: $PYTHON_BIN" echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '##[endgroup]' shell: bash - name: Detect OS @@ -209,6 +210,8 @@ runs: PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} run: | echo '##[group]Create virtualenv' + trap "echo '##[endgroup]'" EXIT + echo "Python that creates venv: $PYTHON_BIN" echo "Creating virtual environment" @@ -238,24 +241,25 @@ runs: PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '##[endgroup]' shell: bash - name: Install Python dependencies run: | echo '##[group]Install Python dependencies' + trap "echo '##[endgroup]'" EXIT + # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '##[endgroup]' shell: bash - name: Publish Test Results id: test-results run: | echo '##[group]Publish Test Results' + trap "echo '##[endgroup]'" EXIT + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '##[endgroup]' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} From 271912948897bd4707010abfbdd7cf8339eebb07 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 11:21:55 +0100 Subject: [PATCH 03/42] Migrate action to Windows PowerShell --- composite/windows/action.yml | 140 ++++++++++++++++------------------- 1 file changed, 64 insertions(+), 76 deletions(-) diff --git a/composite/windows/action.yml b/composite/windows/action.yml index 9d45dda9..19aa59c8 100644 --- a/composite/windows/action.yml +++ b/composite/windows/action.yml @@ -154,44 +154,31 @@ runs: - name: Check for Python3 id: python run: | - echo '##[group]Check for Python3' - # we check version here just to execute `python3` with an argument - # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store - # command `which python3` finds that, but `python3 -V` does not return the version on stdout - if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] - then - if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] - then - echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." - exit 1 - fi + Write-Output "##[group]Check for Python3" + try { + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ( !(Get-Command python3 -ErrorAction SilentlyContinue) -Or -Not ((python3 -V 2> $null) -Like "Python 3.*") ) { + if ( !(Get-Command python -ErrorAction SilentlyContinue) -Or -Not ((python -V 2> $null) -Like "Python 3.*") ) { + Write-Output "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + Write-Output "##[endgroup]" + Exit 1 + } - PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" - else - PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" - fi + $PYTHON_BIN = python -c "import sys; print(sys.executable)" + } else { + $PYTHON_BIN = python3 -c "import sys; print(sys.executable)" + } + Write-Output "Python that creates venv: $PYTHON_BIN" + "PYTHON_BIN=$PYTHON_BIN" | Out-File -FilePath $env:GITHUB_ENV -Append - echo "Python that creates venv: $PYTHON_BIN" - echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" - echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '##[endgroup]' - shell: bash - - - name: Detect OS - id: os - run: | - case "$RUNNER_OS" in - Linux*) - echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" - ;; - macOS*) - echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" - ;; - Windows*) - echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" - echo "pip-options=--user" >> "$GITHUB_OUTPUT" - ;; - esac + $VERSION = Invoke-Expression -Command "& '$PYTHON_BIN' -V" + Write-Output "Python version: $VERSION" + "version=$VERSION" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + } finally { + Write-Output "##[endgroup]" + } shell: bash - name: Restore PIP packages cache @@ -199,63 +186,64 @@ runs: id: cache continue-on-error: true with: - path: ${{ steps.os.outputs.pip-cache }} + path: '~\\AppData\\Local\\pip\\Cache' key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv id: venv continue-on-error: true - env: - PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} run: | - echo '##[group]Create virtualenv' - echo "Python that creates venv: $PYTHON_BIN" + Write-Output "##[group]Create virtualenv" + try { + Write-Output "Python that creates venv: $PYTHON_BIN" - echo "Creating virtual environment" - if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv - then - echo "Looks like there is neither virtualenv nor venv package installed" - if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] - then - echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" - "$PYTHON_BIN" -m pip install virtualenv - fi + Write-Output "Creating virtual environment" + if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) -And -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m venv enricomi-publish-action-venv" 2> $null) ) { + Write-Output "Looks like there is neither virtualenv nor venv package installed" + if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m pip install --user virtualenv" 2> $null) ) { + Write-Output "Installing virtualenv package with PIP option '--user' failed, now trying without" + if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m pip install virtualenv" 2> $null) ) { + Write-Output "::error::Installing virtualenv package failed" + Exit 1 + } + } - if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv - then - echo "Still cannot create venv after installing virtualenv package" - exit 1 - fi - fi + if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) ) { + Write-Output "::error::Cannot create venv after installing virtualenv package" + Exit 1 + } + } - echo "Finding Python interpreter in venv" - case "$RUNNER_OS" in - Linux*|macOS*) - PYTHON_VENV="enricomi-publish-action-venv/bin/python";; - Windows*) - PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; - esac - PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" - echo "Python in venv: $PYTHON_VENV" - echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '##[endgroup]' + Write-Output "Finding Python interpreter in venv" + $PYTHON_VENV = enricomi-publish-action-venv\\Scripts\\python -c "import sys; print(sys.executable)" + Write-Output "Python in venv: $PYTHON_VENV" + "PYTHON_VENV=$PYTHON_VENV" | Out-File -FilePath $env:GITHUB_ENV -Append + } finally { + Write-Output "##[endgroup]" + } shell: bash - name: Install Python dependencies run: | - echo '##[group]Install Python dependencies' - # make sure wheel is installed, which improves installing our dependencies - "$PYTHON_VENV" -m pip install wheel - "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '##[endgroup]' + Write-Output "##[group]Install Python dependencies" + try { + # make sure wheel is installed, which improves installing our dependencies + Invoke-Expression -Command "& '$PYTHON_VENV' -m pip install wheel" + Invoke-Expression -Command "& '$PYTHON_VENV' -m pip install -r '$GITHUB_ACTION_PATH\\..\\python\\requirements.txt'" + } finally { + Write-Output "##[endgroup]" + } shell: bash - name: Publish Test Results id: test-results run: | - echo '##[group]Publish Test Results' - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '##[endgroup]' + Write-Output "##[group]Publish Test Results" + try { + Invoke-Expression -Command "& '$PYTHON_VENV' '$GITHUB_ACTION_PATH\\..\\python\\publish_test_results.py'" + } finally { + Write-Output "##[endgroup]" + } env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -307,7 +295,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: ${{ steps.os.outputs.pip-cache }} + path: '~\\AppData\\Local\\pip\\Cache' key: ${{ steps.cache.outputs.cache-primary-key }} branding: From 3b8a5d641cc2c0a19a6d0defa2f2443220212396 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 11:32:49 +0100 Subject: [PATCH 04/42] Make linux and macos OS specific --- composite/linux/action.yml | 39 +---- composite/macos/action.yml | 295 ++++++++++++++++++++++++++++++++++++- 2 files changed, 301 insertions(+), 33 deletions(-) mode change 120000 => 100644 composite/macos/action.yml diff --git a/composite/linux/action.yml b/composite/linux/action.yml index df204561..fd89d349 100644 --- a/composite/linux/action.yml +++ b/composite/linux/action.yml @@ -178,36 +178,17 @@ runs: echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" shell: bash - - name: Detect OS - id: os - run: | - case "$RUNNER_OS" in - Linux*) - echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" - ;; - macOS*) - echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" - ;; - Windows*) - echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" - echo "pip-options=--user" >> "$GITHUB_OUTPUT" - ;; - esac - shell: bash - - name: Restore PIP packages cache uses: actions/cache/restore@v4 id: cache continue-on-error: true with: - path: ${{ steps.os.outputs.pip-cache }} + path: ~/.cache/pip key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv id: venv continue-on-error: true - env: - PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} run: | echo '##[group]Create virtualenv' trap "echo '##[endgroup]'" EXIT @@ -218,27 +199,21 @@ runs: if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv then echo "Looks like there is neither virtualenv nor venv package installed" - if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] + if ! "$PYTHON_BIN" -m pip install virtualenv then - echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" - "$PYTHON_BIN" -m pip install virtualenv + echo "Installing virtualenv package failed" + exit 1 fi if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv then - echo "Still cannot create venv after installing virtualenv package" + echo "Cannot create venv after installing virtualenv package" exit 1 fi fi echo "Finding Python interpreter in venv" - case "$RUNNER_OS" in - Linux*|macOS*) - PYTHON_VENV="enricomi-publish-action-venv/bin/python";; - Windows*) - PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; - esac - PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" + PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" shell: bash @@ -311,7 +286,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: ${{ steps.os.outputs.pip-cache }} + path: ~/.cache/pip key: ${{ steps.cache.outputs.cache-primary-key }} branding: diff --git a/composite/macos/action.yml b/composite/macos/action.yml deleted file mode 120000 index 10bf9204..00000000 --- a/composite/macos/action.yml +++ /dev/null @@ -1 +0,0 @@ -../linux/action.yml \ No newline at end of file diff --git a/composite/macos/action.yml b/composite/macos/action.yml new file mode 100644 index 00000000..bdf6db69 --- /dev/null +++ b/composite/macos/action.yml @@ -0,0 +1,294 @@ +name: 'Publish Test Results' +author: 'EnricoMi' +description: 'Publishes JUnit, NUnit, XUnit, TRX, JSON test results on GitHub for .NET, Dart, Java, JS, Jest, Mocha, Python, Scala, …' + +inputs: + github_token: + description: 'GitHub API Access Token.' + default: ${{ github.token }} + required: false + github_token_actor: + description: 'The name of the GitHub app that owns the GitHub API Access Token (see github_token). Used to identify pull request comments created by this action during earlier runs. Has to be set when `github_token` is set to a GitHub app installation token (other than GitHub actions). Otherwise, existing comments will not be updated, but new comments created. Note: this does not change the bot name of the pull request comments. Defaults to "github-actions".' + default: 'github-actions' + required: false + github_retries: + description: 'Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.' + default: '10' + required: false + commit: + description: 'Commit SHA to which test results are published. Only needed if the value of GITHUB_SHA does not work for you.' + required: false + check_name: + description: 'Name of the created check run.' + default: 'Test Results' + required: false + comment_title: + description: 'An alternative title for the pull request comment. Defaults to value of check_name input.' + required: false + comment_mode: + description: 'The action posts comments to pull requests that are associated with the commit. Set to "always" - always comment, "changes" - comment when changes w.r.t. the target branch exist, "changes in failures" - when changes in the number of failures and errors exist, "changes in errors" - when changes in the number of (only) errors exist, "failures" - when failures or errors exist, "errors" - when (only) errors exist, "off" - to not create pull request comments.' + default: 'always' + required: false + fail_on: + description: 'The created test result check run has failure state if any test fails or test errors occur. Never fails when set to "nothing", fails only on errors when set to "errors". Default is "test failures".' + default: 'test failures' + required: false + action_fail: + description: 'When set "true", the action itself fails when tests have failed (see option fail_on).' + default: 'false' + required: false + action_fail_on_inconclusive: + description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' + default: 'false' + required: false + files: + description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + required: false + junit_files: + description: 'Deprecated, use "files" option instead.' + required: false + nunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + xunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + trx_files: + description: 'Deprecated, use "files" option instead.' + required: false + time_unit: + description: 'Time values in the test result files have this unit. Supports "seconds" and "milliseconds".' + default: 'seconds' + required: false + test_file_prefix: + description: 'Paths in the test result files should be relative to the git repository for annotations to work best. This prefix is added to (if starting with "+"), or remove from (if starting with "-") test file paths. Examples: "+src/" or "-/opt/actions-runner".' + required: false + report_individual_runs: + description: 'Individual runs of the same test may see different failures. Reports all individual failures when set "true" or the first only otherwise.' + required: false + report_suite_logs: + description: 'In addition to reporting regular test logs, also report test suite logs. These are logs provided on suite level, not individual test level. Set to "info" for normal output, "error" for error output, "any" for both, or "none" for no suite logs at all. Defaults to "none".' + default: 'none' + required: false + deduplicate_classes_by_file_name: + description: 'De-duplicates classes with same name by their file name when set "true", combines test results for those classes otherwise.' + required: false + large_files: + description: 'Support for large files is enabled when set to "true". Defaults to "false", unless ignore_runs is "true".' + required: false + ignore_runs: + description: 'Does not collect test run information from the test result files, which is useful for very large files. This disables any check run annotations.' + default: 'false' + required: false + check_run: + description: 'Set to "true", the results are published as a check run, but it may not be associated with the workflow that ran this action.' + default: 'true' + required: false + job_summary: + description: 'Set to "true", the results are published as part of the job summary page of the workflow run.' + default: 'true' + required: false + compare_to_earlier_commit: + description: 'Test results are compared to results of earlier commits to highlight changes: "false" - disable comparison, "true" - compare across commits.' + default: 'true' + required: false + pull_request_build: + description: 'As part of pull requests, GitHub builds a merge commit, which combines the commit and the target branch. If tests ran on the actual pushed commit, then set this to "commit". Defaults to "merge".' + default: 'merge' + required: false + event_file: + description: 'An alternative event file to use. Useful to replace a "workflow_run" event file with the actual source event file.' + required: false + event_name: + description: 'An alternative event name to use. Useful to replace a "workflow_run" event name with the actual source event name: github.event.workflow_run.event.' + required: false + test_changes_limit: + description: 'Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of 0. The default is 10.' + required: false + check_run_annotations: + description: 'Adds additional information to the check run. This is a comma-separated list of any of the following values: "all tests" - list all found tests, "skipped tests" - list all skipped tests. Set to "none" to add no extra annotations at all.' + default: 'all tests, skipped tests' + required: false + check_run_annotations_branch: + description: 'Adds check run annotations only on given branches. Comma-separated list of branch names allowed, asterisk "*" matches all branches. Defaults to event.repository.default_branch or "main, master".' + required: false + seconds_between_github_reads: + description: 'Sets the number of seconds the action waits between concurrent read requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '0.25' + required: false + seconds_between_github_writes: + description: 'Sets the number of seconds the action waits between concurrent write requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '2.0' + required: false + secondary_rate_limit_wait_seconds: + description: 'Sets the number of seconds to wait before retrying secondary rate limit errors. If not set, the default defined in the PyGithub library is used (currently 60 seconds).' + required: false + json_file: + description: 'Results are written to this JSON file.' + required: false + json_thousands_separator: + description: 'Formatted numbers in JSON use this character to separate groups of thousands. Common values are "," or ".". Defaults to punctuation space (\u2008).' + default: ' ' + required: false + json_suite_details: + description: 'Write out all suite details to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + json_test_case_results: + description: 'Write out all individual test case results to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + search_pull_requests: + description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' + default: 'false' + required: false + +outputs: + json: + description: "Test results as JSON" + value: ${{ steps.test-results.outputs.json }} + +runs: + using: 'composite' + steps: + - name: Check for Python3 + id: python + run: | + echo '##[group]Check for Python3' + trap "echo '##[endgroup]'" EXIT + + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] + then + if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] + then + echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + exit 1 + fi + + PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" + else + PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" + fi + + echo "Python that creates venv: $PYTHON_BIN" + echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" + echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Restore PIP packages cache + uses: actions/cache/restore@v4 + id: cache + continue-on-error: true + with: + path: ~/Library/Caches/pip + key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 + + - name: Create virtualenv + id: venv + continue-on-error: true + run: | + echo '##[group]Create virtualenv' + trap "echo '##[endgroup]'" EXIT + + echo "Python that creates venv: $PYTHON_BIN" + + echo "Creating virtual environment" + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv + then + echo "Looks like there is neither virtualenv nor venv package installed" + if ! "$PYTHON_BIN" -m pip install virtualenv + then + echo "Installing virtualenv package failed" + exit 1 + fi + + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv + then + echo "Cannot create venv after installing virtualenv package" + exit 1 + fi + fi + + echo "Finding Python interpreter in venv" + PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" + echo "Python in venv: $PYTHON_VENV" + echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + shell: bash + + - name: Install Python dependencies + run: | + echo '##[group]Install Python dependencies' + trap "echo '##[endgroup]'" EXIT + + # make sure wheel is installed, which improves installing our dependencies + "$PYTHON_VENV" -m pip install wheel + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + shell: bash + + - name: Publish Test Results + id: test-results + run: | + echo '##[group]Publish Test Results' + trap "echo '##[endgroup]'" EXIT + + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} + shell: bash + + - name: Save PIP packages cache + uses: actions/cache/save@v4 + if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit + continue-on-error: true + with: + path: ~/Library/Caches/pip + key: ${{ steps.cache.outputs.cache-primary-key }} + +branding: + icon: 'check-circle' + color: 'green' From 7b24ef5c5efb1cb662dcf3955e128365accb1e47 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 11:34:58 +0100 Subject: [PATCH 05/42] fix endgroup --- composite/windows/action.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/composite/windows/action.yml b/composite/windows/action.yml index 19aa59c8..b7593d0a 100644 --- a/composite/windows/action.yml +++ b/composite/windows/action.yml @@ -162,7 +162,6 @@ runs: if ( !(Get-Command python3 -ErrorAction SilentlyContinue) -Or -Not ((python3 -V 2> $null) -Like "Python 3.*") ) { if ( !(Get-Command python -ErrorAction SilentlyContinue) -Or -Not ((python -V 2> $null) -Like "Python 3.*") ) { Write-Output "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." - Write-Output "##[endgroup]" Exit 1 } From f8d8051dd73f07c8b01ee48e528c3bf2e3d9ba44 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 11:35:18 +0100 Subject: [PATCH 06/42] Write error as GH actions error --- composite/linux/action.yml | 4 ++-- composite/macos/action.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composite/linux/action.yml b/composite/linux/action.yml index fd89d349..7f512086 100644 --- a/composite/linux/action.yml +++ b/composite/linux/action.yml @@ -201,13 +201,13 @@ runs: echo "Looks like there is neither virtualenv nor venv package installed" if ! "$PYTHON_BIN" -m pip install virtualenv then - echo "Installing virtualenv package failed" + echo "::error::Installing virtualenv package failed" exit 1 fi if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv then - echo "Cannot create venv after installing virtualenv package" + echo "::error::Cannot create venv after installing virtualenv package" exit 1 fi fi diff --git a/composite/macos/action.yml b/composite/macos/action.yml index bdf6db69..f1e42565 100644 --- a/composite/macos/action.yml +++ b/composite/macos/action.yml @@ -201,13 +201,13 @@ runs: echo "Looks like there is neither virtualenv nor venv package installed" if ! "$PYTHON_BIN" -m pip install virtualenv then - echo "Installing virtualenv package failed" + echo "::error::Installing virtualenv package failed" exit 1 fi if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv then - echo "Cannot create venv after installing virtualenv package" + echo "::error::Cannot create venv after installing virtualenv package" exit 1 fi fi From 434ba4df0983e33effef43b23fc19c9b3e2bb4ca Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 12:03:37 +0100 Subject: [PATCH 07/42] Use deprecated Windows bash version for default composite action --- composite/action.yml | 5 +- composite/windows-bash/action.yml | 298 ++++++++++++++++++++++++++++++ 2 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 composite/windows-bash/action.yml diff --git a/composite/action.yml b/composite/action.yml index 243a7d74..07445680 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -164,7 +164,10 @@ runs: - name: Run on Windows id: windows if: startsWith(env.RUNNER_OS, 'Windows') - uses: $GITHUB_ACTION_PATH/windows + # for backward-compatibility (Windows used to be a bash script) + # deprecated, remove in v3 + # prefer to use $GITHUB_ACTION_PATH/windows + uses: $GITHUB_ACTION_PATH/windows-bash branding: icon: 'check-circle' diff --git a/composite/windows-bash/action.yml b/composite/windows-bash/action.yml new file mode 100644 index 00000000..3b04ada4 --- /dev/null +++ b/composite/windows-bash/action.yml @@ -0,0 +1,298 @@ +name: 'Publish Test Results' +author: 'EnricoMi' +description: 'Publishes JUnit, NUnit, XUnit, TRX, JSON test results on GitHub for .NET, Dart, Java, JS, Jest, Mocha, Python, Scala, …' + +inputs: + github_token: + description: 'GitHub API Access Token.' + default: ${{ github.token }} + required: false + github_token_actor: + description: 'The name of the GitHub app that owns the GitHub API Access Token (see github_token). Used to identify pull request comments created by this action during earlier runs. Has to be set when `github_token` is set to a GitHub app installation token (other than GitHub actions). Otherwise, existing comments will not be updated, but new comments created. Note: this does not change the bot name of the pull request comments. Defaults to "github-actions".' + default: 'github-actions' + required: false + github_retries: + description: 'Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.' + default: '10' + required: false + commit: + description: 'Commit SHA to which test results are published. Only needed if the value of GITHUB_SHA does not work for you.' + required: false + check_name: + description: 'Name of the created check run.' + default: 'Test Results' + required: false + comment_title: + description: 'An alternative title for the pull request comment. Defaults to value of check_name input.' + required: false + comment_mode: + description: 'The action posts comments to pull requests that are associated with the commit. Set to "always" - always comment, "changes" - comment when changes w.r.t. the target branch exist, "changes in failures" - when changes in the number of failures and errors exist, "changes in errors" - when changes in the number of (only) errors exist, "failures" - when failures or errors exist, "errors" - when (only) errors exist, "off" - to not create pull request comments.' + default: 'always' + required: false + fail_on: + description: 'The created test result check run has failure state if any test fails or test errors occur. Never fails when set to "nothing", fails only on errors when set to "errors". Default is "test failures".' + default: 'test failures' + required: false + action_fail: + description: 'When set "true", the action itself fails when tests have failed (see option fail_on).' + default: 'false' + required: false + action_fail_on_inconclusive: + description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' + default: 'false' + required: false + files: + description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + required: false + junit_files: + description: 'Deprecated, use "files" option instead.' + required: false + nunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + xunit_files: + description: 'Deprecated, use "files" option instead.' + required: false + trx_files: + description: 'Deprecated, use "files" option instead.' + required: false + time_unit: + description: 'Time values in the test result files have this unit. Supports "seconds" and "milliseconds".' + default: 'seconds' + required: false + test_file_prefix: + description: 'Paths in the test result files should be relative to the git repository for annotations to work best. This prefix is added to (if starting with "+"), or remove from (if starting with "-") test file paths. Examples: "+src/" or "-/opt/actions-runner".' + required: false + report_individual_runs: + description: 'Individual runs of the same test may see different failures. Reports all individual failures when set "true" or the first only otherwise.' + required: false + report_suite_logs: + description: 'In addition to reporting regular test logs, also report test suite logs. These are logs provided on suite level, not individual test level. Set to "info" for normal output, "error" for error output, "any" for both, or "none" for no suite logs at all. Defaults to "none".' + default: 'none' + required: false + deduplicate_classes_by_file_name: + description: 'De-duplicates classes with same name by their file name when set "true", combines test results for those classes otherwise.' + required: false + large_files: + description: 'Support for large files is enabled when set to "true". Defaults to "false", unless ignore_runs is "true".' + required: false + ignore_runs: + description: 'Does not collect test run information from the test result files, which is useful for very large files. This disables any check run annotations.' + default: 'false' + required: false + check_run: + description: 'Set to "true", the results are published as a check run, but it may not be associated with the workflow that ran this action.' + default: 'true' + required: false + job_summary: + description: 'Set to "true", the results are published as part of the job summary page of the workflow run.' + default: 'true' + required: false + compare_to_earlier_commit: + description: 'Test results are compared to results of earlier commits to highlight changes: "false" - disable comparison, "true" - compare across commits.' + default: 'true' + required: false + pull_request_build: + description: 'As part of pull requests, GitHub builds a merge commit, which combines the commit and the target branch. If tests ran on the actual pushed commit, then set this to "commit". Defaults to "merge".' + default: 'merge' + required: false + event_file: + description: 'An alternative event file to use. Useful to replace a "workflow_run" event file with the actual source event file.' + required: false + event_name: + description: 'An alternative event name to use. Useful to replace a "workflow_run" event name with the actual source event name: github.event.workflow_run.event.' + required: false + test_changes_limit: + description: 'Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of 0. The default is 10.' + required: false + check_run_annotations: + description: 'Adds additional information to the check run. This is a comma-separated list of any of the following values: "all tests" - list all found tests, "skipped tests" - list all skipped tests. Set to "none" to add no extra annotations at all.' + default: 'all tests, skipped tests' + required: false + check_run_annotations_branch: + description: 'Adds check run annotations only on given branches. Comma-separated list of branch names allowed, asterisk "*" matches all branches. Defaults to event.repository.default_branch or "main, master".' + required: false + seconds_between_github_reads: + description: 'Sets the number of seconds the action waits between concurrent read requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '0.25' + required: false + seconds_between_github_writes: + description: 'Sets the number of seconds the action waits between concurrent write requests to the GitHub API. This throttles the API usage to avoid abuse rate limits: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits.' + default: '2.0' + required: false + secondary_rate_limit_wait_seconds: + description: 'Sets the number of seconds to wait before retrying secondary rate limit errors. If not set, the default defined in the PyGithub library is used (currently 60 seconds).' + required: false + json_file: + description: 'Results are written to this JSON file.' + required: false + json_thousands_separator: + description: 'Formatted numbers in JSON use this character to separate groups of thousands. Common values are "," or ".". Defaults to punctuation space (\u2008).' + default: ' ' + required: false + json_suite_details: + description: 'Write out all suite details to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + json_test_case_results: + description: 'Write out all individual test case results to the JSON file. Setting this to "true" can greatly increase the size of the output. Defaults to "false".' + default: 'false' + required: false + search_pull_requests: + description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' + default: 'false' + required: false + +outputs: + json: + description: "Test results as JSON" + value: ${{ steps.test-results.outputs.json }} + +runs: + using: 'composite' + steps: + - name: Check for Python3 + id: python + run: | + echo '##[group]Check for Python3' + trap "echo '##[endgroup]'" EXIT + + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] + then + if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] + then + echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + exit 1 + fi + + PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" + else + PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" + fi + + echo "Python that creates venv: $PYTHON_BIN" + echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" + echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Restore PIP packages cache + uses: actions/cache/restore@v4 + id: cache + continue-on-error: true + with: + path: ~\\AppData\\Local\\pip\\Cache + key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 + + - name: Create virtualenv + id: venv + continue-on-error: true + run: | + echo '##[group]Create virtualenv' + trap "echo '##[endgroup]'" EXIT + + echo "Python that creates venv: $PYTHON_BIN" + + echo "Creating virtual environment" + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv + then + echo "Looks like there is neither virtualenv nor venv package installed" + if ! "$PYTHON_BIN" -m pip install --user virtualenv + then + echo "Installing virtualenv package with PIP options '--user' failed, now trying without" + if ! "$PYTHON_BIN" -m pip install virtualenv + then + echo "::error::Installing virtualenv package failed" + exit 1 + fi + fi + + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv + then + echo "::error::Cannot create venv after installing virtualenv package" + exit 1 + fi + fi + + echo "Finding Python interpreter in venv" + PYTHON_VENV="$(enricomi-publish-action-venv\\Scripts\\python -c 'import sys; print(sys.executable)')" + echo "Python in venv: $PYTHON_VENV" + echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + shell: bash + + - name: Install Python dependencies + run: | + echo '##[group]Install Python dependencies' + trap "echo '##[endgroup]'" EXIT + + # make sure wheel is installed, which improves installing our dependencies + "$PYTHON_VENV" -m pip install wheel + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + shell: bash + + - name: Publish Test Results + id: test-results + run: | + echo '##[group]Publish Test Results' + trap "echo '##[endgroup]'" EXIT + + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + env: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} + shell: bash + + - name: Save PIP packages cache + uses: actions/cache/save@v4 + if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit + continue-on-error: true + with: + path: ~\\AppData\\Local\\pip\\Cache + key: ${{ steps.cache.outputs.cache-primary-key }} + +branding: + icon: 'check-circle' + color: 'green' From cebf9c5cb299bfece0775d41ec1b6fa641794062 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 13:15:13 +0100 Subject: [PATCH 08/42] Fail on unsupported operating system --- composite/action.yml | 7 +++++++ composite/linux/action.yml | 1 + 2 files changed, 8 insertions(+) diff --git a/composite/action.yml b/composite/action.yml index 07445680..53f3b146 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -169,6 +169,13 @@ runs: # prefer to use $GITHUB_ACTION_PATH/windows uses: $GITHUB_ACTION_PATH/windows-bash + - name: Run on unsupported Operating System + if: ${{ ! (startsWith(env.RUNNER_OS, 'Linux') || startsWith(env.RUNNER_OS, 'macOS') || startsWith(env.RUNNER_OS, 'Windows')) }} + run: | + echo "::error::Unsupported operating system: $RUNNER_OS" + exit 1 + shell: bash + branding: icon: 'check-circle' color: 'green' diff --git a/composite/linux/action.yml b/composite/linux/action.yml index 7f512086..2a1b1094 100644 --- a/composite/linux/action.yml +++ b/composite/linux/action.yml @@ -156,6 +156,7 @@ runs: run: | echo '##[group]Check for Python3' trap "echo '##[endgroup]'" EXIT + echo "OS: $RUNNER_OS" # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store From 28087514e60cdb5694fd738657a56d9f4b50f1c8 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 13:28:16 +0100 Subject: [PATCH 09/42] Add new actions to README.md --- README.md | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2747f739..e61120b2 100644 --- a/README.md +++ b/README.md @@ -36,12 +36,34 @@ or ![ARM Linux](misc/badge-arm.svg) self-hosted runners: See the [notes on running this action with absolute paths](#running-with-absolute-paths) if you cannot use relative test result file paths. -Use this for ![macOS](misc/badge-macos.svg) (e.g. `runs-on: macos-latest`) -and ![Windows](misc/badge-windows.svg) (e.g. `runs-on: windows-latest`) runners: +Use this for ![macOS](misc/badge-macos.svg) (e.g. `runs-on: macos-latest`) runners: +```yaml +- name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action/macos@v2 + if: always() + with: + files: | + test-results/**/*.xml + test-results/**/*.trx + test-results/**/*.json +``` +… and ![Windows](misc/badge-windows.svg) (e.g. `runs-on: windows-latest`) runners: ```yaml - name: Publish Test Results - uses: EnricoMi/publish-unit-test-result-action/composite@v2 + uses: EnricoMi/publish-unit-test-result-action/windows@v2 + if: always() + with: + files: | + test-results/**/*.xml + test-results/**/*.trx + test-results/**/*.json +``` + +For **self-hosted** Linux GitHub Actions runners **without Docker** installed, please use: +```yaml +- name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action/linux@v2 if: always() with: files: | @@ -810,9 +832,15 @@ Using the non-composite variant of this action is recommended as it starts up mu ## Running as a composite action -Running this action as a composite action allows to run it on various operating systems as it -does not require Docker. The composite action, however, requires a Python3 environment to be setup -on the action runner. All GitHub-hosted runners (Ubuntu, Windows Server and macOS) provide a suitable +Running this action as a composite action (macOs and Windows) allows to run it on operating systems +other than Linux as it does not require Docker: + + uses: EnricoMi/publish-unit-test-result-action/linux@v2 + uses: EnricoMi/publish-unit-test-result-action/macos@v2 + uses: EnricoMi/publish-unit-test-result-action/windows@v2 + +The composite action, however, requires a Python3 environment to be setup on the action runner. +All GitHub-hosted runners (Ubuntu, Windows Server and macOS) provide a suitable Python3 environment out-of-the-box. Self-hosted runners may require setting up a Python environment first: @@ -824,6 +852,4 @@ Self-hosted runners may require setting up a Python environment first: python-version: 3.8 ``` -Self-hosted runners for Windows require Bash shell to be installed. Easiest way to have one is by installing -Git for Windows, which comes with Git BASH. Make sure that the location of `bash.exe` is part of the `PATH` -environment variable seen by the self-hosted runner. +Start-up of the action is faster with `virtualenv` or `venv`, as well as `wheel` packages installed. From c6642a7daeb43cae59c17bbbb0897e9b6dd6efc1 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 13:31:12 +0100 Subject: [PATCH 10/42] Move os-specific composit actions into project root --- composite/action.yml | 6 +++--- {composite/linux => linux}/action.yml | 0 {composite/macos => macos}/action.yml | 0 {composite/windows-bash => windows-bash}/action.yml | 0 {composite/windows => windows}/action.yml | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename {composite/linux => linux}/action.yml (100%) rename {composite/macos => macos}/action.yml (100%) rename {composite/windows-bash => windows-bash}/action.yml (100%) rename {composite/windows => windows}/action.yml (100%) diff --git a/composite/action.yml b/composite/action.yml index 53f3b146..aa046a5a 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -154,12 +154,12 @@ runs: - name: Run on Linux id: linux if: startsWith(env.RUNNER_OS, 'Linux') - uses: $GITHUB_ACTION_PATH/linux + uses: $GITHUB_ACTION_PATH/../linux - name: Run on macOS id: macos if: startsWith(env.RUNNER_OS, 'macOS') - uses: $GITHUB_ACTION_PATH/macos + uses: $GITHUB_ACTION_PATH/../macos - name: Run on Windows id: windows @@ -167,7 +167,7 @@ runs: # for backward-compatibility (Windows used to be a bash script) # deprecated, remove in v3 # prefer to use $GITHUB_ACTION_PATH/windows - uses: $GITHUB_ACTION_PATH/windows-bash + uses: $GITHUB_ACTION_PATH/../windows-bash - name: Run on unsupported Operating System if: ${{ ! (startsWith(env.RUNNER_OS, 'Linux') || startsWith(env.RUNNER_OS, 'macOS') || startsWith(env.RUNNER_OS, 'Windows')) }} diff --git a/composite/linux/action.yml b/linux/action.yml similarity index 100% rename from composite/linux/action.yml rename to linux/action.yml diff --git a/composite/macos/action.yml b/macos/action.yml similarity index 100% rename from composite/macos/action.yml rename to macos/action.yml diff --git a/composite/windows-bash/action.yml b/windows-bash/action.yml similarity index 100% rename from composite/windows-bash/action.yml rename to windows-bash/action.yml diff --git a/composite/windows/action.yml b/windows/action.yml similarity index 100% rename from composite/windows/action.yml rename to windows/action.yml From b80e99e3dac76af82933a45957ad443b93942279 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 14:42:16 +0100 Subject: [PATCH 11/42] Test and do forward inputs to actions --- action.yml | 1 + composite/action.yml | 132 +++++++++++++++++++++++++++++++++ python/test/test_action_yml.py | 68 +++++++++++------ 3 files changed, 179 insertions(+), 22 deletions(-) diff --git a/action.yml b/action.yml index 0481ceb1..8faeb8ec 100644 --- a/action.yml +++ b/action.yml @@ -142,6 +142,7 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + outputs: json: description: "Test results as JSON" diff --git a/composite/action.yml b/composite/action.yml index aa046a5a..f13f50c0 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -155,11 +155,99 @@ runs: id: linux if: startsWith(env.RUNNER_OS, 'Linux') uses: $GITHUB_ACTION_PATH/../linux + with: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} - name: Run on macOS id: macos if: startsWith(env.RUNNER_OS, 'macOS') uses: $GITHUB_ACTION_PATH/../macos + with: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} - name: Run on Windows id: windows @@ -168,6 +256,50 @@ runs: # deprecated, remove in v3 # prefer to use $GITHUB_ACTION_PATH/windows uses: $GITHUB_ACTION_PATH/../windows-bash + with: + GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} + GITHUB_RETRIES: ${{ inputs.github_retries }} + COMMIT: ${{ inputs.commit }} + CHECK_NAME: ${{ inputs.check_name }} + COMMENT_TITLE: ${{ inputs.comment_title }} + COMMENT_MODE: ${{ inputs.comment_mode }} + FAIL_ON: ${{ inputs.fail_on }} + ACTION_FAIL: ${{ inputs.action_fail }} + ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} + FILES: ${{ inputs.files }} + JUNIT_FILES: ${{ inputs.junit_files }} + NUNIT_FILES: ${{ inputs.nunit_files }} + XUNIT_FILES: ${{ inputs.xunit_files }} + TRX_FILES: ${{ inputs.trx_files }} + TIME_UNIT: ${{ inputs.time_unit }} + TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} + REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} + REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} + DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} + LARGE_FILES: ${{ inputs.large_files }} + IGNORE_RUNS: ${{ inputs.ignore_runs }} + COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} + PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} + EVENT_FILE: ${{ inputs.event_file }} + EVENT_NAME: ${{ inputs.event_name }} + TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} + CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} + CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} + SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} + SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} + SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} + JSON_FILE: ${{ inputs.json_file }} + JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} + JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} + JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} + CHECK_RUN: ${{ inputs.check_run }} + JOB_SUMMARY: ${{ inputs.job_summary }} + SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented + ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented + LOG_LEVEL: ${{ inputs.log_level }} - name: Run on unsupported Operating System if: ${{ ! (startsWith(env.RUNNER_OS, 'Linux') || startsWith(env.RUNNER_OS, 'macOS') || startsWith(env.RUNNER_OS, 'Windows')) }} diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index 23529e9e..b2ab5cd8 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -24,10 +24,25 @@ def test_action_version(self): self.assertEqual(__version__, version, 'version in action.yml must match __version__ in python/publish/__init__.py') def test_composite_action(self): + self.do_test_composite_action('composite') + + def test_linux_action(self): + self.do_test_composite_action('linux') + + def test_macos_action(self): + self.do_test_composite_action('macos') + + def test_windows_action(self): + self.do_test_composite_action('windows') + + def test_windows_bash_action(self): + self.do_test_composite_action('windows-bash') + + def do_test_composite_action(self, action: str): with open(project_root / 'action.yml', encoding='utf-8') as r: dockerfile_action = yaml.safe_load(r) - with open(project_root / 'composite/action.yml', encoding='utf-8') as r: + with open(project_root / f'{action}/action.yml', encoding='utf-8') as r: composite_action = yaml.safe_load(r) self.assertIn('runs', dockerfile_action) @@ -43,26 +58,35 @@ def test_composite_action(self): self.assertEqual(dockerfile_action_wo_runs, composite_action_wo_runs) self.assertIn(('using', 'composite'), composite_action.get('runs', {}).items()) - # check cache key hash is up-to-date in composite action - # this md5 is linux-based (on Windows, git uses different newlines, which changes the hash) - if sys.platform != 'win32': - with open(project_root / 'python' / 'requirements.txt', mode='rb') as r: - expected_hash = hashlib.md5(r.read()).hexdigest() - cache_hash = next(step.get('with', {}).get('key', '').split('-')[-1] - for step in composite_action.get('runs', {}).get('steps', []) - if step.get('uses', '').startswith('actions/cache/restore@')) - self.assertEqual(expected_hash, cache_hash, msg='Changing python/requirements.txt requires ' - 'to update the MD5 hash in composite/action.yaml') - - def test_composite_inputs(self): - with open(project_root / 'composite/action.yml', encoding='utf-8') as r: - action = yaml.safe_load(r) - + # check inputs forwarded to action # these are not documented in the action.yml files but still needs to be forwarded extra_inputs = ['files', 'root_log_level', 'log_level'] - expected = {key.upper(): f'${{{{ inputs.{key} }}}}' for key in list(action.get('inputs', {}).keys()) + extra_inputs} - - steps = action.get('runs', {}).get('steps', []) - step = next((step for step in steps if step.get('name') == 'Publish Test Results'), {}) - inputs = {key.upper(): value for key, value in step.get('env', {}).items()} - self.assertEqual(expected, inputs) + expected = {key.upper(): f'${{{{ inputs.{key} }}}}' + for key in list(composite_action.get('inputs', {}).keys()) + extra_inputs} + + steps = composite_action.get('runs', {}).get('steps', []) + if action == 'composite': + # the 'composite' composite action is just a proxy to the os-specific actions, it forwards inputs via 'with' + steps = [step for step in steps if step.get('name') != 'Run on unsupported Operating System'] + inputs_key = 'with' + else: + # the other composite actions forward inputs via env + steps = [step for step in steps if step.get('name') == 'Publish Test Results'] + inputs_key = 'env' + for step in steps: + self.assertIn(inputs_key, step, step.get('name')) + inputs = {key.upper(): value for key, value in step.get(inputs_key, {}).items()} + self.assertEqual(expected, inputs) + + # the 'composite' composite action is just a proxy to the os-specific actions, so there is no caching + if action != 'composite': + # check cache key hash is up-to-date in composite action + # this md5 is linux-based (on Windows, git uses different newlines, which changes the hash) + if sys.platform != 'win32': + with open(project_root / 'python' / 'requirements.txt', mode='rb') as r: + expected_hash = hashlib.md5(r.read()).hexdigest() + cache_hash = next(step.get('with', {}).get('key', '').split('-')[-1] + for step in composite_action.get('runs', {}).get('steps', []) + if step.get('uses', '').startswith('actions/cache/restore@')) + self.assertEqual(expected_hash, cache_hash, msg='Changing python/requirements.txt requires ' + 'to update the MD5 hash in composite/action.yaml') From 9fee217d8ef12a8f17376570db58494cfd7942e1 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 15:14:21 +0100 Subject: [PATCH 12/42] Fix uses in composite action --- composite/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composite/action.yml b/composite/action.yml index f13f50c0..88832551 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -154,7 +154,7 @@ runs: - name: Run on Linux id: linux if: startsWith(env.RUNNER_OS, 'Linux') - uses: $GITHUB_ACTION_PATH/../linux + uses: EnricoMi/publish-unit-test-result-action/linux@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -203,7 +203,7 @@ runs: - name: Run on macOS id: macos if: startsWith(env.RUNNER_OS, 'macOS') - uses: $GITHUB_ACTION_PATH/../macos + uses: EnricoMi/publish-unit-test-result-action/macos@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -254,8 +254,8 @@ runs: if: startsWith(env.RUNNER_OS, 'Windows') # for backward-compatibility (Windows used to be a bash script) # deprecated, remove in v3 - # prefer to use $GITHUB_ACTION_PATH/windows - uses: $GITHUB_ACTION_PATH/../windows-bash + # prefer to use $GITHUB_ACTION_PATH/../windows + uses: EnricoMi/publish-unit-test-result-action/windows-bash@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} From ff4d56bbeb5fec287ab9f38f981ce4aa9b9c12a9 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 18:17:31 +0100 Subject: [PATCH 13/42] Make env.RUNNER_OS available to if --- composite/action.yml | 17 ++++++++++------- python/test/test_action_yml.py | 5 ++++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/composite/action.yml b/composite/action.yml index 88832551..2b812c2d 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -151,9 +151,14 @@ outputs: runs: using: 'composite' steps: + - name: Check OS + # env.RUNNER_OS is not available in if condition of steps + run: echo "OS=$RUNNER_OS" >> "$GITHUB_ENV" + shell: bash + - name: Run on Linux id: linux - if: startsWith(env.RUNNER_OS, 'Linux') + if: startsWith(env.OS, 'Linux') uses: EnricoMi/publish-unit-test-result-action/linux@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} @@ -202,7 +207,7 @@ runs: - name: Run on macOS id: macos - if: startsWith(env.RUNNER_OS, 'macOS') + if: startsWith(env.OS, 'macOS') uses: EnricoMi/publish-unit-test-result-action/macos@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} @@ -251,10 +256,8 @@ runs: - name: Run on Windows id: windows - if: startsWith(env.RUNNER_OS, 'Windows') - # for backward-compatibility (Windows used to be a bash script) - # deprecated, remove in v3 - # prefer to use $GITHUB_ACTION_PATH/../windows + if: startsWith(env.OS, 'Windows') + # this general composite action requires Bash shell, so this calls into windows-bash as well uses: EnricoMi/publish-unit-test-result-action/windows-bash@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} @@ -302,7 +305,7 @@ runs: LOG_LEVEL: ${{ inputs.log_level }} - name: Run on unsupported Operating System - if: ${{ ! (startsWith(env.RUNNER_OS, 'Linux') || startsWith(env.RUNNER_OS, 'macOS') || startsWith(env.RUNNER_OS, 'Windows')) }} + if: steps.linux.outcome == 'skipped' && steps.macos.outcome == 'skipped' && steps.windows.outcome == 'skipped' run: | echo "::error::Unsupported operating system: $RUNNER_OS" exit 1 diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index b2ab5cd8..17f56634 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -67,7 +67,10 @@ def do_test_composite_action(self, action: str): steps = composite_action.get('runs', {}).get('steps', []) if action == 'composite': # the 'composite' composite action is just a proxy to the os-specific actions, it forwards inputs via 'with' - steps = [step for step in steps if step.get('name') != 'Run on unsupported Operating System'] + steps = [step for step in steps + if 'name' in step + and step.get('name').startswith('Run on ') + and step.get('name') != 'Run on unsupported Operating System'] inputs_key = 'with' else: # the other composite actions forward inputs via env From a2bdda8516193a0881bb0347f81149c2751963ba Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 19:43:58 +0100 Subject: [PATCH 14/42] Fix windows shell --- windows/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/windows/action.yml b/windows/action.yml index b7593d0a..8e896527 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -178,7 +178,7 @@ runs: } finally { Write-Output "##[endgroup]" } - shell: bash + shell: pwsh - name: Restore PIP packages cache uses: actions/cache/restore@v4 @@ -220,7 +220,7 @@ runs: } finally { Write-Output "##[endgroup]" } - shell: bash + shell: pwsh - name: Install Python dependencies run: | @@ -232,7 +232,7 @@ runs: } finally { Write-Output "##[endgroup]" } - shell: bash + shell: pwsh - name: Publish Test Results id: test-results @@ -287,7 +287,7 @@ runs: ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} # not documented LOG_LEVEL: ${{ inputs.log_level }} - shell: bash + shell: pwsh - name: Save PIP packages cache uses: actions/cache/save@v4 From b7fd4c9d139f9bc8f92e4b8f2e878d4cfae11a53 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 19:48:58 +0100 Subject: [PATCH 15/42] Publish with os-specific actions thoroughly, composite once per OS --- .github/workflows/publish.yml | 212 +++++++++++++++++++++++++++++++--- 1 file changed, 194 insertions(+), 18 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 010dae01..c37f9687 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -215,7 +215,7 @@ jobs: with: sarif_file: ${{ steps.scan.outputs.sarif }} - publish-composite: + publish-linux: name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) runs-on: ${{ matrix.os }} permissions: @@ -224,10 +224,72 @@ jobs: strategy: fail-fast: false - max-parallel: 3 + max-parallel: 2 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + include: + - os: ubuntu-latest + os-label: Linux + python: "3.8" + - os: ubuntu-latest + os-label: Linux + python: "venv" + - os: ubuntu-latest + os-label: Linux + python: "installed" + - os: ubuntu-20.04 + os-label: Linux 20.04 + python: "installed" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./linux + with: + check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts/**/*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-macos: + name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 2 matrix: # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources - # test *-latest and newer (because newer eventually become 'latest' and should be tested to work before that) include: - os: macos-latest os-label: macOS @@ -248,19 +310,56 @@ jobs: os-label: macOS 14 python: "installed" - - os: ubuntu-latest - os-label: Linux - python: "3.8" - - os: ubuntu-latest - os-label: Linux - python: "venv" - - os: ubuntu-latest - os-label: Linux - python: "installed" - - os: ubuntu-20.04 - os-label: Linux 20.04 - python: "installed" + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./macos + with: + check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts/**/*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-windows: + name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 2 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + include: - os: windows-latest os-label: Windows python: "installed" @@ -283,8 +382,7 @@ jobs: - name: Install virtualenv if: matrix.python == 'venv' - run: | - python3 -m pip install virtualenv + run: python3 -m pip install virtualenv shell: bash - name: Download Artifacts @@ -294,9 +392,87 @@ jobs: - name: Publish Test Results id: test-results - uses: ./composite + uses: ./windows with: check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts\**\*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + - name: Publish Test Results (Bash) + id: test-results-bash + uses: ./windows-bash + with: + check_name: Test Results (${{ matrix.os-label }} bash python ${{ matrix.python }}) + files: artifacts\**\*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output (Bash) + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results-bash.outputs.json }}' + json_file: 'tests.json' + + publish-composite: + name: Publish Test Results (${{ matrix.os-label }} composite) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 1 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + # test *-latest and newer (because newer eventually become 'latest' and should be tested to work before that) + include: + - os: macos-latest + os-label: macOS + python: "installed" + - os: ubuntu-latest + os-label: Linux + python: "installed" + - os: windows-latest + os-label: Windows + python: "installed" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./composite + with: + check_name: Test Results (${{ matrix.os-label }} composite python ${{ matrix.python }}) files: | artifacts/**/*.xml artifacts\**\*.xml From 581113cd0c254809b3c3cab19b2a098ca2090bc7 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 21:54:55 +0100 Subject: [PATCH 16/42] Fix access to env var in powershell --- windows/action.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/windows/action.yml b/windows/action.yml index 8e896527..67e06eb0 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -194,20 +194,20 @@ runs: run: | Write-Output "##[group]Create virtualenv" try { - Write-Output "Python that creates venv: $PYTHON_BIN" + Write-Output "Python that creates venv: $env:PYTHON_BIN" Write-Output "Creating virtual environment" - if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) -And -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m venv enricomi-publish-action-venv" 2> $null) ) { + if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) -And -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m venv enricomi-publish-action-venv" 2> $null) ) { Write-Output "Looks like there is neither virtualenv nor venv package installed" - if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m pip install --user virtualenv" 2> $null) ) { + if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m pip install --user virtualenv" 2> $null) ) { Write-Output "Installing virtualenv package with PIP option '--user' failed, now trying without" - if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m pip install virtualenv" 2> $null) ) { + if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m pip install virtualenv" 2> $null) ) { Write-Output "::error::Installing virtualenv package failed" Exit 1 } } - if ( -Not (Invoke-Expression -Command "& '$PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) ) { + if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) ) { Write-Output "::error::Cannot create venv after installing virtualenv package" Exit 1 } @@ -227,8 +227,8 @@ runs: Write-Output "##[group]Install Python dependencies" try { # make sure wheel is installed, which improves installing our dependencies - Invoke-Expression -Command "& '$PYTHON_VENV' -m pip install wheel" - Invoke-Expression -Command "& '$PYTHON_VENV' -m pip install -r '$GITHUB_ACTION_PATH\\..\\python\\requirements.txt'" + Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install wheel" + Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install -r '$GITHUB_ACTION_PATH\\..\\python\\requirements.txt'" } finally { Write-Output "##[endgroup]" } @@ -239,7 +239,7 @@ runs: run: | Write-Output "##[group]Publish Test Results" try { - Invoke-Expression -Command "& '$PYTHON_VENV' '$GITHUB_ACTION_PATH\\..\\python\\publish_test_results.py'" + Invoke-Expression -Command "& '$env:PYTHON_VENV' '$GITHUB_ACTION_PATH\\..\\python\\publish_test_results.py'" } finally { Write-Output "##[endgroup]" } From 88369ab5249438d46f03f9a31b2a325e81467df8 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 22 Feb 2024 22:29:17 +0100 Subject: [PATCH 17/42] Fix escaped backslashes and env var --- windows/action.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/windows/action.yml b/windows/action.yml index 67e06eb0..7eef688b 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -185,7 +185,7 @@ runs: id: cache continue-on-error: true with: - path: '~\\AppData\\Local\\pip\\Cache' + path: '~\AppData\Local\pip\Cache' key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv @@ -214,7 +214,7 @@ runs: } Write-Output "Finding Python interpreter in venv" - $PYTHON_VENV = enricomi-publish-action-venv\\Scripts\\python -c "import sys; print(sys.executable)" + $PYTHON_VENV = enricomi-publish-action-venv\Scripts\python -c "import sys; print(sys.executable)" Write-Output "Python in venv: $PYTHON_VENV" "PYTHON_VENV=$PYTHON_VENV" | Out-File -FilePath $env:GITHUB_ENV -Append } finally { @@ -228,7 +228,7 @@ runs: try { # make sure wheel is installed, which improves installing our dependencies Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install wheel" - Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install -r '$GITHUB_ACTION_PATH\\..\\python\\requirements.txt'" + Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install -r '$env.GITHUB_ACTION_PATH\..\python\requirements.txt'" } finally { Write-Output "##[endgroup]" } @@ -239,7 +239,7 @@ runs: run: | Write-Output "##[group]Publish Test Results" try { - Invoke-Expression -Command "& '$env:PYTHON_VENV' '$GITHUB_ACTION_PATH\\..\\python\\publish_test_results.py'" + Invoke-Expression -Command "& '$env:PYTHON_VENV' '$env:GITHUB_ACTION_PATH\..\python\publish_test_results.py'" } finally { Write-Output "##[endgroup]" } @@ -294,7 +294,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: '~\\AppData\\Local\\pip\\Cache' + path: '~\AppData\Local\pip\Cache' key: ${{ steps.cache.outputs.cache-primary-key }} branding: From 546639f796ec63f6d39118d47b64163c4bb2d68e Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 07:18:03 +0100 Subject: [PATCH 18/42] Add log level inputs to action.yml files --- action.yml | 6 ++++++ composite/action.yml | 12 ++++++------ linux/action.yml | 8 ++++++-- macos/action.yml | 8 ++++++-- python/test/test_action_yml.py | 4 +--- python/test/test_cicd_yml.py | 2 +- python/test/test_readme_md.py | 3 ++- windows-bash/action.yml | 8 ++++++-- windows/action.yml | 8 ++++++-- 9 files changed, 40 insertions(+), 19 deletions(-) diff --git a/action.yml b/action.yml index 8faeb8ec..4730fb7c 100644 --- a/action.yml +++ b/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: diff --git a/composite/action.yml b/composite/action.yml index 2b812c2d..4d230703 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: @@ -200,9 +206,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} - name: Run on macOS @@ -249,9 +253,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} - name: Run on Windows @@ -299,9 +301,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} - name: Run on unsupported Operating System diff --git a/linux/action.yml b/linux/action.yml index 2a1b1094..662168da 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: @@ -276,9 +282,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/macos/action.yml b/macos/action.yml index f1e42565..92de4631 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: @@ -275,9 +281,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index 17f56634..c0742ae2 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -59,10 +59,8 @@ def do_test_composite_action(self, action: str): self.assertIn(('using', 'composite'), composite_action.get('runs', {}).items()) # check inputs forwarded to action - # these are not documented in the action.yml files but still needs to be forwarded - extra_inputs = ['files', 'root_log_level', 'log_level'] expected = {key.upper(): f'${{{{ inputs.{key} }}}}' - for key in list(composite_action.get('inputs', {}).keys()) + extra_inputs} + for key in list(composite_action.get('inputs', {}).keys())} steps = composite_action.get('runs', {}).get('steps', []) if action == 'composite': diff --git a/python/test/test_cicd_yml.py b/python/test/test_cicd_yml.py index 6e695db6..b0b59e73 100644 --- a/python/test/test_cicd_yml.py +++ b/python/test/test_cicd_yml.py @@ -28,4 +28,4 @@ def test_cicd_workflow(self): for var in [part.strip()] if var.startswith('INPUT_') or var.startswith('"INPUT_')] - self.assertEqual(sorted(list(action.get('inputs', {}).keys()) + ['log_level', 'root_log_level']), sorted(vars)) + self.assertEqual(sorted(list(action.get('inputs', {}).keys())), sorted(vars)) diff --git a/python/test/test_readme_md.py b/python/test/test_readme_md.py index 83ad3107..bdc8d52d 100644 --- a/python/test/test_readme_md.py +++ b/python/test/test_readme_md.py @@ -17,7 +17,8 @@ def test_readme_md(self): for input, config in action.get('inputs').items(): with self.subTest(input=input): - if 'deprecated' not in config.get('description', '').lower(): + if 'deprecated' not in config.get('description', '').lower() and \ + input not in ['log_level', 'root_log_level']: self.assertTrue( any(input in line for line in readme), msg=f'There is no line in README.md that mentions {input}' diff --git a/windows-bash/action.yml b/windows-bash/action.yml index 3b04ada4..9922bd93 100644 --- a/windows-bash/action.yml +++ b/windows-bash/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: @@ -279,9 +285,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/windows/action.yml b/windows/action.yml index 7eef688b..267120fd 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -142,6 +142,12 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false + root_log_level: + description: 'Log level for all Python modules.' + required: false + log_level: + description: 'Log level for the publish action.' + required: false outputs: json: @@ -283,9 +289,7 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: pwsh From 5f7584c0874011f1417d3137a7c622db402a74f2 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 07:46:59 +0100 Subject: [PATCH 19/42] Remove `trap "echo '##[endgroup]'" EXIT` --- linux/action.yml | 13 +++++++------ macos/action.yml | 12 +++++++----- windows-bash/action.yml | 12 +++++++----- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/linux/action.yml b/linux/action.yml index 662168da..ef6f1124 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -161,8 +161,6 @@ runs: id: python run: | echo '##[group]Check for Python3' - trap "echo '##[endgroup]'" EXIT - echo "OS: $RUNNER_OS" # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -183,6 +181,8 @@ runs: echo "Python that creates venv: $PYTHON_BIN" echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + + echo '##[endgroup]' shell: bash - name: Restore PIP packages cache @@ -198,7 +198,6 @@ runs: continue-on-error: true run: | echo '##[group]Create virtualenv' - trap "echo '##[endgroup]'" EXIT echo "Python that creates venv: $PYTHON_BIN" @@ -223,25 +222,27 @@ runs: PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + + echo '##[endgroup]' shell: bash - name: Install Python dependencies run: | echo '##[group]Install Python dependencies' - trap "echo '##[endgroup]'" EXIT # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + + echo '##[endgroup]' shell: bash - name: Publish Test Results id: test-results run: | echo '##[group]Publish Test Results' - trap "echo '##[endgroup]'" EXIT - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '##[endgroup]' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/macos/action.yml b/macos/action.yml index 92de4631..900ba41b 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -161,7 +161,6 @@ runs: id: python run: | echo '##[group]Check for Python3' - trap "echo '##[endgroup]'" EXIT # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,6 +181,8 @@ runs: echo "Python that creates venv: $PYTHON_BIN" echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + + echo '##[endgroup]' shell: bash - name: Restore PIP packages cache @@ -197,7 +198,6 @@ runs: continue-on-error: true run: | echo '##[group]Create virtualenv' - trap "echo '##[endgroup]'" EXIT echo "Python that creates venv: $PYTHON_BIN" @@ -222,25 +222,27 @@ runs: PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + + echo '##[endgroup]' shell: bash - name: Install Python dependencies run: | echo '##[group]Install Python dependencies' - trap "echo '##[endgroup]'" EXIT # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + + echo '##[endgroup]' shell: bash - name: Publish Test Results id: test-results run: | echo '##[group]Publish Test Results' - trap "echo '##[endgroup]'" EXIT - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '##[endgroup]' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/windows-bash/action.yml b/windows-bash/action.yml index 9922bd93..251d6319 100644 --- a/windows-bash/action.yml +++ b/windows-bash/action.yml @@ -161,7 +161,6 @@ runs: id: python run: | echo '##[group]Check for Python3' - trap "echo '##[endgroup]'" EXIT # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,6 +181,8 @@ runs: echo "Python that creates venv: $PYTHON_BIN" echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + + echo '##[endgroup]' shell: bash - name: Restore PIP packages cache @@ -197,7 +198,6 @@ runs: continue-on-error: true run: | echo '##[group]Create virtualenv' - trap "echo '##[endgroup]'" EXIT echo "Python that creates venv: $PYTHON_BIN" @@ -226,25 +226,27 @@ runs: PYTHON_VENV="$(enricomi-publish-action-venv\\Scripts\\python -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + + echo '##[endgroup]' shell: bash - name: Install Python dependencies run: | echo '##[group]Install Python dependencies' - trap "echo '##[endgroup]'" EXIT # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + + echo '##[endgroup]' shell: bash - name: Publish Test Results id: test-results run: | echo '##[group]Publish Test Results' - trap "echo '##[endgroup]'" EXIT - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '##[endgroup]' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} From 59547f96e9726c75c1e7a67b0adda7eeb728a14e Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 07:48:38 +0100 Subject: [PATCH 20/42] Remove some more escaped backslashes --- windows-bash/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/windows-bash/action.yml b/windows-bash/action.yml index 251d6319..02ca492c 100644 --- a/windows-bash/action.yml +++ b/windows-bash/action.yml @@ -190,7 +190,7 @@ runs: id: cache continue-on-error: true with: - path: ~\\AppData\\Local\\pip\\Cache + path: '~\AppData\Local\pip\Cache' key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv @@ -296,7 +296,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: ~\\AppData\\Local\\pip\\Cache + path: '~\AppData\Local\pip\Cache' key: ${{ steps.cache.outputs.cache-primary-key }} branding: From ee791ad2e9ceb0271a18645446f759a2c858080c Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 07:59:40 +0100 Subject: [PATCH 21/42] Fix grouping lines in GH actions output --- linux/action.yml | 16 ++++++++-------- macos/action.yml | 16 ++++++++-------- windows-bash/action.yml | 16 ++++++++-------- windows/action.yml | 16 ++++++++-------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/linux/action.yml b/linux/action.yml index ef6f1124..cfcd9a2c 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -160,7 +160,7 @@ runs: - name: Check for Python3 id: python run: | - echo '##[group]Check for Python3' + echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,7 +182,7 @@ runs: echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Restore PIP packages cache @@ -197,7 +197,7 @@ runs: id: venv continue-on-error: true run: | - echo '##[group]Create virtualenv' + echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -223,26 +223,26 @@ runs: echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Install Python dependencies run: | - echo '##[group]Install Python dependencies' + echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Publish Test Results id: test-results run: | - echo '##[group]Publish Test Results' + echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '##[endgroup]' + echo '::endgroup::' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/macos/action.yml b/macos/action.yml index 900ba41b..27c4a65a 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -160,7 +160,7 @@ runs: - name: Check for Python3 id: python run: | - echo '##[group]Check for Python3' + echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,7 +182,7 @@ runs: echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Restore PIP packages cache @@ -197,7 +197,7 @@ runs: id: venv continue-on-error: true run: | - echo '##[group]Create virtualenv' + echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -223,26 +223,26 @@ runs: echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Install Python dependencies run: | - echo '##[group]Install Python dependencies' + echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Publish Test Results id: test-results run: | - echo '##[group]Publish Test Results' + echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '##[endgroup]' + echo '::endgroup::' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/windows-bash/action.yml b/windows-bash/action.yml index 02ca492c..ef4690d2 100644 --- a/windows-bash/action.yml +++ b/windows-bash/action.yml @@ -160,7 +160,7 @@ runs: - name: Check for Python3 id: python run: | - echo '##[group]Check for Python3' + echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,7 +182,7 @@ runs: echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Restore PIP packages cache @@ -197,7 +197,7 @@ runs: id: venv continue-on-error: true run: | - echo '##[group]Create virtualenv' + echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -227,26 +227,26 @@ runs: echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Install Python dependencies run: | - echo '##[group]Install Python dependencies' + echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" - echo '##[endgroup]' + echo '::endgroup::' shell: bash - name: Publish Test Results id: test-results run: | - echo '##[group]Publish Test Results' + echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" - echo '##[endgroup]' + echo '::endgroup::' env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/windows/action.yml b/windows/action.yml index 267120fd..816d4eb2 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -160,7 +160,7 @@ runs: - name: Check for Python3 id: python run: | - Write-Output "##[group]Check for Python3" + Write-Output "::group::Check for Python3" try { # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store @@ -182,7 +182,7 @@ runs: Write-Output "Python version: $VERSION" "version=$VERSION" | Out-File -FilePath $env:GITHUB_OUTPUT -Append } finally { - Write-Output "##[endgroup]" + Write-Output "::endgroup::" } shell: pwsh @@ -198,7 +198,7 @@ runs: id: venv continue-on-error: true run: | - Write-Output "##[group]Create virtualenv" + Write-Output "::group::Create virtualenv" try { Write-Output "Python that creates venv: $env:PYTHON_BIN" @@ -224,30 +224,30 @@ runs: Write-Output "Python in venv: $PYTHON_VENV" "PYTHON_VENV=$PYTHON_VENV" | Out-File -FilePath $env:GITHUB_ENV -Append } finally { - Write-Output "##[endgroup]" + Write-Output "::endgroup::" } shell: pwsh - name: Install Python dependencies run: | - Write-Output "##[group]Install Python dependencies" + Write-Output "::group::Install Python dependencies" try { # make sure wheel is installed, which improves installing our dependencies Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install wheel" Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install -r '$env.GITHUB_ACTION_PATH\..\python\requirements.txt'" } finally { - Write-Output "##[endgroup]" + Write-Output "::endgroup::" } shell: pwsh - name: Publish Test Results id: test-results run: | - Write-Output "##[group]Publish Test Results" + Write-Output "::group::Publish Test Results" try { Invoke-Expression -Command "& '$env:PYTHON_VENV' '$env:GITHUB_ACTION_PATH\..\python\publish_test_results.py'" } finally { - Write-Output "##[endgroup]" + Write-Output "::endgroup::" } env: GITHUB_TOKEN: ${{ inputs.github_token }} From 86ad9685bfcd9628f1b2551bd8e2a66197c41674 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 08:09:03 +0100 Subject: [PATCH 22/42] Move windows-bash/ to windows/bash --- .github/workflows/publish.yml | 2 +- composite/action.yml | 4 ++-- python/test/test_action_yml.py | 2 +- {windows-bash => windows/bash}/action.yml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename {windows-bash => windows/bash}/action.yml (99%) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c37f9687..d742fb37 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -409,7 +409,7 @@ jobs: - name: Publish Test Results (Bash) id: test-results-bash - uses: ./windows-bash + uses: ./windows/bash with: check_name: Test Results (${{ matrix.os-label }} bash python ${{ matrix.python }}) files: artifacts\**\*.xml diff --git a/composite/action.yml b/composite/action.yml index 4d230703..a2b08c40 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -259,8 +259,8 @@ runs: - name: Run on Windows id: windows if: startsWith(env.OS, 'Windows') - # this general composite action requires Bash shell, so this calls into windows-bash as well - uses: EnricoMi/publish-unit-test-result-action/windows-bash@branch-composite-os-actions-2 + # this general composite action requires Bash shell, so this calls into windows/bash as well + uses: EnricoMi/publish-unit-test-result-action/windows/bash@branch-composite-os-actions-2 with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index c0742ae2..2832e10e 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -36,7 +36,7 @@ def test_windows_action(self): self.do_test_composite_action('windows') def test_windows_bash_action(self): - self.do_test_composite_action('windows-bash') + self.do_test_composite_action('windows/bash') def do_test_composite_action(self, action: str): with open(project_root / 'action.yml', encoding='utf-8') as r: diff --git a/windows-bash/action.yml b/windows/bash/action.yml similarity index 99% rename from windows-bash/action.yml rename to windows/bash/action.yml index ef4690d2..2d50f040 100644 --- a/windows-bash/action.yml +++ b/windows/bash/action.yml @@ -236,7 +236,7 @@ runs: # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel - "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../../python/requirements.txt" echo '::endgroup::' shell: bash @@ -245,7 +245,7 @@ runs: id: test-results run: | echo '::group::Publish Test Results' - "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../../python/publish_test_results.py" echo '::endgroup::' env: GITHUB_TOKEN: ${{ inputs.github_token }} From a97d0b1b4530084dc1508d89ceb550e6467eb273 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 16:38:20 +0100 Subject: [PATCH 23/42] Use actions relative to composite/action.yml --- composite/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composite/action.yml b/composite/action.yml index a2b08c40..61721ee3 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -165,7 +165,7 @@ runs: - name: Run on Linux id: linux if: startsWith(env.OS, 'Linux') - uses: EnricoMi/publish-unit-test-result-action/linux@branch-composite-os-actions-2 + uses: ./../linux with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -212,7 +212,7 @@ runs: - name: Run on macOS id: macos if: startsWith(env.OS, 'macOS') - uses: EnricoMi/publish-unit-test-result-action/macos@branch-composite-os-actions-2 + uses: ./../macos with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -260,7 +260,7 @@ runs: id: windows if: startsWith(env.OS, 'Windows') # this general composite action requires Bash shell, so this calls into windows/bash as well - uses: EnricoMi/publish-unit-test-result-action/windows/bash@branch-composite-os-actions-2 + uses: ./../windows/bash with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} From 5a87324ca1ab27b9110630e14be2e64a0bd9976e Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 16:58:42 +0100 Subject: [PATCH 24/42] Reduce test space --- .github/workflows/ci-cd.yml | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index f8c3b568..03454caa 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -30,42 +30,17 @@ jobs: .github/upgrade-pip-packages.sh shell: bash - test-mac: - name: "Test macOS" - uses: "./.github/workflows/test-os.yml" - with: - os: '["macos-11", "macos-12", "macos-13", "macos-14"]' - python-version: '["3.10", "3.11", "3.12", "installed"]' - include: > - [ - {"os": "macos-11", "python-version": "3.7"}, - {"os": "macos-11", "python-version": "3.8"}, - {"os": "macos-11", "python-version": "3.9"}, - {"os": "macos-12", "python-version": "3.8"}, - {"os": "macos-12", "python-version": "3.9"}, - {"os": "macos-13", "python-version": "3.8"}, - {"os": "macos-13", "python-version": "3.9"}, - ] - test-lnx: name: "Test Ubuntu" uses: "./.github/workflows/test-os.yml" with: - os: '["ubuntu-20.04", "ubuntu-22.04"]' - python-version: '["3.8", "3.9", "3.10", "3.11", "3.12", "installed"]' - include: '[{"os": "ubuntu-20.04", "python-version": "3.7"}]' - - test-win: - name: "Test Windows" - uses: "./.github/workflows/test-os.yml" - with: - os: '["windows-2019", "windows-2022"]' - python-version: '["3.8", "3.9", "3.10", "3.11", "3.12", "installed"]' - include: '[{"os": "windows-2019", "python-version": "3.7"}]' + os: '["ubuntu-20.04"]' + python-version: '["3.8"]' + include: '[]' publish: name: "Publish" - needs: [test-mac, test-lnx, test-win] + needs: [test-lnx] # we run the action from this branch whenever we can (when it runs in our repo's context) if: > ! cancelled() && @@ -79,7 +54,7 @@ jobs: config-deploy: name: Configure Deployment - needs: [test-mac, test-lnx, test-win] + needs: [test-lnx] # do not build or deploy on forked repositories if: github.repository_owner == 'EnricoMi' runs-on: ubuntu-latest From afd456f40755dbd001ecea35210a767802c6385f Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 17:14:53 +0100 Subject: [PATCH 25/42] Reduce publish space --- .github/workflows/publish.yml | 511 ---------------------------------- 1 file changed, 511 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d742fb37..2bf654ca 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,426 +4,6 @@ on: workflow_call: jobs: - publish-dockerfile: - name: Publish Test Results (Dockerfile) - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Prepare publish action from this branch - run: | - sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml - shell: bash - - - name: Publish Test Results - id: test-results - uses: ./ - with: - check_name: Test Results (Dockerfile) - files: "artifacts/**/*.xml" - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - log_level: DEBUG - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - publish-docker-image: - name: Publish Test Results (Docker Image ${{ matrix.arch }}) - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - security-events: write - strategy: - fail-fast: false - matrix: - arch: [amd64, arm64] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - image: tonistiigi/binfmt:latest - platforms: ${{ matrix.arch }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build Docker image - id: build - uses: docker/build-push-action@v5 - with: - load: true - push: false - platforms: linux/${{ matrix.arch }} - tags: enricomi/publish-unit-test-result-action:latest - outputs: type=docker - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Publish Test Results - id: test-results - if: always() - env: - INPUT_GITHUB_TOKEN: ${{ github.token }} - INPUT_CHECK_NAME: Test Results (Docker Image ${{ matrix.arch }}) - INPUT_FILES: "artifacts/**/*.xml" - INPUT_JSON_FILE: "tests.json" - INPUT_JSON_SUITE_DETAILS: true - INPUT_JSON_TEST_CASE_RESULTS: true - INPUT_REPORT_SUITE_LOGS: "any" - run: | - docker run --platform linux/${{ matrix.arch }} \ - --workdir $GITHUB_WORKSPACE \ - --rm \ - -e "INPUT_CHECK_NAME" \ - -e "INPUT_JSON_FILE" \ - -e "INPUT_JSON_SUITE_DETAILS" \ - -e "INPUT_JSON_TEST_CASE_RESULTS" \ - -e "INPUT_LOG_LEVEL" \ - -e "INPUT_ROOT_LOG_LEVEL" \ - -e "INPUT_GITHUB_TOKEN" \ - -e "INPUT_GITHUB_TOKEN_ACTOR" \ - -e "INPUT_GITHUB_RETRIES" \ - -e "INPUT_COMMIT" \ - -e "INPUT_COMMENT_TITLE" \ - -e "INPUT_COMMENT_MODE" \ - -e "INPUT_FAIL_ON" \ - -e "INPUT_ACTION_FAIL" \ - -e "INPUT_ACTION_FAIL_ON_INCONCLUSIVE" \ - -e "INPUT_FILES" \ - -e "INPUT_JUNIT_FILES" \ - -e "INPUT_NUNIT_FILES" \ - -e "INPUT_XUNIT_FILES" \ - -e "INPUT_TRX_FILES" \ - -e "INPUT_TIME_UNIT" \ - -e "INPUT_TEST_FILE_PREFIX" \ - -e "INPUT_REPORT_INDIVIDUAL_RUNS" \ - -e "INPUT_REPORT_SUITE_LOGS" \ - -e "INPUT_DEDUPLICATE_CLASSES_BY_FILE_NAME" \ - -e "INPUT_LARGE_FILES" \ - -e "INPUT_IGNORE_RUNS" \ - -e "INPUT_CHECK_RUN" \ - -e "INPUT_JOB_SUMMARY" \ - -e "INPUT_COMPARE_TO_EARLIER_COMMIT" \ - -e "INPUT_PULL_REQUEST_BUILD" \ - -e "INPUT_EVENT_FILE" \ - -e "INPUT_EVENT_NAME" \ - -e "INPUT_TEST_CHANGES_LIMIT" \ - -e "INPUT_CHECK_RUN_ANNOTATIONS" \ - -e "INPUT_CHECK_RUN_ANNOTATIONS_BRANCH" \ - -e "INPUT_SECONDS_BETWEEN_GITHUB_READS" \ - -e "INPUT_SECONDS_BETWEEN_GITHUB_WRITES" \ - -e "INPUT_SECONDARY_RATE_LIMIT_WAIT_SECONDS" \ - -e "INPUT_JSON_THOUSANDS_SEPARATOR" \ - -e "INPUT_SEARCH_PULL_REQUESTS" \ - -e "HOME" \ - -e "GITHUB_JOB" \ - -e "GITHUB_REF" \ - -e "GITHUB_SHA" \ - -e "GITHUB_REPOSITORY" \ - -e "GITHUB_REPOSITORY_OWNER" \ - -e "GITHUB_RUN_ID" \ - -e "GITHUB_RUN_NUMBER" \ - -e "GITHUB_RETENTION_DAYS" \ - -e "GITHUB_RUN_ATTEMPT" \ - -e "GITHUB_ACTOR" \ - -e "GITHUB_TRIGGERING_ACTOR" \ - -e "GITHUB_WORKFLOW" \ - -e "GITHUB_HEAD_REF" \ - -e "GITHUB_BASE_REF" \ - -e "GITHUB_EVENT_NAME" \ - -e "GITHUB_SERVER_URL" \ - -e "GITHUB_API_URL" \ - -e "GITHUB_GRAPHQL_URL" \ - -e "GITHUB_REF_NAME" \ - -e "GITHUB_REF_PROTECTED" \ - -e "GITHUB_REF_TYPE" \ - -e "GITHUB_WORKSPACE" \ - -e "GITHUB_ACTION" \ - -e "GITHUB_EVENT_PATH" \ - -e "GITHUB_ACTION_REPOSITORY" \ - -e "GITHUB_ACTION_REF" \ - -e "GITHUB_PATH" \ - -e "GITHUB_ENV" \ - -e "GITHUB_STEP_SUMMARY" \ - -e "GITHUB_STATE" \ - -e "GITHUB_OUTPUT" \ - -e "RUNNER_OS" \ - -e "RUNNER_ARCH" \ - -e "RUNNER_NAME" \ - -e "RUNNER_TOOL_CACHE" \ - -e "RUNNER_TEMP" \ - -e "RUNNER_WORKSPACE" \ - -e "ACTIONS_RUNTIME_URL" \ - -e "ACTIONS_RUNTIME_TOKEN" \ - -e "ACTIONS_CACHE_URL" \ - -e GITHUB_ACTIONS=true \ - -e CI=true \ - -v "$RUNNER_TEMP":"$RUNNER_TEMP" \ - -v "/var/run/docker.sock":"/var/run/docker.sock" \ - -v "/home/runner/work/_temp/_github_home":"/github/home" \ - -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ - -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" \ - -v "/home/runner/work/publish-unit-test-result-action/publish-unit-test-result-action":"$GITHUB_WORKSPACE" \ - enricomi/publish-unit-test-result-action:latest - shell: bash - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - - name: Scan for vulnerabilities - id: scan - uses: crazy-max/ghaction-container-scan@v3 - with: - image: enricomi/publish-unit-test-result-action:latest - dockerfile: ./Dockerfile - annotations: true - - name: Upload SARIF artifact - uses: actions/upload-artifact@v4 - with: - name: SARIF ${{ matrix.arch }} - path: ${{ steps.scan.outputs.sarif }} - - name: Upload SARIF file - if: always() && steps.scan.outputs.sarif != '' - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: ${{ steps.scan.outputs.sarif }} - - publish-linux: - name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - runs-on: ${{ matrix.os }} - permissions: - checks: write - pull-requests: write - - strategy: - fail-fast: false - max-parallel: 2 - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources - include: - - os: ubuntu-latest - os-label: Linux - python: "3.8" - - os: ubuntu-latest - os-label: Linux - python: "venv" - - os: ubuntu-latest - os-label: Linux - python: "installed" - - os: ubuntu-20.04 - os-label: Linux 20.04 - python: "installed" - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Python - if: matrix.python != 'installed' && matrix.python != 'venv' - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Install virtualenv - if: matrix.python == 'venv' - run: python3 -m pip install virtualenv - shell: bash - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Publish Test Results - id: test-results - uses: ./linux - with: - check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - files: artifacts/**/*.xml - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - publish-macos: - name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - runs-on: ${{ matrix.os }} - permissions: - checks: write - pull-requests: write - - strategy: - fail-fast: false - max-parallel: 2 - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources - include: - - os: macos-latest - os-label: macOS - python: "3.8" - - os: macos-latest - os-label: macOS - python: "venv" - - os: macos-latest - os-label: macOS - python: "installed" - - os: macos-11 - os-label: macOS 11 - python: "installed" - - os: macos-13 - os-label: macOS 13 - python: "installed" - - os: macos-14 - os-label: macOS 14 - python: "installed" - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Python - if: matrix.python != 'installed' && matrix.python != 'venv' - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Install virtualenv - if: matrix.python == 'venv' - run: python3 -m pip install virtualenv - shell: bash - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Publish Test Results - id: test-results - uses: ./macos - with: - check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - files: artifacts/**/*.xml - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - publish-windows: - name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - runs-on: ${{ matrix.os }} - permissions: - checks: write - pull-requests: write - - strategy: - fail-fast: false - max-parallel: 2 - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources - include: - - os: windows-latest - os-label: Windows - python: "installed" - - os: windows-latest - os-label: Windows - python: "venv" - - os: windows-2019 - os-label: Windows 2019 - python: "installed" - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Python - if: matrix.python != 'installed' && matrix.python != 'venv' - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Install virtualenv - if: matrix.python == 'venv' - run: python3 -m pip install virtualenv - shell: bash - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Publish Test Results - id: test-results - uses: ./windows - with: - check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) - files: artifacts\**\*.xml - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - - name: Publish Test Results (Bash) - id: test-results-bash - uses: ./windows/bash - with: - check_name: Test Results (${{ matrix.os-label }} bash python ${{ matrix.python }}) - files: artifacts\**\*.xml - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - - - name: JSON output (Bash) - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results-bash.outputs.json }}' - json_file: 'tests.json' - publish-composite: name: Publish Test Results (${{ matrix.os-label }} composite) runs-on: ${{ matrix.os }} @@ -438,15 +18,9 @@ jobs: # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources # test *-latest and newer (because newer eventually become 'latest' and should be tested to work before that) include: - - os: macos-latest - os-label: macOS - python: "installed" - os: ubuntu-latest os-label: Linux python: "installed" - - os: windows-latest - os-label: Windows - python: "installed" steps: - name: Checkout @@ -486,88 +60,3 @@ jobs: with: json: '${{ steps.test-results.outputs.json }}' json_file: 'tests.json' - - publish-test-files: - name: Publish Test Files - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Copy test result files - run: cp -rv python/test/files test-files - shell: bash - - - name: Prepare publish action from this branch - run: | - sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml - shell: bash - - - name: Publish Test Results - id: test-results - uses: ./ - with: - check_name: Test Results (Test Files) - fail_on: nothing - files: | - test-files/**/*.xml - test-files/**/*.trx - test-files/**/*.json - junit_files: "test-files/junit-xml/**/*.xml" - nunit_files: "test-files/nunit/**/*.xml" - xunit_files: "test-files/xunit/**/*.xml" - trx_files: "test-files/trx/**/*.trx" - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - log_level: DEBUG - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' - - publish-test-file: - name: Publish Test File - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Copy test junit xml files - run: cp -rv python/test/files/junit-xml test-files - shell: bash - - - name: Prepare publish action from this branch - run: | - sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml - shell: bash - - - name: Publish Test Results - id: test-results - uses: ./ - with: - check_name: Test Results (Test File) - fail_on: nothing - files: "test-files/pytest/junit.gloo.standalone.xml" - json_file: "tests.json" - json_suite_details: true - json_test_case_results: true - report_suite_logs: "any" - log_level: DEBUG - - - name: JSON output - uses: ./misc/action/json-output - with: - json: '${{ steps.test-results.outputs.json }}' - json_file: 'tests.json' From 20ee7c944c7c907f0d61f124aed1ec1565e97c72 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 20:54:21 +0100 Subject: [PATCH 26/42] Redirect composite action through dynamic action --- composite/action.yml | 119 ++++----------------------------- composite/proxy.sh | 41 ++++++++++++ linux/action.yml | 2 + python/test/test_action_yml.py | 10 ++- 4 files changed, 64 insertions(+), 108 deletions(-) create mode 100755 composite/proxy.sh diff --git a/composite/action.yml b/composite/action.yml index 61721ee3..1d38ef5c 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -152,67 +152,22 @@ inputs: outputs: json: description: "Test results as JSON" - value: ${{ steps.linux.outputs.json || steps.macos.outputs.json || steps.windows.outputs.json }} + value: ${{ steps.run.outputs.json }} runs: using: 'composite' steps: - name: Check OS - # env.RUNNER_OS is not available in if condition of steps - run: echo "OS=$RUNNER_OS" >> "$GITHUB_ENV" + run: | + echo "GITHUB_ACTION_PATH: $GITHUB_ACTION_PATH" + cp -rv $GITHUB_ACTION_PATH/.. ./enricomi-publish-action-proxy + $GITHUB_ACTION_PATH/proxy.sh > ./enricomi-publish-action-proxy/action.yml + cat ./enricomi-publish-action-proxy/action.yml shell: bash - - name: Run on Linux - id: linux - if: startsWith(env.OS, 'Linux') - uses: ./../linux - with: - GITHUB_TOKEN: ${{ inputs.github_token }} - GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} - GITHUB_RETRIES: ${{ inputs.github_retries }} - COMMIT: ${{ inputs.commit }} - CHECK_NAME: ${{ inputs.check_name }} - COMMENT_TITLE: ${{ inputs.comment_title }} - COMMENT_MODE: ${{ inputs.comment_mode }} - FAIL_ON: ${{ inputs.fail_on }} - ACTION_FAIL: ${{ inputs.action_fail }} - ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} - FILES: ${{ inputs.files }} - JUNIT_FILES: ${{ inputs.junit_files }} - NUNIT_FILES: ${{ inputs.nunit_files }} - XUNIT_FILES: ${{ inputs.xunit_files }} - TRX_FILES: ${{ inputs.trx_files }} - TIME_UNIT: ${{ inputs.time_unit }} - TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} - REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} - REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} - DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} - LARGE_FILES: ${{ inputs.large_files }} - IGNORE_RUNS: ${{ inputs.ignore_runs }} - COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} - PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} - EVENT_FILE: ${{ inputs.event_file }} - EVENT_NAME: ${{ inputs.event_name }} - TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} - CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} - CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} - SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} - SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} - SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} - JSON_FILE: ${{ inputs.json_file }} - JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} - JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} - JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} - CHECK_RUN: ${{ inputs.check_run }} - JOB_SUMMARY: ${{ inputs.job_summary }} - SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - LOG_LEVEL: ${{ inputs.log_level }} - - - name: Run on macOS - id: macos - if: startsWith(env.OS, 'macOS') - uses: ./../macos + - name: Run + id: run + uses: ./enricomi-publish-action-proxy with: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} @@ -256,59 +211,9 @@ runs: ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} LOG_LEVEL: ${{ inputs.log_level }} - - name: Run on Windows - id: windows - if: startsWith(env.OS, 'Windows') - # this general composite action requires Bash shell, so this calls into windows/bash as well - uses: ./../windows/bash - with: - GITHUB_TOKEN: ${{ inputs.github_token }} - GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} - GITHUB_RETRIES: ${{ inputs.github_retries }} - COMMIT: ${{ inputs.commit }} - CHECK_NAME: ${{ inputs.check_name }} - COMMENT_TITLE: ${{ inputs.comment_title }} - COMMENT_MODE: ${{ inputs.comment_mode }} - FAIL_ON: ${{ inputs.fail_on }} - ACTION_FAIL: ${{ inputs.action_fail }} - ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }} - FILES: ${{ inputs.files }} - JUNIT_FILES: ${{ inputs.junit_files }} - NUNIT_FILES: ${{ inputs.nunit_files }} - XUNIT_FILES: ${{ inputs.xunit_files }} - TRX_FILES: ${{ inputs.trx_files }} - TIME_UNIT: ${{ inputs.time_unit }} - TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }} - REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }} - REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }} - DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }} - LARGE_FILES: ${{ inputs.large_files }} - IGNORE_RUNS: ${{ inputs.ignore_runs }} - COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }} - PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }} - EVENT_FILE: ${{ inputs.event_file }} - EVENT_NAME: ${{ inputs.event_name }} - TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }} - CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }} - CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }} - SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }} - SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }} - SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }} - JSON_FILE: ${{ inputs.json_file }} - JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }} - JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }} - JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }} - CHECK_RUN: ${{ inputs.check_run }} - JOB_SUMMARY: ${{ inputs.job_summary }} - SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} - ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} - LOG_LEVEL: ${{ inputs.log_level }} - - - name: Run on unsupported Operating System - if: steps.linux.outcome == 'skipped' && steps.macos.outcome == 'skipped' && steps.windows.outcome == 'skipped' - run: | - echo "::error::Unsupported operating system: $RUNNER_OS" - exit 1 + - name: Clean up + if: always() + run: rm -rf ./enricomi-publish-action-proxy shell: bash branding: diff --git a/composite/proxy.sh b/composite/proxy.sh new file mode 100755 index 00000000..6789d195 --- /dev/null +++ b/composite/proxy.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -euo pipefail + +case "$RUNNER_OS" in + Linux*) + action="linux" + ;; + macOS*) + action="macos" + ;; + Windows*) + action="windows/bash" + ;; + *) + echo "::error::Unsupported operating system: $RUNNER_OS" + exit 1 + ;; +esac + +in_runs=false +in_check=false +in_run=false +in_cleanup=false + +while IFS= read -r line +do + if [ "$line" == "runs:" ]; then in_runs=true + elif [ $in_runs == true ] && [[ "$line" == *"- name: Check OS" ]]; then in_check=true + elif [ $in_runs == true ] && [[ "$line" == *"- name: Run" ]]; then in_check=false; in_run=true + elif [ $in_runs == true ] && [[ "$line" == *"- name: Clean up" ]]; then in_run=false; in_cleanup=true + elif [ "$line" == "branding:" ]; then in_cleanup=false + fi + + if [ $in_run == true ] && [[ "$line" == *" uses: "* ]]; then + # use $action in uses: ... + echo "${line/%:*/: ./enricomi-publish-action-proxy/$action}" + elif [ $in_check != true ] && [ $in_cleanup != true ] && ( [ $in_run != true ] || [[ "$line" != *" if:"* ]] ); then + echo "$line" + fi +done < "$GITHUB_ACTION_PATH/action.yml" diff --git a/linux/action.yml b/linux/action.yml index cfcd9a2c..6de7e9eb 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -162,6 +162,8 @@ runs: run: | echo '::group::Check for Python3' + echo "GITHUB_ACTION_PATH: $GITHUB_ACTION_PATH" + # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store # command `which python3` finds that, but `python3 -V` does not return the version on stdout diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index 2832e10e..27a26ce7 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -67,13 +67,15 @@ def do_test_composite_action(self, action: str): # the 'composite' composite action is just a proxy to the os-specific actions, it forwards inputs via 'with' steps = [step for step in steps if 'name' in step - and step.get('name').startswith('Run on ') + and step.get('name').startswith('Run') and step.get('name') != 'Run on unsupported Operating System'] inputs_key = 'with' else: # the other composite actions forward inputs via env steps = [step for step in steps if step.get('name') == 'Publish Test Results'] inputs_key = 'env' + + self.assertTrue(len(steps) > 0) for step in steps: self.assertIn(inputs_key, step, step.get('name')) inputs = {key.upper(): value for key, value in step.get(inputs_key, {}).items()} @@ -91,3 +93,9 @@ def do_test_composite_action(self, action: str): if step.get('uses', '').startswith('actions/cache/restore@')) self.assertEqual(expected_hash, cache_hash, msg='Changing python/requirements.txt requires ' 'to update the MD5 hash in composite/action.yaml') + + def test_proxy_action(self): + # TODO + # run RUNNER_OS=Linux|Windows|macOS GITHUB_ACTION_PATH=... composite/proxy.sh + # and compare with python/test/files/proxy.yml + pass From 0949ea497bcb55235a674f1359de99998dca9434 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Fri, 23 Feb 2024 21:44:35 +0100 Subject: [PATCH 27/42] Test composite with sha --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2bf654ca..c16f79d2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,7 +44,7 @@ jobs: - name: Publish Test Results id: test-results - uses: ./composite + uses: EnricoMi/publish-unit-test-result-action/composite@20ee7c944c7c907f0d61f124aed1ec1565e97c72 with: check_name: Test Results (${{ matrix.os-label }} composite python ${{ matrix.python }}) files: | From dd9087178220c9a585b9703cdaae2bc1b1989ac2 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 09:59:17 +0100 Subject: [PATCH 28/42] Revert composite action --- composite/action.yml | 124 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 13 deletions(-) diff --git a/composite/action.yml b/composite/action.yml index 1d38ef5c..50ea571a 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -152,23 +152,117 @@ inputs: outputs: json: description: "Test results as JSON" - value: ${{ steps.run.outputs.json }} + value: ${{ steps.test-results.outputs.json }} runs: using: 'composite' steps: - - name: Check OS + - name: Check for Python3 + id: python run: | - echo "GITHUB_ACTION_PATH: $GITHUB_ACTION_PATH" - cp -rv $GITHUB_ACTION_PATH/.. ./enricomi-publish-action-proxy - $GITHUB_ACTION_PATH/proxy.sh > ./enricomi-publish-action-proxy/action.yml - cat ./enricomi-publish-action-proxy/action.yml + echo '::group::Check for Python3' + # we check version here just to execute `python3` with an argument + # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store + # command `which python3` finds that, but `python3 -V` does not return the version on stdout + if ! which python3 || [[ "$(python3 -V)" != *"python 3."* && "$(python3 -V)" != *"Python 3."* ]] + then + if ! which python || [[ "$(python -V)" != *"python 3."* && "$(python -V)" != *"Python 3."* ]] + then + echo "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python." + exit 1 + fi + + PYTHON_BIN="$(python -c 'import sys; print(sys.executable)')" + else + PYTHON_BIN="$(python3 -c 'import sys; print(sys.executable)')" + fi + + echo "Python that creates venv: $PYTHON_BIN" + echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" + echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + echo '::endgroup::' + shell: bash + + - name: Detect OS + id: os + run: | + case "$RUNNER_OS" in + Linux*) + echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" + ;; + macOS*) + echo "pip-cache=~/Library/Caches/pip" >> "$GITHUB_OUTPUT" + ;; + Windows*) + echo "pip-cache=~\\AppData\\Local\\pip\\Cache" >> "$GITHUB_OUTPUT" + echo "pip-options=--user" >> "$GITHUB_OUTPUT" + ;; + esac shell: bash - - name: Run - id: run - uses: ./enricomi-publish-action-proxy + - name: Restore PIP packages cache + uses: actions/cache/restore@v4 + id: cache + continue-on-error: true with: + path: ${{ steps.os.outputs.pip-cache }} + key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 + + - name: Create virtualenv + id: venv + continue-on-error: true + env: + PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} + run: | + echo '::group::Create virtualenv' + echo "Python that creates venv: $PYTHON_BIN" + + echo "Creating virtual environment" + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv && ! "$PYTHON_BIN" -m venv enricomi-publish-action-venv + then + echo "Looks like there is neither virtualenv nor venv package installed" + if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] + then + echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" + "$PYTHON_BIN" -m pip install virtualenv + fi + + if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv + then + echo "Still cannot create venv after installing virtualenv package" + exit 1 + fi + fi + + echo "Finding Python interpreter in venv" + case "$RUNNER_OS" in + Linux*|macOS*) + PYTHON_VENV="enricomi-publish-action-venv/bin/python";; + Windows*) + PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python";; + esac + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" + echo "Python in venv: $PYTHON_VENV" + echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + echo '::endgroup::' + shell: bash + + - name: Install Python dependencies + run: | + echo '::group::Install Python dependencies' + # make sure wheel is installed, which improves installing our dependencies + "$PYTHON_VENV" -m pip install wheel + "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + echo '::endgroup::' + shell: bash + + - name: Publish Test Results + id: test-results + run: | + echo '::group::Publish Test Results' + "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" + echo '::endgroup::' + env: GITHUB_TOKEN: ${{ inputs.github_token }} GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }} GITHUB_RETRIES: ${{ inputs.github_retries }} @@ -210,12 +304,16 @@ runs: SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} LOG_LEVEL: ${{ inputs.log_level }} - - - name: Clean up - if: always() - run: rm -rf ./enricomi-publish-action-proxy shell: bash + - name: Save PIP packages cache + uses: actions/cache/save@v4 + if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit + continue-on-error: true + with: + path: ${{ steps.os.outputs.pip-cache }} + key: ${{ steps.cache.outputs.cache-primary-key }} + branding: icon: 'check-circle' color: 'green' From ddf2431d4d729a66b53e88bf6094973ac74b638d Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 10:01:35 +0100 Subject: [PATCH 29/42] Revert "Add log level inputs to action.yml files" This reverts commit 546639f796ec63f6d39118d47b64163c4bb2d68e. --- action.yml | 6 ------ composite/action.yml | 8 ++------ linux/action.yml | 8 ++------ macos/action.yml | 8 ++------ python/test/test_action_yml.py | 4 +++- python/test/test_cicd_yml.py | 2 +- python/test/test_readme_md.py | 3 +-- windows/action.yml | 8 ++------ windows/bash/action.yml | 8 ++------ 9 files changed, 15 insertions(+), 40 deletions(-) diff --git a/action.yml b/action.yml index 4730fb7c..8faeb8ec 100644 --- a/action.yml +++ b/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: diff --git a/composite/action.yml b/composite/action.yml index 50ea571a..cda1fed0 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: @@ -302,7 +296,9 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/linux/action.yml b/linux/action.yml index 6de7e9eb..1bbeb392 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: @@ -285,7 +279,9 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/macos/action.yml b/macos/action.yml index 27c4a65a..1f7d7c82 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: @@ -283,7 +277,9 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index 27a26ce7..58760c37 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -59,8 +59,10 @@ def do_test_composite_action(self, action: str): self.assertIn(('using', 'composite'), composite_action.get('runs', {}).items()) # check inputs forwarded to action + # these are not documented in the action.yml files but still needs to be forwarded + extra_inputs = ['files', 'root_log_level', 'log_level'] expected = {key.upper(): f'${{{{ inputs.{key} }}}}' - for key in list(composite_action.get('inputs', {}).keys())} + for key in list(composite_action.get('inputs', {}).keys()) + extra_inputs} steps = composite_action.get('runs', {}).get('steps', []) if action == 'composite': diff --git a/python/test/test_cicd_yml.py b/python/test/test_cicd_yml.py index b0b59e73..6e695db6 100644 --- a/python/test/test_cicd_yml.py +++ b/python/test/test_cicd_yml.py @@ -28,4 +28,4 @@ def test_cicd_workflow(self): for var in [part.strip()] if var.startswith('INPUT_') or var.startswith('"INPUT_')] - self.assertEqual(sorted(list(action.get('inputs', {}).keys())), sorted(vars)) + self.assertEqual(sorted(list(action.get('inputs', {}).keys()) + ['log_level', 'root_log_level']), sorted(vars)) diff --git a/python/test/test_readme_md.py b/python/test/test_readme_md.py index bdc8d52d..83ad3107 100644 --- a/python/test/test_readme_md.py +++ b/python/test/test_readme_md.py @@ -17,8 +17,7 @@ def test_readme_md(self): for input, config in action.get('inputs').items(): with self.subTest(input=input): - if 'deprecated' not in config.get('description', '').lower() and \ - input not in ['log_level', 'root_log_level']: + if 'deprecated' not in config.get('description', '').lower(): self.assertTrue( any(input in line for line in readme), msg=f'There is no line in README.md that mentions {input}' diff --git a/windows/action.yml b/windows/action.yml index 816d4eb2..a316db48 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: @@ -289,7 +283,9 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: pwsh diff --git a/windows/bash/action.yml b/windows/bash/action.yml index 2d50f040..92edbd02 100644 --- a/windows/bash/action.yml +++ b/windows/bash/action.yml @@ -142,12 +142,6 @@ inputs: description: 'Prior to v2.6.0, the action used the "/search/issues" REST API to find pull requests related to a commit. If you need to restore that behaviour, set this to "true". Defaults to "false".' default: 'false' required: false - root_log_level: - description: 'Log level for all Python modules.' - required: false - log_level: - description: 'Log level for the publish action.' - required: false outputs: json: @@ -287,7 +281,9 @@ runs: CHECK_RUN: ${{ inputs.check_run }} JOB_SUMMARY: ${{ inputs.job_summary }} SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }} + # not documented ROOT_LOG_LEVEL: ${{ inputs.root_log_level }} + # not documented LOG_LEVEL: ${{ inputs.log_level }} shell: bash From fb7d567c05d089c50b323595d8cb35ab0fd5e94d Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 10:09:56 +0100 Subject: [PATCH 30/42] Revert "Test composite with sha" This reverts commit 0949ea497bcb55235a674f1359de99998dca9434. --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c16f79d2..2bf654ca 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -44,7 +44,7 @@ jobs: - name: Publish Test Results id: test-results - uses: EnricoMi/publish-unit-test-result-action/composite@20ee7c944c7c907f0d61f124aed1ec1565e97c72 + uses: ./composite with: check_name: Test Results (${{ matrix.os-label }} composite python ${{ matrix.python }}) files: | From 34f90855bcd1b0c75f7dab080685a51c22c287ac Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 10:13:18 +0100 Subject: [PATCH 31/42] Ammend readme --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e61120b2..89b56f11 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,9 @@ Use this for ![macOS](misc/badge-macos.svg) (e.g. `runs-on: macos-latest`) runne if: always() with: files: | - test-results/**/*.xml - test-results/**/*.trx - test-results/**/*.json + test-results\**\*.xml + test-results\**\*.trx + test-results\**\*.json ``` For **self-hosted** Linux GitHub Actions runners **without Docker** installed, please use: @@ -832,16 +832,14 @@ Using the non-composite variant of this action is recommended as it starts up mu ## Running as a composite action -Running this action as a composite action (macOs and Windows) allows to run it on operating systems -other than Linux as it does not require Docker: +Running this action as a composite action allows to run it on self-hosted runners that do not provide Docker: uses: EnricoMi/publish-unit-test-result-action/linux@v2 uses: EnricoMi/publish-unit-test-result-action/macos@v2 uses: EnricoMi/publish-unit-test-result-action/windows@v2 The composite action, however, requires a Python3 environment to be setup on the action runner. -All GitHub-hosted runners (Ubuntu, Windows Server and macOS) provide a suitable -Python3 environment out-of-the-box. +All GitHub-hosted runners (Ubuntu, Windows Server and macOS) provide a suitable Python3 environment out-of-the-box. Self-hosted runners may require setting up a Python environment first: From 08e661819abfa07755e8059d30ed162463d6ddad Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 10:24:29 +0100 Subject: [PATCH 32/42] Align action yamls --- composite/action.yml | 14 ++++++++++++-- linux/action.yml | 9 ++++----- macos/action.yml | 7 ++++--- windows/bash/action.yml | 3 ++- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/composite/action.yml b/composite/action.yml index cda1fed0..41297b7c 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -155,6 +155,7 @@ runs: id: python run: | echo '::group::Check for Python3' + # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store # command `which python3` finds that, but `python3 -V` does not return the version on stdout @@ -174,6 +175,7 @@ runs: echo "Python that creates venv: $PYTHON_BIN" echo "PYTHON_BIN=$PYTHON_BIN" >> "$GITHUB_ENV" echo "version=$("$PYTHON_BIN" -V)" >> "$GITHUB_OUTPUT" + echo '::endgroup::' shell: bash @@ -209,6 +211,7 @@ runs: PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} run: | echo '::group::Create virtualenv' + echo "Python that creates venv: $PYTHON_BIN" echo "Creating virtual environment" @@ -218,12 +221,16 @@ runs: if ! "$PYTHON_BIN" -m pip install $PIP_OPTIONS virtualenv && [ -n "$PIP_OPTIONS" ] then echo "Installing virtualenv package with PIP options '$PIP_OPTIONS' failed, now trying without" - "$PYTHON_BIN" -m pip install virtualenv + if ! "$PYTHON_BIN" -m pip install virtualenv + then + echo "::error::Installing virtualenv package failed" + exit 1 + fi fi if ! "$PYTHON_BIN" -m virtualenv enricomi-publish-action-venv then - echo "Still cannot create venv after installing virtualenv package" + echo "::error::Cannot create venv after installing virtualenv package" exit 1 fi fi @@ -238,15 +245,18 @@ runs: PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" + echo '::endgroup::' shell: bash - name: Install Python dependencies run: | echo '::group::Install Python dependencies' + # make sure wheel is installed, which improves installing our dependencies "$PYTHON_VENV" -m pip install wheel "$PYTHON_VENV" -m pip install -r "$GITHUB_ACTION_PATH/../python/requirements.txt" + echo '::endgroup::' shell: bash diff --git a/linux/action.yml b/linux/action.yml index 1bbeb392..c5060c46 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -156,8 +156,6 @@ runs: run: | echo '::group::Check for Python3' - echo "GITHUB_ACTION_PATH: $GITHUB_ACTION_PATH" - # we check version here just to execute `python3` with an argument # on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store # command `which python3` finds that, but `python3 -V` does not return the version on stdout @@ -186,7 +184,7 @@ runs: id: cache continue-on-error: true with: - path: ~/.cache/pip + path: '~/.cache/pip' key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv @@ -215,7 +213,8 @@ runs: fi echo "Finding Python interpreter in venv" - PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" + PYTHON_VENV="enricomi-publish-action-venv/bin/python" + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" @@ -290,7 +289,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: ~/.cache/pip + path: '~/.cache/pip' key: ${{ steps.cache.outputs.cache-primary-key }} branding: diff --git a/macos/action.yml b/macos/action.yml index 1f7d7c82..93c0acb9 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -184,7 +184,7 @@ runs: id: cache continue-on-error: true with: - path: ~/Library/Caches/pip + path: '~/Library/Caches/pip' key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-70a313922fdbeb7398ec60313d908b11 - name: Create virtualenv @@ -213,7 +213,8 @@ runs: fi echo "Finding Python interpreter in venv" - PYTHON_VENV="$(enricomi-publish-action-venv/bin/python -c 'import sys; print(sys.executable)')" + PYTHON_VENV="enricomi-publish-action-venv/bin/python" + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" @@ -288,7 +289,7 @@ runs: if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit continue-on-error: true with: - path: ~/Library/Caches/pip + path: '~/Library/Caches/pip' key: ${{ steps.cache.outputs.cache-primary-key }} branding: diff --git a/windows/bash/action.yml b/windows/bash/action.yml index 92edbd02..5678955b 100644 --- a/windows/bash/action.yml +++ b/windows/bash/action.yml @@ -217,7 +217,8 @@ runs: fi echo "Finding Python interpreter in venv" - PYTHON_VENV="$(enricomi-publish-action-venv\\Scripts\\python -c 'import sys; print(sys.executable)')" + PYTHON_VENV="enricomi-publish-action-venv\\Scripts\\python" + PYTHON_VENV="$("$PYTHON_VENV" -c 'import sys; print(sys.executable)')" echo "Python in venv: $PYTHON_VENV" echo "PYTHON_VENV=$PYTHON_VENV" >> "$GITHUB_ENV" From e98432e3193301656f61ef1668acd27dd0756f90 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 10:54:13 +0100 Subject: [PATCH 33/42] Revert "Reduce publish space" This reverts commit afd456f40755dbd001ecea35210a767802c6385f. --- .github/workflows/publish.yml | 511 ++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2bf654ca..d742fb37 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,426 @@ on: workflow_call: jobs: + publish-dockerfile: + name: Publish Test Results (Dockerfile) + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Prepare publish action from this branch + run: | + sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml + shell: bash + + - name: Publish Test Results + id: test-results + uses: ./ + with: + check_name: Test Results (Dockerfile) + files: "artifacts/**/*.xml" + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + log_level: DEBUG + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-docker-image: + name: Publish Test Results (Docker Image ${{ matrix.arch }}) + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + security-events: write + strategy: + fail-fast: false + matrix: + arch: [amd64, arm64] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + image: tonistiigi/binfmt:latest + platforms: ${{ matrix.arch }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + id: build + uses: docker/build-push-action@v5 + with: + load: true + push: false + platforms: linux/${{ matrix.arch }} + tags: enricomi/publish-unit-test-result-action:latest + outputs: type=docker + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + if: always() + env: + INPUT_GITHUB_TOKEN: ${{ github.token }} + INPUT_CHECK_NAME: Test Results (Docker Image ${{ matrix.arch }}) + INPUT_FILES: "artifacts/**/*.xml" + INPUT_JSON_FILE: "tests.json" + INPUT_JSON_SUITE_DETAILS: true + INPUT_JSON_TEST_CASE_RESULTS: true + INPUT_REPORT_SUITE_LOGS: "any" + run: | + docker run --platform linux/${{ matrix.arch }} \ + --workdir $GITHUB_WORKSPACE \ + --rm \ + -e "INPUT_CHECK_NAME" \ + -e "INPUT_JSON_FILE" \ + -e "INPUT_JSON_SUITE_DETAILS" \ + -e "INPUT_JSON_TEST_CASE_RESULTS" \ + -e "INPUT_LOG_LEVEL" \ + -e "INPUT_ROOT_LOG_LEVEL" \ + -e "INPUT_GITHUB_TOKEN" \ + -e "INPUT_GITHUB_TOKEN_ACTOR" \ + -e "INPUT_GITHUB_RETRIES" \ + -e "INPUT_COMMIT" \ + -e "INPUT_COMMENT_TITLE" \ + -e "INPUT_COMMENT_MODE" \ + -e "INPUT_FAIL_ON" \ + -e "INPUT_ACTION_FAIL" \ + -e "INPUT_ACTION_FAIL_ON_INCONCLUSIVE" \ + -e "INPUT_FILES" \ + -e "INPUT_JUNIT_FILES" \ + -e "INPUT_NUNIT_FILES" \ + -e "INPUT_XUNIT_FILES" \ + -e "INPUT_TRX_FILES" \ + -e "INPUT_TIME_UNIT" \ + -e "INPUT_TEST_FILE_PREFIX" \ + -e "INPUT_REPORT_INDIVIDUAL_RUNS" \ + -e "INPUT_REPORT_SUITE_LOGS" \ + -e "INPUT_DEDUPLICATE_CLASSES_BY_FILE_NAME" \ + -e "INPUT_LARGE_FILES" \ + -e "INPUT_IGNORE_RUNS" \ + -e "INPUT_CHECK_RUN" \ + -e "INPUT_JOB_SUMMARY" \ + -e "INPUT_COMPARE_TO_EARLIER_COMMIT" \ + -e "INPUT_PULL_REQUEST_BUILD" \ + -e "INPUT_EVENT_FILE" \ + -e "INPUT_EVENT_NAME" \ + -e "INPUT_TEST_CHANGES_LIMIT" \ + -e "INPUT_CHECK_RUN_ANNOTATIONS" \ + -e "INPUT_CHECK_RUN_ANNOTATIONS_BRANCH" \ + -e "INPUT_SECONDS_BETWEEN_GITHUB_READS" \ + -e "INPUT_SECONDS_BETWEEN_GITHUB_WRITES" \ + -e "INPUT_SECONDARY_RATE_LIMIT_WAIT_SECONDS" \ + -e "INPUT_JSON_THOUSANDS_SEPARATOR" \ + -e "INPUT_SEARCH_PULL_REQUESTS" \ + -e "HOME" \ + -e "GITHUB_JOB" \ + -e "GITHUB_REF" \ + -e "GITHUB_SHA" \ + -e "GITHUB_REPOSITORY" \ + -e "GITHUB_REPOSITORY_OWNER" \ + -e "GITHUB_RUN_ID" \ + -e "GITHUB_RUN_NUMBER" \ + -e "GITHUB_RETENTION_DAYS" \ + -e "GITHUB_RUN_ATTEMPT" \ + -e "GITHUB_ACTOR" \ + -e "GITHUB_TRIGGERING_ACTOR" \ + -e "GITHUB_WORKFLOW" \ + -e "GITHUB_HEAD_REF" \ + -e "GITHUB_BASE_REF" \ + -e "GITHUB_EVENT_NAME" \ + -e "GITHUB_SERVER_URL" \ + -e "GITHUB_API_URL" \ + -e "GITHUB_GRAPHQL_URL" \ + -e "GITHUB_REF_NAME" \ + -e "GITHUB_REF_PROTECTED" \ + -e "GITHUB_REF_TYPE" \ + -e "GITHUB_WORKSPACE" \ + -e "GITHUB_ACTION" \ + -e "GITHUB_EVENT_PATH" \ + -e "GITHUB_ACTION_REPOSITORY" \ + -e "GITHUB_ACTION_REF" \ + -e "GITHUB_PATH" \ + -e "GITHUB_ENV" \ + -e "GITHUB_STEP_SUMMARY" \ + -e "GITHUB_STATE" \ + -e "GITHUB_OUTPUT" \ + -e "RUNNER_OS" \ + -e "RUNNER_ARCH" \ + -e "RUNNER_NAME" \ + -e "RUNNER_TOOL_CACHE" \ + -e "RUNNER_TEMP" \ + -e "RUNNER_WORKSPACE" \ + -e "ACTIONS_RUNTIME_URL" \ + -e "ACTIONS_RUNTIME_TOKEN" \ + -e "ACTIONS_CACHE_URL" \ + -e GITHUB_ACTIONS=true \ + -e CI=true \ + -v "$RUNNER_TEMP":"$RUNNER_TEMP" \ + -v "/var/run/docker.sock":"/var/run/docker.sock" \ + -v "/home/runner/work/_temp/_github_home":"/github/home" \ + -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" \ + -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" \ + -v "/home/runner/work/publish-unit-test-result-action/publish-unit-test-result-action":"$GITHUB_WORKSPACE" \ + enricomi/publish-unit-test-result-action:latest + shell: bash + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + - name: Scan for vulnerabilities + id: scan + uses: crazy-max/ghaction-container-scan@v3 + with: + image: enricomi/publish-unit-test-result-action:latest + dockerfile: ./Dockerfile + annotations: true + - name: Upload SARIF artifact + uses: actions/upload-artifact@v4 + with: + name: SARIF ${{ matrix.arch }} + path: ${{ steps.scan.outputs.sarif }} + - name: Upload SARIF file + if: always() && steps.scan.outputs.sarif != '' + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: ${{ steps.scan.outputs.sarif }} + + publish-linux: + name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 2 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + include: + - os: ubuntu-latest + os-label: Linux + python: "3.8" + - os: ubuntu-latest + os-label: Linux + python: "venv" + - os: ubuntu-latest + os-label: Linux + python: "installed" + - os: ubuntu-20.04 + os-label: Linux 20.04 + python: "installed" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./linux + with: + check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts/**/*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-macos: + name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 2 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + include: + - os: macos-latest + os-label: macOS + python: "3.8" + - os: macos-latest + os-label: macOS + python: "venv" + - os: macos-latest + os-label: macOS + python: "installed" + - os: macos-11 + os-label: macOS 11 + python: "installed" + - os: macos-13 + os-label: macOS 13 + python: "installed" + - os: macos-14 + os-label: macOS 14 + python: "installed" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./macos + with: + check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts/**/*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-windows: + name: Publish Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + runs-on: ${{ matrix.os }} + permissions: + checks: write + pull-requests: write + + strategy: + fail-fast: false + max-parallel: 2 + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + include: + - os: windows-latest + os-label: Windows + python: "installed" + - os: windows-latest + os-label: Windows + python: "venv" + - os: windows-2019 + os-label: Windows 2019 + python: "installed" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + if: matrix.python != 'installed' && matrix.python != 'venv' + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Install virtualenv + if: matrix.python == 'venv' + run: python3 -m pip install virtualenv + shell: bash + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Publish Test Results + id: test-results + uses: ./windows + with: + check_name: Test Results (${{ matrix.os-label }} python ${{ matrix.python }}) + files: artifacts\**\*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + - name: Publish Test Results (Bash) + id: test-results-bash + uses: ./windows/bash + with: + check_name: Test Results (${{ matrix.os-label }} bash python ${{ matrix.python }}) + files: artifacts\**\*.xml + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + + - name: JSON output (Bash) + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results-bash.outputs.json }}' + json_file: 'tests.json' + publish-composite: name: Publish Test Results (${{ matrix.os-label }} composite) runs-on: ${{ matrix.os }} @@ -18,9 +438,15 @@ jobs: # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources # test *-latest and newer (because newer eventually become 'latest' and should be tested to work before that) include: + - os: macos-latest + os-label: macOS + python: "installed" - os: ubuntu-latest os-label: Linux python: "installed" + - os: windows-latest + os-label: Windows + python: "installed" steps: - name: Checkout @@ -60,3 +486,88 @@ jobs: with: json: '${{ steps.test-results.outputs.json }}' json_file: 'tests.json' + + publish-test-files: + name: Publish Test Files + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Copy test result files + run: cp -rv python/test/files test-files + shell: bash + + - name: Prepare publish action from this branch + run: | + sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml + shell: bash + + - name: Publish Test Results + id: test-results + uses: ./ + with: + check_name: Test Results (Test Files) + fail_on: nothing + files: | + test-files/**/*.xml + test-files/**/*.trx + test-files/**/*.json + junit_files: "test-files/junit-xml/**/*.xml" + nunit_files: "test-files/nunit/**/*.xml" + xunit_files: "test-files/xunit/**/*.xml" + trx_files: "test-files/trx/**/*.trx" + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + log_level: DEBUG + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' + + publish-test-file: + name: Publish Test File + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Copy test junit xml files + run: cp -rv python/test/files/junit-xml test-files + shell: bash + + - name: Prepare publish action from this branch + run: | + sed --in-place "s/image: .*/image: 'Dockerfile'/" action.yml + shell: bash + + - name: Publish Test Results + id: test-results + uses: ./ + with: + check_name: Test Results (Test File) + fail_on: nothing + files: "test-files/pytest/junit.gloo.standalone.xml" + json_file: "tests.json" + json_suite_details: true + json_test_case_results: true + report_suite_logs: "any" + log_level: DEBUG + + - name: JSON output + uses: ./misc/action/json-output + with: + json: '${{ steps.test-results.outputs.json }}' + json_file: 'tests.json' From db278d74e30ed5d5221e767ddcb3180b589ee1f7 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 11:19:03 +0100 Subject: [PATCH 34/42] Fix composite action test --- python/test/test_action_yml.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/python/test/test_action_yml.py b/python/test/test_action_yml.py index 58760c37..c99338c7 100644 --- a/python/test/test_action_yml.py +++ b/python/test/test_action_yml.py @@ -65,22 +65,11 @@ def do_test_composite_action(self, action: str): for key in list(composite_action.get('inputs', {}).keys()) + extra_inputs} steps = composite_action.get('runs', {}).get('steps', []) - if action == 'composite': - # the 'composite' composite action is just a proxy to the os-specific actions, it forwards inputs via 'with' - steps = [step for step in steps - if 'name' in step - and step.get('name').startswith('Run') - and step.get('name') != 'Run on unsupported Operating System'] - inputs_key = 'with' - else: - # the other composite actions forward inputs via env - steps = [step for step in steps if step.get('name') == 'Publish Test Results'] - inputs_key = 'env' - + steps = [step for step in steps if step.get('name') == 'Publish Test Results'] self.assertTrue(len(steps) > 0) for step in steps: - self.assertIn(inputs_key, step, step.get('name')) - inputs = {key.upper(): value for key, value in step.get(inputs_key, {}).items()} + self.assertIn('env', step, step.get('name')) + inputs = {key.upper(): value for key, value in step.get('env', {}).items()} self.assertEqual(expected, inputs) # the 'composite' composite action is just a proxy to the os-specific actions, so there is no caching From 2eea82296a33320fb28c54eab5d6ce44d385acd4 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 11:20:01 +0100 Subject: [PATCH 35/42] Revert "Reduce test space" This reverts commit 5a87324ca1ab27b9110630e14be2e64a0bd9976e. --- .github/workflows/ci-cd.yml | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 03454caa..f8c3b568 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -30,17 +30,42 @@ jobs: .github/upgrade-pip-packages.sh shell: bash + test-mac: + name: "Test macOS" + uses: "./.github/workflows/test-os.yml" + with: + os: '["macos-11", "macos-12", "macos-13", "macos-14"]' + python-version: '["3.10", "3.11", "3.12", "installed"]' + include: > + [ + {"os": "macos-11", "python-version": "3.7"}, + {"os": "macos-11", "python-version": "3.8"}, + {"os": "macos-11", "python-version": "3.9"}, + {"os": "macos-12", "python-version": "3.8"}, + {"os": "macos-12", "python-version": "3.9"}, + {"os": "macos-13", "python-version": "3.8"}, + {"os": "macos-13", "python-version": "3.9"}, + ] + test-lnx: name: "Test Ubuntu" uses: "./.github/workflows/test-os.yml" with: - os: '["ubuntu-20.04"]' - python-version: '["3.8"]' - include: '[]' + os: '["ubuntu-20.04", "ubuntu-22.04"]' + python-version: '["3.8", "3.9", "3.10", "3.11", "3.12", "installed"]' + include: '[{"os": "ubuntu-20.04", "python-version": "3.7"}]' + + test-win: + name: "Test Windows" + uses: "./.github/workflows/test-os.yml" + with: + os: '["windows-2019", "windows-2022"]' + python-version: '["3.8", "3.9", "3.10", "3.11", "3.12", "installed"]' + include: '[{"os": "windows-2019", "python-version": "3.7"}]' publish: name: "Publish" - needs: [test-lnx] + needs: [test-mac, test-lnx, test-win] # we run the action from this branch whenever we can (when it runs in our repo's context) if: > ! cancelled() && @@ -54,7 +79,7 @@ jobs: config-deploy: name: Configure Deployment - needs: [test-lnx] + needs: [test-mac, test-lnx, test-win] # do not build or deploy on forked repositories if: github.repository_owner == 'EnricoMi' runs-on: ubuntu-latest From 20929ed8c54ddb6af133384f2358f8460f2d4b40 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 11:25:38 +0100 Subject: [PATCH 36/42] Remove redundant composite/proxy.sh --- composite/proxy.sh | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100755 composite/proxy.sh diff --git a/composite/proxy.sh b/composite/proxy.sh deleted file mode 100755 index 6789d195..00000000 --- a/composite/proxy.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -case "$RUNNER_OS" in - Linux*) - action="linux" - ;; - macOS*) - action="macos" - ;; - Windows*) - action="windows/bash" - ;; - *) - echo "::error::Unsupported operating system: $RUNNER_OS" - exit 1 - ;; -esac - -in_runs=false -in_check=false -in_run=false -in_cleanup=false - -while IFS= read -r line -do - if [ "$line" == "runs:" ]; then in_runs=true - elif [ $in_runs == true ] && [[ "$line" == *"- name: Check OS" ]]; then in_check=true - elif [ $in_runs == true ] && [[ "$line" == *"- name: Run" ]]; then in_check=false; in_run=true - elif [ $in_runs == true ] && [[ "$line" == *"- name: Clean up" ]]; then in_run=false; in_cleanup=true - elif [ "$line" == "branding:" ]; then in_cleanup=false - fi - - if [ $in_run == true ] && [[ "$line" == *" uses: "* ]]; then - # use $action in uses: ... - echo "${line/%:*/: ./enricomi-publish-action-proxy/$action}" - elif [ $in_check != true ] && [ $in_cleanup != true ] && ( [ $in_run != true ] || [[ "$line" != *" if:"* ]] ); then - echo "$line" - fi -done < "$GITHUB_ACTION_PATH/action.yml" From 65a3238500a5777855f1dc2225601aaea4c344f7 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 11:44:31 +0100 Subject: [PATCH 37/42] Remove redundant steps from publish-composite job --- .github/workflows/publish.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d742fb37..030f9dea 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -440,29 +440,15 @@ jobs: include: - os: macos-latest os-label: macOS - python: "installed" - os: ubuntu-latest os-label: Linux - python: "installed" - os: windows-latest os-label: Windows - python: "installed" steps: - name: Checkout uses: actions/checkout@v4 - - name: Setup Python - if: matrix.python != 'installed' && matrix.python != 'venv' - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Install virtualenv - if: matrix.python == 'venv' - run: python3 -m pip install virtualenv - shell: bash - - name: Download Artifacts uses: actions/download-artifact@v4 with: From ab47cbd0fd03164bea81ece0ae58049717d30f14 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 11:54:34 +0100 Subject: [PATCH 38/42] Replace mentioning of 'composite' with 'non-Docker' --- README.md | 24 ++++++++++++++---------- action.yml | 2 +- composite/action.yml | 2 +- linux/action.yml | 2 +- macos/action.yml | 2 +- windows/action.yml | 2 +- windows/bash/action.yml | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 89b56f11..dcee5330 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ publishes the results on GitHub. It supports [JSON (Dart, Mocha), TRX (MSTest, V and runs on Linux, macOS and Windows. You can use this action with ![Ubuntu Linux](misc/badge-ubuntu.svg) runners (e.g. `runs-on: ubuntu-latest`) -or ![ARM Linux](misc/badge-arm.svg) self-hosted runners: +or ![ARM Linux](misc/badge-arm.svg) self-hosted runners that support Docker: ```yaml - name: Publish Test Results @@ -72,7 +72,7 @@ For **self-hosted** Linux GitHub Actions runners **without Docker** installed, p test-results/**/*.json ``` -See the [notes on running this action as a composite action](#running-as-a-composite-action) if you run it on Windows or macOS. +See the [notes on running this action as a non-Docker action](#running-as-a-non-docker-action). If you see the `"Resource not accessible by integration"` error, you have to grant additional [permissions](#permissions), or [setup the support for pull requests from fork repositories and branches created by Dependabot](#support-fork-repositories-and-dependabot-branches). @@ -295,7 +295,7 @@ The list of most notable options: |Option|Default Value|Description| |:-----|:-----:|:----------| -|`files`|_no default_|File patterns of test result files. Relative paths are known to work best, while the composite action [also works with absolute paths](#running-with-absolute-paths). Supports `*`, `**`, `?`, and `[]` character ranges. Use multiline string for multiple patterns. Patterns starting with `!` exclude the matching files. There have to be at least one pattern starting without a `!`.| +|`files`|_no default_|File patterns of test result files. Relative paths are known to work best, while the non-Docker action [also works with absolute paths](#running-with-absolute-paths). Supports `*`, `**`, `?`, and `[]` character ranges. Use multiline string for multiple patterns. Patterns starting with `!` exclude the matching files. There have to be at least one pattern starting without a `!`.| |`check_name`|`"Test Results"`|An alternative name for the check result. Required to be unique for each instance in one workflow.| |`comment_title`|same as `check_name`|An alternative name for the pull request comment.| |`comment_mode`|`always`|The action posts comments to pull requests that are associated with the commit. Set to:
`always` - always comment
`changes` - comment when changes w.r.t. the target branch exist
`changes in failures` - when changes in the number of failures and errors exist
`changes in errors` - when changes in the number of (only) errors exist
`failures` - when failures or errors exist
`errors` - when (only) errors exist
`off` - to not create pull request comments.| @@ -805,10 +805,14 @@ You can then use the badge via this URL: https://gist.githubusercontent.com/{use ## Running with absolute paths It is known that this action works best with relative paths (e.g. `test-results/**/*.xml`), -but most absolute paths (e.g. `/tmp/test-results/**/*.xml`) require to use the composite variant -of this action (`uses: EnricoMi/publish-unit-test-result-action/composite@v2`). +but most absolute paths (e.g. `/tmp/test-results/**/*.xml`) require to use the non-Docker variant +of this action: -If you have to use absolute paths with the non-composite variant of this action (`uses: EnricoMi/publish-unit-test-result-action@v2`), + uses: EnricoMi/publish-unit-test-result-action/linux@v2 + uses: EnricoMi/publish-unit-test-result-action/macos@v2 + uses: EnricoMi/publish-unit-test-result-action/windows@v2 + +If you have to use absolute paths with the Docker variant of this action (`uses: EnricoMi/publish-unit-test-result-action@v2`), you have to copy files to a relative path first, and then use the relative path: ```yaml @@ -828,17 +832,17 @@ you have to copy files to a relative path first, and then use the relative path: test-results/**/*.json ``` -Using the non-composite variant of this action is recommended as it starts up much quicker. +Using the Docker variant of this action is recommended as it starts up much quicker. -## Running as a composite action +## Running as a non-Docker action -Running this action as a composite action allows to run it on self-hosted runners that do not provide Docker: +Running this action as below allows to run it on self-hosted runners that do not provide Docker: uses: EnricoMi/publish-unit-test-result-action/linux@v2 uses: EnricoMi/publish-unit-test-result-action/macos@v2 uses: EnricoMi/publish-unit-test-result-action/windows@v2 -The composite action, however, requires a Python3 environment to be setup on the action runner. +These actions, however, require a Python3 environment to be setup on the action runner. All GitHub-hosted runners (Ubuntu, Windows Server and macOS) provide a suitable Python3 environment out-of-the-box. Self-hosted runners may require setting up a Python environment first: diff --git a/action.yml b/action.yml index 8faeb8ec..4d5e35f6 100644 --- a/action.yml +++ b/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' diff --git a/composite/action.yml b/composite/action.yml index 41297b7c..a4f731c6 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' diff --git a/linux/action.yml b/linux/action.yml index c5060c46..8dbd565f 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' diff --git a/macos/action.yml b/macos/action.yml index 93c0acb9..d5691830 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' diff --git a/windows/action.yml b/windows/action.yml index a316db48..e8324695 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' diff --git a/windows/bash/action.yml b/windows/bash/action.yml index 5678955b..b0382e14 100644 --- a/windows/bash/action.yml +++ b/windows/bash/action.yml @@ -42,7 +42,7 @@ inputs: default: 'false' required: false files: - description: 'File patterns of test result files. Relative paths are known to work best, while the composite action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' + description: 'File patterns of test result files. Relative paths are known to work best, while the non-Docker action also works with absolute paths. Supports "*", "**", "?", and "[]" character ranges. Use multiline string for multiple patterns. Patterns starting with "!" exclude the matching files. There have to be at least one pattern starting without a "!".' required: false junit_files: description: 'Deprecated, use "files" option instead.' From 7afc3cdcad82ef7081b6daa70664ac4c77dfef13 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 12:00:25 +0100 Subject: [PATCH 39/42] Deprecate composite action --- composite/action.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/composite/action.yml b/composite/action.yml index a4f731c6..16bcc6e4 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -151,6 +151,17 @@ outputs: runs: using: 'composite' steps: + - name: Deprecation warning + run: | + # Print deprecation warning + echo "::warning::Running this action via 'uses: EnricoMi/publish-unit-test-result-action/composite@v2 is deprecated!" + echo "::warning::Please use an action appropriate for your operating system and shell:" + echo "::warning::- Linux (Bash shell): EnricoMi/publish-unit-test-result-action/linux@v2" + echo "::warning::- macOS (Bash shell): EnricoMi/publish-unit-test-result-action/macos@v2" + echo "::warning::- Windows (PowerShell): EnricoMi/publish-unit-test-result-action/windows@v2" + echo "::warning::- Windows (Bash shell): EnricoMi/publish-unit-test-result-action/windows/bash@v2" + shell: bash + - name: Check for Python3 id: python run: | From c1155fe5c7c12afd03f928c75713232abcfe65f6 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 12:51:50 +0100 Subject: [PATCH 40/42] Reduce deprecation warning to single line, link to readme --- README.md | 17 +++++++++++++++-- composite/action.yml | 7 +------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dcee5330..02a3d625 100644 --- a/README.md +++ b/README.md @@ -836,7 +836,7 @@ Using the Docker variant of this action is recommended as it starts up much quic ## Running as a non-Docker action -Running this action as below allows to run it on self-hosted runners that do not provide Docker: +Running this action as below allows to run it on action runners that do not provide Docker: uses: EnricoMi/publish-unit-test-result-action/linux@v2 uses: EnricoMi/publish-unit-test-result-action/macos@v2 @@ -854,4 +854,17 @@ Self-hosted runners may require setting up a Python environment first: python-version: 3.8 ``` -Start-up of the action is faster with `virtualenv` or `venv`, as well as `wheel` packages installed. +Start-up of the action is faster with `virtualenv` or `venv`, as well as `wheel` packages are installed. + +## Running as a composite action + +Running this action via: + + uses: EnricoMi/publish-unit-test-result-action/composite@v2 + +is **deprecated**, please use an action appropriate for your operating system and shell: + +- Linux (Bash shell): `uses: EnricoMi/publish-unit-test-result-action/linux@v2` +- macOS (Bash shell): `uses: EnricoMi/publish-unit-test-result-action/macos@v2` +- Windows (PowerShell): `uses: EnricoMi/publish-unit-test-result-action/windows@v2` +- Windows (Bash shell): `uses: EnricoMi/publish-unit-test-result-action/windows/bash@v2` diff --git a/composite/action.yml b/composite/action.yml index 16bcc6e4..e1796600 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -154,12 +154,7 @@ runs: - name: Deprecation warning run: | # Print deprecation warning - echo "::warning::Running this action via 'uses: EnricoMi/publish-unit-test-result-action/composite@v2 is deprecated!" - echo "::warning::Please use an action appropriate for your operating system and shell:" - echo "::warning::- Linux (Bash shell): EnricoMi/publish-unit-test-result-action/linux@v2" - echo "::warning::- macOS (Bash shell): EnricoMi/publish-unit-test-result-action/macos@v2" - echo "::warning::- Windows (PowerShell): EnricoMi/publish-unit-test-result-action/windows@v2" - echo "::warning::- Windows (Bash shell): EnricoMi/publish-unit-test-result-action/windows/bash@v2" + echo "::warning::Running this action via 'uses: EnricoMi/publish-unit-test-result-action/composite@v2 is deprecated! For details, see: https://github.com/EnricoMi/publish-unit-test-result-action/tree/v2#running-as-a-composite-action" shell: bash - name: Check for Python3 From 62d3b4f98b5969d6c47995a0dfd6bd79695eac93 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 22:21:10 +0100 Subject: [PATCH 41/42] Link in readme from composite to non-Docker section --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 02a3d625..4604b6a0 100644 --- a/README.md +++ b/README.md @@ -868,3 +868,5 @@ is **deprecated**, please use an action appropriate for your operating system an - macOS (Bash shell): `uses: EnricoMi/publish-unit-test-result-action/macos@v2` - Windows (PowerShell): `uses: EnricoMi/publish-unit-test-result-action/windows@v2` - Windows (Bash shell): `uses: EnricoMi/publish-unit-test-result-action/windows/bash@v2` + +These are non-Docker variations of this action. For details, see section ["Running as a non-Docker action"](#running-as-a-non-docker-action) above. From dff220b47efda9bcf979964298b50111abec39a5 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Sat, 24 Feb 2024 22:22:30 +0100 Subject: [PATCH 42/42] Beautify logs --- composite/action.yml | 5 +++++ linux/action.yml | 4 ++++ macos/action.yml | 4 ++++ windows/action.yml | 4 ++++ windows/bash/action.yml | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/composite/action.yml b/composite/action.yml index e1796600..e16c0ad5 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -160,6 +160,7 @@ runs: - name: Check for Python3 id: python run: | + # Check for Python3 echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument @@ -188,6 +189,7 @@ runs: - name: Detect OS id: os run: | + # Detect OS case "$RUNNER_OS" in Linux*) echo "pip-cache=~/.cache/pip" >> "$GITHUB_OUTPUT" @@ -216,6 +218,7 @@ runs: env: PIP_OPTIONS: ${{ steps.os.outputs.pip-options }} run: | + # Create virtualenv echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -257,6 +260,7 @@ runs: - name: Install Python dependencies run: | + # Install Python dependencies echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies @@ -269,6 +273,7 @@ runs: - name: Publish Test Results id: test-results run: | + # Publish Test Results echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" echo '::endgroup::' diff --git a/linux/action.yml b/linux/action.yml index 8dbd565f..b57869a5 100644 --- a/linux/action.yml +++ b/linux/action.yml @@ -154,6 +154,7 @@ runs: - name: Check for Python3 id: python run: | + # Check for Python3 echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument @@ -191,6 +192,7 @@ runs: id: venv continue-on-error: true run: | + # Create virtualenv echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -223,6 +225,7 @@ runs: - name: Install Python dependencies run: | + # Install Python dependencies echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies @@ -235,6 +238,7 @@ runs: - name: Publish Test Results id: test-results run: | + # Publish Test Results echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" echo '::endgroup::' diff --git a/macos/action.yml b/macos/action.yml index d5691830..439d7891 100644 --- a/macos/action.yml +++ b/macos/action.yml @@ -154,6 +154,7 @@ runs: - name: Check for Python3 id: python run: | + # Check for Python3 echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument @@ -191,6 +192,7 @@ runs: id: venv continue-on-error: true run: | + # Create virtualenv echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -223,6 +225,7 @@ runs: - name: Install Python dependencies run: | + # Install Python dependencies echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies @@ -235,6 +238,7 @@ runs: - name: Publish Test Results id: test-results run: | + # Publish Test Results echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../python/publish_test_results.py" echo '::endgroup::' diff --git a/windows/action.yml b/windows/action.yml index e8324695..c04b810d 100644 --- a/windows/action.yml +++ b/windows/action.yml @@ -154,6 +154,7 @@ runs: - name: Check for Python3 id: python run: | + # Check for Python3 Write-Output "::group::Check for Python3" try { # we check version here just to execute `python3` with an argument @@ -192,6 +193,7 @@ runs: id: venv continue-on-error: true run: | + # Create virtualenv Write-Output "::group::Create virtualenv" try { Write-Output "Python that creates venv: $env:PYTHON_BIN" @@ -224,6 +226,7 @@ runs: - name: Install Python dependencies run: | + # Install Python dependencies Write-Output "::group::Install Python dependencies" try { # make sure wheel is installed, which improves installing our dependencies @@ -237,6 +240,7 @@ runs: - name: Publish Test Results id: test-results run: | + # Publish Test Results Write-Output "::group::Publish Test Results" try { Invoke-Expression -Command "& '$env:PYTHON_VENV' '$env:GITHUB_ACTION_PATH\..\python\publish_test_results.py'" diff --git a/windows/bash/action.yml b/windows/bash/action.yml index b0382e14..77925df4 100644 --- a/windows/bash/action.yml +++ b/windows/bash/action.yml @@ -154,6 +154,7 @@ runs: - name: Check for Python3 id: python run: | + # Check for Python3 echo '::group::Check for Python3' # we check version here just to execute `python3` with an argument @@ -191,6 +192,7 @@ runs: id: venv continue-on-error: true run: | + # Create virtualenv echo '::group::Create virtualenv' echo "Python that creates venv: $PYTHON_BIN" @@ -227,6 +229,7 @@ runs: - name: Install Python dependencies run: | + # Install Python dependencies echo '::group::Install Python dependencies' # make sure wheel is installed, which improves installing our dependencies @@ -239,6 +242,7 @@ runs: - name: Publish Test Results id: test-results run: | + # Publish Test Results echo '::group::Publish Test Results' "$PYTHON_VENV" "$GITHUB_ACTION_PATH/../../python/publish_test_results.py" echo '::endgroup::'