Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .github/workflows/template-pr-inspection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Template PR Inspection

on:
pull_request:
paths:
- 'src/fastapi_fastkit/fastapi_project_template/**'
types:
- opened
- synchronize

permissions:
contents: read
pull-requests: write

jobs:
inspect-changed-templates:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for git diff

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"

- name: Setup PDM
uses: pdm-project/setup-pdm@v4

- name: Install dependencies
run: pdm install -G dev

- name: Setup UV
uses: astral-sh/setup-uv@v7

- name: Verify Docker and Compose
run: |
docker --version
docker compose version

- name: Inspect changed templates
run: pdm run python scripts/inspect-changed-templates.py

- name: Create or Update PR Comment
if: always()
uses: actions/github-script@v7
with:
script: |
const marker = '<!-- template-inspection-bot -->';
const success = '${{ job.status }}' === 'success';

const successBody = `${marker}
✅ **Template Inspection Passed**

All changed templates have been validated successfully.

---
*Last updated: ${new Date().toISOString()}*`;

const failureBody = `${marker}
❌ **Template Inspection Failed**

Please check the workflow logs for details on what needs to be fixed.

[View Logs](${context.payload.repository.html_url}/actions/runs/${context.runId})

---
*Last updated: ${new Date().toISOString()}*`;

const body = success ? successBody : failureBody;

// Find existing bot comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});

const botComment = comments.find(comment =>
comment.body.includes(marker)
);

if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
console.log('Updated existing comment');
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
console.log('Created new comment');
}
53 changes: 35 additions & 18 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.12
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -15,29 +13,48 @@ repos:
hooks:
- id: format
name: format
entry: bash scripts/format.sh
language: system
entry: black --config pyproject.toml --check .
language: python
types: [python]
additional_dependencies: ['black>=24.10.0']
pass_filenames: false

- id: isort-check
name: isort check
entry: isort --sp pyproject.toml --check-only --diff .
language: python
types: [python]
additional_dependencies: ['isort>=5.13.2']
pass_filenames: false

- id: lint
name: lint
entry: bash scripts/lint.sh
language: system
- id: isort-fix
name: isort fix
entry: isort --sp pyproject.toml .
language: python
types: [python]
additional_dependencies: ['isort>=5.13.2']
pass_filenames: false

- id: coverage-test
name: coverage test
entry: bash scripts/coverage-report.sh
language: system
- id: black-fix
name: black fix
entry: black --config pyproject.toml .
language: python
types: [python]
additional_dependencies: ['black>=24.10.0']
pass_filenames: false

- id: inspect-templates
name: inspect changed fastapi templates
entry: python scripts/inspect-changed-templates.py
language: system
- id: mypy
name: mypy
entry: mypy --config-file pyproject.toml src
language: python
types: [python]
additional_dependencies:
- mypy>=1.12.0
- rich>=13.9.2
- click>=8.1.7
- pyyaml>=6.0.0
- types-PyYAML>=6.0.12
pass_filenames: false
stages: [commit]

ci:
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ template-name/

FastAPI-fastkit includes **automated template testing** that provides comprehensive validation:

#### ✅ CI/CD Template Inspection

When you submit a PR that modifies template files, the **Template PR Inspection** workflow automatically runs:

- 🔍 **Automatic Trigger**: Runs when files in `src/fastapi_fastkit/fastapi_project_template/` are modified
- ✅ **Validation**: Inspects changed templates using `inspect-changed-templates.py`
- 💬 **PR Feedback**: Posts success/failure comments directly on your PR

Additionally, a **Weekly Template Inspection** runs every Wednesday to validate all templates.

#### ✅ Automatic Template Testing

**Zero Configuration Required:**
Expand Down
74 changes: 57 additions & 17 deletions docs/en/contributing/code-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -645,35 +645,75 @@ We use pre-commit hooks to enforce standards:
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: black
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml

- repo: https://github.com/pycqa/isort
rev: 5.12.0
- repo: local
hooks:
- id: isort

- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.0.1
hooks:
- id: mypy
- id: format
name: format
entry: black --config pyproject.toml --check .
language: python
types: [python]
additional_dependencies: ['black>=24.10.0']
pass_filenames: false

- id: isort-check
name: isort check
entry: isort --sp pyproject.toml --check-only --diff .
language: python
types: [python]
additional_dependencies: ['isort>=5.13.2']
pass_filenames: false

- id: isort-fix
name: isort fix
entry: isort --sp pyproject.toml .
language: python
types: [python]
additional_dependencies: ['isort>=5.13.2']
pass_filenames: false

- id: black-fix
name: black fix
entry: black --config pyproject.toml .
language: python
types: [python]
additional_dependencies: ['black>=24.10.0']
pass_filenames: false

- id: mypy
name: mypy
entry: mypy --config-file pyproject.toml src
language: python
types: [python]
additional_dependencies:
- mypy>=1.12.0
- rich>=13.9.2
- click>=8.1.7
- pyyaml>=6.0.0
- types-PyYAML>=6.0.12
pass_filenames: false

ci:
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate
```

> **Note:** Pre-commit hooks use isolated Python environments (`language: python`).

### IDE Configuration

Recommended VS Code settings:

```json
{
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.mypyEnabled": true,
"python.formatting.provider": "black",
"python.sortImports.path": "isort",
Expand Down
Loading
Loading