Skip to content

Commit a7682be

Browse files
authored
Remove dependency on tox in the CI/CD pipeline (#118)
* remove ruff from venv * no tox in ci * improve tests * update makefile
1 parent 0db00df commit a7682be

File tree

15 files changed

+194
-142
lines changed

15 files changed

+194
-142
lines changed

.github/actions/setup-poetry-env/action.yml

+12-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ runs:
1616
python-version: ${{ inputs.python-version }}
1717

1818
- name: Install Poetry
19-
uses: snok/install-poetry@v1
20-
with:
21-
virtualenvs-in-project: true
19+
env:
20+
POETRY_VERSION: "1.7.1"
21+
run: curl -sSL https://install.python-poetry.org | python - -y
22+
shell: bash
23+
24+
- name: Add Poetry to Path
25+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
26+
shell: bash
27+
28+
- name: Configure Poetry virtual environment in project
29+
run: poetry config virtualenvs.in-project true
30+
shell: bash
2231

2332
- name: Load cached venv
2433
id: cached-poetry-dependencies

.github/workflows/main.yml

+15-24
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
name: Main
22

33
on:
4-
push:
5-
branches:
6-
- main
74
pull_request:
85
types: [opened, synchronize, reopened]
6+
push:
7+
branches: [main]
98

109
jobs:
1110
quality:
@@ -31,40 +30,32 @@ jobs:
3130
- name: Check Poetry lock file consistency
3231
run: poetry lock --check
3332

34-
tox:
33+
tests-and-type-check:
3534
runs-on: ubuntu-latest
3635
strategy:
3736
matrix:
38-
python-version: ["3.8", "3.9", "3.10", "3.11"]
37+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
3938
fail-fast: false
39+
defaults:
40+
run:
41+
shell: bash
4042
steps:
4143
- name: Check out
4244
uses: actions/checkout@v4
4345

44-
- name: Set up python
45-
uses: actions/setup-python@v5
46+
- name: Set up the environment
47+
uses: ./.github/actions/setup-poetry-env
4648
with:
4749
python-version: ${{ matrix.python-version }}
4850

49-
- name: Install Poetry
50-
uses: snok/install-poetry@v1
51-
52-
- name: Load cached venv
53-
uses: actions/cache@v4
54-
with:
55-
path: .tox
56-
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
57-
58-
- name: Install tox
59-
run: |
60-
python -m pip install --upgrade pip
61-
python -m pip install tox tox-gh-actions
51+
- name: Run tests
52+
run: poetry run pytest tests --cov --cov-config=pyproject.toml --cov-report=xml
6253

63-
- name: Test with tox
64-
run: tox
54+
- name: Check typing
55+
run: poetry run mypy
6556

66-
- name: Upload coverage reports to Codecov with GitHub Action on Python 3.11
67-
uses: codecov/codecov-action@v4
57+
- name: Upload coverage reports to Codecov with GitHub Action on Python 3.11 for Ubuntu
58+
uses: codecov/codecov-action@v3
6859
if: ${{ matrix.python-version == '3.11' }}
6960

7061
check-docs:

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repos:
88
- id: trailing-whitespace
99

1010
- repo: https://github.com/astral-sh/ruff-pre-commit
11-
rev: "v0.5.0"
11+
rev: "v0.5.2"
1212
hooks:
1313
- id: ruff
1414
args: [--exit-non-zero-on-fix, --config=pyproject.toml]

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ build-and-publish: build publish ## Build and publish.
7272

7373
.PHONY: docs-test
7474
docs-test: ## Test if documentation can be built without warnings or errors
75-
@mkdocs build -s
75+
@poetry run mkdocs build -s
7676

7777
.PHONY: docs
7878
docs: ## Build and serve the documentation
79-
@mkdocs serve
79+
@poetry run mkdocs serve
8080

8181
.PHONY: help
8282
help:

cookiecutter_poetry/cli.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import os
24

35

hooks/post_gen_project.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/usr/bin/env python
2+
from __future__ import annotations
3+
24
import os
35
import shutil
46

hooks/pre_gen_project.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import re
24
import sys
35

poetry.lock

+72-65
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+5-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pytest = "^7.2.0"
2525
pre-commit = "^2.20.0"
2626
pytest-cookies = "^0.6.1"
2727
tox = "^3.25.1"
28-
deptry = "^0.12.0"
28+
deptry = "^0.16.2"
2929
mypy = "^0.991"
3030
pytest-cov = "^4.0.0"
3131

@@ -37,11 +37,6 @@ mkdocs-material = "^8.5.10"
3737
requires = ["poetry-core>=1.0.0"]
3838
build-backend = "poetry.core.masonry.api"
3939

40-
[tool.black]
41-
line-length = 120
42-
target-version = ['py37']
43-
preview = true
44-
4540
[tool.poetry.scripts]
4641
ccp = 'cookiecutter_poetry.cli:main'
4742

@@ -67,7 +62,7 @@ show_error_codes = "True"
6762

6863
[tool.deptry]
6964
extend_exclude = [
70-
"{{cookiecutter.project_name}}"
65+
".+/test_foo.py"
7166
]
7267

7368
[tool.deptry.per_rule_ignores]
@@ -120,3 +115,6 @@ ignore = [
120115

121116
[tool.ruff.lint.per-file-ignores]
122117
"tests/*" = ["S101", "S603"]
118+
119+
[tool.ruff.lint.isort]
120+
required-imports = ["from __future__ import annotations"]

tests/test_cookiecutter.py

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
1+
from __future__ import annotations
2+
13
import os
24
import shlex
35
import subprocess
4-
from contextlib import contextmanager
5-
6-
7-
@contextmanager
8-
def run_within_dir(path: str):
9-
oldpwd = os.getcwd()
10-
os.chdir(path)
11-
try:
12-
yield
13-
finally:
14-
os.chdir(oldpwd)
15-
166

17-
def file_contains_text(file: str, text: str) -> bool:
18-
with open(file) as f:
19-
return f.read().find(text) != -1
7+
from tests.utils import file_contains_text, is_valid_yaml, run_within_dir
208

219

2210
def test_bake_project(cookies):
@@ -37,6 +25,7 @@ def test_using_pytest(cookies, tmp_path):
3725
assert result.exception is None
3826
assert result.project_path.name == "example-project"
3927
assert result.project_path.is_dir()
28+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "main.yml")
4029

4130
# Install the poetry environment and run the tests.
4231
with run_within_dir(str(result.project_path)):
@@ -66,6 +55,7 @@ def test_cicd_contains_artifactory_secrets(cookies, tmp_path):
6655
with run_within_dir(tmp_path):
6756
result = cookies.bake(extra_context={"publish_to": "artifactory"})
6857
assert result.exit_code == 0
58+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "on-release-main.yml")
6959
for text in ["ARTIFACTORY_URL", "ARTIFACTORY_USERNAME", "ARTIFACTORY_PASSWORD"]:
7060
assert file_contains_text(f"{result.project_path}/.github/workflows/on-release-main.yml", text)
7161
assert file_contains_text(f"{result.project_path}/Makefile", "build-and-publish")
@@ -75,6 +65,7 @@ def test_cicd_contains_pypi_secrets(cookies, tmp_path):
7565
with run_within_dir(tmp_path):
7666
result = cookies.bake(extra_context={"publish_to": "pypi"})
7767
assert result.exit_code == 0
68+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "on-release-main.yml")
7869
assert file_contains_text(f"{result.project_path}/.github/workflows/on-release-main.yml", "PYPI_TOKEN")
7970
assert file_contains_text(f"{result.project_path}/Makefile", "build-and-publish")
8071

