Skip to content

Commit 7eb6cea

Browse files
committed
feat: initial commit
0 parents  commit 7eb6cea

File tree

14 files changed

+460
-0
lines changed

14 files changed

+460
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: CI
2+
3+
permissions:
4+
contents: read
5+
pull-requests: read
6+
7+
on:
8+
push:
9+
branches: [main]
10+
pull_request:
11+
branches: [main]
12+
13+
env:
14+
PYTHON_VERSION: "3.13"
15+
16+
jobs:
17+
lint-format:
18+
name: Ruff Lint & Format
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: ${{ env.PYTHON_VERSION }}
28+
29+
- uses: astral-sh/setup-uv@v6.1.0
30+
with:
31+
enable-cache: true
32+
33+
- name: Create virtual environment
34+
run: uv venv
35+
36+
- name: Install dev dependencies
37+
run: uv pip install --group dev
38+
39+
- name: Run Ruff Lint
40+
run: uv run ruff check .
41+
42+
- name: Run Ruff Format Check
43+
run: uv run ruff format --check .
44+
45+
test:
46+
name: Run Tests
47+
runs-on: ubuntu-latest
48+
49+
steps:
50+
- uses: actions/checkout@v4
51+
52+
- name: Set up Python
53+
uses: actions/setup-python@v5
54+
with:
55+
python-version: ${{ env.PYTHON_VERSION }}
56+
57+
- uses: astral-sh/setup-uv@v6.1.0
58+
with:
59+
enable-cache: true
60+
61+
- name: Create virtual environment
62+
run: uv venv
63+
64+
- name: Install dev dependencies
65+
run: uv pip install --group dev
66+
67+
- name: Run Pytest
68+
run: uv run pytest
69+
70+
gitleaks:
71+
name: Scan for Secrets
72+
runs-on: ubuntu-latest
73+
74+
steps:
75+
- uses: actions/checkout@v4
76+
with:
77+
fetch-depth: 0
78+
- uses: gitleaks/gitleaks-action@v2
79+
env:
80+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
6+
permissions:
7+
contents: write
8+
id-token: write
9+
10+
env:
11+
PYTHON_VERSION: "3.13"
12+
13+
jobs:
14+
bump:
15+
if: "!startsWith(github.event.head_commit.message, 'bump:')"
16+
runs-on: ubuntu-latest
17+
name: "Bump version and create changelog with commitizen"
18+
steps:
19+
- name: Check out
20+
uses: actions/checkout@v3
21+
with:
22+
fetch-depth: 0
23+
token: "${{ secrets.GITHUB_TOKEN }}"
24+
- id: cz
25+
name: Create bump and changelog
26+
uses: commitizen-tools/commitizen-action@master
27+
with:
28+
github_token: ${{ secrets.GITHUB_TOKEN }}
29+
- name: Print Version
30+
run: echo "Bumped to version ${{ steps.cz.outputs.version }}"
31+
32+
build:
33+
needs: bump
34+
runs-on: ubuntu-latest
35+
outputs:
36+
version: ${{ steps.version.outputs.version }}
37+
steps:
38+
- uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
42+
- uses: astral-sh/setup-uv@v6.1.0
43+
with:
44+
enable-cache: true
45+
46+
- uses: actions/setup-python@v5
47+
with:
48+
python-version: ${{ env.PYTHON_VERSION }}
49+
50+
- name: Set reproducible build timestamp
51+
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
52+
53+
- run: uv build
54+
55+
- uses: actions/upload-artifact@v4
56+
with:
57+
name: dist
58+
path: dist
59+
60+
create-release:
61+
needs: build
62+
runs-on: ubuntu-latest
63+
permissions:
64+
contents: write
65+
steps:
66+
- uses: actions/download-artifact@v4
67+
with:
68+
name: dist
69+
path: dist
70+
71+
- name: Create GitHub Draft Release
72+
run: |
73+
gh release create --draft --repo ${{ github.repository }} ${{ github.ref_name }} dist/*
74+
env:
75+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
77+
publish:
78+
needs: build
79+
runs-on: ubuntu-latest
80+
steps:
81+
- uses: actions/download-artifact@v4
82+
with:
83+
name: dist
84+
path: dist
85+
86+
- uses: astral-sh/setup-uv@v6.1.0
87+
with:
88+
enable-cache: true
89+
90+
- uses: actions/setup-python@v5
91+
with:
92+
python-version: ${{ env.PYTHON_VERSION }}
93+
94+
- name: Publish to PyPI
95+
run: uv publish

.gitignore

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[codz]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# Unit test / coverage reports
30+
htmlcov/
31+
.tox/
32+
.nox/
33+
.coverage
34+
.coverage.*
35+
.cache
36+
nosetests.xml
37+
coverage.xml
38+
*.cover
39+
*.py.cover
40+
.hypothesis/
41+
.pytest_cache/
42+
cover/
43+
44+
# Celery stuff
45+
celerybeat-schedule
46+
celerybeat.pid
47+
48+
# Environments
49+
.env
50+
.envrc
51+
.venv
52+
env/
53+
venv/
54+
ENV/
55+
env.bak/
56+
venv.bak/
57+
58+
59+
# mypy
60+
.mypy_cache/
61+
.dmypy.json
62+
dmypy.json
63+
64+
# Pyre type checker
65+
.pyre/
66+
67+
# pytype static type analyzer
68+
.pytype/
69+
70+
# Cython debug symbols
71+
cython_debug/
72+
73+
# PyCharm
74+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
75+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
76+
# and can be added to the global gitignore or merged into this file. For a more nuclear
77+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
78+
.idea/
79+
80+
# Abstra
81+
# Abstra is an AI-powered process automation framework.
82+
# Ignore directories containing user credentials, local state, and settings.
83+
# Learn more at https://abstra.io/docs
84+
.abstra/
85+
86+
# Visual Studio Code
87+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
88+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
89+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
90+
# you could uncomment the following to ignore the entire vscode folder
91+
.vscode/
92+
93+
# Ruff stuff:
94+
.ruff_cache/
95+
96+
# PyPI configuration file
97+
.pypirc
98+
99+
# Cursor
100+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
101+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
102+
# refer to https://docs.cursor.com/context/ignore-files
103+
.cursorignore
104+
.cursorindexingignore
105+
106+
# ignore manual test
107+
manual/

.pre-commit-config.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: check-commit-message
5+
name: Check Conventional Commit
6+
entry: cz check --commit-msg-file
7+
language: system
8+
stages: [commit-msg]
9+
- repo: https://github.com/astral-sh/ruff-pre-commit
10+
rev: v0.12.2
11+
hooks:
12+
- id: ruff
13+
args: [ --fix ]
14+
- id: ruff-format
15+
- repo: https://github.com/astral-sh/uv-pre-commit
16+
rev: 0.7.19
17+
hooks:
18+
- id: uv-lock
19+
- repo: https://github.com/gitleaks/gitleaks
20+
rev: v8.18.0
21+
hooks:
22+
- id: gitleaks
23+
exclude: '^\.env\.test$'
24+
- repo: https://github.com/pre-commit/pre-commit-hooks
25+
rev: v5.0.0
26+
hooks:
27+
- id: check-added-large-files
28+
- id: check-ast
29+
- id: check-builtin-literals
30+
- id: check-case-conflict
31+
- id: check-docstring-first
32+
- id: check-illegal-windows-names
33+
- id: check-json
34+
- id: check-shebang-scripts-are-executable
35+
- id: check-symlinks
36+
- id: check-toml
37+
- id: check-xml
38+
- id: check-yaml
39+
- id: debug-statements
40+
- id: destroyed-symlinks
41+
- id: detect-private-key
42+
- id: end-of-file-fixer
43+
types: [ python ]
44+
- id: fix-byte-order-marker
45+
- id: mixed-line-ending
46+
args: [--fix=lf]
47+
- id: name-tests-test
48+
args: [ --pytest ]
49+
- id: trailing-whitespace
50+
types: [ python ]
51+
- id: pretty-format-json
52+
args: [--autofix]

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

CHANGELOG.md

Whitespace-only changes.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2025 Marc-Olivier Gagnon
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

0 commit comments

Comments
 (0)