Skip to content

Commit ec615d4

Browse files
authored
feat: init repo (#1)
1 parent 04f8ed4 commit ec615d4

23 files changed

+1748
-0
lines changed

.codecov.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coverage:
2+
status:
3+
project:
4+
default:
5+
target: 70%
6+
patch:
7+
default:
8+
target: 70%

.github/renovate.json5

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
$schema: "https://docs.renovatebot.com/renovate-schema.json",
3+
extends: ["config:recommended"],
4+
}

.github/workflows/cd.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: cd
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
issues: write
12+
pull-requests: write
13+
14+
jobs:
15+
# ====================================================
16+
# Versioning and Release
17+
# ====================================================
18+
semantic-release:
19+
name: semantic-release
20+
uses: wislertt/zerv/.github/workflows/shared-semantic-release.yml@v0
21+
with:
22+
allowed_workflow_dispatch_branches: '["main"]'
23+
fail_on_invalid_workflow_dispatch_ref: true
24+
25+
zerv-versioning:
26+
needs: semantic-release
27+
if: needs.semantic-release.outputs.is_valid_semantic_release == 'true'
28+
uses: wislertt/zerv/.github/workflows/shared-zerv-versioning.yml@v0
29+
30+
create-version-prefix-tags:
31+
needs: zerv-versioning
32+
uses: wislertt/zerv/.github/workflows/shared-create-tags.yml@v0
33+
with:
34+
tags: >-
35+
[
36+
"${{ fromJson(needs.zerv-versioning.outputs.versions).v_major }}",
37+
"${{ fromJson(needs.zerv-versioning.outputs.versions).v_major_minor }}"
38+
]
39+
40+
# ====================================================
41+
# Test and Lint
42+
# ====================================================
43+
test:
44+
uses: ./.github/workflows/test.yml
45+
secrets:
46+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
47+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
48+
49+
pre-commit:
50+
uses: ./.github/workflows/pre-commit.yml
51+
52+
# ====================================================
53+
# Deployment
54+
# ====================================================
55+
publish-pypi:
56+
needs: zerv-versioning
57+
uses: ./.github/workflows/publish.yml
58+
with:
59+
version: ${{ fromJson(needs.zerv-versioning.outputs.versions).pep440 }}
60+
python_version: "3.14"
61+
secrets:
62+
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
63+
64+
publish-test-pypi:
65+
needs: zerv-versioning
66+
uses: ./.github/workflows/publish.yml
67+
with:
68+
version: ${{ fromJson(needs.zerv-versioning.outputs.versions).pep440 }}
69+
python_version: "3.14"
70+
repository_url: https://test.pypi.org/legacy/
71+
secrets:
72+
PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}

.github/workflows/ci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
types: [labeled, unlabeled, opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: write
9+
id-token: write
10+
11+
jobs:
12+
# ====================================================
13+
# Versioning and Release
14+
# ====================================================
15+
check-pre-release:
16+
name: check-pre-release
17+
uses: wislertt/zerv/.github/workflows/shared-check-pr-label-and-branch.yml@v0
18+
with:
19+
target_label: "pre-release"
20+
branch_prefixes: '["release/"]'
21+
branch_names: '["develop"]'
22+
23+
zerv-versioning:
24+
name: zerv-versioning
25+
needs: check-pre-release
26+
uses: wislertt/zerv/.github/workflows/shared-zerv-versioning.yml@v0
27+
with:
28+
schema: ${{ (needs.check-pre-release.outputs.is_valid == 'true' && 'standard-base-prerelease-post') || '' }}
29+
30+
tag-pre-release:
31+
name: tag-pre-release
32+
needs: [zerv-versioning, check-pre-release]
33+
if: needs.check-pre-release.outputs.is_valid == 'true'
34+
uses: wislertt/zerv/.github/workflows/shared-create-tags.yml@v0
35+
with:
36+
tags: '["${{ fromJson(needs.zerv-versioning.outputs.versions).v_semver }}"]'
37+
38+
# ====================================================
39+
# Test and Lint
40+
# ====================================================
41+
test:
42+
uses: ./.github/workflows/test.yml
43+
secrets:
44+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
45+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
46+
47+
pre-commit:
48+
uses: ./.github/workflows/pre-commit.yml
49+
50+
# ====================================================
51+
# Deployment
52+
# ====================================================
53+
publish-test-pypi:
54+
if: needs.check-pre-release.outputs.is_valid == 'true'
55+
needs: [zerv-versioning, check-pre-release]
56+
uses: ./.github/workflows/publish.yml
57+
with:
58+
version: ${{ fromJson(needs.zerv-versioning.outputs.versions).pep440 }}
59+
python_version: "3.14"
60+
repository_url: https://test.pypi.org/legacy/
61+
secrets:
62+
PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}

