From 66c84b64637cd56d3a2ab48a916bdf17ed3989a3 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 00:19:00 +0100 Subject: [PATCH 01/11] add flag-name and base-path options --- src/entrypoint.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index 9379e7a..2729529 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -23,19 +23,24 @@ def set_failed(message): sys.exit(ExitCode.FAILURE) -def patch_os_environ(repo_token, parallel): +def patch_os_environ(repo_token, parallel, flag_name): """ Temporarily updates the environment variable to satisfy coveralls Python API. That is because the coveralls package API consumes mostly environment variables. """ # https://github.com/coveralls-clients/coveralls-python/blob/2.0.0/coveralls/api.py#L146 parallel = "true" if parallel else "" - environ = {"COVERALLS_REPO_TOKEN": repo_token, "COVERALLS_PARALLEL": parallel} + environ = { + "COVERALLS_REPO_TOKEN": repo_token, + "COVERALLS_PARALLEL": parallel + } + if flag_name: + environ["COVERALLS_FLAG_NAME"] = flag_name log.debug(f"Patching os.environ with: {environ}") return mock.patch.dict("os.environ", environ) -def run_coveralls(repo_token, parallel=False): +def run_coveralls(repo_token, parallel, flag_name, base_path): """Submits job to coveralls.""" # note that coveralls.io "service_name" can either be: # - "github-actions" (local development?) @@ -44,9 +49,11 @@ def run_coveralls(repo_token, parallel=False): # (depending on where it's ran from?) service_names = ("github", "github-actions") result = None + if base_path and os.path.exists(base_path): + os.chdir(base_path) for service_name in service_names: log.info(f"Trying submitting coverage with service_name: {service_name}...") - with patch_os_environ(repo_token, parallel): + with patch_os_environ(repo_token, parallel, flag_name): coveralls = Coveralls(service_name=service_name) try: result = coveralls.wear() @@ -84,6 +91,11 @@ def get_github_repository(): return os.environ.get("GITHUB_REPOSITORY") +def get_github_run_id(): + """e.g. 88748489334""" + return os.environ.get("GITHUB_RUN_ID") + + def get_pull_request_number(github_ref): """ >>> get_pull_request_number("refs/pull//merge") @@ -96,18 +108,10 @@ def is_pull_request(github_ref): return github_ref and github_ref.startswith("refs/pull/") -def get_build_number(github_sha, github_ref): - build_number = github_sha - if is_pull_request(github_ref): - pull_request_number = get_pull_request_number(github_ref) - build_number = f"{github_sha}-PR-{pull_request_number}" - return build_number - - def post_webhook(repo_token): """https://docs.coveralls.io/parallel-build-webhook""" url = "https://coveralls.io/webhook" - build_num = get_build_number(get_github_sha(), get_github_ref()) + build_num = get_github_run_id() # note this (undocumented) parameter is optional, but needed for using # `GITHUB_TOKEN` rather than `COVERALLS_REPO_TOKEN` repo_name = get_github_repository() @@ -137,6 +141,8 @@ def str_to_bool(value): def parse_args(): parser = argparse.ArgumentParser(description="Greetings") parser.add_argument("--github-token", nargs=1, required=True) + parser.add_argument("--flag-name", required=False, default=False) + parser.add_argument("--base-path", required=False, default=False) parser.add_argument( "--parallel", type=str_to_bool, nargs="?", const=True, default=False ) @@ -160,13 +166,15 @@ def main(): debug = args.debug repo_token = args.github_token[0] parallel = args.parallel + flag_name = args.flag_name + base_path = args.base_path parallel_finished = args.parallel_finished set_log_level(debug) log.debug(f"args: {args}") if parallel_finished: post_webhook(repo_token) else: - run_coveralls(repo_token, parallel) + run_coveralls(repo_token, parallel, flag_name, base_path) def try_main(): From 610b76915d4feba90b9f7327f8e8e6d7035c5642 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 09:57:22 +0100 Subject: [PATCH 02/11] Add tests --- action.yml | 10 +++++ src/entrypoint.py | 2 +- tests/test_entrypoint.py | 91 +++++++++++----------------------------- 3 files changed, 35 insertions(+), 68 deletions(-) diff --git a/action.yml b/action.yml index 09bde97..a2e0bfd 100644 --- a/action.yml +++ b/action.yml @@ -14,6 +14,12 @@ inputs: parallel-finished: description: 'Set to true for the last action when using `parallel: true`.' default: false + base-path: + description: 'The name of a sub-directory in which the coverage files are to be found.' + default: false + flag-name: + description: 'A description of the current job used in connection with parallel.' + default: false debug: description: 'Set to `true` to increase logger verbosity.' default: false @@ -23,6 +29,10 @@ runs: args: - --github-token - ${{ inputs.github-token }} + - --base-path + - ${{ inputs.base-path }} + - --flag-name + - ${{ inputs.flag-name }} - --parallel - ${{ inputs.parallel }} - --parallel-finished diff --git a/src/entrypoint.py b/src/entrypoint.py index 2729529..08ce14e 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -40,7 +40,7 @@ def patch_os_environ(repo_token, parallel, flag_name): return mock.patch.dict("os.environ", environ) -def run_coveralls(repo_token, parallel, flag_name, base_path): +def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): """Submits job to coveralls.""" # note that coveralls.io "service_name" can either be: # - "github-actions" (local development?) diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index f83a0be..1bfcf17 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -44,7 +44,23 @@ def test_main(self): "entrypoint.run_coveralls" ) as m_run_coveralls: entrypoint.main() - assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False)] + assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, False, False)] + + def test_main_flag_name(self): + argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--flag-name", "FLAG"] + with patch_sys_argv(argv), mock.patch( + "entrypoint.run_coveralls" + ) as m_run_coveralls: + entrypoint.main() + assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, "FLAG", False)] + + def test_main_base_path(self): + argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--base-path", "SRC"] + with patch_sys_argv(argv), mock.patch( + "entrypoint.run_coveralls" + ) as m_run_coveralls: + entrypoint.main() + assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, False, "SRC")] def test_main_parallel_finished(self): argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--parallel-finished"] @@ -123,31 +139,11 @@ def test_run_coveralls_wear_error_twice(self): entrypoint.run_coveralls(repo_token="TOKEN") assert ex_info.value.args == (entrypoint.ExitCode.FAILURE,) - def test_get_build_number(self): - github_sha = "ffac537e6cbbf934b08745a378932722df287a53" - github_ref = "refs/pull/123/merge" - assert ( - entrypoint.get_build_number(github_sha, github_ref) - == "ffac537e6cbbf934b08745a378932722df287a53-PR-123" - ) - github_ref = "refs/heads/feature-branch-1" - assert ( - entrypoint.get_build_number(github_sha, github_ref) - == "ffac537e6cbbf934b08745a378932722df287a53" - ) - github_ref = None - assert ( - entrypoint.get_build_number(github_sha, github_ref) - == "ffac537e6cbbf934b08745a378932722df287a53" - ) - def test_post_webhook(self): """ Tests different uses cases: 1) default, no environment variable - 2) only `GITHUB_SHA` is set - 3) `GITHUB_REF` is a branch - 4) `GITHUB_REF` is a pull request + 2) `GITHUB_RUN_ID` is set """ repo_token = "TOKEN" json_response = {"done": True} @@ -165,9 +161,10 @@ def test_post_webhook(self): }, ) ] - # 2) only `GITHUB_SHA` is set + # 2) `GITHUB_RUN_ID` and `GITHUB_REPOSITORY` are set environ = { - "GITHUB_SHA": "ffac537e6cbbf934b08745a378932722df287a53", + "GITHUB_RUN_ID": "845347868344", + "GITHUB_REPOSITORY": "AndreMiras/coveralls-python-action" } with patch_requests_post(json_response) as m_post, patch_os_envirion(environ): entrypoint.post_webhook(repo_token) @@ -176,56 +173,16 @@ def test_post_webhook(self): "https://coveralls.io/webhook", json={ "repo_token": "TOKEN", - "repo_name": None, + "repo_name": "AndreMiras/coveralls-python-action", "payload": { - "build_num": "ffac537e6cbbf934b08745a378932722df287a53", - "status": "done", - }, - }, - ) - ] - # 3) `GITHUB_REF` is a branch - environ = { - "GITHUB_SHA": "ffac537e6cbbf934b08745a378932722df287a53", - "GITHUB_REF": "refs/heads/feature-branch-1", - } - with patch_requests_post(json_response) as m_post, patch_os_envirion(environ): - entrypoint.post_webhook(repo_token) - assert m_post.call_args_list == [ - mock.call( - "https://coveralls.io/webhook", - json={ - "repo_token": "TOKEN", - "repo_name": None, - "payload": { - "build_num": "ffac537e6cbbf934b08745a378932722df287a53", - "status": "done", - }, - }, - ) - ] - # 4) `GITHUB_REF` is a pull request - environ = { - "GITHUB_SHA": "ffac537e6cbbf934b08745a378932722df287a53", - "GITHUB_REF": "refs/pull/123/merge", - "GITHUB_REPOSITORY": "octocat/Hello-World", - } - with patch_requests_post(json_response) as m_post, patch_os_envirion(environ): - entrypoint.post_webhook(repo_token) - assert m_post.call_args_list == [ - mock.call( - "https://coveralls.io/webhook", - json={ - "repo_token": "TOKEN", - "repo_name": "octocat/Hello-World", - "payload": { - "build_num": "ffac537e6cbbf934b08745a378932722df287a53-PR-123", + "build_num": "845347868344", "status": "done", }, }, ) ] + def test_post_webhook_error(self): """Coveralls.io json error response should raise an exception.""" repo_token = "TOKEN" From df496267ba2fd1cf3e32c45667b6fd933fec0314 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 10:09:09 +0100 Subject: [PATCH 03/11] Update readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 28aefdd..c386f99 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ jobs: uses: AndreMiras/coveralls-python-action@develop with: parallel: true + flag-name: Unit Test coveralls_finish: needs: test @@ -56,6 +57,12 @@ jobs: # Set to `true` for the last action when using `parallel: true`. # Default: false parallel-finished: '' + # A name to identify the current job. This is useful in combination with `parallel: true`. + # Default: false + flag-name: '' + # A sub-directory in which coverage was executed. + # Default: false + base-path: '' # Set to true to increase logger verbosity. # Default: false debug: '' From 5141bc4281c2a1fbda4738c98ba38f387db7c5e3 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 10:17:04 +0100 Subject: [PATCH 04/11] add cwd to debug log --- src/entrypoint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/entrypoint.py b/src/entrypoint.py index 08ce14e..e5e4a98 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -51,6 +51,8 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): result = None if base_path and os.path.exists(base_path): os.chdir(base_path) + cwd = os.getcwd() + log.debug(f"Current Working Directory: {cwd}") for service_name in service_names: log.info(f"Trying submitting coverage with service_name: {service_name}...") with patch_os_environ(repo_token, parallel, flag_name): From 355f505a9d8837c546d818c7d2223e2d67c63ad6 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 10:25:36 +0100 Subject: [PATCH 05/11] Don't check for existence of base_path --- src/entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index e5e4a98..a7866b2 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -49,7 +49,7 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): # (depending on where it's ran from?) service_names = ("github", "github-actions") result = None - if base_path and os.path.exists(base_path): + if base_path: os.chdir(base_path) cwd = os.getcwd() log.debug(f"Current Working Directory: {cwd}") From 7a55079f4ce127dbf3c210f503a8e0735b8310ac Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 11:02:28 +0100 Subject: [PATCH 06/11] debug base_path --- src/entrypoint.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index a7866b2..3f422c7 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -49,8 +49,9 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): # (depending on where it's ran from?) service_names = ("github", "github-actions") result = None - if base_path: - os.chdir(base_path) + log.debug(f"Current Working Directory: {cwd}") + #if base_path: + os.chdir(base_path) cwd = os.getcwd() log.debug(f"Current Working Directory: {cwd}") for service_name in service_names: From 733e3e324b6b7bb07ed0dd07eae33ea7dd9ee63e Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 11:02:47 +0100 Subject: [PATCH 07/11] debug base_path --- src/entrypoint.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/entrypoint.py b/src/entrypoint.py index 3f422c7..e649e39 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -49,6 +49,7 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): # (depending on where it's ran from?) service_names = ("github", "github-actions") result = None + cwd = os.getcwd() log.debug(f"Current Working Directory: {cwd}") #if base_path: os.chdir(base_path) From 0b61d396bf02d0afb1a1e3183c4ad423b2c59705 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 11:44:29 +0100 Subject: [PATCH 08/11] log cwd files --- src/entrypoint.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index e649e39..72e9414 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -51,10 +51,13 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): result = None cwd = os.getcwd() log.debug(f"Current Working Directory: {cwd}") - #if base_path: - os.chdir(base_path) + if base_path and os.path.exists(base_path): + os.chdir(base_path) cwd = os.getcwd() log.debug(f"Current Working Directory: {cwd}") + for entry in os.scandir('.'): + if entry.is_file(): + log.debug(entry.name) for service_name in service_names: log.info(f"Trying submitting coverage with service_name: {service_name}...") with patch_os_environ(repo_token, parallel, flag_name): From e4ecbdb0499b934f84febd79d0073041a89a8b79 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 12:07:24 +0100 Subject: [PATCH 09/11] add more debug --- src/entrypoint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/entrypoint.py b/src/entrypoint.py index 72e9414..006459d 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -62,6 +62,8 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): log.info(f"Trying submitting coverage with service_name: {service_name}...") with patch_os_environ(repo_token, parallel, flag_name): coveralls = Coveralls(service_name=service_name) + report = coveralls.create_report() + log.info(report) try: result = coveralls.wear() break From b4ce31b990ea48e1d0ad2e186f63006c2f30b30f Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 16:40:51 +0100 Subject: [PATCH 10/11] remove logging --- src/entrypoint.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index 006459d..08ce14e 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -49,21 +49,12 @@ def run_coveralls(repo_token, parallel=False, flag_name=False, base_path=False): # (depending on where it's ran from?) service_names = ("github", "github-actions") result = None - cwd = os.getcwd() - log.debug(f"Current Working Directory: {cwd}") if base_path and os.path.exists(base_path): os.chdir(base_path) - cwd = os.getcwd() - log.debug(f"Current Working Directory: {cwd}") - for entry in os.scandir('.'): - if entry.is_file(): - log.debug(entry.name) for service_name in service_names: log.info(f"Trying submitting coverage with service_name: {service_name}...") with patch_os_environ(repo_token, parallel, flag_name): coveralls = Coveralls(service_name=service_name) - report = coveralls.create_report() - log.info(report) try: result = coveralls.wear() break From 23073d88e8aea22ffbe0c59691f63e7f744d1f99 Mon Sep 17 00:00:00 2001 From: Johannes Wilm Date: Sun, 22 Nov 2020 17:06:16 +0100 Subject: [PATCH 11/11] black --- src/entrypoint.py | 5 +---- tests/test_entrypoint.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/entrypoint.py b/src/entrypoint.py index 08ce14e..585ca73 100755 --- a/src/entrypoint.py +++ b/src/entrypoint.py @@ -30,10 +30,7 @@ def patch_os_environ(repo_token, parallel, flag_name): """ # https://github.com/coveralls-clients/coveralls-python/blob/2.0.0/coveralls/api.py#L146 parallel = "true" if parallel else "" - environ = { - "COVERALLS_REPO_TOKEN": repo_token, - "COVERALLS_PARALLEL": parallel - } + environ = {"COVERALLS_REPO_TOKEN": repo_token, "COVERALLS_PARALLEL": parallel} if flag_name: environ["COVERALLS_FLAG_NAME"] = flag_name log.debug(f"Patching os.environ with: {environ}") diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py index 1bfcf17..f412cb5 100644 --- a/tests/test_entrypoint.py +++ b/tests/test_entrypoint.py @@ -44,7 +44,9 @@ def test_main(self): "entrypoint.run_coveralls" ) as m_run_coveralls: entrypoint.main() - assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, False, False)] + assert m_run_coveralls.call_args_list == [ + mock.call("TOKEN", False, False, False) + ] def test_main_flag_name(self): argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--flag-name", "FLAG"] @@ -52,7 +54,9 @@ def test_main_flag_name(self): "entrypoint.run_coveralls" ) as m_run_coveralls: entrypoint.main() - assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, "FLAG", False)] + assert m_run_coveralls.call_args_list == [ + mock.call("TOKEN", False, "FLAG", False) + ] def test_main_base_path(self): argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--base-path", "SRC"] @@ -60,7 +64,9 @@ def test_main_base_path(self): "entrypoint.run_coveralls" ) as m_run_coveralls: entrypoint.main() - assert m_run_coveralls.call_args_list == [mock.call("TOKEN", False, False, "SRC")] + assert m_run_coveralls.call_args_list == [ + mock.call("TOKEN", False, False, "SRC") + ] def test_main_parallel_finished(self): argv = ["src/entrypoint.py", "--github-token", "TOKEN", "--parallel-finished"] @@ -164,7 +170,7 @@ def test_post_webhook(self): # 2) `GITHUB_RUN_ID` and `GITHUB_REPOSITORY` are set environ = { "GITHUB_RUN_ID": "845347868344", - "GITHUB_REPOSITORY": "AndreMiras/coveralls-python-action" + "GITHUB_REPOSITORY": "AndreMiras/coveralls-python-action", } with patch_requests_post(json_response) as m_post, patch_os_envirion(environ): entrypoint.post_webhook(repo_token) @@ -182,7 +188,6 @@ def test_post_webhook(self): ) ] - def test_post_webhook_error(self): """Coveralls.io json error response should raise an exception.""" repo_token = "TOKEN"