Skip to content

Commit 4b9dbee

Browse files
committed
Add powershell variant for Windows
1 parent 170bf24 commit 4b9dbee

File tree

1 file changed

+312
-0
lines changed

1 file changed

+312
-0
lines changed

windows/powershell/action.yml

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
name: 'Publish Test Results'
2+
author: 'EnricoMi'
3+
description: 'Publishes JUnit, NUnit, XUnit, TRX, JSON test results on GitHub for .NET, Dart, Java, JS, Jest, Mocha, Python, Scala, …'
4+
5+
inputs:
6+
github_token:
7+
description: 'GitHub API Access Token.'
8+
default: ${{ github.token }}
9+
required: false
10+
github_token_actor:
11+
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".'
12+
default: 'github-actions'
13+
required: false
14+
github_retries:
15+
description: 'Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.'
16+
default: '10'
17+
required: false
18+
commit:
19+
description: 'Commit SHA to which test results are published. Only needed if the value of GITHUB_SHA does not work for you.'
20+
required: false
21+
check_name:
22+
description: 'Name of the created check run.'
23+
default: 'Test Results'
24+
required: false
25+
comment_title:
26+
description: 'An alternative title for the pull request comment. Defaults to value of check_name input.'
27+
required: false
28+
comment_mode:
29+
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.'
30+
default: 'always'
31+
required: false
32+
fail_on:
33+
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".'
34+
default: 'test failures'
35+
required: false
36+
action_fail:
37+
description: 'When set "true", the action itself fails when tests have failed (see option fail_on).'
38+
default: 'false'
39+
required: false
40+
action_fail_on_inconclusive:
41+
description: 'When set "true", the action itself fails when tests are inconclusive (no test results).'
42+
default: 'false'
43+
required: false
44+
files:
45+
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 "!".'
46+
required: false
47+
junit_files:
48+
description: 'Deprecated, use "files" option instead.'
49+
required: false
50+
nunit_files:
51+
description: 'Deprecated, use "files" option instead.'
52+
required: false
53+
xunit_files:
54+
description: 'Deprecated, use "files" option instead.'
55+
required: false
56+
trx_files:
57+
description: 'Deprecated, use "files" option instead.'
58+
required: false
59+
time_unit:
60+
description: 'Time values in the test result files have this unit. Supports "seconds" and "milliseconds".'
61+
default: 'seconds'
62+
required: false
63+
test_file_prefix:
64+
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".'
65+
required: false
66+
report_individual_runs:
67+
description: 'Individual runs of the same test may see different failures. Reports all individual failures when set "true" or the first only otherwise.'
68+
required: false
69+
report_suite_logs:
70+
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".'
71+
default: 'none'
72+
required: false
73+
deduplicate_classes_by_file_name:
74+
description: 'De-duplicates classes with same name by their file name when set "true", combines test results for those classes otherwise.'
75+
required: false
76+
large_files:
77+
description: 'Support for large files is enabled when set to "true". Defaults to "false", unless ignore_runs is "true".'
78+
required: false
79+
ignore_runs:
80+
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.'
81+
default: 'false'
82+
required: false
83+
check_run:
84+
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.'
85+
default: 'true'
86+
required: false
87+
job_summary:
88+
description: 'Set to "true", the results are published as part of the job summary page of the workflow run.'
89+
default: 'true'
90+
required: false
91+
compare_to_earlier_commit:
92+
description: 'Test results are compared to results of earlier commits to highlight changes: "false" - disable comparison, "true" - compare across commits.'
93+
default: 'true'
94+
required: false
95+
pull_request_build:
96+
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".'
97+
default: 'merge'
98+
required: false
99+
event_file:
100+
description: 'An alternative event file to use. Useful to replace a "workflow_run" event file with the actual source event file.'
101+
required: false
102+
event_name:
103+
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.'
104+
required: false
105+
test_changes_limit:
106+
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.'
107+
required: false
108+
check_run_annotations:
109+
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.'
110+
default: 'all tests, skipped tests'
111+
required: false
112+
check_run_annotations_branch:
113+
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".'
114+
required: false
115+
seconds_between_github_reads:
116+
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.'
117+
default: '0.25'
118+
required: false
119+
seconds_between_github_writes:
120+
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.'
121+
default: '2.0'
122+
required: false
123+
secondary_rate_limit_wait_seconds:
124+
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).'
125+
required: false
126+
json_file:
127+
description: 'Results are written to this JSON file.'
128+
required: false
129+
json_thousands_separator:
130+
description: 'Formatted numbers in JSON use this character to separate groups of thousands. Common values are "," or ".". Defaults to punctuation space (\u2008).'
131+
default: ''
132+
required: false
133+
json_suite_details:
134+
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".'
135+
default: 'false'
136+
required: false
137+
json_test_case_results:
138+
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".'
139+
default: 'false'
140+
required: false
141+
search_pull_requests:
142+
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".'
143+
default: 'false'
144+
required: false
145+
146+
outputs:
147+
json:
148+
description: "Test results as JSON"
149+
value: ${{ steps.test-results.outputs.json }}
150+
151+
runs:
152+
using: 'composite'
153+
steps:
154+
- name: Check for Python3
155+
id: python
156+
run: |
157+
# Check for Python3
158+
Write-Output "::group::Check for Python3"
159+
try {
160+
# we check version here just to execute `python3` with an argument
161+
# on Windows, there is a `python3.exe` that is a proxy to trigger installation from app store
162+
# command `which python3` finds that, but `python3 -V` does not return the version on stdout
163+
if ( !(Get-Command python3 -ErrorAction SilentlyContinue) -Or -Not ((python3 -V 2> $null) -Like "Python 3.*") ) {
164+
if ( !(Get-Command python -ErrorAction SilentlyContinue) -Or -Not ((python -V 2> $null) -Like "Python 3.*") ) {
165+
Write-Output "::error::No python3 interpreter found. Please setup python before running this action. You could use https://github.com/actions/setup-python."
166+
Exit 1
167+
}
168+
169+
$PYTHON_BIN = python -c "import sys; print(sys.executable)"
170+
} else {
171+
$PYTHON_BIN = python3 -c "import sys; print(sys.executable)"
172+
}
173+
Write-Output "Python that creates venv: $PYTHON_BIN"
174+
"PYTHON_BIN=$PYTHON_BIN" | Out-File -FilePath $env:GITHUB_ENV -Append
175+
176+
$PYTHON_VERSION = Invoke-Expression -Command "& '$PYTHON_BIN' -c 'import sys; print(sys.version_info.major, sys.version_info.minor, sep=chr(46))'"
177+
Write-Output "Python version: $PYTHON_VERSION"
178+
179+
if ( $PYTHON_VERSION -eq "3.7" ) {
180+
"DEPENDENCIES_VERSION=3.7" | Out-File -FilePath $env:GITHUB_ENV -Append
181+
} elseif ( $PYTHON_VERSION -eq "3.8" ) {
182+
"DEPENDENCIES_VERSION=3.8" | Out-File -FilePath $env:GITHUB_ENV -Append
183+
} else {
184+
"DEPENDENCIES_VERSION=post-3.8" | Out-File -FilePath $env:GITHUB_ENV -Append
185+
}
186+
"version=$PYTHON_VERSION" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
187+
} finally {
188+
Write-Output "::endgroup::"
189+
}
190+
shell: powershell
191+
192+
- name: Restore PIP packages cache
193+
uses: actions/cache/restore@v4
194+
id: cache
195+
continue-on-error: true
196+
with:
197+
path: '~\AppData\Local\pip\Cache'
198+
key: enricomi-publish-action-${{ runner.os }}-${{ runner.arch }}-pip-${{ steps.python.outputs.version }}-b0048519e3287ae9cfc634aeda40cbfe
199+
200+
- name: Create virtualenv
201+
id: venv
202+
continue-on-error: true
203+
run: |
204+
# Create virtualenv
205+
Write-Output "::group::Create virtualenv"
206+
try {
207+
Write-Output "Python that creates venv: $env:PYTHON_BIN"
208+
209+
Write-Output "Creating virtual environment"
210+
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) ) {
211+
Write-Output "Looks like there is neither virtualenv nor venv package installed"
212+
if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m pip install --user virtualenv" 2> $null) ) {
213+
Write-Output "Installing virtualenv package with PIP option '--user' failed, now trying without"
214+
if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m pip install virtualenv" 2> $null) ) {
215+
Write-Output "::error::Installing virtualenv package failed"
216+
Exit 1
217+
}
218+
}
219+
220+
if ( -Not (Invoke-Expression -Command "& '$env:PYTHON_BIN' -m virtualenv enricomi-publish-action-venv" 2> $null) ) {
221+
Write-Output "::error::Cannot create venv after installing virtualenv package"
222+
Exit 1
223+
}
224+
}
225+
226+
Write-Output "Finding Python interpreter in venv"
227+
$PYTHON_VENV = enricomi-publish-action-venv\Scripts\python -c "import sys; print(sys.executable)"
228+
Write-Output "Python in venv: $PYTHON_VENV"
229+
"PYTHON_VENV=$PYTHON_VENV" | Out-File -FilePath $env:GITHUB_ENV -Append
230+
} finally {
231+
Write-Output "::endgroup::"
232+
}
233+
shell: powershell
234+
235+
- name: Install Python dependencies
236+
run: |
237+
# Install Python dependencies
238+
Write-Output "::group::Install Python dependencies"
239+
try {
240+
Invoke-Expression -Command "& '$env:PYTHON_VENV' -m pip install -r '$env:GITHUB_ACTION_PATH\..\python\requirements-$env:DEPENDENCIES_VERSION.txt'"
241+
} finally {
242+
Write-Output "::endgroup::"
243+
}
244+
shell: powershell
245+
246+
- name: Publish Test Results
247+
id: test-results
248+
run: |
249+
# Publish Test Results
250+
Write-Output "::group::Publish Test Results"
251+
try {
252+
Invoke-Expression -Command "& '$env:PYTHON_VENV' '$env:GITHUB_ACTION_PATH\..\python\publish_test_results.py'"
253+
} finally {
254+
Write-Output "::endgroup::"
255+
}
256+
env:
257+
GITHUB_TOKEN: ${{ inputs.github_token }}
258+
GITHUB_TOKEN_ACTOR: ${{ inputs.github_token_actor }}
259+
GITHUB_RETRIES: ${{ inputs.github_retries }}
260+
COMMIT: ${{ inputs.commit }}
261+
CHECK_NAME: ${{ inputs.check_name }}
262+
COMMENT_TITLE: ${{ inputs.comment_title }}
263+
COMMENT_MODE: ${{ inputs.comment_mode }}
264+
FAIL_ON: ${{ inputs.fail_on }}
265+
ACTION_FAIL: ${{ inputs.action_fail }}
266+
ACTION_FAIL_ON_INCONCLUSIVE: ${{ inputs.action_fail_on_inconclusive }}
267+
FILES: ${{ inputs.files }}
268+
JUNIT_FILES: ${{ inputs.junit_files }}
269+
NUNIT_FILES: ${{ inputs.nunit_files }}
270+
XUNIT_FILES: ${{ inputs.xunit_files }}
271+
TRX_FILES: ${{ inputs.trx_files }}
272+
TIME_UNIT: ${{ inputs.time_unit }}
273+
TEST_FILE_PREFIX: ${{ inputs.test_file_prefix }}
274+
REPORT_INDIVIDUAL_RUNS: ${{ inputs.report_individual_runs }}
275+
REPORT_SUITE_LOGS: ${{ inputs.report_suite_logs }}
276+
DEDUPLICATE_CLASSES_BY_FILE_NAME: ${{ inputs.deduplicate_classes_by_file_name }}
277+
LARGE_FILES: ${{ inputs.large_files }}
278+
IGNORE_RUNS: ${{ inputs.ignore_runs }}
279+
COMPARE_TO_EARLIER_COMMIT: ${{ inputs.compare_to_earlier_commit }}
280+
PULL_REQUEST_BUILD: ${{ inputs.pull_request_build }}
281+
EVENT_FILE: ${{ inputs.event_file }}
282+
EVENT_NAME: ${{ inputs.event_name }}
283+
TEST_CHANGES_LIMIT: ${{ inputs.test_changes_limit }}
284+
CHECK_RUN_ANNOTATIONS: ${{ inputs.check_run_annotations }}
285+
CHECK_RUN_ANNOTATIONS_BRANCH: ${{ inputs.check_run_annotations_branch }}
286+
SECONDS_BETWEEN_GITHUB_READS: ${{ inputs.seconds_between_github_reads }}
287+
SECONDS_BETWEEN_GITHUB_WRITES: ${{ inputs.seconds_between_github_writes }}
288+
SECONDARY_RATE_LIMIT_WAIT_SECONDS: ${{ inputs.secondary_rate_limit_wait_seconds }}
289+
JSON_FILE: ${{ inputs.json_file }}
290+
JSON_THOUSANDS_SEPARATOR: ${{ inputs.json_thousands_separator }}
291+
JSON_SUITE_DETAILS: ${{ inputs.json_suite_details }}
292+
JSON_TEST_CASE_RESULTS: ${{ inputs.json_test_case_results }}
293+
CHECK_RUN: ${{ inputs.check_run }}
294+
JOB_SUMMARY: ${{ inputs.job_summary }}
295+
SEARCH_PULL_REQUESTS: ${{ inputs.search_pull_requests }}
296+
# not documented
297+
ROOT_LOG_LEVEL: ${{ inputs.root_log_level }}
298+
# not documented
299+
LOG_LEVEL: ${{ inputs.log_level }}
300+
shell: powershell
301+
302+
- name: Save PIP packages cache
303+
uses: actions/cache/save@v4
304+
if: ( success() || failure() ) && ! steps.cache.outputs.cache-hit
305+
continue-on-error: true
306+
with:
307+
path: '~\AppData\Local\pip\Cache'
308+
key: ${{ steps.cache.outputs.cache-primary-key }}
309+
310+
branding:
311+
icon: 'check-circle'
312+
color: 'green'

0 commit comments

Comments
 (0)