initial commit

This commit is contained in:
Brian Bjarke Jensen
2025-09-19 19:20:47 +02:00
parent a481796d07
commit 0abd398c10
8 changed files with 956 additions and 2 deletions
+74
View File
@@ -0,0 +1,74 @@
name: Python Code Quality Pipeline
on:
workflow_call:
inputs:
python-version:
description: 'Python version to use (e.g., "3.12")'
required: false
type: string
default: "3.12"
working-directory:
description: 'Working directory for the project'
required: false
type: string
default: "."
skip-mypy:
description: 'Skip mypy type checking'
required: false
type: boolean
default: false
skip-pyupgrade:
description: 'Skip pyupgrade check'
required: false
type: boolean
default: false
uv-extras:
description: 'UV extras to install (e.g., "dev,test")'
required: false
type: string
default: "all-extras"
jobs:
code-quality:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- name: Install uv
run: pip install uv
- name: Install dependencies
env:
UV_LINK_MODE: copy
run: |
if [ "${{ inputs.uv-extras }}" = "all-extras" ]; then
uv sync --all-extras
else
uv sync --extra ${{ inputs.uv-extras }}
fi
- name: Type check with mypy
if: ${{ !inputs.skip-mypy }}
run: uv run mypy .
- name: Ruff lint
run: uv run ruff check .
- name: Ruff format
run: uv run ruff format --check .
- name: Pyupgrade check
if: ${{ !inputs.skip-pyupgrade }}
run: uv run pyupgrade --py312-plus $(git ls-files '*.py') && git diff --exit-code
+101
View File
@@ -0,0 +1,101 @@
name: Python Test Pipeline
on:
workflow_call:
inputs:
python-version:
description: 'Python version to use (e.g., "3.12")'
required: false
type: string
default: "3.12"
working-directory:
description: 'Working directory for the project'
required: false
type: string
default: "."
uv-extras:
description: 'UV extras to install (e.g., "dev,test")'
required: false
type: string
default: "all-extras"
pytest-args:
description: 'Additional arguments to pass to pytest'
required: false
type: string
default: ""
coverage-package:
description: 'Package name for coverage reporting (e.g., "my_package")'
required: false
type: string
default: ""
skip-coverage-comment:
description: 'Skip posting coverage comment to PR'
required: false
type: boolean
default: false
api-url:
description: 'Gitea API URL for posting comments'
required: false
type: string
default: ""
secrets:
CI_RUNNER_TOKEN:
description: 'Token for posting PR comments'
required: false
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- name: Install uv
run: pip install uv
- name: Install dependencies
env:
UV_LINK_MODE: copy
run: |
if [ "${{ inputs.uv-extras }}" = "all-extras" ]; then
uv sync --all-extras
else
uv sync --extra ${{ inputs.uv-extras }}
fi
- name: Run pytest
env:
PYTHONPATH: .
run: |
if [ -n "${{ inputs.coverage-package }}" ]; then
uv run pytest --cov=${{ inputs.coverage-package }} --cov-report=term-missing ${{ inputs.pytest-args }} > coverage.txt
else
uv run pytest ${{ inputs.pytest-args }}
fi
- name: Post coverage summary to PR
if: ${{ !inputs.skip-coverage-comment && inputs.coverage-package != '' && github.event_name == 'pull_request' && inputs.api-url != '' }}
env:
API_URL: ${{ inputs.api-url }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }}
run: |
if [ -f coverage.txt ]; then
COVERAGE=$(cat coverage.txt)
COMMENT_BODY="**Test Coverage Report:**\n\`\`\`\n$COVERAGE\n\`\`\`"
curl -s -X POST "$API_URL/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments" \
-H "Authorization: token $CI_RUNNER_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"body\": \"$COMMENT_BODY\"}"
fi
+87
View File
@@ -0,0 +1,87 @@
name: Web/General Formatting Pipeline
on:
workflow_call:
inputs:
working-directory:
description: 'Working directory for the project'
required: false
type: string
default: "."
node-version:
description: 'Node.js version to use for prettier (e.g., "20")'
required: false
type: string
default: "20"
skip-prettier:
description: 'Skip prettier formatting check'
required: false
type: boolean
default: false
prettier-config:
description: 'Path to prettier config file (optional)'
required: false
type: string
default: ""
check-yaml:
description: 'Check YAML files with yamllint'
required: false
type: boolean
default: false
check-json:
description: 'Check JSON files for validity'
required: false
type: boolean
default: false
jobs:
formatting:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
if: ${{ !inputs.skip-prettier }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Install prettier
if: ${{ !inputs.skip-prettier }}
run: npm install --save-dev --save-exact prettier
- name: Run prettier check
if: ${{ !inputs.skip-prettier }}
run: |
if [ -n "${{ inputs.prettier-config }}" ]; then
npx prettier --check . --config ${{ inputs.prettier-config }}
else
npx prettier --check .
fi
- name: Set up Python for YAML linting
if: ${{ inputs.check-yaml }}
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install yamllint
if: ${{ inputs.check-yaml }}
run: pip install yamllint
- name: Check YAML files
if: ${{ inputs.check-yaml }}
run: yamllint .
- name: Check JSON files
if: ${{ inputs.check-json }}
run: |
find . -name "*.json" -type f | while read -r file; do
echo "Checking $file"
python -m json.tool "$file" > /dev/null
done
+126
View File
@@ -0,0 +1,126 @@
# Python Code Quality Pipeline Template
A reusable Gitea Actions workflow for Python code quality checks including type checking, linting, and formatting.
## Features
- **Type checking** with mypy
- **Linting** with ruff
- **Code formatting** with ruff
- **Python version upgrades** with pyupgrade
- **Flexible configuration** with optional steps and customizable inputs
## Usage
To use this reusable workflow in your repository, create a workflow file (e.g., `.gitea/workflows/python/code-quality.yml`) in your target repository:
### Basic Usage
```yaml
name: Code Quality
on:
push:
branches:
- main
pull_request:
jobs:
code-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
```
### Advanced Usage with Custom Inputs
```yaml
name: Code Quality
on:
push:
branches:
- main
pull_request:
jobs:
code-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
python-version: "3.11"
working-directory: "./backend"
uv-extras: "dev,test"
```
## Available Inputs
| Input | Description | Required | Default | Type |
|-------|-------------|----------|---------|------|
| `python-version` | Python version to use (e.g., "3.12") | No | "3.12" | string |
| `working-directory` | Working directory for the project | No | "." | string |
| `skip-mypy` | Skip mypy type checking | No | false | boolean |
| `skip-pyupgrade` | Skip pyupgrade check | No | false | boolean |
| `uv-extras` | UV extras to install (e.g., "dev,test") | No | "all-extras" | string |
## Requirements
Your Python project should have:
1. A `pyproject.toml` file with uv dependency management
2. Properly configured tools:
- `mypy` for type checking (if not skipped)
- `ruff` for linting and formatting
- `pyupgrade` for Python version upgrades (if not skipped)
3. Optional: prettier configuration for non-Python files (if not skipped)
## Examples
### Skip mypy for a project without type hints
```yaml
jobs:
code-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
skip-mypy: true
```
### Use specific Python version and extras
```yaml
jobs:
code-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
python-version: "3.11"
uv-extras: "dev,lint"
```
### Monorepo with specific working directory
```yaml
jobs:
backend-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
working-directory: "./backend"
ml-service-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
working-directory: "./ml-service"
python-version: "3.11"
```
## Repository Structure
For this template to work properly, ensure your repository has the workflow file in the correct location:
```
.gitea/
workflows/
python/
code-quality.yml # This reusable workflow
```
## Contributing
To update this template, modify the workflow file and ensure all changes are backward compatible or properly versioned using git tags.
+248
View File
@@ -0,0 +1,248 @@
# Python Test Pipeline Template
A reusable Gitea Actions workflow for running Python tests with pytest, including optional coverage reporting and PR comment integration.
## Features
- **Pytest testing** with configurable arguments
- **Coverage reporting** with pytest-cov
- **PR comment integration** for coverage reports
- **UV package management** support
- **Flexible configuration** with optional steps and customizable inputs
- **Monorepo support** with working directory configuration
## Usage
### Basic Usage
Create a workflow file in your repository (e.g., `.github/workflows/test.yml`):
```yaml
name: Tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
coverage-package: "my_package"
```
### Advanced Usage with PR Comments
```yaml
name: Tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
python-version: "3.11"
coverage-package: "data_store"
pytest-args: "--verbose --tb=short"
api-url: "https://gitea.gt-proj.com/api/v1"
secrets:
CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }}
```
### Examples
### Skip coverage reporting
```yaml
jobs:
test:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
pytest-args: "--verbose"
```
### Custom pytest configuration
```yaml
jobs:
test:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
coverage-package: "myapp"
pytest-args: "--maxfail=1 --tb=short -x"
uv-extras: "test,dev"
```
### Monorepo with specific working directory
```yaml
jobs:
backend-tests:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
working-directory: "./backend"
coverage-package: "backend_api"
ml-service-tests:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/pytest.yml@main
with:
working-directory: "./ml-service"
coverage-package: "ml_models"
python-version: "3.11"
```
## Available Inputs
| Input | Description | Required | Default | Type |
|-------|-------------|----------|---------|------|
| `python-version` | Python version to use (e.g., "3.12") | No | "3.12" | string |
| `working-directory` | Working directory for the project | No | "." | string |
| `uv-extras` | UV extras to install (e.g., "dev,test") | No | "all-extras" | string |
| `pytest-args` | Additional arguments to pass to pytest | No | "" | string |
| `coverage-package` | Package name for coverage reporting | No | "" | string |
| `skip-coverage-comment` | Skip posting coverage comment to PR | No | false | boolean |
| `api-url` | Gitea API URL for posting comments | No | "" | string |
## Available Secrets
| Secret | Description | Required |
|--------|-------------|----------|
| `CI_RUNNER_TOKEN` | Token for posting PR comments | No* |
*Required only if you want coverage comments on PRs
## Coverage Reporting
### Enabling Coverage
Set the `coverage-package` input to your main package name:
```yaml
with:
coverage-package: "my_package"
```
This will:
1. Run pytest with `--cov=my_package --cov-report=term-missing`
2. Generate a coverage report
3. Save the output to `coverage.txt`
### PR Comments
To enable coverage comments on pull requests:
1. **Set required inputs:**
```yaml
with:
coverage-package: "my_package"
api-url: "https://your-gitea-instance.com/api/v1"
```
2. **Provide the CI token secret:**
```yaml
secrets:
CI_RUNNER_TOKEN: ${{ secrets.CI_RUNNER_TOKEN }}
```
3. **Create the token in Gitea:**
- Go to your Gitea instance → Settings → Applications → Generate New Token
- Grant `repo` permissions
- Add it as a repository secret named `CI_RUNNER_TOKEN`
### Coverage Comment Format
The coverage comment will appear on PRs like this:
```
**Test Coverage Report:**
```
Name Stmts Miss Cover Missing
-------------------------------------------------
my_package/__init__.py 12 2 83% 45-46
my_package/utils.py 25 0 100%
-------------------------------------------------
TOTAL 37 2 95%
```
## Pytest Configuration
The workflow respects your project's pytest configuration:
- **pytest.ini** - Standard pytest configuration
- **pyproject.toml** - Modern Python project configuration
- **setup.cfg** - Legacy configuration
Example `pyproject.toml` configuration:
```toml
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"--strict-config",
"--verbose",
]
markers = [
"slow: marks tests as slow",
"unit: marks tests as unit tests",
"integration: marks tests as integration tests",
]
```
## Requirements
- Repository must be public or you must have access to the template repository
- Python project with `pyproject.toml` and UV for dependency management
- Test dependencies should be specified in your project's extras (e.g., `test`, `dev`)
- For coverage comments: Gitea API access and `CI_RUNNER_TOKEN` secret
## Dependencies
The workflow expects these to be available in your project's test dependencies:
- **pytest**: Test runner
- **pytest-cov**: Coverage plugin (if using coverage reporting)
Example `pyproject.toml` dependencies:
```toml
[project.optional-dependencies]
test = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"pytest-mock>=3.10.0",
]
```
## Troubleshooting
### Coverage not working
1. Ensure `coverage-package` matches your actual package name
2. Check that `pytest-cov` is installed in your test dependencies
3. Verify your package is importable (check `PYTHONPATH`)
### PR comments not appearing
1. Verify `api-url` is correct (should include `/api/v1`)
2. Check `CI_RUNNER_TOKEN` secret exists and has repo permissions
3. Ensure the workflow runs on `pull_request` events
4. Verify coverage is being generated (`coverage-package` is set)
### Tests not found
1. Check your `pytest` configuration in `pyproject.toml` or `pytest.ini`
2. Verify test files follow naming conventions (`test_*.py` or `*_test.py`)
3. Use `pytest-args` to specify custom test discovery options
## Contributing
To update this template, modify the workflow file and ensure all changes are backward compatible or properly versioned using git tags.
+119
View File
@@ -0,0 +1,119 @@
# Web/General Formatting Pipeline Template
This reusable Gitea Actions workflow provides formatting checks for web technologies and general file formats including JavaScript, TypeScript, JSON, YAML, Markdown, and more using Prettier and other tools.
## Features
- **Prettier formatting**: Check formatting for JS, TS, JSON, YAML, Markdown, HTML, CSS, and more
- **YAML validation**: Optional yamllint checking for YAML files
- **JSON validation**: Optional JSON syntax validation
- **Configurable**: Skip specific checks, custom prettier config, and more
## Usage
### Basic Usage
Create a workflow file in your repository (e.g., `.gitea/workflows/formatting.yml`):
```yaml
name: Formatting Check
on:
push:
branches: [main]
pull_request:
jobs:
formatting:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/web/formatting.yml@main
```
### Advanced Usage with Custom Options
```yaml
name: Formatting Check
on:
push:
branches: [main]
pull_request:
jobs:
formatting:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/web/formatting.yml@main
with:
working-directory: "./frontend"
node-version: "18"
prettier-config: ".prettierrc.json"
check-yaml: true
check-json: true
```
### Combined with Python Code Quality
For repositories that contain both Python and web technologies:
```yaml
name: Code Quality
on:
push:
branches: [main]
pull_request:
jobs:
python-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
python-version: "3.12"
working-directory: "./backend"
web-formatting:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/web/formatting.yml@main
with:
working-directory: "./frontend"
check-yaml: true
```
## Input Parameters
| Parameter | Description | Required | Default | Type |
|-----------|-------------|----------|---------|------|
| `working-directory` | Working directory for the project | No | `"."` | string |
| `node-version` | Node.js version to use for prettier | No | `"20"` | string |
| `skip-prettier` | Skip prettier formatting check | No | `false` | boolean |
| `prettier-config` | Path to prettier config file | No | `""` | string |
| `check-yaml` | Check YAML files with yamllint | No | `false` | boolean |
| `check-json` | Check JSON files for validity | No | `false` | boolean |
## Prettier Configuration
You can customize Prettier behavior by:
1. **Using a config file**: Set the `prettier-config` input to point to your config file
2. **Using default prettier discovery**: Prettier will automatically find `.prettierrc`, `.prettierrc.json`, `.prettierrc.js`, etc.
3. **Using package.json**: Add prettier config to your `package.json`
Example `.prettierrc.json`:
```json
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}
```
## What Files Are Checked
- **Prettier**: JavaScript, TypeScript, JSON, YAML, Markdown, HTML, CSS, and more
- **yamllint**: All `.yml` and `.yaml` files (when enabled)
- **JSON validation**: All `.json` files (when enabled)
## Requirements
- Repository must be public or you must have access to the template repository
- For YAML checking: Repository should contain YAML files
- For JSON checking: Repository should contain JSON files
+114 -2
View File
@@ -1,3 +1,115 @@
# CI-templates
# CI Templates
CI pipeline templates
Reusable Gitea Actions workflow templates for consistent code quality across repositories.
## Available Templates
### Python Code Quality (`.gitea/workflows/python/code-quality.yml`)
A comprehensive Python code quality pipeline including type checking, linting, formatting, and modernization.
**Features:**
- Type checking with mypy
- Linting with ruff
- Code formatting with ruff format
- Python syntax modernization with pyupgrade
- UV package management support
📖 [Read the full documentation](README-python-code-quality.md)
### Python Test Pipeline (`.gitea/workflows/python/pytest.yml`)
A comprehensive Python testing pipeline using pytest with coverage reporting and PR comment integration.
**Features:**
- Pytest testing with configurable arguments
- Coverage reporting with pytest-cov
- PR comment integration for coverage reports
- UV package management support
- Monorepo support
📖 [Read the full documentation](README-python-pytest.md)
### Web/General Formatting (`.gitea/workflows/web/formatting.yml`)
A formatting pipeline for web technologies and general file formats using Prettier and other tools.
**Features:**
- Prettier formatting for JS, TS, JSON, YAML, Markdown, HTML, CSS
- Optional YAML validation with yamllint
- Optional JSON syntax validation
- Node.js environment setup
📖 [Read the full documentation](README-web-formatting.md)
## Quick Start
### For Python Projects
```yaml
name: Code Quality
on: [push, pull_request]
jobs:
python-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
```
### For Web/General Projects
```yaml
name: Formatting
on: [push, pull_request]
jobs:
formatting:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/web/formatting.yml@main
```
### For Mixed Projects
```yaml
name: Code Quality
on: [push, pull_request]
jobs:
python-quality:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/python/code-quality.yml@main
with:
working-directory: "./backend"
web-formatting:
uses: gitea.gt-proj.com/brian/CI-templates/.gitea/workflows/web/formatting.yml@main
with:
working-directory: "./frontend"
```
## Repository Structure
```text
.gitea/workflows/
├── python/
│ ├── code-quality.yml # Python code quality template
│ └── pytest.yml # Python testing template
└── web/
└── formatting.yml # Web/general formatting template
README-python-code-quality.md # Python code quality documentation
README-python-pytest.md # Python testing documentation
README-web-formatting.md # Web formatting documentation
```
## Contributing
When updating templates:
1. Ensure backward compatibility
2. Update documentation
3. Test with sample projects
4. Consider versioning with git tags for breaking changes
+87
View File
@@ -0,0 +1,87 @@
name: Web/General Formatting Pipeline
on:
workflow_call:
inputs:
working-directory:
description: 'Working directory for the project'
required: false
type: string
default: "."
node-version:
description: 'Node.js version to use for prettier (e.g., "20")'
required: false
type: string
default: "20"
skip-prettier:
description: 'Skip prettier formatting check'
required: false
type: boolean
default: false
prettier-config:
description: 'Path to prettier config file (optional)'
required: false
type: string
default: ""
check-yaml:
description: 'Check YAML files with yamllint'
required: false
type: boolean
default: false
check-json:
description: 'Check JSON files for validity'
required: false
type: boolean
default: false
jobs:
formatting:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
if: ${{ !inputs.skip-prettier }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Install prettier
if: ${{ !inputs.skip-prettier }}
run: npm install --save-dev --save-exact prettier
- name: Run prettier check
if: ${{ !inputs.skip-prettier }}
run: |
if [ -n "${{ inputs.prettier-config }}" ]; then
npx prettier --check . --config ${{ inputs.prettier-config }}
else
npx prettier --check .
fi
- name: Set up Python for YAML linting
if: ${{ inputs.check-yaml }}
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install yamllint
if: ${{ inputs.check-yaml }}
run: pip install yamllint
- name: Check YAML files
if: ${{ inputs.check-yaml }}
run: yamllint .
- name: Check JSON files
if: ${{ inputs.check-json }}
run: |
find . -name "*.json" -type f | while read -r file; do
echo "Checking $file"
python -m json.tool "$file" > /dev/null
done