Skip to content

Commit 142332b

Browse files
authored
Modernize project infrastructure with pyproject.toml, uv, and comprehensive CI/CD (#56)
1 parent c0e99fb commit 142332b

24 files changed

Lines changed: 1097 additions & 330 deletions

.github/workflows/ci.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ['3.10', '3.11', '3.12', '3.13']
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Install uv
20+
uses: astral-sh/setup-uv@v5
21+
with:
22+
enable-cache: true
23+
24+
- name: Set up Python ${{ matrix.python-version }}
25+
run: uv python install ${{ matrix.python-version }}
26+
27+
- name: Install dependencies
28+
run: uv sync --extra dev
29+
30+
- name: Lint with ruff
31+
id: ruff-check
32+
run: |
33+
source .venv/bin/activate
34+
35+
echo "::group::Ruff Check"
36+
if ! ruff check .; then
37+
echo "::error::Ruff check failed. Please run 'ruff check --fix .' locally to fix issues."
38+
echo "::notice::See contributing guidelines at https://github.com/viddexa/safetext/blob/main/CONTRIBUTING.md"
39+
exit 1
40+
fi
41+
echo "::endgroup::"
42+
43+
echo "::group::Ruff Format"
44+
if ! ruff format --check .; then
45+
echo "::error::Ruff format check failed. Please run 'ruff format .' locally to fix formatting."
46+
echo "::notice::See contributing guidelines at https://github.com/viddexa/safetext/blob/main/CONTRIBUTING.md"
47+
exit 1
48+
fi
49+
echo "::endgroup::"
50+
51+
- name: Run tests
52+
run: |
53+
source .venv/bin/activate
54+
pytest -v --cov=safetext --cov-report=term-missing -n auto
55+
56+
- name: Test package installation
57+
run: |
58+
source .venv/bin/activate
59+
python -m build
60+
pip install --no-deps dist/*.whl
61+
python -c "from safetext import SafeText; st = SafeText('en'); print('Package imported successfully')"

.github/workflows/daily-test.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Daily Package Test
2+
3+
on:
4+
schedule:
5+
# Runs at 08:00 UTC every day
6+
- cron: '0 8 * * *'
7+
workflow_dispatch: # Allow manual triggering
8+
9+
jobs:
10+
test-install:
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
matrix:
14+
os: [ubuntu-latest, windows-latest, macos-latest]
15+
python-version: ['3.10', '3.11', '3.12', '3.13']
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v5
22+
with:
23+
enable-cache: true
24+
25+
- name: Set up Python ${{ matrix.python-version }}
26+
run: uv python install ${{ matrix.python-version }}
27+
28+
- name: Test PyPI package installation
29+
shell: bash
30+
run: |
31+
python -m venv test-env
32+
if [[ "$RUNNER_OS" == "Windows" ]]; then
33+
source test-env/Scripts/activate
34+
else
35+
source test-env/bin/activate
36+
fi
37+
pip install safetext
38+
python -c "from safetext import SafeText; st = SafeText('en'); result = st.check_profanity('test shit'); print(f'Profanity detection working: {result}')"
39+
40+
- name: Test development installation
41+
shell: bash
42+
run: |
43+
uv sync --extra dev
44+
if [[ "$RUNNER_OS" == "Windows" ]]; then
45+
source .venv/Scripts/activate
46+
else
47+
source .venv/bin/activate
48+
fi
49+
pytest -v -n auto
50+
51+
- name: Test all language support
52+
shell: bash
53+
run: |
54+
if [[ "$RUNNER_OS" == "Windows" ]]; then
55+
source .venv/Scripts/activate
56+
else
57+
source .venv/bin/activate
58+
fi
59+
cat > test_languages.py << 'EOF'
60+
from safetext import SafeText
61+
languages = ['ar', 'az', 'de', 'en', 'es', 'fa', 'fr', 'hi', 'ja', 'pt', 'ru', 'tr', 'zh']
62+
for lang in languages:
63+
try:
64+
st = SafeText(lang)
65+
print(f'✓ {lang} loaded successfully')
66+
except Exception as e:
67+
print(f'✗ {lang} failed: {e}')
68+
exit(1)
69+
EOF
70+
python test_languages.py
71+
72+
- name: Check for dependency conflicts
73+
shell: bash
74+
run: |
75+
if [[ "$RUNNER_OS" == "Windows" ]]; then
76+
source .venv/Scripts/activate
77+
else
78+
source .venv/bin/activate
79+
fi
80+
pip check
81+
82+
- name: Report status
83+
if: failure()
84+
uses: actions/github-script@v7
85+
with:
86+
script: |
87+
const os = '${{ matrix.os }}';
88+
const python = '${{ matrix.python-version }}';
89+
github.rest.issues.create({
90+
owner: context.repo.owner,
91+
repo: context.repo.repo,
92+
title: `Daily test failed on ${os} Python ${python}`,
93+
body: `The daily package test failed. Please check the [workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}).`,
94+
labels: ['ci-failure', 'automated']
95+
})

.github/workflows/publish-pypi.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Publish Python Package
2+
3+
on:
4+
release:
5+
types: [published, edited]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v5
16+
with:
17+
enable-cache: true
18+
19+
- name: Set up Python
20+
run: uv python install 3.12
21+
22+
- name: Build package
23+
run: |
24+
uv sync --extra dev
25+
source .venv/bin/activate
26+
python -m build
27+
28+
- name: Publish to PyPI
29+
env:
30+
TWINE_USERNAME: __token__
31+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
32+
run: |
33+
source .venv/bin/activate
34+
twine upload --verbose --skip-existing dist/*

.github/workflows/publish_pypi.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

.gitignore

Lines changed: 17 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ parts/
2020
sdist/
2121
var/
2222
wheels/
23-
pip-wheel-metadata/
2423
share/python-wheels/
2524
*.egg-info/
2625
.installed.cfg
2726
*.egg
2827
MANIFEST
2928

3029
# PyInstaller
31-
# Usually these files are written by a python script from a template
32-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
3330
*.manifest
3431
*.spec
3532

@@ -50,58 +47,9 @@ coverage.xml
5047
*.py,cover
5148
.hypothesis/
5249
.pytest_cache/
50+
cover/
5351

54-
# Translations
55-
*.mo
56-
*.pot
57-
58-
# Django stuff:
59-
*.log
60-
local_settings.py
61-
db.sqlite3
62-
db.sqlite3-journal
63-
64-
# Flask stuff:
65-
instance/
66-
.webassets-cache
67-
68-
# Scrapy stuff:
69-
.scrapy
70-
71-
# Sphinx documentation
72-
docs/_build/
73-
74-
# PyBuilder
75-
target/
76-
77-
# Jupyter Notebook
78-
.ipynb_checkpoints
79-
80-
# IPython
81-
profile_default/
82-
ipython_config.py
83-
84-
# pyenv
85-
.python-version
86-
87-
# pipenv
88-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
90-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
91-
# install all needed dependencies.
92-
#Pipfile.lock
93-
94-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
95-
__pypackages__/
96-
97-
# Celery stuff
98-
celerybeat-schedule
99-
celerybeat.pid
100-
101-
# SageMath parsed files
102-
*.sage.py
103-
104-
# Environments
52+
# Virtual environments
10553
.env
10654
.venv
10755
env/
@@ -110,15 +58,17 @@ ENV/
11058
env.bak/
11159
venv.bak/
11260

113-
# Spyder project settings
114-
.spyderproject
115-
.spyproject
116-
117-
# Rope project settings
118-
.ropeproject
61+
# IDEs
62+
.idea/
63+
.vscode/
64+
*.swp
65+
*.swo
66+
*~
67+
.DS_Store
11968

120-
# mkdocs documentation
121-
/site
69+
# uv
70+
.uv/
71+
uv.lock
12272

12373
# mypy
12474
.mypy_cache/
@@ -128,4 +78,8 @@ dmypy.json
12878
# Pyre type checker
12979
.pyre/
13080

131-
testing.py
81+
# pytype static type analyzer
82+
.pytype/
83+
84+
# Cython debug symbols
85+
cython_debug/

0 commit comments

Comments
 (0)