From cea614c67027fb3960f66aa821ad856bd1f3aaac Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Sat, 27 May 2023 10:53:21 +0600 Subject: [PATCH 1/8] Optional actor name --- README.md | 1 + action.yml | 4 ++++ python/publish/publisher.py | 3 ++- python/publish_test_results.py | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9036d63b..e3aea3e5 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,7 @@ The list of most notable options: |`time_unit`|`seconds`|Time values in the XML files have this unit. Supports `seconds` and `milliseconds`.| |`job_summary`|`true`| Set to `true`, the results are published as part of the [job summary page](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/) of the workflow run.| |`compare_to_earlier_commit`|`true`|Test results are compared to results of earlier commits to show changes:
`false` - disable comparison, `true` - compare across commits.'| +|`actor_name`|`github-actions`|Used to find older comment to update. Note: this does not change the bot name while commenting. If you use any other GH app, you need provide that app name here. Otherwise all your run will create a new comment.| |`test_changes_limit`|`10`|Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of `0`.| |`report_individual_runs`|`false`|Individual runs of the same test may see different failures. Reports all individual failures when set `true`, and the first failure only otherwise.| |`report_suite_logs`|`none`|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`.| diff --git a/action.yml b/action.yml index 9ba05459..58243815 100644 --- a/action.yml +++ b/action.yml @@ -37,6 +37,10 @@ inputs: description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' default: 'false' required: false + actor_name: + description: 'The name of the actor that is used for the check run. Defaults: 'github-actions'' + default: 'github-actions' + required: false files: description: 'File patterns of test result files. Supports *, **, ?, and []. 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 diff --git a/python/publish/publisher.py b/python/publish/publisher.py index dd016ead..c0ece32e 100644 --- a/python/publish/publisher.py +++ b/python/publish/publisher.py @@ -47,6 +47,7 @@ class Settings: fail_on_failures: bool action_fail: bool action_fail_on_inconclusive: bool + actor_name: str # one of these *files_glob must be set files_glob: Optional[str] junit_files_glob: Optional[str] @@ -734,7 +735,7 @@ def get_pull_request_comments(self, pull: PullRequest, order_by_updated: bool) - def get_action_comments(self, comments: List[Mapping[str, Any]], is_minimized: Optional[bool] = False): return list([comment for comment in comments - if comment.get('author', {}).get('login') == 'github-actions' + if comment.get('author', {}).get('login') == self._settings.actor_name and (is_minimized is None or comment.get('isMinimized') == is_minimized) and comment.get('body', '').startswith(f'## {self._settings.comment_title}\n') and ('\nresults for commit ' in comment.get('body') or '\nResults for commit ' in comment.get('body'))]) diff --git a/python/publish_test_results.py b/python/publish_test_results.py index dcbef7d9..9924f980 100644 --- a/python/publish_test_results.py +++ b/python/publish_test_results.py @@ -442,6 +442,7 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: annotations = get_annotations_config(options, event) suite_logs_mode = get_var('REPORT_SUITE_LOGS', options) or default_report_suite_logs ignore_runs = get_bool_var('IGNORE_RUNS', options, default=False) + actor_name = get_var('ACTOR_NAME', options) or 'github-actions' fail_on = get_var('FAIL_ON', options) or 'test failures' check_var(fail_on, 'FAIL_ON', 'Check fail mode', fail_on_modes) @@ -475,6 +476,7 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: fail_on_failures=fail_on_failures, action_fail=get_bool_var('ACTION_FAIL', options, default=False), action_fail_on_inconclusive=get_bool_var('ACTION_FAIL_ON_INCONCLUSIVE', options, default=False), + actor_name=actor_name, files_glob=get_var('FILES', options) or default_files_glob, junit_files_glob=get_var('JUNIT_FILES', options), nunit_files_glob=get_var('NUNIT_FILES', options), From f138010f286ce024adc38839c6153859818b8c8d Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Sat, 27 May 2023 11:00:09 +0600 Subject: [PATCH 2/8] Lint --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 58243815..210ec271 100644 --- a/action.yml +++ b/action.yml @@ -38,7 +38,7 @@ inputs: default: 'false' required: false actor_name: - description: 'The name of the actor that is used for the check run. Defaults: 'github-actions'' + description: 'The name of the actor that is used for the check run. Defaults: "github-actions"' default: 'github-actions' required: false files: From 7fa206c2eaa5b8c909ea78b73c2828b82b0be829 Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Sat, 27 May 2023 12:19:02 +0600 Subject: [PATCH 3/8] Update docker image --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 210ec271..5b3d344e 100644 --- a/action.yml +++ b/action.yml @@ -139,7 +139,7 @@ outputs: runs: using: 'docker' - image: 'docker://ghcr.io/enricomi/publish-unit-test-result-action:v2.7.0' + image: 'docker://ghcr.io/RafikFarhad/publish-unit-test-result-action:optional-actor-name' branding: icon: 'check-circle' From 0eb834f6092837a570b84ba6db6b7439f83d52aa Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Sat, 27 May 2023 12:22:38 +0600 Subject: [PATCH 4/8] Update docker image name case --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 5b3d344e..4c383c8a 100644 --- a/action.yml +++ b/action.yml @@ -139,7 +139,7 @@ outputs: runs: using: 'docker' - image: 'docker://ghcr.io/RafikFarhad/publish-unit-test-result-action:optional-actor-name' + image: 'docker://ghcr.io/rafikfarhad/publish-unit-test-result-action:optional-actor-name' branding: icon: 'check-circle' From 8f3482af0391dc9c80bd47b76d409a12ed72b94e Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Sat, 27 May 2023 12:42:02 +0600 Subject: [PATCH 5/8] revert action.yml image name --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 4c383c8a..210ec271 100644 --- a/action.yml +++ b/action.yml @@ -139,7 +139,7 @@ outputs: runs: using: 'docker' - image: 'docker://ghcr.io/rafikfarhad/publish-unit-test-result-action:optional-actor-name' + image: 'docker://ghcr.io/enricomi/publish-unit-test-result-action:v2.7.0' branding: icon: 'check-circle' From dcf099818f4d0f74382675dc0f7939637e5e9f4d Mon Sep 17 00:00:00 2001 From: Rafik Farhad Date: Wed, 31 May 2023 15:06:27 +0600 Subject: [PATCH 6/8] Input name change --- README.md | 2 +- action.yml | 8 ++++---- composite/action.yml | 4 ++++ python/publish/publisher.py | 4 ++-- python/publish_test_results.py | 4 ++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e3aea3e5..10b57823 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,7 @@ The list of most notable options: |:-----|:-----:|:----------| |`commit`|`${{env.GITHUB_SHA}}`|An alternative commit SHA to which test results are published. The `push` and `pull_request`events are handled, but for other [workflow events](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#push) `GITHUB_SHA` may refer to different kinds of commits. See [GitHub Workflow documentation](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows) for details.| |`github_token`|`${{github.token}}`|An alternative GitHub token, other than the default provided by GitHub Actions runner.| +|`github_actor`|`github-actions`|Used to find older comment to update. Note: this does not change the bot name while commenting. If you use any other GH app, you need provide that app name here. Otherwise all your run will create a new comment.| |`github_retries`|`10`|Requests to the GitHub API are retried this number of times. The value must be a positive integer or zero.| |`seconds_between_github_reads`|`0.25`|Sets the number of seconds the action waits between concurrent read requests to the GitHub API.| |`seconds_between_github_writes`|`2.0`|Sets the number of seconds the action waits between concurrent write requests to the GitHub API.| @@ -291,7 +292,6 @@ The list of most notable options: |`time_unit`|`seconds`|Time values in the XML files have this unit. Supports `seconds` and `milliseconds`.| |`job_summary`|`true`| Set to `true`, the results are published as part of the [job summary page](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/) of the workflow run.| |`compare_to_earlier_commit`|`true`|Test results are compared to results of earlier commits to show changes:
`false` - disable comparison, `true` - compare across commits.'| -|`actor_name`|`github-actions`|Used to find older comment to update. Note: this does not change the bot name while commenting. If you use any other GH app, you need provide that app name here. Otherwise all your run will create a new comment.| |`test_changes_limit`|`10`|Limits the number of removed or skipped tests reported on pull request comments. This report can be disabled with a value of `0`.| |`report_individual_runs`|`false`|Individual runs of the same test may see different failures. Reports all individual failures when set `true`, and the first failure only otherwise.| |`report_suite_logs`|`none`|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`.| diff --git a/action.yml b/action.yml index 210ec271..2bfd7ac9 100644 --- a/action.yml +++ b/action.yml @@ -7,6 +7,10 @@ inputs: description: 'GitHub API Access Token.' default: ${{ github.token }} required: false + github_actor: + description: 'The name of the actor that runs this action. 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' @@ -37,10 +41,6 @@ inputs: description: 'When set "true", the action itself fails when tests are inconclusive (no test results).' default: 'false' required: false - actor_name: - description: 'The name of the actor that is used for the check run. Defaults: "github-actions"' - default: 'github-actions' - required: false files: description: 'File patterns of test result files. Supports *, **, ?, and []. 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 diff --git a/composite/action.yml b/composite/action.yml index d6fee265..d5523bfc 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -7,6 +7,10 @@ inputs: description: 'GitHub API Access Token.' default: ${{ github.token }} required: false + github_actor: + description: 'The name of the actor that runs this action. 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' diff --git a/python/publish/publisher.py b/python/publish/publisher.py index c0ece32e..6684b41d 100644 --- a/python/publish/publisher.py +++ b/python/publish/publisher.py @@ -30,6 +30,7 @@ @dataclass(frozen=True) class Settings: token: str + actor: str api_url: str graphql_url: str api_retries: int @@ -47,7 +48,6 @@ class Settings: fail_on_failures: bool action_fail: bool action_fail_on_inconclusive: bool - actor_name: str # one of these *files_glob must be set files_glob: Optional[str] junit_files_glob: Optional[str] @@ -735,7 +735,7 @@ def get_pull_request_comments(self, pull: PullRequest, order_by_updated: bool) - def get_action_comments(self, comments: List[Mapping[str, Any]], is_minimized: Optional[bool] = False): return list([comment for comment in comments - if comment.get('author', {}).get('login') == self._settings.actor_name + if comment.get('author', {}).get('login') == self._settings.actor and (is_minimized is None or comment.get('isMinimized') == is_minimized) and comment.get('body', '').startswith(f'## {self._settings.comment_title}\n') and ('\nresults for commit ' in comment.get('body') or '\nResults for commit ' in comment.get('body'))]) diff --git a/python/publish_test_results.py b/python/publish_test_results.py index 9924f980..47ffe2ed 100644 --- a/python/publish_test_results.py +++ b/python/publish_test_results.py @@ -442,7 +442,7 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: annotations = get_annotations_config(options, event) suite_logs_mode = get_var('REPORT_SUITE_LOGS', options) or default_report_suite_logs ignore_runs = get_bool_var('IGNORE_RUNS', options, default=False) - actor_name = get_var('ACTOR_NAME', options) or 'github-actions' + actor = get_var('GITUHB_ACTOR', options) or 'github-actions' fail_on = get_var('FAIL_ON', options) or 'test failures' check_var(fail_on, 'FAIL_ON', 'Check fail mode', fail_on_modes) @@ -459,6 +459,7 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: settings = Settings( token=get_var('GITHUB_TOKEN', options), + actor=actor, api_url=api_url, graphql_url=graphql_url, api_retries=int(retries), @@ -476,7 +477,6 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: fail_on_failures=fail_on_failures, action_fail=get_bool_var('ACTION_FAIL', options, default=False), action_fail_on_inconclusive=get_bool_var('ACTION_FAIL_ON_INCONCLUSIVE', options, default=False), - actor_name=actor_name, files_glob=get_var('FILES', options) or default_files_glob, junit_files_glob=get_var('JUNIT_FILES', options), nunit_files_glob=get_var('NUNIT_FILES', options), From 6c8030e7c15a91a6ab166991913b511afdcde1f2 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 1 Jun 2023 08:23:41 +0200 Subject: [PATCH 7/8] Fix typo in get_settings --- python/publish_test_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/publish_test_results.py b/python/publish_test_results.py index 47ffe2ed..bd6280d0 100644 --- a/python/publish_test_results.py +++ b/python/publish_test_results.py @@ -442,7 +442,7 @@ def get_settings(options: dict, gha: GithubAction) -> Settings: annotations = get_annotations_config(options, event) suite_logs_mode = get_var('REPORT_SUITE_LOGS', options) or default_report_suite_logs ignore_runs = get_bool_var('IGNORE_RUNS', options, default=False) - actor = get_var('GITUHB_ACTOR', options) or 'github-actions' + actor = get_var('GITHUB_ACTOR', options) or 'github-actions' fail_on = get_var('FAIL_ON', options) or 'test failures' check_var(fail_on, 'FAIL_ON', 'Check fail mode', fail_on_modes) From 5ea5598dad56ce72b5498918a5f991bf7da1d9fd Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 1 Jun 2023 08:25:52 +0200 Subject: [PATCH 8/8] Add new option to tests, action.yml and CI --- .github/workflows/ci-cd.yml | 1 + composite/action.yml | 1 + python/test/test_action_script.py | 7 +++++++ python/test/test_publisher.py | 32 ++++++++++++++++++++++++++----- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 0f2991a3..d84be337 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -300,6 +300,7 @@ jobs: -e "INPUT_LOG_LEVEL" \ -e "INPUT_ROOT_LOG_LEVEL" \ -e "INPUT_GITHUB_TOKEN" \ + -e "INPUT_GITHUB_ACTOR" \ -e "INPUT_GITHUB_RETRIES" \ -e "INPUT_COMMIT" \ -e "INPUT_COMMENT_TITLE" \ diff --git a/composite/action.yml b/composite/action.yml index d5523bfc..e6ca48c9 100644 --- a/composite/action.yml +++ b/composite/action.yml @@ -208,6 +208,7 @@ runs: echo '##[endgroup]' env: GITHUB_TOKEN: ${{ inputs.github_token }} + GITHUB_ACTOR: ${{ inputs.github_actor }} GITHUB_RETRIES: ${{ inputs.github_retries }} COMMIT: ${{ inputs.commit }} CHECK_NAME: ${{ inputs.check_name }} diff --git a/python/test/test_action_script.py b/python/test/test_action_script.py index 16fcea09..0ceffda7 100644 --- a/python/test/test_action_script.py +++ b/python/test/test_action_script.py @@ -160,6 +160,7 @@ def get_settings_no_default_files(cls, @staticmethod def get_settings(token='token', + actor='actor', api_url='http://github.api.url/', graphql_url='http://github.graphql.url/', retries=2, @@ -202,6 +203,7 @@ def get_settings(token='token', search_pull_requests=False) -> Settings: return Settings( token=token, + actor=actor, api_url=api_url, graphql_url=graphql_url, api_retries=retries, @@ -265,6 +267,10 @@ def test_get_settings_event_file(self): self.do_test_get_settings(EVENT_FILE=filepath, expected=self.get_settings(event=event, event_file=filepath)) + def test_get_settings_github_actor(self): + self.do_test_get_settings(GITHUB_ACTOR='other-actor', expected=self.get_settings(actor='other-actor')) + self.do_test_get_settings(GITHUB_ACTOR=None, expected=self.get_settings(actor='github-actions')) + def test_get_settings_github_api_url(self): self.do_test_get_settings(GITHUB_API_URL='https://api.github.onpremise.com', expected=self.get_settings(api_url='https://api.github.onpremise.com')) self.do_test_get_settings(GITHUB_API_URL=None, expected=self.get_settings(api_url='https://api.github.com')) @@ -621,6 +627,7 @@ def do_test_get_settings(self, TEST_CHANGES_LIMIT='10', # not an int CHECK_NAME='check name', # defaults to 'Test Results' GITHUB_TOKEN='token', + GITHUB_ACTOR='actor', GITHUB_REPOSITORY='repo', COMMIT='commit', # defaults to get_commit_sha(event, event_name) FILES='all-files', diff --git a/python/test/test_publisher.py b/python/test/test_publisher.py index 4a25cc3a..f1135709 100644 --- a/python/test/test_publisher.py +++ b/python/test/test_publisher.py @@ -77,7 +77,8 @@ def create_github_pr(repo: str, return pr @staticmethod - def create_settings(comment_mode=comment_mode_always, + def create_settings(actor='actor', + comment_mode=comment_mode_always, job_summary=True, compare_earlier=True, report_individual_runs=False, @@ -95,6 +96,7 @@ def create_settings(comment_mode=comment_mode_always, search_pull_requests: bool = False): return Settings( token=None, + actor=actor, api_url='https://the-github-api-url', graphql_url='https://the-github-graphql-url', api_retries=1, @@ -2608,11 +2610,19 @@ def test_get_pull_request_comments_order_updated(self): 'body': '## Comment Title\n' 'results for commit dee59820\u2003± comparison against base commit 70b5dd18\n', 'isMinimized': False - } + }, + # comment of different actor + { + 'id': 'comment eight', + 'author': {'login': 'other-actor'}, + 'body': '## Comment Title\n' + 'Results for commit dee59820.\u2003± Comparison against base commit 70b5dd18.\n', + 'isMinimized': False + }, ] def test_get_action_comments(self): - settings = self.create_settings() + settings = self.create_settings(actor='github-actions') gh, gha, req, repo, commit = self.create_mocks() publisher = Publisher(settings, gh, gha) @@ -2620,11 +2630,23 @@ def test_get_action_comments(self): for comment in self.comments if comment.get('id') in ['comment one', 'comment five', 'comment seven']] actual = publisher.get_action_comments(self.comments, is_minimized=None) + self.assertEqual(3, len(expected)) + self.assertEqual(expected, actual) + def test_get_action_comments_other_actor(self): + settings = self.create_settings(actor='other-actor') + gh, gha, req, repo, commit = self.create_mocks() + publisher = Publisher(settings, gh, gha) + + expected = [comment + for comment in self.comments + if comment.get('id') == 'comment eight'] + actual = publisher.get_action_comments(self.comments, is_minimized=None) + self.assertEqual(1, len(expected)) self.assertEqual(expected, actual) def test_get_action_comments_not_minimized(self): - settings = self.create_settings() + settings = self.create_settings(actor='github-actions') gh, gha, req, repo, commit = self.create_mocks() publisher = Publisher(settings, gh, gha) @@ -2632,5 +2654,5 @@ def test_get_action_comments_not_minimized(self): for comment in self.comments if comment.get('id') in ['comment one', 'comment seven']] actual = publisher.get_action_comments(self.comments, is_minimized=False) - + self.assertEqual(2, len(expected)) self.assertEqual(expected, actual)