Skip to content

Commit

Permalink
Merge pull request #134 from ymyzk/custom-behaviors
Browse files Browse the repository at this point in the history
Expose fail_on_no_env and problem_matcher options to customize behaviors
  • Loading branch information
ymyzk authored Dec 13, 2022
2 parents 7910a78 + 892e2e1 commit dea8814
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
# https://help.github.com/articles/virtual-environments-for-github-actions
platform:
- ubuntu-latest # ubuntu-20.04
- ubuntu-20.04
- macos-latest # macOS-11
- windows-latest # windows-2022
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11', 3.12-dev, pypy-2.7, pypy-3.7, pypy-3.8, pypy-3.9]
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ please check [the tox4 branch](https://github.com/ymyzk/tox-gh-actions/tree/tox4
- [Advanced Examples](#advanced-examples)
- [Factor-Conditional Settings: Python Version](#factor-conditional-settings-python-version)
- [Factor-Conditional Settings: Environment Variable](#factor-conditional-settings-environment-variable)
- [Fail when no environments are matched](#fail-when-no-environments-are-matched)
- [Disable problem matchers](#disable-problem-matchers)
- [tox requires](#tox-requires)
- [Overriding Environments to Run](#overriding-environments-to-run)
- [Versioning](#versioning)
Expand Down Expand Up @@ -300,6 +302,40 @@ deps =

See [tox's documentation about factor-conditional settings](https://tox.readthedocs.io/en/latest/config.html#factors-and-factor-conditional-settings) as well.

#### Fail when no environments are matched
By default, tox-gh-actions won't fail the run even if it cannot find environments matching the criteria.
If you want to fail the run in such a case, you can tune the `fail_on_no_env` option.

`tox.ini`:
```ini
[tox]
envlist = py{38,39}
[gh-actions]
python =
3.8: py38
3.9: py39
# tox run using Python 3.10 will fail because tox-gh-actions cannot find an environment contains py310 in the envlist.
3.10: py310
fail_on_no_env = True
```

#### Disable problem matchers
For annotating error messages on GitHub Actions, tox-gh-actions uses [the problem matcher functionality](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md).
However, there is a case that GitHub Actions reports an error like the following in certain environments.

```
Error: Could not find a part of the path '/usr/local/lib/python3.10/site-packages/tox_gh_actions/matcher.json'.
```
To prevent such errors, you can explicitly disable the problem matcher using the `problem_matcher` option.
`tox.ini`:
```ini
[gh-actions]
problem_matcher = False
```

#### tox requires
If your project uses [tox's `requires` configuration](https://tox.wiki/en/latest/config.html#conf-requires),
you must add `tox-gh-actions` to the `requires` configuration as well. Otherwise, tox-gh-actions won't be loaded as a tox plugin.
Expand Down
63 changes: 47 additions & 16 deletions src/tox_gh_actions/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import os
import sys
import threading
from typing import Any, Dict, Iterable, List
from typing import Any, Dict, Iterable, List, NoReturn

import importlib_resources
import pluggy
from tox.action import Action
from tox.config import Config, TestenvConfig, _split_env as split_env
from tox.reporter import verbosity1, verbosity2, warning
from tox.reporter import verbosity1, verbosity2, warning, error
from tox.venv import VirtualEnv


Expand All @@ -26,17 +26,6 @@ def tox_configure(config):
# type: (Config) -> None
verbosity1("running tox-gh-actions")

if is_running_on_container():
verbosity2(
"not enabling problem matcher as tox seems to be running on a container"
)
# Trying to add a problem matcher from a container without proper host mount can
# cause an error like the following:
# Unable to process command '::add-matcher::/.../matcher.json' successfully.
else:
verbosity2("enabling problem matcher")
print("::add-matcher::" + get_problem_matcher_file_path())

if not is_log_grouping_enabled(config):
verbosity2(
"disabling log line grouping on GitHub Actions based on the configuration"
Expand Down Expand Up @@ -65,6 +54,22 @@ def tox_configure(config):
gh_actions_config = parse_config(config._cfg.sections)
verbosity2("tox-gh-actions config: {}".format(gh_actions_config))

if is_running_on_container():
verbosity2(
"not enabling problem matcher as tox seems to be running on a container"
)
# Trying to add a problem matcher from a container without proper host mount can
# cause an error like the following:
# Unable to process command '::add-matcher::/.../matcher.json' successfully.
elif not gh_actions_config["problem_matcher"]:
verbosity2(
"not enabling problem matcher as it's disabled by the problem_matcher "
"option"
)
else:
verbosity2("enabling problem matcher")
print("::add-matcher::" + get_problem_matcher_file_path())

factors = get_factors(gh_actions_config, versions)
verbosity2("using the following factors to decide envlist: {}".format(factors))

Expand All @@ -75,6 +80,9 @@ def tox_configure(config):
"tox-gh-actions couldn't find environments matching the provided factors "
"from envlist. Please use `tox -vv` to get more detailed logs."
)
if gh_actions_config["fail_on_no_env"]:
error("Failing the run because the fail_on_no_env option is enabled.")
abort_tox()
verbosity1("overriding envlist with: {}".format(envlist))


Expand Down Expand Up @@ -108,9 +116,12 @@ def tox_runtest_post(venv):

@hookimpl
def tox_cleanup(session):
gh_actions_config = parse_config(session.config._cfg.sections)
# This hook can be called multiple times especially when using parallel mode
if not is_running_on_actions():
return
if not gh_actions_config["problem_matcher"]:
return
verbosity2("disabling problem matcher")
for owner in get_problem_matcher_owners():
print("::remove-matcher owner={}::".format(owner))
Expand Down Expand Up @@ -148,15 +159,18 @@ def start_grouping_if_necessary(venv):
def parse_config(config):
# type: (Dict[str, Dict[str, str]]) -> Dict[str, Dict[str, Any]]
"""Parse gh-actions section in tox.ini"""
config_python = parse_dict(config.get("gh-actions", {}).get("python", ""))
main_config = config.get("gh-actions", {})
config_python = parse_dict(main_config.get("python", ""))
config_env = {
name: {k: split_env(v) for k, v in parse_dict(conf).items()}
for name, conf in config.get("gh-actions:env", {}).items()
}
# Example of split_env:
# "py{27,38}" => ["py27", "py38"]
return {
# Example of split_env:
# "py{27,38}" => ["py27", "py38"]
"python": {k: split_env(v) for k, v in config_python.items()},
"fail_on_no_env": parse_bool(main_config.get("fail_on_no_env", "false")),
"problem_matcher": parse_bool(main_config.get("problem_matcher", "true")),
"env": config_env,
}

Expand Down Expand Up @@ -306,6 +320,23 @@ def get_problem_matcher_owners():
return [m["owner"] for m in matcher["problemMatcher"]]


def parse_bool(value):
# type: (str) -> bool
"""Parse a boolean value in the tox config."""
clean_value = value.strip().lower()
if clean_value in {"true", "1"}:
return True
elif clean_value in {"false", "0"}:
return False
error("Failed to parse a boolean value in tox-gh-actions config: {}")
abort_tox()


def abort_tox():
# type: () -> NoReturn
raise SystemExit(1)


# The following function was copied from
# https://github.com/tox-dev/tox-travis/blob/0.12/src/tox_travis/utils.py#L11-L32
# which is licensed under MIT LICENSE
Expand Down
12 changes: 11 additions & 1 deletion tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,17 @@ def test_start_grouping_ignores_isolated_build_env(capsys, mocker):
"3.7": ["py37", "flake8"],
},
"env": {},
"fail_on_no_env": False,
"problem_matcher": True,
},
),
(
{
"gh-actions": {
"python": """2.7: py27
3.8: py38"""
3.8: py38""",
"fail_on_no_env": "True",
"problem_matcher": "False",
},
"gh-actions:env": {
"PLATFORM": """ubuntu-latest: linux
Expand All @@ -82,20 +86,26 @@ def test_start_grouping_ignores_isolated_build_env(capsys, mocker):
"windows-latest": ["windows"],
},
},
"fail_on_no_env": True,
"problem_matcher": False,
},
),
(
{"gh-actions": {}},
{
"python": {},
"env": {},
"fail_on_no_env": False,
"problem_matcher": True,
},
),
(
{},
{
"python": {},
"env": {},
"fail_on_no_env": False,
"problem_matcher": True,
},
),
],
Expand Down

0 comments on commit dea8814

Please sign in to comment.