diff --git a/.editorconfig b/.editorconfig
index bea1011..74f0751 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,5 @@
# ==============================================================================
-# EditorConfig for {{project_name}}
+# EditorConfig for project_name
# https://editorconfig.org
#
# This file enforces consistent coding styles across multiple editors and IDEs.
diff --git a/.env.example b/.env.example
index df53bbb..15bfebd 100644
--- a/.env.example
+++ b/.env.example
@@ -15,7 +15,7 @@
APP_ENV=development
# Enable/disable debug mode (verbose logging, stack traces)
APP_DEBUG=true
-APP_NAME="{{project_name}}"
+APP_NAME="project_name"
APP_VERSION="1.0.0"
# Base URL for the application (useful for generating absolute links, emails)
APP_URL=http://localhost:8080
@@ -42,13 +42,13 @@ CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080
DB_CONNECTION=postgres
DB_HOST=localhost
DB_PORT=5432
-DB_DATABASE={{project_name}}_dev
+DB_DATABASE=project_name_dev
DB_USERNAME=admin
DB_PASSWORD=secret
# Database schema (if applicable, e.g., public for postgres)
DB_SCHEMA=public
# Full connection string alternative (often used by ORMs like Prisma or SQLAlchemy)
-# DATABASE_URL=postgres://admin:secret@localhost:5432/{{project_name}}_dev
+# DATABASE_URL=postgres://admin:secret@localhost:5432/project_name_dev
# ------------------------------------------------------------------------------
# Cache / Key-Value Store / Message Brokers
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 52d667e..90a249f 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,28 +1,29 @@
+---
name: 🐛 Bug Report
-description: Create a report to help us improve {{project_name}}
-labels: ["bug", "triage"]
+description: Create a report to help us improve project_name
+labels:
+ - "bug"
+ - "triage"
body:
- type: markdown
attributes:
value: |
- Thanks for taking the time to report a bug to `{{project_name}}`!
-
+ Thanks for taking the time to report a bug to `project_name`!
> [!IMPORTANT]
> If you have found a **security vulnerability**, please refer to our [Security Policy](../SECURITY.md) and do not open a public issue.
-
- For general help and Q&A, please use [GitHub Discussions](https://github.com/{{organization}}/{{project_name}}/discussions) instead.
-
+ For general help and Q&A, please use [GitHub Discussions](https://github.com/{{organization}}/project_name/discussions) instead.
- type: checkboxes
id: checks
attributes:
label: Search before asking
- description: Please confirm that you have checked the following before submitting your bug report.
+ description: Please confirm that you have checked the following before submitting your
+ bug report.
options:
- - label: I have searched the [existing issues](https://github.com/{{organization}}/{{project_name}}/issues) and could not find a similar bug.
+ - label: I have searched the [existing issues](https://github.com/{{organization}}/project_name/issues)
+ and could not find a similar bug.
required: true
- - label: I have read the [Official Documentation](https://{{organization}}.github.io/{{project_name}}).
+ - label: I have read the [Official Documentation](https://{{organization}}.github.io/project_name).
required: true
-
- type: textarea
id: description
attributes:
@@ -31,12 +32,12 @@ body:
placeholder: Tell us what happened...
validations:
required: true
-
- type: textarea
id: reproduction
attributes:
label: Steps to Reproduce
- description: Provide a minimal, reproducible example or the exact steps to reproduce the behavior.
+ description: Provide a minimal, reproducible example or the exact steps to reproduce
+ the behavior.
placeholder: |
1. Go to '...'
2. Click on '....'
@@ -44,7 +45,6 @@ body:
4. See error
validations:
required: true
-
- type: textarea
id: expected
attributes:
@@ -52,7 +52,6 @@ body:
description: A clear and concise description of what you expected to happen instead.
validations:
required: true
-
- type: textarea
id: environment
attributes:
@@ -61,15 +60,15 @@ body:
value: |
- OS (e.g., Linux, macOS, Windows):
- Language Version (e.g., Python 3.10):
- - `{{project_name}}` Version:
+ - `project_name` Version:
- Other relevant dependency versions:
validations:
required: true
-
- type: textarea
id: logs
attributes:
label: Relevant Logs or Screenshots
- description: If applicable, add screenshots or paste command output/logs to help explain your problem. Please use code blocks (```) to format logs.
+ description: If applicable, add screenshots or paste command output/logs to help explain
+ your problem. Please use code blocks (```) to format logs.
validations:
required: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index ba7f226..354012c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -1,13 +1,14 @@
+---
name: Feature Request
-description: Suggest an idea for {{project_name}}
-labels: ["enhancement"]
+description: Suggest an idea for project_name
+labels:
+ - "enhancement"
body:
- type: markdown
attributes:
value: |
- Thanks for taking the time to suggest a feature for {{project_name}}!
-
- Before submitting, please ensure you have searched our existing [Issues](https://github.com/{{organization}}/{{project_name}}/issues) and [Discussions](https://github.com/{{organization}}/{{project_name}}/discussions) to see if this feature has already been requested.
+ Thanks for taking the time to suggest a feature for project_name!
+ Before submitting, please ensure you have searched our existing [Issues](https://github.com/{{organization}}/project_name/issues) and [Discussions](https://github.com/{{organization}}/project_name/discussions) to see if this feature has already been requested.
- type: textarea
id: problem
attributes:
@@ -28,7 +29,8 @@ body:
id: alternatives
attributes:
label: Describe alternatives you've considered
- description: A clear and concise description of any alternative solutions or features you've considered.
+ description: A clear and concise description of any alternative solutions or features
+ you've considered.
placeholder: "Ex. I tried using feature X, but it didn't work because [...]"
- type: textarea
id: additional
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c3847a5..34a1606 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,16 +1,16 @@
-
## Description
-
--
+-
## Type of Change
@@ -28,12 +28,12 @@ If this PR introduces a new feature or changes existing behavior, describe the c
List the steps needed to manually test this PR, or describe the automated tests you have added.
-->
--
+-
## Related Issues
-
@@ -41,8 +41,8 @@ Use `Fixes #ISSUE_NUMBER` or `Closes #ISSUE_NUMBER` to automatically close the i
## Screenshots / Visuals (if applicable)
-
@@ -57,11 +57,11 @@ please add screenshots, terminal output, or recordings to demonstrate the change
## Checklist
> [!IMPORTANT]
-> Please review and complete this checklist before submitting your PR. This helps our maintainers process your contribution faster and ensures it meets the quality standards of `{{project_name}}`.
+> Please review and complete this checklist before submitting your PR. This helps our maintainers process your contribution faster and ensures it meets the quality standards of `project_name`.
- [ ] "I certify that all code in this PR is my own, except as noted below."
- [ ] I have read the [CONTRIBUTING.md](../CONTRIBUTING.md) guide.
-- [ ] My code follows the established style guidelines of `{{project_name}}`.
+- [ ] My code follows the established style guidelines of `project_name`.
- [ ] I have performed a self-review of my own code.
- [ ] I have commented my code, particularly in hard-to-understand areas.
- [ ] I have made corresponding changes to the documentation.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 8c7cb68..d424fff 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# dependabot.yml — Automated Dependency Management
#
@@ -13,7 +14,6 @@
# After PRs are opened, weekly.yml surfaces them via Slack for human review.
# =============================================================================
version: 2
-
updates:
# ── GitHub Actions ──────────────────────────────────────────────────────────
- package-ecosystem: "github-actions"
@@ -35,29 +35,28 @@ updates:
prefix: "chore(actions)"
# TODO: Add at least one reviewer here! Without an assigned reviewer,
# Dependabot PRs often rot in the queue and are ignored.
- reviewers: [] # e.g., ["maintainer1", "org/platform-team"]
- assignees: [] # e.g., ["maintainer1"]
+ reviewers: [] # e.g., ["maintainer1", "org/platform-team"]
+ assignees: [] # e.g., ["maintainer1"]
open-pull-requests-limit: 5
# ── Python (pip) ────────────────────────────────────────────────────────────
- # Uncomment when this repository contains Python dependencies.
- # - package-ecosystem: "pip"
- # directory: "/"
- # schedule:
- # interval: "weekly"
- # day: "monday"
- # time: "09:00"
- # timezone: "America/New_York"
- # groups:
- # python-dependencies:
- # patterns:
- # - "*"
- # labels:
- # - "dependencies"
- # - "python"
- # commit-message:
- # prefix: "chore(deps)"
- # open-pull-requests-limit: 5
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ day: "monday"
+ time: "09:00"
+ timezone: "America/New_York"
+ groups:
+ python-dependencies:
+ patterns:
+ - "*"
+ labels:
+ - "dependencies"
+ - "python"
+ commit-message:
+ prefix: "chore(deps)"
+ open-pull-requests-limit: 5
# ── Node.js (npm) ────────────────────────────────────────────────────────────
# Uncomment when this repository contains a package.json.
diff --git a/.github/workflows/_build_container.yml b/.github/workflows/_build_container.yml
index edee836..89e8ae2 100644
--- a/.github/workflows/_build_container.yml
+++ b/.github/workflows/_build_container.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _build_container.yml — Reusable Container Builder
#
@@ -7,6 +8,7 @@
#
# Inputs:
# build_type (required): "release", "post", "nightly", or "dev"
+# push (optional): Whether to push the image to GHCR (default: false)
#
# Outputs:
# image_name — The name of the built container image
@@ -15,7 +17,6 @@
# Callers: development.yml, nightly.yml, release.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Build Container (Reusable)"
-
on:
workflow_call:
inputs:
@@ -23,6 +24,11 @@ on:
description: "Type of build: release, post, nightly, or dev"
required: true
type: string
+ push:
+ description: "Whether to push the built container image to GHCR"
+ required: false
+ type: boolean
+ default: false
outputs:
image_name:
description: "The name of the built container image"
@@ -30,12 +36,10 @@ on:
image_tag:
description: "The tag of the built container image"
value: ${{ jobs.build-container.outputs.image_tag }}
-
permissions:
contents: read
-
+ packages: write # To push to GHCR
jobs:
-
build-container:
name: "Build Container (${{ inputs.build_type }})"
runs-on: ubuntu-latest
@@ -44,28 +48,28 @@ jobs:
image_tag: ${{ steps.build.outputs.image_tag }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up container toolchain"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Set up Docker, Buildx, or other container tools.
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: set up container toolchain"
- # exit 1 # Uncomment when enforcing implementation
-
- - name: "# TODO: Build container"
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
+ - name: Log in to GitHub Container Registry
+ if: ${{ inputs.push }}
+ uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - name: Build and push container
+ uses: docker/build-push-action@2cdde99a3119bfeb512642f4c2201b17b620eeff # v5
+ with:
+ context: .
+ push: ${{ inputs.push }}
+ load: ${{ !inputs.push }}
+ tags: ghcr.io/${{ github.repository }}:${{ inputs.build_type }}-${{ github.sha }},ghcr.io/${{
+ github.repository }}:latest
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ - name: Export outputs
id: build
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Build the container image.
- # Example: docker build -t "my-app:${{ inputs.build_type }}" .
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: build container for ${{ inputs.build_type }}"
-
- IMAGE_NAME="my-app"
- IMAGE_TAG="${{ inputs.build_type }}-${{ github.sha }}"
-
- echo "image_name=${IMAGE_NAME}" >> "$GITHUB_OUTPUT"
- echo "image_tag=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
- # exit 1 # Uncomment when enforcing implementation
+ run: |-
+ echo "image_name=ghcr.io/${{ github.repository }}" >> "$GITHUB_OUTPUT"
+ echo "image_tag=${{ inputs.build_type }}-${{ github.sha }}" >> "$GITHUB_OUTPUT"
diff --git a/.github/workflows/_build_package.yml b/.github/workflows/_build_package.yml
index 754bec7..a8d5260 100644
--- a/.github/workflows/_build_package.yml
+++ b/.github/workflows/_build_package.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _build_package.yml — Reusable Package Builder
#
@@ -15,7 +16,6 @@
# Callers: development.yml, nightly.yml, release.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Build Package (Reusable)"
-
on:
workflow_call:
inputs:
@@ -30,12 +30,9 @@ on:
build_metadata:
description: "Metadata regarding the build (e.g. SHA256)"
value: ${{ jobs.build-package.outputs.metadata }}
-
permissions:
contents: read
-
jobs:
-
build-package:
name: "Build Package (${{ inputs.build_type }})"
runs-on: ubuntu-latest
@@ -44,41 +41,22 @@ jobs:
metadata: ${{ steps.build.outputs.metadata }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up build toolchain"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Install tools and dependencies for packaging.
- # Example (Python): pip install build
- # Example (Node.js): npm ci
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: set up build toolchain"
- # exit 1 # Uncomment when enforcing implementation
-
- - name: "# TODO: Build package"
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: "Set up build toolchain"
+ uses: pypa/hatch@install
+ - name: "Build package"
id: build
run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Compile/package the distributable artifact.
- # The output must land in a specific directory (e.g., dist/)
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: build project for ${{ inputs.build_type }}"
-
- # Simulate build output directory creation
- mkdir -p dist/
- echo "dummy package content" > dist/dummy.pkg
-
+ hatch build
+
# Output the location
echo "location=dist/" >> "$GITHUB_OUTPUT"
-
- # Optional: compute SHA256 or other metadata
+
+ # Compute SHA256 or other metadata
SHA=$(find dist/ -type f | sort | xargs sha256sum | sha256sum | awk '{print $1}')
echo "metadata=${SHA}" >> "$GITHUB_OUTPUT"
- # exit 1 # Uncomment when enforcing implementation
-
- name: Upload build artifact
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: build-artifact-${{ inputs.build_type }}-${{ github.run_id }}
path: dist/
diff --git a/.github/workflows/_docs.yml b/.github/workflows/_docs.yml
index 88524db..20553cd 100644
--- a/.github/workflows/_docs.yml
+++ b/.github/workflows/_docs.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _docs.yml — Reusable Documentation Builder & Deployer
#
@@ -14,7 +15,6 @@
# Callers: development.yml, nightly.yml, release.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Docs Builder & Deployer (Reusable)"
-
on:
workflow_call:
inputs:
@@ -26,16 +26,18 @@ on:
description: "The alias to use for the documentation version (e.g., latest, nightly)"
required: true
type: string
+ include_coverage:
+ description: "Whether to download and include unit test coverage in the docs"
+ required: false
+ type: boolean
+ default: false
outputs:
deployed_url:
description: "Path where the docs were deployed"
value: ${{ jobs.build-and-deploy-docs.outputs.deployed_url }}
-
permissions:
- contents: write # Push to gh-pages branch
-
+ contents: write # Push to gh-pages branch
jobs:
-
build-and-deploy-docs:
name: "Build & Deploy Docs (${{ inputs.build_type }})"
runs-on: ubuntu-latest
@@ -43,27 +45,42 @@ jobs:
deployed_url: ${{ steps.dest.outputs.path }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
-
- name: Set up Python
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.x"
-
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
-
- - name: Install MkDocs and dependencies
+ - name: Install hatch and trigger docs sync
run: |
- # Install standard mkdocs, material theme, and mike for versioning
- pip install mkdocs-material mike
- # Install any other requirements if they exist
- if [ -f docs/requirements.txt ]; then pip install -r docs/requirements.txt; fi
-
+ pip install uv hatch
+ hatch run docs:mkdocs --version
+ - name: Download unit test coverage
+ if: ${{ inputs.include_coverage }}
+ uses: actions/download-artifact@v4
+ with:
+ pattern: coverage-report-unit-*
+ path: docs/coverage/unit
+ merge-multiple: true
+ - name: Download integration test coverage
+ if: ${{ inputs.include_coverage }}
+ uses: actions/download-artifact@v4
+ with:
+ pattern: coverage-report-integration-*
+ path: docs/coverage/integration
+ merge-multiple: true
+ - name: Download e2e test coverage
+ if: ${{ inputs.include_coverage }}
+ uses: actions/download-artifact@v4
+ with:
+ pattern: coverage-report-e2e-*
+ path: docs/coverage/e2e
+ merge-multiple: true
- name: Compute deployment destination path
id: dest
run: |
@@ -75,22 +92,21 @@ jobs:
post) echo "path=post" >> "$GITHUB_OUTPUT" ;;
*) echo "path=${{ inputs.alias }}" >> "$GITHUB_OUTPUT" ;;
esac
-
- name: Build and deploy using Mike
- run: |
+ run: |-
VERSION_PATH="${{ steps.dest.outputs.path }}"
ALIAS="${{ inputs.alias }}"
-
+
# Use mike to deploy to gh-pages branch
# --push: push to origin
# --update-aliases: update the alias pointer
if [ "$ALIAS" != "" ] && [ "$ALIAS" != "$VERSION_PATH" ]; then
- mike deploy --push --update-aliases $VERSION_PATH $ALIAS
+ hatch run docs:mike deploy --push --update-aliases $VERSION_PATH $ALIAS
else
- mike deploy --push $VERSION_PATH
+ hatch run docs:mike deploy --push $VERSION_PATH
fi
-
+
# If release, also set it as default
if [ "${{ inputs.build_type }}" == "release" ]; then
- mike set-default --push $ALIAS
+ hatch run docs:mike set-default --push $ALIAS
fi
diff --git a/.github/workflows/_link-check.yml b/.github/workflows/_link-check.yml
index 6847222..3596b46 100644
--- a/.github/workflows/_link-check.yml
+++ b/.github/workflows/_link-check.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _link-check.yml — Reusable Documentation Link Checker
#
@@ -13,7 +14,6 @@
# Callers: development.yml, nightly.yml, release.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Link Checker (Reusable)"
-
on:
workflow_call:
inputs:
@@ -26,12 +26,9 @@ on:
report_content:
description: "The contents of the link check report"
value: ${{ jobs.link-check.outputs.report_content }}
-
permissions:
contents: read
-
jobs:
-
link-check:
name: "Check Links"
runs-on: ubuntu-latest
@@ -39,21 +36,20 @@ jobs:
report_content: ${{ steps.read-report.outputs.content }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Run lychee link checker
- uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
+ uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
id: lychee
with:
- args: --verbose --no-progress --accept 200,206,301,302,429 --exclude-loopback --exclude-mail --exclude "\{\{[^}]+\}\}" '**/*.md'
+ args: --verbose --no-progress --accept 200,206,301,302,429 --exclude-loopback --exclude-mail
+ --exclude "\{\{[^}]+\}\}" '**/*.md'
fail: ${{ inputs.fail_on_error }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- name: Read report content
id: read-report
if: always()
- run: |
+ run: |-
if [ -f "lychee/out.md" ]; then
# Read file into output variable safely
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
diff --git a/.github/workflows/pr_comment.yml b/.github/workflows/_pr_comment.yml
similarity index 93%
rename from .github/workflows/pr_comment.yml
rename to .github/workflows/_pr_comment.yml
index ca52d05..61abb7e 100644
--- a/.github/workflows/pr_comment.yml
+++ b/.github/workflows/_pr_comment.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# pr_comment.yml — Safe PR Commenting
#
@@ -9,17 +10,15 @@
# comments. `workflow_run` executes in the context of the base repository.
# =============================================================================
name: "PR Commenter"
-
on:
workflow_run:
- workflows: ["CI — Development"]
+ workflows:
+ - "CI — Development"
types:
- completed
-
permissions:
pull-requests: write
actions: read
-
jobs:
post_comment:
name: "Post PR Status Comment"
@@ -30,33 +29,27 @@ jobs:
- name: "Download PR Number Artifact"
# Wait, how does it know the PR number? The `development.yml` needs to upload the PR number as an artifact
# so this workflow can read it. Let's write the script to find the PR associated with the commit.
- uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
+ uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
- script: |
+ script: |-
const workflowRun = context.payload.workflow_run;
-
// Get the pull request associated with the commit
const response = await github.rest.search.issuesAndPullRequests({
q: `is:pr repo:${context.repo.owner}/${context.repo.repo} sha:${workflowRun.head_sha}`
});
-
if (response.data.total_count === 0) {
console.log('No PR found for this commit.');
return;
}
-
const prNumber = response.data.items[0].number;
const runUrl = workflowRun.html_url;
const status = workflowRun.conclusion;
-
let body = `## CI Development Pipeline Status\n\n`;
-
if (status === 'success') {
body += `✅ **Pipeline**: Completed successfully. [View Run Details](${runUrl})\n`;
} else {
body += `❌ **Pipeline**: Failed or was cancelled. [Check logs](${runUrl})\n`;
}
-
// Post comment
await github.rest.issues.createComment({
owner: context.repo.owner,
diff --git a/.github/workflows/_publish.yml b/.github/workflows/_publish.yml
index 93af4e2..8809844 100644
--- a/.github/workflows/_publish.yml
+++ b/.github/workflows/_publish.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _publish.yml — Reusable Artifact Publisher
#
@@ -11,7 +12,6 @@
# Callers: nightly.yml, release.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Publish Artifacts (Reusable)"
-
on:
workflow_call:
inputs:
@@ -24,29 +24,19 @@ on:
description: "The type of build (e.g., nightly, release)"
required: true
type: string
-
permissions:
contents: read
+ id-token: write # For PyPI OIDC trusted publishing
packages: write # To publish to GitHub Container Registry or GitHub Packages
-
jobs:
-
publish:
name: "Publish (${{ inputs.build_type }})"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Publish artifacts"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Publish artifacts to a registry.
- #
- # Examples:
- # Python (PyPI): twine upload ${{ inputs.build_location }}/*
- # Node.js (npm): npm publish
- # Container (GHCR): docker push ...
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: publish artifacts located in ${{ inputs.build_location }} for build type ${{ inputs.build_type }}"
- # exit 1 # Uncomment when enforcing implementation
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: Publish to PyPI
+ if: ${{ inputs.build_location != '' }}
+ uses: pypa/gh-action-pypi-publish@81e9d935c883d0b210363ab89cf05f3894778450 # v1.8.14
+ with:
+ packages-dir: ${{ inputs.build_location }}
diff --git a/.github/workflows/_quality.yml b/.github/workflows/_quality.yml
index 18686bf..644e0cf 100644
--- a/.github/workflows/_quality.yml
+++ b/.github/workflows/_quality.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _quality.yml — Reusable Quality Gate
#
@@ -7,78 +8,56 @@
# Callers: development.yml, main.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Quality Gate (Reusable)"
-
on:
workflow_call:
-
+ inputs:
+ python_versions:
+ description: "JSON array of Python versions"
+ required: true
+ type: string
permissions:
contents: read
security-events: write
-
jobs:
-
quality:
- name: "Code Quality"
+ name: "Quality (Python ${{ matrix.python-version }})"
runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ${{ fromJson(inputs.python_versions) }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up toolchain"
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: "Set up Python ${{ matrix.python-version }}"
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: "Install uv"
+ run: pip install uv
+ - name: "Set up toolchain"
+ uses: pypa/hatch@install
+ - name: "Run quality checks"
run: |
- echo "TODO: set up toolchain for quality checks"
- # exit 1
-
- - name: "# TODO: Run quality checks"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Run code quality analysis.
- # Example (Python): ruff check .
- # Example (Node.js): npm run lint:quality
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: run quality checks"
- # exit 1
-
- style:
- name: "Code Style"
- runs-on: ubuntu-latest
- steps:
- - name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up toolchain"
- run: |
- echo "TODO: set up toolchain for style checks"
- # exit 1
-
- - name: "# TODO: Run style checks"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Run code formatting checks.
- # Example (Python): black --check .
- # Example (Node.js): prettier --check .
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: run style checks"
- # exit 1
-
+ hatch run lint:pre-commit
types:
- name: "Type Checking"
+ name: "Types (Python ${{ matrix.python-version }})"
runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ${{ fromJson(inputs.python_versions) }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up toolchain"
- run: |
- echo "TODO: set up toolchain for type checks"
- # exit 1
-
- - name: "# TODO: Run type checks"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Run static type checking.
- # Example (Python): mypy .
- # Example (Node.js): tsc --noEmit
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: run type checks"
- # exit 1
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: "Set up Python ${{ matrix.python-version }}"
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: "Install uv"
+ run: pip install uv
+ - name: "Set up toolchain"
+ uses: pypa/hatch@install
+ - name: "Run type checks"
+ run: |-
+ hatch run types:check
diff --git a/.github/workflows/_security.yml b/.github/workflows/_security.yml
index 2d2210c..332b14e 100644
--- a/.github/workflows/_security.yml
+++ b/.github/workflows/_security.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _security.yml — Reusable Security Audit
#
@@ -6,56 +7,42 @@
# Callers: development.yml, main.yml, nightly.yml, release.yml, weekly.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Security Audit (Reusable)"
-
on:
workflow_call:
-
permissions:
contents: read
security-events: write # Upload SARIF to GitHub Security tab
-
jobs:
-
secret-scan:
name: "Secret Scan"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
-
- - name: "# TODO: Run your secret scanner"
- run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Perform a repository secret scan.
- # Examples:
- # TruffleHog: https://github.com/trufflesecurity/trufflehog
- # Gitleaks: https://github.com/gitleaks/gitleaks-action
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: run secret scan"
- # exit 1
-
+ - name: Run TruffleHog
+ uses: trufflesecurity/trufflehog@8a12e8e2fb6f3c4a4294a8e63b3659af6c08cfe3 # main
+ with:
+ path: ./
+ base: ${{ github.event.repository.default_branch }}
+ head: HEAD
dependency-audit:
name: "Dependency Vulnerability Scan"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Run your deep dependency vulnerability scan"
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: Set up toolchain
+ run: pip install pip-audit hatch
+ - name: Run dependency vulnerability scan
run: |
- # ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Perform a deep SCA scan of your dependency tree.
- # Examples:
- # Python: pip install pip-audit && pip-audit --output json -o audit.json
- # Node.js: npm audit --json > audit.json
- # ───────────────────────────────────────────────────────────────────
- echo "TODO: run SCA dependency audit"
- # exit 1
-
+ # Use hatch to export dependencies and run pip-audit
+ hatch dep show requirements > requirements.txt
+ pip-audit -r requirements.txt --output json -o audit.json
- name: Upload SCA results
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
+ if: always()
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: sca-results-${{ github.run_id }}
path: audit.json
diff --git a/.github/workflows/_tests.yml b/.github/workflows/_tests.yml
index b263d6b..896f970 100644
--- a/.github/workflows/_tests.yml
+++ b/.github/workflows/_tests.yml
@@ -1,3 +1,4 @@
+---
# ─────────────────────────────────────────────────────────────────────────────
# _tests.yml — Reusable Test Runner
#
@@ -17,12 +18,16 @@
# Callers: development.yml, main.yml, nightly.yml, release.yml, weekly.yml
# ─────────────────────────────────────────────────────────────────────────────
name: "Test Runner (Reusable)"
-
on:
workflow_call:
inputs:
test_matrix:
- description: "JSON array of test levels and types (e.g., '[{\"level\": \"unit\", \"types\": \"smoke, sanity\"}]')"
+ description: "JSON array of test levels and types (e.g., '[{\"level\": \"unit\", \"\
+ types\": \"smoke, sanity\"}]')"
+ required: true
+ type: string
+ python_versions:
+ description: "JSON array of Python versions"
required: true
type: string
generate_coverage:
@@ -47,63 +52,72 @@ on:
coverage_location:
description: "Path to the coverage artifact"
value: ${{ jobs.run-tests.outputs.coverage_location }}
-
permissions:
contents: read
-
jobs:
-
run-tests:
- name: "Run ${{ matrix.level }} Tests"
+ name: "Run ${{ matrix.test-config.level }} Tests (Python ${{ matrix.python-version }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
- include: ${{ fromJson(inputs.test_matrix) }}
+ python-version: ${{ fromJson(inputs.python_versions) }}
+ test-config: ${{ fromJson(inputs.test_matrix) }}
outputs:
results_location: "reports/"
coverage_location: "coverage/"
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-
- - name: "# TODO: Set up language runtime and test dependencies"
- run: |
- echo "TODO: set up test environment"
- # exit 1
-
- - name: "# TODO: Run tests"
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ - name: "Set up Python ${{ matrix.python-version }}"
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: "Install uv"
+ run: pip install uv
+ - name: "Set up toolchain"
+ uses: pypa/hatch@install
+ - name: "Run tests"
run: |
# ───────────────────────────────────────────────────────────────────
- # PLACEHOLDER — Execute the test suite for the requested scope.
- # Use inputs to filter what tests run.
- # Level: ${{ matrix.level }}
- # Types: ${{ matrix.types }}
- # Coverage: ${{ inputs.generate_coverage }}
+ # Level: ${{ matrix.test-config.level }}
+ # Types: ${{ matrix.test-config.types }}
+ # Coverage: ${{ inputs.generate_coverage }} / ${{ matrix.test-config.coverage }}
# ───────────────────────────────────────────────────────────────────
- echo "TODO: run tests matching level '${{ matrix.level }}' and types '${{ matrix.types }}'"
-
- mkdir -p reports/ coverage/
- echo "dummy report" > reports/test-report.xml
- if [ "${{ inputs.generate_coverage }}" == "true" ]; then
- echo "dummy coverage" > coverage/coverage.xml
+ TYPES="${{ matrix.test-config.types }}"
+ MARKERS=$(echo "$TYPES" | sed 's/, / or /g' | sed 's/,/ or /g')
+ GENERATE_COVERAGE="false"
+ if [ "${{ inputs.generate_coverage }}" == "true" ] || [ "${{ matrix.test-config.coverage }}" == "true" ]; then
+ GENERATE_COVERAGE="true"
+ fi
+ if [[ -z "$TYPES" ]] || [[ "$TYPES" == *"smoke"* && "$TYPES" == *"sanity"* && "$TYPES" == *"regression"* ]]; then
+ if [ "$GENERATE_COVERAGE" == "true" ]; then
+ hatch run test:cov-${{ matrix.test-config.level }} --cov-report=xml:coverage/coverage.xml --cov-report=html:coverage/htmlcov --junitxml=reports/test-report.xml
+ else
+ hatch run test:${{ matrix.test-config.level }} --junitxml=reports/test-report.xml
+ fi
+ else
+ if [ "$GENERATE_COVERAGE" == "true" ]; then
+ hatch run test:cov-${{ matrix.test-config.level }} -m "$MARKERS" --cov-report=xml:coverage/coverage.xml --cov-report=html:coverage/htmlcov --junitxml=reports/test-report.xml
+ else
+ hatch run test:${{ matrix.test-config.level }} -m "$MARKERS" --junitxml=reports/test-report.xml
+ fi
fi
- # exit 1
-
- name: Upload test results
if: ${{ inputs.publish_results }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
- name: test-results-${{ matrix.level }}-${{ github.run_id }}
+ name: test-results-${{ matrix.test-config.level }}-py${{ matrix.python-version }}-${{
+ github.run_id }}
path: reports/
retention-days: ${{ inputs.retention_days }}
if-no-files-found: warn
-
- name: Upload coverage report
- if: ${{ inputs.publish_results && inputs.generate_coverage }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
+ if: ${{ inputs.publish_results && (inputs.generate_coverage == true || matrix.test-config.coverage == true) }}
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
- name: coverage-report-${{ matrix.level }}-${{ github.run_id }}
+ name: coverage-report-${{ matrix.test-config.level }}-py${{ matrix.python-version
+ }}-${{ github.run_id }}
path: coverage/
retention-days: ${{ inputs.retention_days }}
if-no-files-found: warn
diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml
index 6e0c8c8..423266b 100644
--- a/.github/workflows/development.yml
+++ b/.github/workflows/development.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# development.yml — PR CI
#
@@ -11,19 +12,15 @@
# Stage 5 — Comment on PR
# =============================================================================
name: "CI — Development"
-
on:
pull_request:
branches:
- main
-
concurrency:
group: "dev-${{ github.head_ref }}"
cancel-in-progress: true
-
permissions:
contents: read
-
jobs:
# ── Determine Changes ──────────────────────────────────────────────────────
@@ -34,9 +31,9 @@ jobs:
docs: ${{ steps.filter.outputs.docs }}
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Check for docs changes
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
+ uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
filters: |
@@ -48,10 +45,11 @@ jobs:
quality:
name: "Quality Gate"
uses: ./.github/workflows/_quality.yml
+ with:
+ python_versions: '["3.10", "3.14"]'
permissions:
contents: read
security-events: write
-
security:
name: "Security Audit"
uses: ./.github/workflows/_security.yml
@@ -69,6 +67,7 @@ jobs:
{"level": "unit", "types": "smoke, sanity"},
{"level": "integration", "types": "smoke"}
]
+ python_versions: '["3.10", "3.14"]'
generate_coverage: true
publish_results: true
retention_days: 7
@@ -77,13 +76,15 @@ jobs:
docs:
name: "Build & Deploy Docs"
needs: changes
- if: needs.changes.outputs.docs == 'true' && github.event.pull_request.head.repo.fork == false
+ if: needs.changes.outputs.docs == 'true' && github.event.pull_request.head.repo.fork ==
+ false
uses: ./.github/workflows/_docs.yml
permissions:
contents: write
with:
build_type: "dev-branch"
alias: "pr-${{ github.event.pull_request.number }}"
+ include_coverage: true
# ── Stage 4: Build ─────────────────────────────────────────────────────────
build:
@@ -91,4 +92,3 @@ jobs:
uses: ./.github/workflows/_build_package.yml
with:
build_type: "dev"
-
diff --git a/.github/workflows/development_cleanup.yml b/.github/workflows/development_cleanup.yml
index d3e0f0d..94f5196 100644
--- a/.github/workflows/development_cleanup.yml
+++ b/.github/workflows/development_cleanup.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# development_cleanup.yml — PR Documentation Cleanup
#
@@ -9,40 +10,33 @@
# during the PR lifecycle (e.g., pr-123/) to prevent gh-pages branch bloat.
# =============================================================================
name: "CI — Development Cleanup"
-
on:
pull_request:
- types: [closed]
-
+ types:
+ - closed
permissions:
contents: write # Required to push deletion to gh-pages
-
jobs:
-
cleanup-pr-docs:
name: "Delete PR Docs Preview"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
-
- name: Set up Python
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
+ uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.x"
-
- name: Configure Git Credentials
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
-
- name: Install Mike
run: pip install mike
-
- name: Delete PR docs preview
- run: |
+ run: |-
PR_PATH="pr-${{ github.event.pull_request.number }}"
echo "Deleting docs preview at path: ${PR_PATH}"
# Delete the versioned path from gh-pages; ignore errors if it doesn't exist
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index aa54d28..ac31bc9 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# main.yml — Post-Merge CI
#
@@ -9,28 +10,25 @@
# Stage 3 — Documentation (dev)
# =============================================================================
name: "CI — Main"
-
on:
push:
branches:
- main
-
concurrency:
group: "main-${{ github.ref_name }}"
cancel-in-progress: true
-
permissions:
contents: write
security-events: write
actions: read
-
jobs:
# ── Stage 1: Quality Gate & Security ───────────────────────────────────────
quality:
name: "Quality Gate"
uses: ./.github/workflows/_quality.yml
-
+ with:
+ python_versions: '["3.10", "3.14"]'
security:
name: "Security Audit"
uses: ./.github/workflows/_security.yml
@@ -46,6 +44,7 @@ jobs:
{"level": "integration", "types": "smoke, sanity"},
{"level": "e2e", "types": "smoke"}
]
+ python_versions: '["3.10", "3.14"]'
generate_coverage: true
publish_results: true
retention_days: 14
@@ -58,3 +57,4 @@ jobs:
with:
build_type: "dev"
alias: "latest"
+ include_coverage: true
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 379e23e..ec421a4 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# nightly.yml — The Deep Dive
#
@@ -5,18 +6,15 @@
# Purpose: Extended regression, security SCA, alpha build, docs & publish
# =============================================================================
name: "CI — Nightly Deep Dive"
-
on:
schedule:
- cron: "0 0 * * *" # 00:00 UTC daily
workflow_dispatch:
-
permissions:
contents: write
packages: write
security-events: write
actions: read
-
jobs:
# ── Stage 1: Security Audit ────────────────────────────────────────────────
@@ -31,11 +29,12 @@ jobs:
with:
test_matrix: >-
[
- {"level": "unit", "types": "smoke, sanity, regression"},
+ {"level": "unit", "types": "smoke, sanity, regression", "coverage": true},
{"level": "integration", "types": "smoke, sanity"},
{"level": "e2e", "types": "smoke, sanity"}
]
- generate_coverage: true
+ python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
+ generate_coverage: false
publish_results: true
retention_days: 14
@@ -53,11 +52,14 @@ jobs:
with:
build_type: "nightly"
alias: "nightly"
+ include_coverage: true
# ── Stage 5: Alpha Build ───────────────────────────────────────────────────
build:
name: "Nightly Build"
- needs: [test, security]
+ needs:
+ - test
+ - security
uses: ./.github/workflows/_build_package.yml
with:
build_type: "nightly"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index eb22b77..1c9d49b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# release.yml — The Gold Master
#
@@ -5,20 +6,17 @@
# Purpose: Final verification, immutable build, versioned docs, release publish
# =============================================================================
name: "CI — Release Gold Master"
-
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+" # Strict semver: v1.2.3
- "v[0-9]+.[0-9]+.[0-9]+-*" # Pre-releases: v1.2.3-rc.1
-
permissions:
contents: write
packages: write
id-token: write
security-events: write
attestations: write
-
jobs:
# ── Stage 1: Security Audit ────────────────────────────────────────────────
@@ -44,6 +42,7 @@ jobs:
{"level": "integration", "types": "smoke, sanity, regression"},
{"level": "e2e", "types": "smoke, sanity, regression"}
]
+ python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
generate_coverage: true
publish_results: true
retention_days: 90
@@ -55,11 +54,14 @@ jobs:
with:
build_type: "release"
alias: "${{ github.ref_name }}"
+ include_coverage: true
# ── Stage 5: Immutable Build ───────────────────────────────────────────────
build:
name: "Release Build"
- needs: [test, security]
+ needs:
+ - test
+ - security
uses: ./.github/workflows/_build_package.yml
with:
build_type: "release"
@@ -72,4 +74,3 @@ jobs:
with:
build_type: "release"
build_location: "dist/"
-
diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml
index e2279a7..dfb80f3 100644
--- a/.github/workflows/weekly.yml
+++ b/.github/workflows/weekly.yml
@@ -1,3 +1,4 @@
+---
# =============================================================================
# weekly.yml — The Janitor
#
@@ -5,16 +6,13 @@
# Purpose: Dependency hygiene, full test suite regression.
# =============================================================================
name: "CI — Weekly Housekeeping"
-
on:
schedule:
- cron: "0 0 * * 0" # 00:00 UTC every Sunday
- workflow_dispatch: # Allow manual trigger
-
+ workflow_dispatch: # Allow manual trigger
permissions:
contents: read
security-events: write
-
jobs:
# ── Stage 1: Security Audit ────────────────────────────────────────────────
@@ -30,9 +28,10 @@ jobs:
test_matrix: >-
[
{"level": "unit", "types": "smoke, sanity, regression"},
- {"level": "integration", "types": "smoke, sanity, regression"},
- {"level": "e2e", "types": "smoke, sanity, regression"}
+ {"level": "integration", "types": "smoke, sanity, regression", "coverage": true},
+ {"level": "e2e", "types": "smoke, sanity, regression", "coverage": true}
]
- generate_coverage: true
+ python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
+ generate_coverage: false
publish_results: true
retention_days: 14
diff --git a/.gitignore b/.gitignore
index 01f7d8e..2ce81eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,7 +49,7 @@ out/
cmake-build-*/
.run/
-# VS Code
+# VS Code / Cursor
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
@@ -57,6 +57,7 @@ cmake-build-*/
!.vscode/extensions.json
*.code-workspace
.history/
+.cursor/
# Eclipse
.project
@@ -66,7 +67,7 @@ cmake-build-*/
.metadata/
bin/
-# Vim / Emacs / Sublime Text
+# Vim / Emacs / Sublime Text / Fleet / Zed
*~
*.swp
*.swo
@@ -75,6 +76,8 @@ bin/
*.sublime-project
\#*\#
.\#*
+.fleet/
+.zed/
# Xcode
build/
@@ -123,6 +126,11 @@ captures/
*.p12
*.pfx
+# Direnv / Devbox / Nix
+.direnv/
+.devbox/
+result
+
# ==============================================================================
# Logs, Caches, and Coverage
# ==============================================================================
@@ -145,6 +153,8 @@ coverage.xml
htmlcov/
*.cover
*.py,cover
+cover/
+nosetests.xml
# ==============================================================================
# Programming Languages
@@ -175,23 +185,51 @@ share/python-wheels/
MANIFEST
.tox/
.nox/
+.hatch/
.hypothesis/
.pytest_cache/
.mypy_cache/
+.dmypy.json
+dmypy.json
+.pyre/
+.pytype/
.ruff_cache/
profile_default/
ipython_config.py
*.ipynb_checkpoints/
pip-log.txt
pip-delete-this-directory.txt
+pip-wheel-metadata/
.venv/
venv/
env/
ENV/
virtualenv/
.virtualenv/
+env.bak/
+venv.bak/
# Pipfile.lock # Note: Often committed for reproducible builds
# poetry.lock # Note: Often committed for reproducible builds
+# pdm.lock
+.pdm.toml
+.pdm-python
+.pdm-build/
+__pypackages__/
+pyrightconfig.json
+cython_debug/
+
+# Python Frameworks & Tools
+docs/_build/
+docs/build/
+.scrapy/
+instance/
+.webassets-cache
+celerybeat-schedule
+celerybeat.pid
+*.manifest
+*.spec
+*.mo
+*.pot
# Node.js / JavaScript / TypeScript
node_modules/
@@ -293,9 +331,10 @@ Package.resolved
.nuxt/
.output/
-# Gatsby / Jekyll / Hugo / Docusaurus
+# Gatsby / Jekyll / Hugo / Docusaurus / MkDocs
_site/
.docusaurus/
+site/
# ==============================================================================
# Infrastructure, DevOps & CI/CD
@@ -351,4 +390,3 @@ cdk.out/
*.csv
*.dat
*.seed
-
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..c0f1537
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,38 @@
+---
+default_install_hook_types:
+ - pre-commit
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.6.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ args:
+ - --unsafe
+ - id: check-added-large-files
+ - id: check-merge-conflict
+ - repo: local
+ hooks:
+ - id: lint-check
+ name: Quality and Formatting (Hatch)
+ entry: hatch run lint:check
+ language: python
+ additional_dependencies:
+ - hatch
+ - uv
+ types_or:
+ - python
+ - markdown
+ - yaml
+ pass_filenames: false
+ - id: type-check
+ name: Type Check (Hatch)
+ entry: hatch run types:check
+ language: python
+ additional_dependencies:
+ - hatch
+ - uv
+ types:
+ - python
+ pass_filenames: false
diff --git a/AGENTS.md b/AGENTS.md
index a2c20ce..0cef8ab 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -5,18 +5,19 @@
## Project Context
-**`{{project_name}}`** is a production-ready Apache 2.0 template repository for bootstrapping modern software projects.
-**Primary language:** ``
-**Package manager:** ``
+**`project_name`** is a production-ready Apache 2.0 template repository for bootstrapping modern software projects.
+**Primary language:** `Python 3.10+`\
+**Package manager:** `Hatch`
## Critical Constraints
> [!CAUTION]
+>
> 1. **Never commit secrets.** Do not add API keys, tokens, or credentials anywhere.
-> 2. **Do not modify `LICENSE` or `NOTICE`.** These are legally binding.
-> 3. **Do not modify workflow trigger conditions** without human review.
-> 4. **All new source files must include the Apache 2.0 copyright header.**
-> 5. **Use `{{double_braces}}` for template placeholders.** Never hard-code them.
+> 1. **Do not modify `LICENSE` or `NOTICE`.** These are legally binding.
+> 1. **Do not modify workflow trigger conditions** without human review.
+> 1. **All new source files must include the Apache 2.0 copyright header.**
+> 1. **Use `{{double_braces}}` for template placeholders.** Never hard-code them.
## Repository Layout
@@ -27,10 +28,11 @@
## Executable Commands
-- **Linting:** ``
-- **Testing:** ``
-- **Docs:** `mkdocs serve` / `mkdocs build`
-- **Build:** ``
+- **Linting:** `hatch run lint:check` (Ruff & mdformat) and `hatch run types:check` (Mypy)
+- **Pre-commit:** `pre-commit run --all-files` (Runs formatting and quality checks)
+- **Testing:** `hatch run test:all` (Pytest) and `hatch run test:cov-all` (Coverage)
+- **Docs:** `hatch run docs:serve` / `hatch run docs:build`
+- **Build:** `hatch build`
## Code Style & Patterns
@@ -52,7 +54,7 @@
- **`docs/`** and **`mkdocs.yml`** control the site. Do not create docs outside the `nav:` tree.
- `docs/index.md` dynamically includes `README.md` via MkDocs snippets.
-- Use `{{placeholder}}` variables for templated fields (e.g., `{{project_name}}`, `{{organization}}`).
+- Use `{{placeholder}}` variables for templated fields (e.g., `project_name`, `{{organization}}`).
## Agent Notes
diff --git a/CITATION.cff b/CITATION.cff
index 8b57e90..c9894c2 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -3,14 +3,14 @@
# For more information on the CFF format, see: https://citation-file-format.github.io/
cff-version: 1.2.0
-title: "{{project_name}}"
+title: "project_name"
message: "If you use this software, please cite it as below."
type: software
version: "{{version}}"
date-released: "{{date_released}}"
license: Apache-2.0
-# You can list individual authors or an organization.
+# You can list individual authors or an organization.
# This defaults to the organization to match the README's BibTeX.
authors:
- name: "{{organization}}"
@@ -18,5 +18,5 @@ authors:
# given-names: "{{author_given_name}}"
# orcid: "https://orcid.org/{{orcid}}"
-repository-code: "https://github.com/{{organization}}/{{project_name}}"
-url: "https://{{organization}}.github.io/{{project_name}}"
+repository-code: "https://github.com/{{organization}}/project_name"
+url: "https://{{organization}}.github.io/project_name"
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 6fd9a98..92544c5 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,4 +1,4 @@
-# Code of Conduct for `{{project_name}}`
+# Code of Conduct for `project_name`
## Our Pledge
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the
+- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
-* The use of sexualized language or imagery, and sexual attention or
+- The use of sexualized language or imagery, and sexual attention or
advances of any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email
address, without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
+- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@@ -73,12 +73,12 @@ reporter of any incident.
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
-| Level | Community Impact | Consequence |
-| :--- | :--- | :--- |
-| **1. Correction** | Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. | A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. |
-| **2. Warning** | A violation through a single incident or series of actions. | A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. |
-| **3. Temporary Ban** | A serious violation of community standards, including sustained inappropriate behavior. | A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. |
-| **4. Permanent Ban** | Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. | A permanent ban from any sort of public interaction within the community. |
+| Level | Community Impact | Consequence |
+| :------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **1. Correction** | Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. | A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. |
+| **2. Warning** | A violation through a single incident or series of actions. | A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. |
+| **3. Temporary Ban** | A serious violation of community standards, including sustained inappropriate behavior. | A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. |
+| **4. Permanent Ban** | Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. | A permanent ban from any sort of public interaction within the community. |
## Attribution
@@ -87,14 +87,14 @@ version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
-[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+[Mozilla's code of conduct enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at
-[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
+[https://www.contributor-covenant.org/faq][faq]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
+[faq]: https://www.contributor-covenant.org/faq
[homepage]: https://www.contributor-covenant.org
-[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
-[Mozilla CoC]: https://github.com/mozilla/diversity
-[FAQ]: https://www.contributor-covenant.org/faq
+[mozilla coc]: https://github.com/mozilla/diversity
[translations]: https://www.contributor-covenant.org/translations
+[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 08fff53..50f5d68 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
-# Contributing to {{project_name}}
+# Contributing to project_name
-First off, thank you for considering contributing to `{{project_name}}`! It's people like you that make this project great.
+First off, thank you for considering contributing to `project_name`! It's people like you that make this project great.
## Code of Conduct
@@ -15,13 +15,13 @@ If you discover a security issue, please refer to our [Security Policy](SECURITY
## How Can I Contribute?
-There are many ways to contribute to `{{project_name}}`, and not all of them involve writing code:
+There are many ways to contribute to `project_name`, and not all of them involve writing code:
- **Reporting Bugs:** Help us improve by submitting detailed bug reports via our issue tracker.
- **Suggesting Features:** Propose new features or enhancements that could benefit the project.
- **Improving Documentation:** Fix typos, add examples, or write new guides.
- **Writing Code:** Fix bugs, implement features, or improve performance.
-- **Helping Others:** Answer questions in [Discussions](https://github.com/{{organization}}/{{project_name}}/discussions) or issue comments.
+- **Helping Others:** Answer questions in [Discussions](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/discussions) or issue comments.
For general questions and help, please see [SUPPORT.md](SUPPORT.md).
@@ -32,6 +32,7 @@ If you are contributing code, please follow these structured steps:
### 1. Development Setup
Before you start coding, please refer to our [Development Guide](DEVELOPING.md) (`DEVELOPING.md`) for detailed instructions on:
+
- Setting up your local environment
- Installing dependencies
- Running the test suite
@@ -44,11 +45,11 @@ Before you start coding, please refer to our [Development Guide](DEVELOPING.md)
### 3. Making Changes
-1. **Fork the Repository:** Fork the `{{project_name}}` repository to your GitHub account.
-2. **Create a Branch:** Create a new branch from `main` for your work (e.g., `git checkout -b feat/add-new-feature`).
-3. **Write Code:** Implement your changes, adhering to the project's coding standards.
-4. **Write Tests:** Add unit tests or integration tests for your changes to ensure stability.
-5. **Run Tests:** Ensure all tests and linters pass locally before committing.
+1. **Fork the Repository:** Fork the `project_name` repository to your GitHub account.
+1. **Create a Branch:** Create a new branch from `main` for your work (e.g., `git checkout -b feat/add-new-feature`).
+1. **Write Code:** Implement your changes, adhering to the project's coding standards.
+1. **Write Tests:** Add unit tests or integration tests for your changes to ensure stability.
+1. **Run Tests:** Ensure all tests and linters pass locally before committing.
### 4. Committing Your Changes
@@ -59,11 +60,11 @@ Before you start coding, please refer to our [Development Guide](DEVELOPING.md)
### 5. Submitting a Pull Request
1. **Push your branch:** `git push origin your-branch-name`.
-2. **Open a Pull Request:** Open a PR against the `main` branch of the upstream repository.
-3. **Fill out the PR Template:** Provide a clear description of your changes, link to any relevant issues (e.g., `Closes #123`), and complete any required checklists.
-4. **Pass CI:** Ensure all GitHub Actions CI checks pass.
-5. **Review:** Address any feedback from the maintainers. Once approved and checks pass, a maintainer will merge your PR.
+1. **Open a Pull Request:** Open a PR against the `main` branch of the upstream repository.
+1. **Fill out the PR Template:** Provide a clear description of your changes, link to any relevant issues (e.g., `Closes #123`), and complete any required checklists.
+1. **Pass CI:** Ensure all GitHub Actions CI checks pass.
+1. **Review:** Address any feedback from the maintainers. Once approved and checks pass, a maintainer will merge your PR.
## Licensing
-By contributing to `{{project_name}}`, you agree that your contributions will be licensed under its [Apache 2.0 License](LICENSE).
+By contributing to `project_name`, you agree that your contributions will be licensed under its [Apache 2.0 License](LICENSE).
diff --git a/DEVELOPING.md b/DEVELOPING.md
index fd1ada5..52aca94 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -1,4 +1,4 @@
-# Developing `{{project_name}}`
+# Developing `project_name`
This guide provides instructions for setting up your development environment, navigating the project structure, and adhering to our coding standards.
@@ -8,7 +8,8 @@ Ensure your system meets the following requirements before getting started:
- **[Docker](https://docs.docker.com/get-docker/)** (Recommended for isolated environments)
- **[Git](https://git-scm.com/)** (Version control)
--
+- **[Python](https://www.python.org/)** 3.10+
+- **[Hatch](https://hatch.pypa.io/)** (Project manager)
> [!NOTE]
> We strongly recommend using our Docker setup to ensure your local environment exactly matches our CI/CD pipelines.
@@ -19,15 +20,17 @@ Ensure your system meets the following requirements before getting started:
> The `Dockerfile` and `docker-compose.yml` files included in this template are **placeholders** that must be filled in for your specific language stack before they are usable. The default `CMD` in both files will exit with an error if run without modification.
>
> Once implemented, you can spin up the development environment with:
+>
> ```bash
-> git clone https://github.com/{{organization}}/{{project_name}}.git
-> cd {{project_name}}
+> git clone https://github.com/{{organization}}/project_name.git
+> cd project_name
>
> # Build and start the development environment in the background
> docker-compose up -d --build
> ```
To view the logs of your running containers:
+
```bash
docker-compose logs -f
```
@@ -37,105 +40,109 @@ docker-compose logs -f
If you prefer to develop directly on your host machine, follow the steps for your language stack.
> [!NOTE]
-> **A note on shared tooling:** This project uses [MkDocs](https://www.mkdocs.org/) for documentation. MkDocs requires Python, regardless of your application's primary language. Install it once globally or in a dedicated virtual environment using `docs/requirements.txt`.
+> **A note on shared tooling:** This project uses [MkDocs](https://www.mkdocs.org/) for documentation.
-### Python
+### Python Development with Hatch
-```bash
-# 1. Create and activate a virtual environment
-python -m venv .venv
-source .venv/bin/activate # Windows: .venv\Scripts\activate
+This project uses [Hatch](https://hatch.pypa.io/) for environment management, dependency resolution, and building.
-# 2. Install the package and development dependencies
-pip install -e ".[dev]"
+```bash
+# 1. Install hatch globally (if not already installed)
+pipx install hatch # or pip install hatch
+# 2. Enter the default development environment
+hatch shell
+# Or run commands directly in the environment without entering it:
+hatch run test:all
+hatch run lint:check
```
-### Node.js / TypeScript
-
-```bash
-# 1. Install all dependencies (uses lockfile for reproducibility)
-npm ci
+## Running Tests
+We maintain strict testing standards. Our tests are located in the `tests/` directory and are categorized by tier.
-```
+| Test Tier | Directory | Description |
+| :-------------- | :------------------- | :----------------------------------------------------------------- |
+| **Unit** | `tests/unit/` | Fast, isolated tests for individual functions and classes. |
+| **Integration** | `tests/integration/` | Slower tests that verify interactions between multiple components. |
+| **End-to-End** | `tests/e2e/` | Full-stack tests simulating real user workflows. |
-### Go
+Replace the commands below with those appropriate for your language stack:
```bash
-# 1. Download module dependencies
-go mod download
+# Run unit tests
+hatch run test:unit
+# Run integration tests
+hatch run test:integration
+# Run all tests with coverage
+hatch run test:cov-all
```
-### Rust
+## Code Quality and Formatting
-```bash
-# 1. All dependencies are managed by Cargo automatically
-cargo build
+We use opinionated formatters and linters to maintain consistency: Ruff for linting/formatting and Mypy for static type checking.
+- **Formatters & Linters:**
+ ```bash
+ # Check for linting and formatting issues
+ hatch run lint:check
+ hatch run types:check
-```
+ # Auto-format code
+ hatch run lint:format
+ ```
-## Running Tests
+> [!TIP]
+> **IDE Configuration:** We highly recommend configuring your editor (e.g., VSCode, IntelliJ) to format on save using the project's formatting tools. For VSCode, ensure you have the relevant extensions installed and check `.vscode/settings.json` if available.
-We maintain strict testing standards. Our tests are located in the `tests/` directory and are categorized by tier.
+### Pre-commit Hooks
-| Test Tier | Directory | Description |
-| :--- | :--- | :--- |
-| **Unit** | `tests/unit/` | Fast, isolated tests for individual functions and classes. |
-| **Integration** | `tests/integration/` | Slower tests that verify interactions between multiple components. |
-| **End-to-End** | `tests/e2e/` | Full-stack tests simulating real user workflows. |
+We use [pre-commit](https://pre-commit.com/) to ensure code quality standards are met before changes are committed. This repository is configured to use our existing Hatch environments for these checks, guaranteeing consistency with CI/CD pipelines.
-Replace the commands below with those appropriate for your language stack:
+**Setup:**
-```bash
-# Python (pytest)
-pytest tests/unit/
-pytest tests/integration/
-pytest tests/ # full suite with coverage
-pytest tests/ --cov=src --cov-report=xml
-
-# Node.js (Jest)
-npx jest tests/unit/
-npx jest --ci --coverage
-
-# Go
-go test ./tests/unit/...
-go test ./...
-
-# Rust
-cargo test --lib # unit tests
-cargo test --test '*' # integration tests
-```
+1. Install pre-commit globally or in your local virtual environment:
-## Code Quality and Formatting
+ ```bash
+ pip install pre-commit
+ ```
-We use opinionated formatters and linters to maintain consistency.
+1. Install the git hook scripts:
-- **Formatters & Linters:** We enforce code quality through CI/CD pipelines. Please refer to your language-specific guidelines for setting up local linting.
+ ```bash
+ pre-commit install
+ ```
-> [!TIP]
-> **IDE Configuration:** We highly recommend configuring your editor (e.g., VSCode, IntelliJ) to format on save using the project's formatting tools. For VSCode, ensure you have the relevant extensions installed and check `.vscode/settings.json` if available.
+**Usage:**
+
+Once installed, pre-commit will automatically run on the modified files whenever you commit. To run the hooks manually on all files:
+
+```bash
+pre-commit run --all-files
+```
## Git Workflow & Branching
We follow a structured branching strategy to maintain a clean git history.
1. **Branch Naming:**
+
- Feature branches: `feature/short-description`
- Bug fixes: `bugfix/short-description`
- Documentation: `docs/short-description`
-2. **Commit Messages:**
+1. **Commit Messages:**
We encourage following [Conventional Commits](https://www.conventionalcommits.org/).
+
- `feat: add new user endpoint`
- `fix: resolve crash on startup`
- `docs: update developing guide`
-3. **Pull Requests:**
+1. **Pull Requests:**
+
- Push your branch to the remote repository.
- Open a Pull Request against the `main` branch.
- Ensure all CI checks (tests, linters) pass.
@@ -147,13 +154,13 @@ This repository uses a modular, standardized GitHub Actions architecture. Workfl
### Lifecycle Workflows
-| Workflow | Trigger | Purpose |
-| :--- | :--- | :--- |
+| Workflow | Trigger | Purpose |
+| :---------------------------------- | :--------------------- | :---------------------------------------------------------------------------------------------------------------------------- |
| **Development** (`development.yml`) | Pull Request to `main` | Runs quality gates, security audits, unit/integration tests, and builds documentation previews. Blocks merges if checks fail. |
-| **Main** (`main.yml`) | Push to `main` | Post-merge validation. Runs unit/integration/e2e tests, quality/security checks, and updates the `latest` documentation. |
-| **Nightly** (`nightly.yml`) | Cron (Daily 00:00 UTC) | Runs extended regression tests, alpha builds, nightly documentation deployment, and deeper security analysis. |
-| **Release** (`release.yml`) | Push of `v*.*.*` tag | Performs full verification, builds immutable release packages, versioned documentation, and publishes artifacts. |
-| **Weekly** (`weekly.yml`) | Cron (Sun 00:00 UTC) | Conducts dependency hygiene and full test suite regression to catch configuration drift. |
+| **Main** (`main.yml`) | Push to `main` | Post-merge validation. Runs unit/integration/e2e tests, quality/security checks, and updates the `latest` documentation. |
+| **Nightly** (`nightly.yml`) | Cron (Daily 00:00 UTC) | Runs extended regression tests, alpha builds, nightly documentation deployment, and deeper security analysis. |
+| **Release** (`release.yml`) | Push of `v*.*.*` tag | Performs full verification, builds immutable release packages, versioned documentation, and publishes artifacts. |
+| **Weekly** (`weekly.yml`) | Cron (Sun 00:00 UTC) | Conducts dependency hygiene and full test suite regression to catch configuration drift. |
### PR Feedback & Cleanup
@@ -169,11 +176,9 @@ Our pipelines rely on modular templates located in `.github/workflows/_*.yml` (e
Our documentation is built using [MkDocs Material](https://squidfunk.github.io/mkdocs-material/). To preview documentation changes locally:
```bash
-# Install docs dependencies (if not already installed)
-pip install mkdocs-material
-
+# Hatch manages the isolated docs environment
# Serve documentation on http://127.0.0.1:8000 with hot-reload
-mkdocs serve
+hatch run docs:serve
```
For further assistance, please refer to our [SUPPORT.md](SUPPORT.md).
diff --git a/Dockerfile b/Dockerfile
index f92bc16..c2ad751 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,14 +1,13 @@
# ---------------------------------------------------------
-# {{project_name}} Dockerfile
+# project_name Dockerfile
# Licensed under the Apache License, Version 2.0
# ---------------------------------------------------------
-# Standardized Multi-stage Dockerfile Template
+# Standardized Multi-stage Dockerfile Template for Python
# ---------------------------------------------------------
# Build Stage
# ---------------------------------------------------------
-# Choose an appropriate base image for building (e.g., ubuntu, alpine, node, golang)
-FROM ubuntu:24.04 AS builder
+FROM python:3.10-slim AS builder
# Set working directory
WORKDIR /app
@@ -18,40 +17,38 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential ca-certificates \
&& rm -rf /var/lib/apt/lists/*
-# ---------------------------------------------------------
-# [DEPENDENCIES]
-# Copy package manifests (package.json, Cargo.toml, go.mod, etc.)
-# and install dependencies to leverage Docker layer caching.
-# Example:
-# COPY package*.json ./
-# RUN npm ci
-# ---------------------------------------------------------
+# Install uv for fast dependency management
+RUN pip install uv hatch
+
+# Copy package manifests and install dependencies
+COPY pyproject.toml README.md ./
+# Create a dummy src directory to satisfy hatch build if needed
+RUN mkdir -p src/project_name && touch src/project_name/__init__.py
+RUN uv pip install --system --no-cache -e .
# Copy application source code
COPY src/ ./src/
# ---------------------------------------------------------
-# [BUILD]
-# Run your compilation or build step here.
-# Example:
-# RUN npm run build
-# RUN make build
+# Build any required distribution artifacts
# ---------------------------------------------------------
+RUN hatch build
# ---------------------------------------------------------
# Runtime Stage
# ---------------------------------------------------------
-# Choose a minimal base image for runtime (e.g., ubuntu, alpine, distroless)
-FROM ubuntu:24.04
+FROM python:3.10-slim
# OCI Standard Labels
-LABEL org.opencontainers.image.title="{{project_name}}"
-LABEL org.opencontainers.image.description="Production-ready application container"
+LABEL org.opencontainers.image.title="project_name"
+LABEL org.opencontainers.image.description="Production-ready Python application container"
LABEL org.opencontainers.image.licenses="Apache-2.0"
-LABEL org.opencontainers.image.source="https://github.com/{{organization}}/{{project_name}}"
+LABEL org.opencontainers.image.source="https://github.com/{{organization}}/project_name"
# Define environment variables
-ENV APP_ENV=production
+ENV APP_ENV=production \
+ PYTHONUNBUFFERED=1 \
+ PYTHONDONTWRITEBYTECODE=1
# Set working directory
WORKDIR /app
@@ -59,16 +56,10 @@ WORKDIR /app
# Create a non-root user and set permissions
RUN useradd -m appuser && chown -R appuser /app
-# ---------------------------------------------------------
-# [RUNTIME_ARTIFACTS]
-# Copy necessary built artifacts from the builder stage.
-# Example:
-# COPY --from=builder --chown=appuser:appuser /app/dist ./dist
-# COPY --from=builder --chown=appuser:appuser /app/bin/server ./server
-# ---------------------------------------------------------
-
-# Copy generic source files if needed (uncomment or modify as required)
-# COPY --chown=appuser:appuser src/ ./src/
+# Install runtime dependencies (or copy from builder if using a virtualenv)
+# For simplicity, we copy the project and install it
+COPY --from=builder /app/dist/*.whl ./
+RUN pip install *.whl && rm *.whl
# Switch to the non-root user for security
USER appuser
@@ -77,5 +68,4 @@ USER appuser
EXPOSE 8080
# Define the command to run the application
-# Replace with the language-specific startup command (e.g., ["node", "dist/index.js"])
-CMD ["/bin/sh", "-c", "echo 'Please define a runtime command in the Dockerfile!'; exit 1"]
+CMD ["python", "-m", "project_name"]
diff --git a/NOTICE b/NOTICE
index eed78e4..c4c3b8f 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,8 +1,8 @@
-{{project_name}}
+project_name
Copyright {{year}} {{organization}}
-This product includes software developed by {{organization}}
-(https://github.com/{{organization}}/{{project_name}}).
+This product includes software developed by {{organization}}
+(https://github.com/{{organization}}/project_name).
=========================================================================
Third-Party Attributions
diff --git a/README.md b/README.md
index 8e84d4a..dd03314 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -47,14 +47,14 @@
- Documentation | + Documentation | Blog | - Roadmap | + Roadmap | Slack | Weekly Syncs
---- +______________________________________________________________________ ## Overview @@ -66,11 +66,11 @@ -Welcome to the {{project_name}} template repository! This template provides a robust foundation for building high-quality, scalable software projects. It includes standard directories, issue templates, CI/CD workflows, and comprehensive placeholder documentation. +Welcome to the project_name template repository! This template provides a robust foundation for building high-quality, scalable software projects. It includes standard directories, issue templates, CI/CD workflows, and comprehensive placeholder documentation. -To use this template, simply find and replace all instances of `{{project_name}}` and `{{organization}}` with your actual project details, update the placeholder SVG images in `docs/assets/branding/`, and you are ready to start coding. +To use this template, simply find and replace all instances of `project_name` and `{{organization}}` with your actual project details, update the placeholder SVG images in `docs/assets/branding/`, and you are ready to start coding. -### Why Use {{project_name}}? +### Why Use project_name? - **Consistency:** Enforces a standardized layout and structure across your organization's repositories. - **Speed:** Bootstraps your project with pre-configured Actions, badges, and templates so you don't start from scratch. @@ -78,19 +78,18 @@ To use this template, simply find and replace all instances of `{{project_name}} ### Comparisons -When evaluating {{project_name}} against other templates, consider the following differences: - -| Feature | {{project_name}} Template | Standard GitHub Init | Cookiecutter / Copier | -| :--- | :--- | :--- | :--- | -| **Setup Speed** | Very Fast | Fast | Slower (requires CLI tool) | -| **Visual Assets** | Pre-configured Light/Dark assets | None | Varies | -| **CI/CD Built-in** | Yes (GitHub Actions) | No | Optional | -| **Complexity** | Low (Find and Replace) | None | Medium (Jinja templates) | +When evaluating project_name against other templates, consider the following differences: +| Feature | project_name Template | Standard GitHub Init | Cookiecutter / Copier | +| :----------------- | :------------------------------- | :------------------- | :------------------------- | +| **Setup Speed** | Very Fast | Fast | Slower (requires CLI tool) | +| **Visual Assets** | Pre-configured Light/Dark assets | None | Varies | +| **CI/CD Built-in** | Yes (GitHub Actions) | No | Optional | +| **Complexity** | Low (Find and Replace) | None | Medium (Jinja templates) | ## What's New -**Welcome to the {{project_name}} Launch!** +**Welcome to the project_name Launch!** This project has just been instantiated from the template repository. Keep an eye on this section for future release highlights, new features, and community announcements! @@ -99,32 +98,32 @@ This project has just been instantiated from the template repository. Keep an ey ## Quick Start ```bash - -# e.g., npm install {{project_name}} OR pip install {{project_name}} OR cargo add {{project_name}} +pip install project_name ``` -For full installation options (from source, Docker, platform-specific notes) and step-by-step onboarding, see the **[Getting Started guide](https://{{organization}}.github.io/{{project_name}}/getting-started/)**. +For full installation options (from source, Docker, platform-specific notes) and step-by-step onboarding, see the **[Getting Started guide](https://%7B%7Borganization%7D%7D.github.io/%7B%7Bproject_name%7D%7D/getting-started/)**. ## Core Concepts - +This project is built using modern Python tooling, ensuring a stable and typed foundation. It utilizes Pydantic for data validation and Ruff/Mypy for code quality. ### Component Architecture The template is organized into several key areas: + - `docs/`: Stores your documentation and branding assets. - `src/` (or your primary package directory): The core application logic. - `tests/`: Automated tests to ensure code quality. ## Advanced Usage - +Please check the [`docs/examples/`](docs/examples/) directory for advanced examples and configurations. ## General ### Contributing -We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details. For development setup, check out [DEVELOPING.md](DEVELOPING.md). +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details. For development setup, check out [DEVELOPING.md](DEVELOPING.md). Please ensure you follow our [Code of Conduct](CODE_OF_CONDUCT.md) in all interactions. ### Support and Security @@ -148,12 +147,12 @@ This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE If you use this template or the resulting software in your research, please cite it using the following BibTeX entry: ```bibtex -@software{{{project_name}}, +@software{project_name, author = {{{organization}}}, - title = {{{project_name}}}, + title = {project_name}, version = {{{version}}}, month = {{{month}}}, year = {2026}, - url = {https://github.com/{{organization}}/{{project_name}}} + url = {https://github.com/{{organization}}/project_name} } ``` diff --git a/SECURITY.md b/SECURITY.md index a999843..cca8520 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,15 +1,15 @@ -# Security Policy for `{{project_name}}` +# Security Policy for `project_name` -We take the security of `{{project_name}}` seriously. This document outlines our security policies, supported versions, and how to responsibly disclose a vulnerability. +We take the security of `project_name` seriously. This document outlines our security policies, supported versions, and how to responsibly disclose a vulnerability. ## Supported Versions -Please check the table below for the versions of `{{project_name}}` that are currently being supported with security updates. +Please check the table below for the versions of `project_name` that are currently being supported with security updates. -| Version | Supported | -| :--- | :--- | -| `{{current_major_version}}.x` | :white_check_mark: | -| `< {{current_major_version}}.0` | :x: | +| Version | Supported | +| :------------------------------ | :----------------- | +| `{{current_major_version}}.x` | :white_check_mark: | +| `< {{current_major_version}}.0` | :x: | *(Note: Replace the table contents with your actual versioning scheme once released.)* @@ -20,37 +20,40 @@ Please check the table below for the versions of `{{project_name}}` that are cur If you discover a security vulnerability, please bring it to our attention right away using one of the following methods: -1. **GitHub Security Advisories (Preferred):** Use the "Report a vulnerability" button on the **[Security tab](https://github.com/{{organization}}/{{project_name}}/security/advisories)** of this repository. -2. **Email:** Send your report directly to **[INSERT EMAIL ADDRESS OR SECURITY CONTACT]**. *(Optional: Encrypt your email using our PGP key: [INSERT PGP KEY LINK/FINGERPRINT])* +1. **GitHub Security Advisories (Preferred):** Use the "Report a vulnerability" button on the **[Security tab](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/security/advisories)** of this repository. +1. **Email:** Send your report directly to **[INSERT EMAIL ADDRESS OR SECURITY CONTACT]**. *(Optional: Encrypt your email using our PGP key: [INSERT PGP KEY LINK/FINGERPRINT])* ### What to Include in Your Report To help us resolve the issue quickly, please include the following information: + - **Type of vulnerability** (e.g., XSS, SQLi, RCE, authorization bypass). - **Detailed description** of the vulnerability and its potential impact. - **Step-by-step instructions** to reproduce the issue. - **Proof of Concept (PoC)** code or screenshots, if available. -- **Environment details** (e.g., version of `{{project_name}}`, OS, relevant configurations). +- **Environment details** (e.g., version of `project_name`, OS, relevant configurations). ## Triage and Resolution Process We will handle your report with strict confidentiality. Our process is as follows: 1. **Acknowledgment:** We will respond to your report as soon as possible, usually within **[INSERT NUMBER, e.g., 48] hours**. -2. **Triage:** We will investigate the issue and determine its validity and severity. We may contact you for further clarification. -3. **Fix:** If the vulnerability is verified, we will develop and test a patch. -4. **Disclosure:** We will coordinate with you to publicly disclose the vulnerability once a fix is released. We will publicly acknowledge your responsible disclosure, if you wish. +1. **Triage:** We will investigate the issue and determine its validity and severity. We may contact you for further clarification. +1. **Fix:** If the vulnerability is verified, we will develop and test a patch. +1. **Disclosure:** We will coordinate with you to publicly disclose the vulnerability once a fix is released. We will publicly acknowledge your responsible disclosure, if you wish. ## Scope **In Scope:** -- Vulnerabilities within the core `{{project_name}}` codebase. + +- Vulnerabilities within the core `project_name` codebase. - Security issues in our default configurations. **Out of Scope:** + - Volumetric Denial of Service (DoS) attacks. - Theoretical issues without a reproducible PoC. -- Vulnerabilities in third-party dependencies that are not exploitable through `{{project_name}}`. +- Vulnerabilities in third-party dependencies that are not exploitable through `project_name`. - Missing security headers or best practices that do not lead to a direct exploit. *(Note: We currently **[do/do not]** operate a bug bounty program. Disclosures are greatly appreciated but are not eligible for financial rewards at this time.)* diff --git a/SUPPORT.md b/SUPPORT.md index dd8714d..532325f 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,6 +1,6 @@ -# Support for `{{project_name}}` +# Support for `project_name` -We are excited to have you use `{{project_name}}`! If you need help, please follow these guidelines to ensure you get support quickly and efficiently. +We are excited to have you use `project_name`! If you need help, please follow these guidelines to ensure you get support quickly and efficiently. ## Security Vulnerabilities @@ -13,19 +13,19 @@ If you have found a security vulnerability, please refer to our [Security Policy Before reaching out, we recommend checking the following resources. Many common questions and issues are already covered there. -- **[Official Documentation](https://{{organization}}.github.io/{{project_name}}):** Comprehensive guides, tutorials, and API references. -- **[GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues):** Search existing issues to see if someone else has already reported your problem or requested your feature. Feel free to add a "+1" reaction to existing issues to show your interest. -- **[GitHub Discussions](https://github.com/{{organization}}/{{project_name}}/discussions):** Search our discussions for Q&A, general advice, and community knowledge. +- **[Official Documentation](https://%7B%7Borganization%7D%7D.github.io/%7B%7Bproject_name%7D%7D):** Comprehensive guides, tutorials, and API references. +- **[GitHub Issues](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/issues):** Search existing issues to see if someone else has already reported your problem or requested your feature. Feel free to add a "+1" reaction to existing issues to show your interest. +- **[GitHub Discussions](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/discussions):** Search our discussions for Q&A, general advice, and community knowledge. ## Opening a New Issue If you cannot find an answer in the documentation or existing issues, please open a new issue. To help us resolve your issue faster, please choose the correct venue: -| Issue Type | Venue | Description | -| :--- | :--- | :--- | -| **Bug Report** | [GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues/new) | Use the "Bug Report" template. Provide reproducible steps, environment details, and relevant logs. | -| **Feature Request** | [GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues/new) | Use the "Feature Request" template. Clearly describe your use case and the problem the feature would solve. | -| **Q&A / General Help** | [GitHub Discussions](https://github.com/{{organization}}/{{project_name}}/discussions/new) | Start a discussion for questions about how to use `{{project_name}}`, architecture queries, or advice. | +| Issue Type | Venue | Description | +| :--------------------- | :--------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | +| **Bug Report** | [GitHub Issues](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/issues/new) | Use the "Bug Report" template. Provide reproducible steps, environment details, and relevant logs. | +| **Feature Request** | [GitHub Issues](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/issues/new) | Use the "Feature Request" template. Clearly describe your use case and the problem the feature would solve. | +| **Q&A / General Help** | [GitHub Discussions](https://github.com/%7B%7Borganization%7D%7D/%7B%7Bproject_name%7D%7D/discussions/new) | Start a discussion for questions about how to use `project_name`, architecture queries, or advice. | ## Community Channels @@ -38,4 +38,5 @@ Join our community to chat with other users, contributors, and the core maintain ## Commercial Support -At this time, there is no official commercial support available for `{{project_name}}`. Support is provided on a best-effort basis by the open-source community and maintainers. + +At this time, there is no official commercial support available for `project_name`. Support is provided on a best-effort basis by the open-source community and maintainers. diff --git a/docker-compose.yml b/docker-compose.yml index da6a338..ff79821 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,8 @@ +--- # --------------------------------------------------------- -# {{project_name}} Docker Compose +# project_name Docker Compose # Licensed under the Apache License, Version 2.0 # --------------------------------------------------------- - services: app: build: @@ -15,9 +15,11 @@ services: environment: - APP_ENV=${APP_ENV:-development} - APP_DEBUG=${APP_DEBUG:-true} - # Replace this with your language-specific live-reload or run command - # Examples: ["npm", "run", "dev"], ["make", "run"], ["cargo", "run"] - command: ["/bin/sh", "-c", "echo 'Please define a command in docker-compose.yml!'; exit 1"] + # Standard Python development command + command: + - "python" + - "-m" + - "project_name" # Standard Database Profile # Use `docker-compose --profile db up` to start this service @@ -30,9 +32,8 @@ services: environment: POSTGRES_USER: ${DB_USER:-admin} POSTGRES_PASSWORD: ${DB_PASSWORD:-secret} - POSTGRES_DB: ${DB_NAME:-{{project_name}}_dev} + POSTGRES_DB: ${DB_NAME:-project_name_dev} volumes: - db_data:/var/lib/postgresql/data - volumes: db_data: diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 68d078c..0000000 --- a/docs/README.md +++ /dev/null @@ -1,172 +0,0 @@ -# Documentation - -This directory contains the source files for the `{{project_name}}` documentation site, built with [MkDocs](https://www.mkdocs.org/) and the [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) theme. - -## Directory Structure - -``` -docs/ -├── assets/ # Branding assets (logos, diagrams, favicons) -├── community/ # Contributing, Code of Conduct, Security, Support -├── examples/ # Runnable code examples and demos -├── getting-started/ # Installation, quick start, and workflow guides -├── guides/ # Task-oriented how-to guides -├── reference/ # API reference and configuration schema -├── scripts/ # Custom JavaScript for the docs site (extra.js) -├── stylesheets/ # Custom CSS for the docs site (extra.css) -├── index.md # Docs home page (hero landing page) -└── README.md # This file -``` - -The MkDocs configuration lives at the repository root: [`mkdocs.yml`](../mkdocs.yml). - - -## Prerequisites - -- **Python 3.9+** — Required to run MkDocs and its plugins. -- **pip** — For installing documentation dependencies. - -All documentation dependencies are listed in `docs/requirements.txt`. Install them with: - -```bash -pip install -r docs/requirements.txt -``` - -> **Tip:** See [DEVELOPING.md](../DEVELOPING.md) for the full local setup guide. Even if your main project is not in Python, the documentation is built with MkDocs and requires a Python environment to build locally. - - - -## Local Development - -### Serve the Docs Locally - -Start the live-reloading development server from the **repository root**: - -```bash -mkdocs serve -``` - -The site will be available at [http://127.0.0.1:8000](http://127.0.0.1:8000). Any change you save to a source file is reflected immediately in the browser — no manual refresh needed. - -### Specify a Custom Host or Port - -```bash -mkdocs serve --dev-addr 0.0.0.0:8080 -``` - -### Template Variables - -All `{{ variable }}` references in the docs (e.g. `{{ project_name }}`, `{{ org_name }}`) are driven by the `extra:` block in [`mkdocs.yml`](../mkdocs.yml). Update those values once and the change propagates across the entire site: - -```yaml -# mkdocs.yml -extra: - project_name: "my-project" - org_name: "my-org" - # ... other variables -``` - - -## Building the Docs - -Produce a static build of the site in the `site/` directory: - -```bash -mkdocs build -``` - -> The `site/` directory is intentionally excluded from version control via `.gitignore`. Do **not** commit it manually. - -To perform a clean build (removes the previous `site/` output first): - -```bash -mkdocs build --clean -``` - -Validate that all internal links resolve correctly: - -```bash -mkdocs build --strict -``` - -The `--strict` flag is recommended before opening a pull request or cutting a release to catch broken links early. - - -## Publishing the Docs - -### Automated Publishing (Recommended) - -Documentation is published automatically to **GitHub Pages** on every merge to `main` (or on a tagged release, depending on your workflow configuration). No manual steps are required — simply merge your changes and the CI/CD pipeline handles the rest. - -See the relevant workflow file in [`.github/workflows/`](../.github/workflows/) for the exact trigger and deployment steps. - -### Manual Publishing - -If you need to publish outside of the normal CI/CD cycle, run the following from the **repository root**: - -```bash -mkdocs gh-deploy --force -``` - -This command builds the static site and force-pushes it to the `gh-pages` branch of your repository, which GitHub Pages then serves automatically. - -> **Note:** Manual deploys require you to have write access to the repository and a configured `git` identity (`user.name` and `user.email`). - -#### Dry-run First - -To preview what `gh-deploy` would do without actually pushing: - -```bash -mkdocs gh-deploy --dry-run -``` - - -## Adding and Editing Pages - -1. **Create a new `.md` file** in the appropriate subdirectory (e.g., `guides/my-new-guide.md`). -2. **Register it in the nav** by adding an entry to the `nav:` block in [`mkdocs.yml`](../mkdocs.yml). -3. **Preview locally** with `mkdocs serve` before opening a pull request. - -### Page Metadata - -Every page should include a top-level `# Heading` that matches its nav label. Optionally, add MkDocs front matter for advanced layout control: - -```yaml ---- -hide: - - toc # Hide the table of contents - - navigation # Hide the left-hand nav ---- -``` - -### Admonitions - -This site uses [PyMdown Extensions](https://facelessuser.github.io/pymdown-extensions/) and MkDocs Material admonitions. Use them liberally: - -```markdown -!!! note - This is an informational note. - -!!! warning - This is a warning. -``` - - -## Common Troubleshooting - -| Symptom | Likely Cause | Fix | -| :--- | :--- | :--- | -| `mkdocs: command not found` | Dependencies not installed | `pip install mkdocs mkdocs-material mkdocs-macros-plugin pymdown-extensions` | -| `{{ variable }}` renders literally | `mkdocs-macros-plugin` missing or misconfigured | Confirm `macros` is listed under `plugins:` in `mkdocs.yml` | -| Broken links on `--strict` build | Missing or misnamed file in `nav:` | Verify file path and `nav:` registration in `mkdocs.yml` | -| Styles missing in local preview | Custom CSS path wrong | Confirm `extra_css` path in `mkdocs.yml` matches `docs/stylesheets/extra.css` | -| `gh-deploy` push rejected | Stale `gh-pages` branch | Use `mkdocs gh-deploy --force` or delete and re-create the `gh-pages` branch | - - -## Related Resources - -- [MkDocs Documentation](https://www.mkdocs.org/) -- [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) -- [MkDocs Macros Plugin](https://mkdocs-macros-plugin.readthedocs.io/) -- [PyMdown Extensions](https://facelessuser.github.io/pymdown-extensions/) -- [GitHub Pages — Publishing Source](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) diff --git a/docs/community/agents.md b/docs/community/agents.md index 97ecbc2..ece8699 100644 --- a/docs/community/agents.md +++ b/docs/community/agents.md @@ -1 +1,5 @@ ---8<-- "AGENTS.md" + + +--8\<-- "AGENTS.md" + + diff --git a/docs/community/code-of-conduct.md b/docs/community/code-of-conduct.md index 01f2ea2..2c30ec8 100644 --- a/docs/community/code-of-conduct.md +++ b/docs/community/code-of-conduct.md @@ -1 +1,5 @@ ---8<-- "CODE_OF_CONDUCT.md" + + +--8\<-- "CODE_OF_CONDUCT.md" + + diff --git a/docs/community/contributing.md b/docs/community/contributing.md index ea38c9b..adcb4b8 100644 --- a/docs/community/contributing.md +++ b/docs/community/contributing.md @@ -1 +1,5 @@ ---8<-- "CONTRIBUTING.md" + + +--8\<-- "CONTRIBUTING.md" + + diff --git a/docs/community/developing.md b/docs/community/developing.md index 6e6ec19..6cb61e8 100644 --- a/docs/community/developing.md +++ b/docs/community/developing.md @@ -1 +1,5 @@ ---8<-- "DEVELOPING.md" + + +--8\<-- "DEVELOPING.md" + + diff --git a/docs/community/index.md b/docs/community/index.md index 7f3e639..bf1ee89 100644 --- a/docs/community/index.md +++ b/docs/community/index.md @@ -2,60 +2,58 @@ `{{ project_name }}` is an open-source project and we welcome participation from everyone. This section contains all the resources you need to get involved, stay informed, and interact with the community. - ## Get Involved
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -53,9 +53,9 @@ This file contains the concatenated core documentation for the project to provid
- Documentation | + Documentation | Blog | - Roadmap | + Roadmap | Slack | Weekly Syncs
@@ -70,11 +70,11 @@ This file contains the concatenated core documentation for the project to provid -Welcome to the {{project_name}} template repository! This template provides a robust foundation for building high-quality, scalable software projects. It includes standard directories, issue templates, CI/CD workflows, and comprehensive placeholder documentation. +Welcome to the project_name template repository! This template provides a robust foundation for building high-quality, scalable software projects. It includes standard directories, issue templates, CI/CD workflows, and comprehensive placeholder documentation. -To use this template, simply find and replace all instances of `{{project_name}}` and `{{organization}}` with your actual project details, update the placeholder SVG images in `docs/assets/branding/`, and you are ready to start coding. +To use this template, simply find and replace all instances of `project_name` and `{{organization}}` with your actual project details, update the placeholder SVG images in `docs/assets/branding/`, and you are ready to start coding. -### Why Use {{project_name}}? +### Why Use project_name? - **Consistency:** Enforces a standardized layout and structure across your organization's repositories. - **Speed:** Bootstraps your project with pre-configured Actions, badges, and templates so you don't start from scratch. @@ -82,9 +82,9 @@ To use this template, simply find and replace all instances of `{{project_name}} ### Comparisons -When evaluating {{project_name}} against other templates, consider the following differences: +When evaluating project_name against other templates, consider the following differences: -| Feature | {{project_name}} Template | Standard GitHub Init | Cookiecutter / Copier | +| Feature | project_name Template | Standard GitHub Init | Cookiecutter / Copier | | :--- | :--- | :--- | :--- | | **Setup Speed** | Very Fast | Fast | Slower (requires CLI tool) | | **Visual Assets** | Pre-configured Light/Dark assets | None | Varies | @@ -94,7 +94,7 @@ When evaluating {{project_name}} against other templates, consider the following ## What's New -**Welcome to the {{project_name}} Launch!** +**Welcome to the project_name Launch!** This project has just been instantiated from the template repository. Keep an eye on this section for future release highlights, new features, and community announcements! @@ -103,10 +103,10 @@ This project has just been instantiated from the template repository. Keep an ey ## Quick Start ```bash -pip install {{project_name}} +pip install project_name ``` -For full installation options (from source, Docker, platform-specific notes) and step-by-step onboarding, see the **[Getting Started guide](https://{{organization}}.github.io/{{project_name}}/getting-started/)**. +For full installation options (from source, Docker, platform-specific notes) and step-by-step onboarding, see the **[Getting Started guide](https://{{organization}}.github.io/project_name/getting-started/)**. ## Core Concepts @@ -127,7 +127,7 @@ The template is organized into several key areas: ### Contributing -We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details. For development setup, check out [DEVELOPING.md](DEVELOPING.md). +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details. For development setup, check out [DEVELOPING.md](DEVELOPING.md). Please ensure you follow our [Code of Conduct](CODE_OF_CONDUCT.md) in all interactions. ### Support and Security @@ -151,13 +151,13 @@ This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE If you use this template or the resulting software in your research, please cite it using the following BibTeX entry: ```bibtex -@software{{{project_name}}, +@software{project_name, author = {{{organization}}}, - title = {{{project_name}}}, + title = {project_name}, version = {{{version}}}, month = {{{month}}}, year = {2026}, - url = {https://github.com/{{organization}}/{{project_name}}} + url = {https://github.com/{{organization}}/project_name} } ``` @@ -170,9 +170,9 @@ If you use this template or the resulting software in your research, please cite ## Project Context -**`{{project_name}}`** is a production-ready Apache 2.0 template repository for bootstrapping modern software projects. -**Primary language:** `` -**Package manager:** `` +**`project_name`** is a production-ready Apache 2.0 template repository for bootstrapping modern software projects. +**Primary language:** `` +**Package manager:** `` ## Critical Constraints @@ -217,7 +217,7 @@ If you use this template or the resulting software in your research, please cite - **`docs/`** and **`mkdocs.yml`** control the site. Do not create docs outside the `nav:` tree. - `docs/index.md` dynamically includes `README.md` via MkDocs snippets. -- Use `{{placeholder}}` variables for templated fields (e.g., `{{project_name}}`, `{{organization}}`). +- Use `{{placeholder}}` variables for templated fields (e.g., `project_name`, `{{organization}}`). ## Agent Notes @@ -225,7 +225,7 @@ _Add notes here when updating instructions for AI agents._ ## File: DEVELOPING.md -# Developing `{{project_name}}` +# Developing `project_name` This guide provides instructions for setting up your development environment, navigating the project structure, and adhering to our coding standards. @@ -235,7 +235,7 @@ Ensure your system meets the following requirements before getting started: - **[Docker](https://docs.docker.com/get-docker/)** (Recommended for isolated environments) - **[Git](https://git-scm.com/)** (Version control) -- +- Python 3.10+ > [!NOTE] > We strongly recommend using our Docker setup to ensure your local environment exactly matches our CI/CD pipelines. @@ -247,8 +247,8 @@ Ensure your system meets the following requirements before getting started: > > Once implemented, you can spin up the development environment with: > ```bash -> git clone https://github.com/{{organization}}/{{project_name}}.git -> cd {{project_name}} +> git clone https://github.com/{{organization}}/project_name.git +> cd project_name > > # Build and start the development environment in the background > docker-compose up -d --build @@ -285,37 +285,6 @@ pip install -e ".[dev]" pre-commit install ``` -### Node.js / TypeScript - -```bash -# 1. Install all dependencies (uses lockfile for reproducibility) -npm ci - -# 2. Install pre-commit hooks (requires Python; see note above) -pre-commit install -# Alternatively, use Husky for a pure Node.js hook solution: -# npx husky install -``` - -### Go - -```bash -# 1. Download module dependencies -go mod download - -# 2. Install pre-commit hooks (requires Python; see note above) -pre-commit install -``` - -### Rust - -```bash -# 1. All dependencies are managed by Cargo automatically -cargo build - -# 2. Install pre-commit hooks (requires Python; see note above) -pre-commit install -``` ## Running Tests @@ -335,18 +304,6 @@ pytest tests/unit/ pytest tests/integration/ pytest tests/ # full suite with coverage pytest tests/ --cov=src --cov-report=xml - -# Node.js (Jest) -npx jest tests/unit/ -npx jest --ci --coverage - -# Go -go test ./tests/unit/... -go test ./... - -# Rust -cargo test --lib # unit tests -cargo test --test '*' # integration tests ``` ## Code Quality and Formatting @@ -401,9 +358,9 @@ For further assistance, please refer to our [SUPPORT.md](SUPPORT.md). ## File: CONTRIBUTING.md -# Contributing to {{project_name}} +# Contributing to project_name -First off, thank you for considering contributing to `{{project_name}}`! It's people like you that make this project great. +First off, thank you for considering contributing to `project_name`! It's people like you that make this project great. ## Code of Conduct @@ -418,13 +375,13 @@ If you discover a security issue, please refer to our [Security Policy](SECURITY ## How Can I Contribute? -There are many ways to contribute to `{{project_name}}`, and not all of them involve writing code: +There are many ways to contribute to `project_name`, and not all of them involve writing code: - **Reporting Bugs:** Help us improve by submitting detailed bug reports via our issue tracker. - **Suggesting Features:** Propose new features or enhancements that could benefit the project. - **Improving Documentation:** Fix typos, add examples, or write new guides. - **Writing Code:** Fix bugs, implement features, or improve performance. -- **Helping Others:** Answer questions in [Discussions](https://github.com/{{organization}}/{{project_name}}/discussions) or issue comments. +- **Helping Others:** Answer questions in [Discussions](https://github.com/{{organization}}/project_name/discussions) or issue comments. For general questions and help, please see [SUPPORT.md](SUPPORT.md). @@ -447,7 +404,7 @@ Before you start coding, please refer to our [Development Guide](DEVELOPING.md) ### 3. Making Changes -1. **Fork the Repository:** Fork the `{{project_name}}` repository to your GitHub account. +1. **Fork the Repository:** Fork the `project_name` repository to your GitHub account. 2. **Create a Branch:** Create a new branch from `main` for your work (e.g., `git checkout -b feat/add-new-feature`). 3. **Write Code:** Implement your changes, adhering to the project's coding standards. 4. **Write Tests:** Add unit tests or integration tests for your changes to ensure stability. @@ -469,17 +426,17 @@ Before you start coding, please refer to our [Development Guide](DEVELOPING.md) ## Licensing -By contributing to `{{project_name}}`, you agree that your contributions will be licensed under its [Apache 2.0 License](LICENSE). +By contributing to `project_name`, you agree that your contributions will be licensed under its [Apache 2.0 License](LICENSE). ## File: SECURITY.md -# Security Policy for `{{project_name}}` +# Security Policy for `project_name` -We take the security of `{{project_name}}` seriously. This document outlines our security policies, supported versions, and how to responsibly disclose a vulnerability. +We take the security of `project_name` seriously. This document outlines our security policies, supported versions, and how to responsibly disclose a vulnerability. ## Supported Versions -Please check the table below for the versions of `{{project_name}}` that are currently being supported with security updates. +Please check the table below for the versions of `project_name` that are currently being supported with security updates. | Version | Supported | | :--- | :--- | @@ -495,7 +452,7 @@ Please check the table below for the versions of `{{project_name}}` that are cur If you discover a security vulnerability, please bring it to our attention right away using one of the following methods: -1. **GitHub Security Advisories (Preferred):** Use the "Report a vulnerability" button on the **[Security tab](https://github.com/{{organization}}/{{project_name}}/security/advisories)** of this repository. +1. **GitHub Security Advisories (Preferred):** Use the "Report a vulnerability" button on the **[Security tab](https://github.com/{{organization}}/project_name/security/advisories)** of this repository. 2. **Email:** Send your report directly to **[INSERT EMAIL ADDRESS OR SECURITY CONTACT]**. *(Optional: Encrypt your email using our PGP key: [INSERT PGP KEY LINK/FINGERPRINT])* ### What to Include in Your Report @@ -505,7 +462,7 @@ To help us resolve the issue quickly, please include the following information: - **Detailed description** of the vulnerability and its potential impact. - **Step-by-step instructions** to reproduce the issue. - **Proof of Concept (PoC)** code or screenshots, if available. -- **Environment details** (e.g., version of `{{project_name}}`, OS, relevant configurations). +- **Environment details** (e.g., version of `project_name`, OS, relevant configurations). ## Triage and Resolution Process @@ -519,22 +476,22 @@ We will handle your report with strict confidentiality. Our process is as follow ## Scope **In Scope:** -- Vulnerabilities within the core `{{project_name}}` codebase. +- Vulnerabilities within the core `project_name` codebase. - Security issues in our default configurations. **Out of Scope:** - Volumetric Denial of Service (DoS) attacks. - Theoretical issues without a reproducible PoC. -- Vulnerabilities in third-party dependencies that are not exploitable through `{{project_name}}`. +- Vulnerabilities in third-party dependencies that are not exploitable through `project_name`. - Missing security headers or best practices that do not lead to a direct exploit. *(Note: We currently **[do/do not]** operate a bug bounty program. Disclosures are greatly appreciated but are not eligible for financial rewards at this time.)* ## File: SUPPORT.md -# Support for `{{project_name}}` +# Support for `project_name` -We are excited to have you use `{{project_name}}`! If you need help, please follow these guidelines to ensure you get support quickly and efficiently. +We are excited to have you use `project_name`! If you need help, please follow these guidelines to ensure you get support quickly and efficiently. ## Security Vulnerabilities @@ -547,9 +504,9 @@ If you have found a security vulnerability, please refer to our [Security Policy Before reaching out, we recommend checking the following resources. Many common questions and issues are already covered there. -- **[Official Documentation](https://{{organization}}.github.io/{{project_name}}):** Comprehensive guides, tutorials, and API references. -- **[GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues):** Search existing issues to see if someone else has already reported your problem or requested your feature. Feel free to add a "+1" reaction to existing issues to show your interest. -- **[GitHub Discussions](https://github.com/{{organization}}/{{project_name}}/discussions):** Search our discussions for Q&A, general advice, and community knowledge. +- **[Official Documentation](https://{{organization}}.github.io/project_name):** Comprehensive guides, tutorials, and API references. +- **[GitHub Issues](https://github.com/{{organization}}/project_name/issues):** Search existing issues to see if someone else has already reported your problem or requested your feature. Feel free to add a "+1" reaction to existing issues to show your interest. +- **[GitHub Discussions](https://github.com/{{organization}}/project_name/discussions):** Search our discussions for Q&A, general advice, and community knowledge. ## Opening a New Issue @@ -557,9 +514,9 @@ If you cannot find an answer in the documentation or existing issues, please ope | Issue Type | Venue | Description | | :--- | :--- | :--- | -| **Bug Report** | [GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues/new) | Use the "Bug Report" template. Provide reproducible steps, environment details, and relevant logs. | -| **Feature Request** | [GitHub Issues](https://github.com/{{organization}}/{{project_name}}/issues/new) | Use the "Feature Request" template. Clearly describe your use case and the problem the feature would solve. | -| **Q&A / General Help** | [GitHub Discussions](https://github.com/{{organization}}/{{project_name}}/discussions/new) | Start a discussion for questions about how to use `{{project_name}}`, architecture queries, or advice. | +| **Bug Report** | [GitHub Issues](https://github.com/{{organization}}/project_name/issues/new) | Use the "Bug Report" template. Provide reproducible steps, environment details, and relevant logs. | +| **Feature Request** | [GitHub Issues](https://github.com/{{organization}}/project_name/issues/new) | Use the "Feature Request" template. Clearly describe your use case and the problem the feature would solve. | +| **Q&A / General Help** | [GitHub Discussions](https://github.com/{{organization}}/project_name/discussions/new) | Start a discussion for questions about how to use `project_name`, architecture queries, or advice. | ## Community Channels @@ -572,4 +529,4 @@ Join our community to chat with other users, contributors, and the core maintain ## Commercial Support -At this time, there is no official commercial support available for `{{project_name}}`. Support is provided on a best-effort basis by the open-source community and maintainers. +At this time, there is no official commercial support available for `project_name`. Support is provided on a best-effort basis by the open-source community and maintainers. diff --git a/llms.txt b/llms.txt index 69340ed..c964fa0 100644 --- a/llms.txt +++ b/llms.txt @@ -1,20 +1,20 @@ -# {{project_name}} +# project_name > An opinionated, production-ready Apache 2.0 template repository for bootstrapping modern software projects. -`{{project_name}}` is designed to eliminate boilerplate and enforce consistency across an organization's repositories. +`project_name` is designed to eliminate boilerplate and enforce consistency across an organization's repositories. For comprehensive context and full documentation, please see [llms-full.txt](llms-full.txt). ## Docs -- [Home](https://{{organization}}.github.io/{{project_name}}/): Documentation site home page -- [Getting Started](https://{{organization}}.github.io/{{project_name}}/getting-started/): Installation, quickstart, and workflow guides -- [Guides](https://{{organization}}.github.io/{{project_name}}/guides/): How-to guides for common tasks -- [API Reference](https://{{organization}}.github.io/{{project_name}}/reference/): Full API reference documentation +- [Home](https://{{organization}}.github.io/project_name/): Documentation site home page +- [Getting Started](https://{{organization}}.github.io/project_name/getting-started/): Installation, quickstart, and workflow guides +- [Guides](https://{{organization}}.github.io/project_name/guides/): How-to guides for common tasks +- [API Reference](https://{{organization}}.github.io/project_name/reference/): Full API reference documentation ## Repository Files -- [README.md](https://github.com/{{organization}}/{{project_name}}/blob/main/README.md): Project overview and quick start -- [AGENTS.md](https://github.com/{{organization}}/{{project_name}}/blob/main/AGENTS.md): AI agent coding instructions -- [DEVELOPING.md](https://github.com/{{organization}}/{{project_name}}/blob/main/DEVELOPING.md): Developer setup guide +- [README.md](https://github.com/{{organization}}/project_name/blob/main/README.md): Project overview and quick start +- [AGENTS.md](https://github.com/{{organization}}/project_name/blob/main/AGENTS.md): AI agent coding instructions +- [DEVELOPING.md](https://github.com/{{organization}}/project_name/blob/main/DEVELOPING.md): Developer setup guide ## Optional -- [Full Documentation](https://{{organization}}.github.io/{{project_name}}/llms-full.txt): The complete concatenated documentation for {{project_name}} +- [Full Documentation](https://{{organization}}.github.io/project_name/llms-full.txt): The complete concatenated documentation for project_name diff --git a/mkdocs.yml b/mkdocs.yml index e2b5fe3..e02bb22 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,28 +1,26 @@ -site_name: "{{ project_name }}" -site_description: "{{ project_description }}" -site_author: "{{ org_name }}" -site_url: "https://{{ org_name }}.github.io/{{ project_name }}/" - -repo_url: "https://github.com/{{ org_name }}/{{ project_name }}" -repo_name: "{{ org_name }}/{{ project_name }}" +--- +site_name: "{{project_name}}" +site_description: "{{project_description}}" +site_author: "{{org_name}}" +site_url: "https://{{org_name}}.github.io/{{project_name}}/" +repo_url: "https://github.com/{{org_name}}/{{project_name}}" +repo_name: "{{org_name}}/{{project_name}}" edit_uri: edit/main/docs/ - # --------------------------------------------------------------------------- # Template Variables — Update these when using this template. # All {{ variable }} references across the docs site are driven from here. # --------------------------------------------------------------------------- extra: - project_name: "{{project_name}}" + project_name: "project_name" project_description: "{{project_description}}" org_name: "{{organization}}" org_email: "conduct@{{organization}}.com" - docs_url: "https://{{organization}}.github.io/{{project_name}}" + docs_url: "https://{{org_name}}.github.io/{{project_name}}" min_python: "3.9" current_major_version: "0" slack_url: "https://slack.{{organization}}.org" blog_url: "https://blog.{{organization}}.org" - roadmap_url: "https://github.com/{{organization}}/{{project_name}}/milestones" - + roadmap_url: "https://github.com/{{organization}}/project_name/milestones" theme: name: material features: @@ -55,7 +53,6 @@ theme: toggle: icon: material/brightness-4 name: Switch to light mode - markdown_extensions: - pymdownx.highlight: anchor_linenums: true @@ -63,7 +60,8 @@ markdown_extensions: pygments_lang_class: true - pymdownx.inlinehilite - pymdownx.snippets: - base_path: ["."] + base_path: + - "." - pymdownx.superfences: custom_fences: - name: mermaid @@ -78,36 +76,37 @@ markdown_extensions: - tables - toc: permalink: true - plugins: - search - macros - + - mkdocstrings: + handlers: + python: + paths: + - src nav: - Home: index.md - Getting Started: - - getting-started/index.md - - Installation: getting-started/installation.md - - Quick Start: getting-started/quickstart.md - - Workflows: getting-started/workflows.md + - getting-started/index.md + - Installation: getting-started/installation.md + - Quick Start: getting-started/quickstart.md + - Workflows: getting-started/workflows.md - Guides: guides/index.md - Examples: examples/index.md - - Reference: reference/index.md + - Reference: + - reference/index.md - Community: - - community/index.md - - Contributing: community/contributing.md - - Developer Setup: community/developing.md - - AI Agent Guide: community/agents.md - - Code of Conduct: community/code-of-conduct.md - - Security Policy: community/security.md - - Support: community/support.md - + - community/index.md + - Contributing: community/contributing.md + - Developer Setup: community/developing.md + - AI Agent Guide: community/agents.md + - Code of Conduct: community/code-of-conduct.md + - Security Policy: community/security.md + - Support: community/support.md extra_css: - stylesheets/extra.css - extra_javascript: - scripts/extra.js - # --------------------------------------------------------------------------- # LLM & AI Tooling # --------------------------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0ecfcae --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,291 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "project_name" +dynamic = ["version"] +description = "{{project_description}}" +readme = "README.md" +requires-python = ">=3.10" +license = { text = "Apache-2.0" } +authors = [{ name = "{{organization}}" }] +dependencies = [] + +[project.optional-dependencies] +dev = [ + # testing + "pytest>=8.0.0", + "pytest-asyncio", + "pytest-cov", + "pytest-mock", + "respx", + + # code quality + "mypy", + "ruff", + + # docs quality + "mdformat", + "mdformat-frontmatter", + "mdformat-gfm", + + # general and configurations + "yamlfix", +] +docs = [ + # documentation + "mike", + "mkdocs>=1.6.0", + "mkdocs-macros-plugin", + "mkdocs-material>=9.5.0", + "pymdown-extensions", +] + +[project.scripts] +project_name = "project_name.__main__:main" + +[project.urls] +Homepage = "https://github.com/{{org_name}}/{{project_name}}" +Repository = "https://github.com/{{org_name}}/{{project_name}}.git" +Issues = "https://github.com/{{org_name}}/{{project_name}}/issues" + +[tool.hatch.version] +path = "src/project_name/__init__.py" + +# ============================================================================== +# Hatch Environment Configurations +# ============================================================================== + +[tool.hatch.envs.default] +installer = "uv" +dependencies = [ + "pytest", + "pytest-cov", + "pytest-mock", + "pytest-asyncio", + "respx", +] + +# ------------------------------------------------------------------------------ +# Quality & Style: Ruff, mdformat, yamlfix +# ------------------------------------------------------------------------------ +[tool.hatch.envs.lint] +detached = true +installer = "uv" +dependencies = [ + "pre-commit", + "ruff", + "mdformat", + "mdformat-gfm", + "mdformat-frontmatter", + "yamlfix>=1.16.0", +] + +[tool.hatch.envs.lint.scripts] +# Quality checks (Read-only) +check = [ + "ruff check {args:.}", + "ruff format --check {args:.}", + "mdformat --check {args:.}", + "yamlfix --check {args:.}", +] +pre-commit = "SKIP=type-check pre-commit run --all-files --show-diff-on-failure" +# Style runs (Applies fixes) +format = [ + "ruff check --fix {args:.}", + "ruff format {args:.}", + "mdformat {args:.}", + "yamlfix {args:.}", +] + +# ------------------------------------------------------------------------------ +# Type Checking: Mypy +# ------------------------------------------------------------------------------ +[tool.hatch.envs.types] +# Needs project dependencies to resolve imports +template = "default" +dependencies = [ + "mypy>=1.0.0", +] + +[tool.hatch.envs.types.scripts] +check = "mypy --install-types --non-interactive {args:src tests}" + +# ------------------------------------------------------------------------------ +# Testing: Pytest with segmented coverage +# ------------------------------------------------------------------------------ +[tool.hatch.envs.test] +# Use the default env which contains pytest and pytest-cov +template = "default" + +[tool.hatch.envs.test.scripts] +# Standard runs (no coverage) +all = "pytest tests {args}" +unit = "pytest tests/unit {args}" +integration = "pytest tests/integration {args}" +e2e = "pytest tests/e2e {args}" + +# Coverage specific runs +# These use --cov=src to ensure only your source code is measured +cov-unit = "pytest --cov=src --cov-report=term-missing --cov-report=html:docs/coverage/unit/htmlcov tests/unit {args}" +cov-integration = "pytest --cov=src --cov-report=term-missing --cov-report=html:docs/coverage/integration/htmlcov tests/integration {args}" +cov-e2e = "pytest --cov=src --cov-report=term-missing --cov-report=html:docs/coverage/e2e/htmlcov tests/e2e {args}" +# Full suite coverage +cov-all = "pytest --cov=src --cov-report=term-missing --cov-report=html:docs/coverage/all/htmlcov tests {args}" + +# ------------------------------------------------------------------------------ +# Documentation: MkDocs +# ------------------------------------------------------------------------------ +[tool.hatch.envs.docs] +detached = true +installer = "uv" +dependencies = [ + "mkdocs>=1.6.0", + "mkdocs-material>=9.5.0", + "mkdocstrings[python]", + "mike", + "pymdown-extensions", + "mkdocs-macros-plugin", +] + +[tool.hatch.envs.docs.scripts] +build = "mkdocs build --clean --strict" +serve = "mkdocs serve --dev-addr 0.0.0.0:8000" + +# ------------------------------------------------------------------------------ +# Build Configuration (hatch build) +# ------------------------------------------------------------------------------ +[tool.hatch.build.targets.sdist] +exclude = [ + "/.github", + "/docs", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/project_name"] + + +# --- Tool Configurations --- +[tool.mypy] +files = ["src/project_name", "tests"] +python_version = "3.10" +warn_redundant_casts = true +warn_unused_ignores = false +show_error_codes = true +namespace_packages = true +exclude = ["venv", "build", "dist", ".venv"] +follow_imports = "silent" +ignore_missing_imports = true + +[tool.ruff] +line-length = 88 +indent-width = 4 +exclude = ["build", "dist", "env", ".venv"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + +[tool.ruff.lint] +ignore = [ + "COM812", # ignore trailing comma errors due to older Python versions + "ISC001", # implicit string concatenation (often disabled when using ruff format) + "PD011", # ignore .values usage since ruff assumes it's a Pandas DataFrame + "PLR0913", # ignore too many arguments in function definitions + "PLW1514", # allow Path.open without encoding + "RET505", # allow `else` blocks + "RET506", # allow `else` blocks + "S311", # allow standard pseudo-random generators + "TC001", # ignore imports used only for type checking + "TC002", # ignore imports used only for type checking + "TC003", # ignore imports used only for type checking +] +select = [ + # Rules reference: https://docs.astral.sh/ruff/rules/ + + # Code Style / Formatting + "E", # pycodestyle: checks adherence to PEP 8 conventions including spacing, indentation, and line length + "W", # pycodestyle: checks adherence to PEP 8 conventions including spacing, indentation, and line length + "A", # flake8-builtins: prevents shadowing of Python built-in names + "C", # Convention: ensures code adheres to specific style and formatting conventions + "COM", # flake8-commas: enforces the correct use of trailing commas + "ERA", # eradicate: detects commented-out code that should be removed + "I", # isort: ensures imports are sorted in a consistent manner + "ICN", # flake8-import-conventions: enforces import conventions for better readability + "N", # pep8-naming: enforces PEP 8 naming conventions for classes, functions, and variables + "NPY", # NumPy: enforces best practices for using the NumPy library + "PD", # pandas-vet: enforces best practices for using the pandas library + "PT", # flake8-pytest-style: enforces best practices and style conventions for pytest tests + "PTH", # flake8-use-pathlib: encourages the use of pathlib over os.path for file system operations + "Q", # flake8-quotes: enforces consistent use of single or double quotes + "TCH", # flake8-type-checking: enforces type checking practices and standards + "TID", # flake8-tidy-imports: enforces tidy and well-organized imports + "RUF022", # flake8-ruff: enforce sorting of __all__ in modules + + # Code Structure / Complexity + "C4", # flake8-comprehensions: improves readability and performance of list, set, and dict comprehensions + "C90", # mccabe: checks for overly complex code using cyclomatic complexity + "ISC", # flake8-implicit-str-concat: prevents implicit string concatenation + "PIE", # flake8-pie: identifies and corrects common code inefficiencies and mistakes + "R", # Refactor: suggests improvements to code structure and readability + "SIM", # flake8-simplify: simplifies complex expressions and improves code readability + + # Code Security / Bug Prevention + "ARG", # flake8-unused-arguments: detects unused function and method arguments + "ASYNC", # flake8-async: identifies incorrect or inefficient usage patterns in asynchronous code + "B", # flake8-bugbear: detects common programming mistakes and potential bugs + "BLE", # flake8-blind-except: prevents blind exceptions that catch all exceptions without handling + "E", # Error: detects and reports errors in the code + "F", # Pyflakes: detects unused imports, shadowed imports, undefined variables, and various formatting errors in string operations + "INP", # flake8-no-pep420: prevents implicit namespace packages by requiring __init__.py + "PGH", # pygrep-hooks: detects deprecated and dangerous code patterns + "PL", # Pylint: comprehensive source code analyzer for enforcing coding standards and detecting errors + "RSE", # flake8-raise: ensures exceptions are raised correctly + "S", # flake8-bandit: detects security issues and vulnerabilities in the code + "SLF", # flake8-self: prevents incorrect usage of the self argument in class methods + "T10", # flake8-debugger: detects the presence of debugging tools such as pdb + "T20", # flake8-print: detects print statements left in the code + "UP", # pyupgrade: automatically upgrades syntax for newer versions of Python + "W", # Warning: provides warnings about potential issues in the code + "YTT", # flake8-2020: identifies code that will break with future Python releases + + # Code Documentation + "FIX", # flake8-fixme: detects FIXMEs and other temporary comments that should be resolved +] + +[tool.ruff.lint.extend-per-file-ignores] +"tests/**/*.py" = [ + "S101", # asserts allowed in tests + "ARG", # Unused function args allowed in tests + "PLR2004", # Magic value used in comparison + "TCH002", # No import only type checking in tests + "SLF001", # enable private member access in tests + "S105", # allow hardcoded passwords in tests + "S106", # allow hardcoded passwords in tests + "S311", # allow standard pseudo-random generators in tests + "PT011", # allow generic exceptions in tests + "N806", # allow uppercase variable names in tests + "PGH003", # allow general ignores in tests + "PLR0915", # allow complex statements in tests +] + +[tool.ruff.lint.isort] +known-first-party = ["project_name", "tests"] + +[tool.pytest.ini_options] +addopts = "-s -vvv --cache-clear" +asyncio_mode = "auto" +markers = [ + "smoke: quick tests to check basic functionality", + "sanity: detailed tests to ensure major functions work correctly", + "regression: tests to ensure that new changes do not break existing functionality", + "e2e: end-to-end integration tests" +] +testpaths = ["tests"] + +[tool.yamlfix] +line_length = 88 +sequence_style = "block_style" +preserve_quotes = true diff --git a/scripts/README.md b/scripts/README.md index 2bed465..4e853c7 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,11 +1,10 @@ -# `{{project_name}}` - Utility Scripts +# `project_name` - Utility Scripts -This directory contains utility scripts designed to assist with local development, maintenance, and automation tasks for `{{project_name}}`. +This directory contains utility scripts designed to assist with local development, maintenance, and automation tasks for `project_name`. > [!NOTE] > These scripts are intended for developer and CI/CD use only and are **not** distributed as part of the final application package. - ## Usage Guidelines To ensure a consistent development experience across the organization, please adhere to the following guidelines when running or adding scripts. @@ -35,14 +34,12 @@ If you are adding or modifying a script in this directory, please ensure it adhe - **Provide Help:** Scripts should ideally accept a `-h` or `--help` flag that outputs usage instructions. - **Log Clearly:** Prefix output with `[INFO]`, `[WARN]`, or `[ERROR]` to make CI/CD logs easier to read. - ## Available Scripts -| Script | Description | -| :--- | :--- | -| `setup_dev_env.sh` | *(Example)* Bootstraps the local development environment. | -| `release.sh` | *(Example)* Automates the version bumping and release tagging process. | - +| Script | Description | +| :----------------- | :--------------------------------------------------------------------- | +| `setup_dev_env.sh` | *(Example)* Bootstraps the local development environment. | +| `release.sh` | *(Example)* Automates the version bumping and release tagging process. | ## Contributing diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 77d2d98..ec732f7 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -2,7 +2,7 @@ # ============================================================================= # bootstrap.sh — Template Initialization # -# Automatically replaces all template placeholders (e.g., {{project_name}}) +# Automatically replaces all template placeholders (e.g., project_name) # with your actual project values. # # Usage: @@ -17,7 +17,7 @@ if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then echo "Bootstraps the repository by replacing template variables." echo "" echo "Options:" - echo " --project-name NAME Replacement for {{project_name}}" + echo " --project-name NAME Replacement for project_name" echo " --project-desc DESC Replacement for {{project_description}}" echo " --organization ORG Replacement for {{organization}}" echo " --org-name ORG Replacement for {{org_name}}" @@ -76,6 +76,18 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$PROJECT_NAME" ]] || [[ -z "$PROJECT_DESC" ]] || [[ -z "$ORGANIZATION" ]] || [[ -z "$ORG_NAME" ]]; then + echo "[ERROR] Missing required arguments." + echo "All of the following options must be provided:" + echo " --project-name" + echo " --project-desc" + echo " --organization" + echo " --org-name" + echo "" + echo "Use $0 --help for usage guidance." + exit 1 +fi + echo "[INFO] Starting repository bootstrap..." export PROJECT_NAME @@ -84,21 +96,23 @@ export ORGANIZATION export ORG_NAME python3 -c " -import os, sys +import os, sys, shutil + +project_name = os.environ.get('PROJECT_NAME', '') +python_pkg = project_name.replace('-', '_') replacements = { - '{{project_name}}': os.environ.get('PROJECT_NAME', ''), + '{{project_name}}': project_name, + '%7B%7Bproject_name%7D%7D': project_name, + 'project_name': python_pkg, '{{project_description}}': os.environ.get('PROJECT_DESC', ''), + '%7B%7Bproject_description%7D%7D': os.environ.get('PROJECT_DESC', ''), '{{organization}}': os.environ.get('ORGANIZATION', ''), - '{{org_name}}': os.environ.get('ORG_NAME', '') + '%7B%7Borganization%7D%7D': os.environ.get('ORGANIZATION', ''), + '{{org_name}}': os.environ.get('ORG_NAME', ''), + '%7B%7Borg_name%7D%7D': os.environ.get('ORG_NAME', '') } -# Filter out empty arguments -replacements = {k: v for k, v in replacements.items() if v} - -if not replacements: - print('[INFO] No replacements provided. Use -h for options.') - sys.exit(0) ignore_dirs = {'.git', '.venv', 'node_modules', 'site', '__pycache__', 'assets'} ignore_exts = ('.pyc', '.png', '.svg', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot') @@ -108,23 +122,30 @@ for root, dirs, files in os.walk('.'): for file in files: if file.endswith(ignore_exts) or file == 'bootstrap.sh': continue - + filepath = os.path.join(root, file) - + try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() except UnicodeDecodeError: continue - + new_content = content for placeholder, replacement in replacements.items(): new_content = new_content.replace(placeholder, replacement) - + if content != new_content: with open(filepath, 'w', encoding='utf-8') as f: f.write(new_content) print(f'[INFO] Updated: {filepath}') + +src_dir = os.path.join('.', 'src', 'project_name') +dst_dir = os.path.join('.', 'src', python_pkg) +if os.path.exists(src_dir) and src_dir != dst_dir: + os.rename(src_dir, dst_dir) + print(f'[INFO] Renamed directory: {src_dir} -> {dst_dir}') + " echo "[INFO] Bootstrap complete! You may now delete this script if desired." diff --git a/src/{{project_name}}/.gitkeep b/src/project_name/.gitkeep similarity index 100% rename from src/{{project_name}}/.gitkeep rename to src/project_name/.gitkeep diff --git a/src/project_name/__init__.py b/src/project_name/__init__.py new file mode 100644 index 0000000..3dd0b09 --- /dev/null +++ b/src/project_name/__init__.py @@ -0,0 +1,5 @@ +from __future__ import annotations + +__all__ = ["__version__"] + +__version__ = "0.1.0" diff --git a/src/project_name/__main__.py b/src/project_name/__main__.py new file mode 100644 index 0000000..2bdfc20 --- /dev/null +++ b/src/project_name/__main__.py @@ -0,0 +1,23 @@ +# --------------------------------------------------------- +# {{project_name}} # noqa: ERA001 +# Licensed under the Apache License, Version 2.0 +# --------------------------------------------------------- +"""Main entrypoint for the {{project_name}} package.""" + +from __future__ import annotations + +import logging +import sys + +logger = logging.getLogger(__name__) + + +def main() -> int: + """Execute the main routine.""" + logging.basicConfig(level=logging.INFO) + logger.info("Hello from {{project_name}}!") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/project_name/py.typed b/src/project_name/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/test.md b/test.md new file mode 100644 index 0000000..1e3c2c5 --- /dev/null +++ b/test.md @@ -0,0 +1 @@ +[View on GitHub](https://github.com/%7B%7Borg_name%7D%7D/%7B%7Bproject_name%7D%7D){ .md-button } diff --git a/test2.md b/test2.md new file mode 100644 index 0000000..dfa753e --- /dev/null +++ b/test2.md @@ -0,0 +1 @@ +[link](http://a.com/%7B%7Btest%7D%7D) diff --git a/test_link.md b/test_link.md new file mode 100644 index 0000000..2c96ea1 --- /dev/null +++ b/test_link.md @@ -0,0 +1 @@ +[View on GitHub](https://github.com/%7B%7B%20org_name%20%7D%7D/%7B%7B%20project_name%20%7D%7D) diff --git a/test_snippet.md b/test_snippet.md new file mode 100644 index 0000000..6cb61e8 --- /dev/null +++ b/test_snippet.md @@ -0,0 +1,5 @@ + + +--8\<-- "DEVELOPING.md" + + diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py new file mode 100644 index 0000000..626cf5a --- /dev/null +++ b/tests/e2e/__init__.py @@ -0,0 +1 @@ +# E2E tests package. diff --git a/tests/e2e/test_e2e.py b/tests/e2e/test_e2e.py new file mode 100644 index 0000000..87b9591 --- /dev/null +++ b/tests/e2e/test_e2e.py @@ -0,0 +1,24 @@ +"""Example end-to-end tests for the project.""" + +import pytest + + +@pytest.mark.smoke +@pytest.mark.e2e +def test_smoke_e2e_example() -> None: + """A basic smoke test for end-to-end functionality.""" + assert True + + +@pytest.mark.sanity +@pytest.mark.e2e +def test_sanity_e2e_example() -> None: + """A sanity test for end-to-end functionality.""" + assert True + + +@pytest.mark.regression +@pytest.mark.e2e +def test_regression_e2e_example() -> None: + """A regression test for end-to-end functionality.""" + assert True diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..a78ea06 --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1 @@ +# Integration tests package. diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py new file mode 100644 index 0000000..09eea9b --- /dev/null +++ b/tests/integration/test_integration.py @@ -0,0 +1,21 @@ +"""Example integration tests for the project.""" + +import pytest + + +@pytest.mark.smoke +def test_smoke_integration_example() -> None: + """A basic smoke test for integration functionality.""" + assert True + + +@pytest.mark.sanity +def test_sanity_integration_example() -> None: + """A sanity test for integration functionality.""" + assert True + + +@pytest.mark.regression +def test_regression_integration_example() -> None: + """A regression test for integration functionality.""" + assert True diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..1a351fa --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1 @@ +# Unit tests package. diff --git a/tests/unit/test_unit.py b/tests/unit/test_unit.py new file mode 100644 index 0000000..c2716bc --- /dev/null +++ b/tests/unit/test_unit.py @@ -0,0 +1,21 @@ +"""Example unit tests for the project.""" + +import pytest + + +@pytest.mark.smoke +def test_smoke_example() -> None: + """A basic smoke test to ensure the unit test suite runs.""" + assert True + + +@pytest.mark.sanity +def test_sanity_example() -> None: + """A sanity test for detailed unit testing.""" + assert True + + +@pytest.mark.regression +def test_regression_example() -> None: + """A regression test for unit testing.""" + assert True