{"action":"created","issue":{"url":"https://api.github.com/repos/tox-dev/tox-travis/issues/77","repository_url":"https://api.github.com/repos/tox-dev/tox-travis","labels_url":"https://api.github.com/repos/tox-dev/tox-travis/issues/77/labels{/name}","comments_url":"https://api.github.com/repos/tox-dev/tox-travis/issues/77/comments","events_url":"https://api.github.com/repos/tox-dev/tox-travis/issues/77/events","html_url":"https://github.com/tox-dev/tox-travis/issues/77","id":265614156,"number":77,"title":"What is simplest Travis config for full Django matrix?","user":{"login":"bittner","id":665072,"avatar_url":"https://avatars2.githubusercontent.com/u/665072?v=4","gravatar_id":"","url":"https://api.github.com/users/bittner","html_url":"https://github.com/bittner","followers_url":"https://api.github.com/users/bittner/followers","following_url":"https://api.github.com/users/bittner/following{/other_user}","gists_url":"https://api.github.com/users/bittner/gists{/gist_id}","starred_url":"https://api.github.com/users/bittner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bittner/subscriptions","organizations_url":"https://api.github.com/users/bittner/orgs","repos_url":"https://api.github.com/users/bittner/repos","events_url":"https://api.github.com/users/bittner/events{/privacy}","received_events_url":"https://api.github.com/users/bittner/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2017-10-15T23:28:08Z","updated_at":"2017-10-16T18:34:46Z","closed_at":null,"author_association":"NONE","body":"I'm maintaining a few Django packages, and running a matrix build against all supported Python/Django combinations is what we typically do.\r\n\r\nNow I'm wondering, what the simplest Travis setup is for a full build matrix for Django (say, all Django versions >= 1.7 by their supported Python versions). I really want to avoid doing things twice, or things that overlap, in two different configuration files, `tox.ini` and `.travis.yml`.\r\n\r\nExample `tox.ini` and `.travis.yml`\r\n=============\r\nLet's omit Python 3.2 for heaven's sake (all the packages seem to drop support anyway) and let's add `flake8`. Here's what I have come up with:\r\n\r\n```ini\r\n# -- FILE: tox.ini\r\n[tox]\r\nenvlist =\r\n    py{27,33,34}-django17\r\n    py{27,33,34,35}-django18\r\n    py{27,34,35}-django19\r\n    py{27,34,35}-django110\r\n    py{27,34,35,36}-django111\r\n    flake8\r\n\r\n[testenv]\r\ncommands =\r\n    coverage run setup.py test\r\ndeps =\r\n    coverage\r\n    django17: Django>=1.7,<1.8\r\n    django18: Django>=1.8,<1.9\r\n    django19: Django>=1.9,<1.10\r\n    django110: Django>=1.10,<1.11\r\n    django111: Django>=1.11,<2.0\r\n\r\n[testenv:flake8]\r\nbasepython = python2.7\r\ndeps = flake8\r\ncommands = flake8\r\n\r\n[travis:env]\r\nDJANGO =\r\n    1.7: django17\r\n    1.8: django18\r\n    1.9: django19\r\n    1.10: django110\r\n    1.11: django111\r\n```\r\n\r\nThis is already longer than I want, but probably as short as it gets. Now for the worse:\r\n\r\n```yaml\r\n# -- FILE: .travis.yml\r\nlanguage: python\r\npython:\r\n  - 2.7\r\n  - 3.3\r\n  - 3.4\r\n  - 3.5\r\n  - 3.6\r\nenv:\r\n  - DJANGO=1.7\r\n  - DJANGO=1.8\r\n  - DJANGO=1.9\r\n  - DJANGO=1.10\r\n  - DJANGO=1.11\r\nmatrix:\r\n  exclude:\r\n    - python: 3.3\r\n      env: DJANGO=1.9\r\n    - python: 3.3\r\n      env: DJANGO=1.10\r\n    - python: 3.3\r\n      env: DJANGO=1.11\r\n    - python: 3.5\r\n      env: DJANGO=1.7\r\n    - python: 3.6\r\n      env: DJANGO=1.7\r\n    - python: 3.6\r\n      env: DJANGO=1.8\r\n    - python: 3.6\r\n      env: DJANGO=1.9\r\n    - python: 3.6\r\n      env: DJANGO=1.10\r\n  include:\r\n    - python: 2.7\r\n      env: TOXENV=flake8\r\n\r\ninstall:\r\n  - pip install tox-travis\r\nscript:\r\n  - tox\r\n```\r\n\r\nThis is terribly long, and the `exclude:` section in the Travis configuration duplicates what is already specified in the Tox config, in a negative form, to make it all more complicated.  -- Is that really as simple as it gets, for a full build matrix?\r\n\r\nThe result we get looks somewhat like [Travis build #288326510](https://travis-ci.org/jcassee/django-analytical/builds/288326510), which is fine.\r\n\r\nCan We Derive Environments Automatically?\r\n==========================\r\nI prefer to specify my \"build matrix\" in Tox, because that ensures that I can run the same set of checks and tests locally _and_ on a CI infrastructure. I only need to change a single file, that's how I want it.\r\n\r\nCan I configure a much simpler `.travis.yml` that lets me avoid doing the same work twice?  Maybe have both the `env:` section and the `matrix: exclude: ` section be built automagically? With the same result as above, each combination listed as a separate job in the Travis build.\r\n\r\n```yaml\r\n# -- FILE: .travis.yml\r\nlanguage: python\r\npython:\r\n  - 2.7\r\n  - 3.3\r\n  - 3.4\r\n  - 3.5\r\n  - 3.6\r\nmatrix:\r\n  include:\r\n    - python: 2.7\r\n      env: TOXENV=flake8\r\n\r\ninstall:\r\n  - pip install tox-travis\r\nscript:\r\n  - tox\r\n```\r\n(That file doesn't do it, which is part of the question.)\r\n\r\nIs something like that feasible at all? Is that already possible? If yes, what is missing for a concise solution?\r\n\r\nWhat I Have Stopped Doing\r\n===================\r\nLet me mention what I have stopped doing, mainly due to the [limitations the Travis build images have](https://github.com/travis-ci/travis-ci/issues/4990) for Python since well over a year.\r\n\r\n```yaml\r\n#-- FILE: .travis.yml\r\nlanguage: python\r\npython: \"3.5\"\r\ninstall:\r\n  - pip install tox\r\nscript:\r\n  - tox\r\nenv:\r\n  # NOTE: To generate (update) the env list run\r\n  # $ tox -l | sort | xargs -I ITEM echo \"  - TOXENV=\"ITEM\r\n  - TOXENV=py27-django17\r\n  - TOXENV=py27-django18\r\n  - TOXENV=py27-django19\r\n  - TOXENV=py27-django110\r\n  - TOXENV=py27-django111\r\n  - TOXENV=py33-django17\r\n  - TOXENV=py33-django18\r\n  - TOXENV=py34-django17\r\n  - TOXENV=py34-django18\r\n  - TOXENV=py34-django19\r\n  - TOXENV=py34-django110\r\n  - TOXENV=py34-django111\r\n  - TOXENV=py35-django18\r\n  - TOXENV=py35-django19\r\n  - TOXENV=py35-django110\r\n  - TOXENV=py35-django111\r\n  - TOXENV=py36-django111\r\n```\r\n\r\nThis is less stable than builds with dedicated Python versions and requires some manual maintenance (demonstrated by the NOTE comment in the code). It is technically though the result we need:\r\n\r\n- The `env:` section lists the jobs we would want to otherwise generate with a `tox-travis` solution,\r\n- or by simply a  `matrix: include: ` section with a full list of Python/Django combinations (which would be double the lines of code of the `env:` section, though).\r\n\r\nPlease let me know your thoughts!"},"comment":{"url":"https://api.github.com/repos/tox-dev/tox-travis/issues/comments/336987296","html_url":"https://github.com/tox-dev/tox-travis/issues/77#issuecomment-336987296","issue_url":"https://api.github.com/repos/tox-dev/tox-travis/issues/77","id":336987296,"user":{"login":"bittner","id":665072,"avatar_url":"https://avatars2.githubusercontent.com/u/665072?v=4","gravatar_id":"","url":"https://api.github.com/users/bittner","html_url":"https://github.com/bittner","followers_url":"https://api.github.com/users/bittner/followers","following_url":"https://api.github.com/users/bittner/following{/other_user}","gists_url":"https://api.github.com/users/bittner/gists{/gist_id}","starred_url":"https://api.github.com/users/bittner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bittner/subscriptions","organizations_url":"https://api.github.com/users/bittner/orgs","repos_url":"https://api.github.com/users/bittner/repos","events_url":"https://api.github.com/users/bittner/events{/privacy}","received_events_url":"https://api.github.com/users/bittner/received_events","type":"User","site_admin":false},"created_at":"2017-10-16T18:34:46Z","updated_at":"2017-10-16T18:34:46Z","author_association":"NONE","body":"I can answer a few questions of yours:\r\n\r\n> First, who am I to decide which convention is right for a project to use with Tox?\r\n\r\nSeriously, it looks like you're a much more considerate and careful person than quite a few other folks, especially from the Tox project. This is certainly a good thing, but fear not. Pick a [beautiful solution](https://www.python.org/dev/peps/pep-0020/) and let us get a :+1: from, say, @RonnyPfannschmidt, @obestwalter, and others. Then nobody will complain.\r\n\r\n> In your example, you have used `djangoXX` for the env names, whereas I have preferred to use `djXX`. In the case of the Python variants, it's Tox that has chosen, not me\r\n\r\nWhatever helps the Python eco-system to get [more readable](https://www.python.org/dev/peps/pep-0020/) and self-explaining configuration files and code. `pyXX` was certainly also not the most obvious choice, but we have now gotten used to it, and to translating it to `pythonX.X`.\r\n\r\nMy [example from above](https://github.com/tox-dev/tox-travis/issues/77#issuecomment-336852502) was to show a logical naming scheme that could be applied quite straight-forward to every framework that has a `<name>` and a semantic `<Major><minor>` version, to get translated to `NAME=M.m` as an environment value.\r\n\r\n> which frameworks need to have this shortcut\r\n\r\nThere are PRs for this. I'd start with Django, because I'm interested in it. (I could argue, it's the most popular framework. But let's have the community decide via PRs.)\r\n\r\nIn the end, it should really be just a list of accepted names (if at all). With the naming scheme explained above there is no maintenance nightmare to be expected.\r\n\r\n> I totally agree that Travis' configuration for excludes and environments is unfortunately verbose, but I don't see a great way around it.\r\n\r\nIf there is a way, technically, it would be cool to have a minimum setup (e.g. just the Python versions) and have them be split up into jobs according to the Tox configuration automagically, when `tox-travis` is operating.\r\n\r\nThat would be nice. Really nice."}}
{"actor":{"display_login":"bittner"}}