.github/workflows/pre-commit.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: pre-commit
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
pre-commit:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: checkout
11+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
12+
with:
13+
fetch-depth: 0
14+
submodules: recursive
15+
token: ${{ secrets.GITHUB_TOKEN }}
16+
17+
- name: setup-python
18+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
19+
with:
20+
python-version: "3.14"
21+
22+
- name: setup-uv
23+
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
24+
with:
25+
version: "latest"
26+
enable-cache: true
27+
28+
- name: cache-uv
29+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
30+
with:
31+
path: ${{ github.workspace }}/.venv
32+
key: uv-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('uv.lock') }}
33+
restore-keys: |
34+
uv-${{ runner.os }}-py${{ matrix.python-version }}-
35+
uv-${{ runner.os }}-
36+
37+
- name: install-dependencies
38+
run: uv sync --all-groups
39+
40+
- name: setup-bun
41+
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2
42+
with:
43+
bun-version: latest
44+
45+
- name: run-pre-commit
46+
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
47+
with:
48+
extra_args: --all-files

.github/workflows/publish.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: publish-python-package
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
version:
7+
required: true
8+
type: string
9+
description: "PEP440 version string"
10+
repository_url:
11+
required: false
12+
type: string
13+
description: "PyPI repository URL (default: official PyPI)"
14+
default: ""
15+
python_version:
16+
required: false
17+
type: string
18+
description: "Python version"
19+
secrets:
20+
PYPI_API_TOKEN:
21+
required: true
22+
23+
jobs:
24+
publish:
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- name: checkout
29+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
30+
31+
- name: update-version-in-pyproject-toml
32+
run: |
33+
sed -i.bak 's/^version = .*/version = "${{ inputs.version }}"/' pyproject.toml
34+
grep '^version' pyproject.toml
35+
36+
- name: setup-python
37+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
38+
with:
39+
python-version: ${{ inputs.python_version }}
40+
41+
- name: setup-uv
42+
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
43+
44+
- name: build-package
45+
run: uv build
46+
47+
- name: publish-to-pypi
48+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
49+
with:
50+
repository-url: ${{ inputs.repository_url || '' }}
51+
password: ${{ secrets.PYPI_API_TOKEN }}
52+
verbose: true
53+
skip-existing: true

.github/workflows/security.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: security
2+
on:
3+
push:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "0 4 * * *" # run once a day at 4 AM
7+
8+
jobs:
9+
trivy-scan:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: checkout
14+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
15+
16+
- name: run-trivy-scan
17+
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
18+
with:
19+
scan-type: fs
20+
format: table
21+
exit-code: "1"
22+
vuln-type: "os,library"
23+
24+
gitleaks:
25+
name: gitleaks
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: checkout
30+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
31+
with:
32+
fetch-depth: 0
33+
34+
- name: run-gitleaks
35+
uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
36+
env:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
types: [opened, edited, synchronize, reopened]
7+
8+
permissions:
9+
pull-requests: read
10+
11+
jobs:
12+
semantic-pull-request:
13+
name: semantic-pull-request
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
17+
name: validate-py-title
18+
env:
19+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Reusable Test Workflow
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
python_versions:
7+
type: string
8+
default: "['3.10', '3.11', '3.12', '3.13', '3.14']"
9+
description: "JSON array of Python versions to test"
10+
target_python_version:
11+
type: string
12+
default: "3.14"
13+
description: "Python version to use for coverage and SonarQube scans"
14+
upload_coverage:
15+
type: boolean
16+
default: true
17+
description: "Whether to upload coverage reports"
18+
secrets:
19+
SONAR_TOKEN:
20+
required: false
21+
CODECOV_TOKEN:
22+
required: false
23+
24+
jobs:
25+
test:
26+
runs-on: ubuntu-latest
27+
strategy:
28+
matrix:
29+
python-version: ${{ fromJson(inputs.python_versions) }}
30+
31+
steps:
32+
- name: checkout
33+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
34+
35+
- name: setup-python
36+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
37+
with:
38+
python-version: ${{ matrix.python-version }}
39+
40+
- name: setup-uv
41+
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
42+
with:
43+
version: "latest"
44+
enable-cache: true
45+
46+
- name: cache-uv
47+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
48+
with:
49+
path: ${{ github.workspace }}/.venv
50+
key: uv-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('uv.lock') }}
51+
restore-keys: |
52+
uv-${{ runner.os }}-py${{ matrix.python-version }}-
53+
uv-${{ runner.os }}-
54+
55+
- name: install-dependencies
56+
run: uv sync --all-groups --frozen
57+
58+
- name: run-tests
59+
run: make test
60+
61+
- name: sonarqube-scan
62+
if: matrix.python-version == inputs.target_python_version && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
63+
uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6.0.0
64+
env:
65+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
66+
67+
- name: upload-coverage-reports-to-codecov
68+
if: matrix.python-version == inputs.target_python_version && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
69+
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
70+
with:
71+
fail_ci_if_error: true
72+
token: ${{ secrets.CODECOV_TOKEN }}
73+
verbose: true

0 commit comments

Comments
 (0)