@@ -83,6 +74,7 @@ def test_dont_publish(cookies, tmp_path):
8374
with run_within_dir(tmp_path):
8475
result = cookies.bake(extra_context={"publish_to": "none"})
8576
assert result.exit_code == 0
77+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "on-release-main.yml")
8678
assert not file_contains_text(
8779
f"{result.project_path}/.github/workflows/on-release-main.yml", "make build-and-publish"
8880
)
@@ -92,6 +84,8 @@ def test_mkdocs(cookies, tmp_path):
9284
with run_within_dir(tmp_path):
9385
result = cookies.bake(extra_context={"mkdocs": "y"})
9486
assert result.exit_code == 0
87+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "main.yml")
88+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "on-release-main.yml")
9589
assert file_contains_text(f"{result.project_path}/.github/workflows/on-release-main.yml", "mkdocs gh-deploy")
9690
assert file_contains_text(f"{result.project_path}/Makefile", "docs:")
9791
assert os.path.isdir(f"{result.project_path}/docs")
@@ -101,6 +95,8 @@ def test_not_mkdocs(cookies, tmp_path):
10195
with run_within_dir(tmp_path):
10296
result = cookies.bake(extra_context={"mkdocs": "n"})
10397
assert result.exit_code == 0
98+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "main.yml")
99+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "on-release-main.yml")
104100
assert not file_contains_text(
105101
f"{result.project_path}/.github/workflows/on-release-main.yml", "mkdocs gh-deploy"
106102
)
@@ -112,7 +108,6 @@ def test_tox(cookies, tmp_path):
112108
with run_within_dir(tmp_path):
113109
result = cookies.bake()
114110
assert result.exit_code == 0
115-
assert file_contains_text(f"{result.project_path}/.github/workflows/main.yml", "pip install tox tox-gh-actions")
116111
assert os.path.isfile(f"{result.project_path}/tox.ini")
117112
assert file_contains_text(f"{result.project_path}/tox.ini", "[tox]")
118113

@@ -135,6 +130,7 @@ def test_codecov(cookies, tmp_path):
135130
with run_within_dir(tmp_path):
136131
result = cookies.bake()
137132
assert result.exit_code == 0
133+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "main.yml")
138134
assert os.path.isfile(f"{result.project_path}/codecov.yaml")
139135
assert os.path.isfile(f"{result.project_path}/.github/workflows/validate-codecov-config.yml")
140136

@@ -143,6 +139,7 @@ def test_not_codecov(cookies, tmp_path):
143139
with run_within_dir(tmp_path):
144140
result = cookies.bake(extra_context={"codecov": "n"})
145141
assert result.exit_code == 0
142+
assert is_valid_yaml(result.project_path / ".github" / "workflows" / "main.yml")
146143
assert not os.path.isfile(f"{result.project_path}/codecov.yaml")
147144
assert not os.path.isfile(f"{result.project_path}/.github/workflows/validate-codecov-config.yml")
148145

tests/utils.py

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from __future__ import annotations
2+
3+
import os
4+
from contextlib import contextmanager
5+
from pathlib import Path
6+
7+
import yaml
8+
9+
10+
def is_valid_yaml(path: str | Path):
11+
path = Path(path)
12+
13+
if not path.is_file():
14+
print(f"File does not exist: {path}")
15+
return False
16+
17+
try:
18+
with path.open("r") as file:
19+
yaml.safe_load(file)
20+
except yaml.YAMLError as e:
21+
print(f"Invalid YAML file: {path} - Error: {e}")
22+
return False
23+
except OSError as e:
24+
print(f"Error reading file: {path} - Error: {e}")
25+
return False
26+
27+
return True
28+
29+
30+
@contextmanager
31+
def run_within_dir(path: str):
32+
oldpwd = os.getcwd()
33+
os.chdir(path)
34+
try:
35+
yield
36+
finally:
37+
os.chdir(oldpwd)
38+
39+
40+
def file_contains_text(file: str, text: str) -> bool:
41+
with open(file) as f:
42+
return f.read().find(text) != -1

{{cookiecutter.project_name}}/.github/actions/setup-poetry-env/action.yml

+12-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ runs:
1616
python-version: {% raw %}${{ inputs.python-version }}{% endraw %}
1717

1818
- name: Install Poetry
19-
uses: snok/install-poetry@v1
20-
with:
21-
virtualenvs-in-project: true
19+
env:
20+
POETRY_VERSION: "1.7.1"
21+
run: curl -sSL https://install.python-poetry.org | python - -y
22+
shell: bash
23+
24+
- name: Add Poetry to Path
25+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
26+
shell: bash
27+
28+
- name: Configure Poetry virtual environment in project
29+
run: poetry config virtualenvs.in-project true
30+
shell: bash
2231

2332
- name: Load cached venv
2433
id: cached-poetry-dependencies

{{cookiecutter.project_name}}/.github/workflows/main.yml

+11-18
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,30 @@ jobs:
2525
- name: Run checks
2626
run: make check
2727

28-
tox:
28+
tests-and-type-check:
2929
runs-on: ubuntu-latest
3030
strategy:
3131
matrix:
32-
python-version: ['3.8', '3.9', '3.10', '3.11']
32+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
3333
fail-fast: false
34+
defaults:
35+
run:
36+
shell: bash
3437
steps:
3538
- name: Check out
3639
uses: actions/checkout@v4
3740

38-
- name: Set up python
39-
uses: actions/setup-python@v5
41+
- name: Set up the environment
42+
uses: ./.github/actions/setup-poetry-env
4043
with:
4144
python-version: {% raw %}${{ matrix.python-version }}{% endraw %}
4245

43-
- name: Install Poetry
44-
uses: snok/install-poetry@v1
45-
46-
- name: Load cached venv
47-
uses: actions/cache@v4
48-
with:
49-
path: .tox
50-
key: {% raw %}venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}{% endraw %}
46+
- name: Run tests
47+
run: poetry run pytest tests --cov --cov-config=pyproject.toml --cov-report=xml
5148

52-
- name: Install tox
53-
run: |
54-
python -m pip install --upgrade pip
55-
python -m pip install tox tox-gh-actions
49+
- name: Check typing
50+
run: poetry run mypy
5651

57-
- name: Test with tox
58-
run: tox
5952
{% if cookiecutter.codecov == "y" %}
6053
- name: Upload coverage reports to Codecov with GitHub Action on Python 3.11
6154
uses: codecov/codecov-action@v4

{{cookiecutter.project_name}}/.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repos:
1010
- id: trailing-whitespace
1111

1212
- repo: https://github.com/astral-sh/ruff-pre-commit
13-
rev: "v0.1.6"
13+
rev: "v0.5.2"
1414
hooks:
1515
- id: ruff
1616
args: [--exit-non-zero-on-fix]

0 commit comments

Comments
 (0)