feat: Initial project setup with CI/CD, Docker, and issue creation script

- Added Codecov configuration to enforce 75% coverage.
- Created .dockerignore to exclude unnecessary files from Docker context.
- Implemented GitHub Actions CI workflow for linting, testing, and coverage reporting.
- Added a workflow to propagate changes between main and development branches.
- Configured pre-commit hooks for code quality checks.
- Developed a multi-stage Dockerfile for a Python web backend.
- Added MIT License to the project.
- Created README.md with project overview and setup instructions.
- Implemented a script to create GitHub issues from project planning.
- Defined development and runtime requirements in requirements.txt and requirements.dev.txt.
This commit is contained in:
Wikid82
2025-11-17 15:52:40 -05:00
parent 5b946ac880
commit 4f3b7d8f99
11 changed files with 1608 additions and 0 deletions

18
.codecov.yml Normal file
View File

@@ -0,0 +1,18 @@
# Codecov configuration - require 75% overall coverage by default
# Adjust target as needed
coverage:
status:
project:
default:
target: 75%
threshold: 0%
# Fail CI if Codecov upload/report indicates a problem
require_ci_to_pass: yes
# Exclude folders from Codecov (adjust as needed)
ignore:
- tests/*
- docs/*
- .github/*

27
.dockerignore Normal file
View File

@@ -0,0 +1,27 @@
.git
.gitignore
node_modules
venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
build/
dist/
*.egg-info
.DS_Store
.idea/
.vscode/
.env
.env.*
coverage/
.coverage
.pytest_cache/
*.log
*.sqlite3
# Docker
docker-compose.override.yml
**/Dockerfile.*

70
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
name: CI - Lint, Test & Coverage
on:
push:
branches: [ main, development, 'feature/**' ]
pull_request:
branches: [ main, development ]
jobs:
lint:
name: Lint (ruff & flake8)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dev dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.dev.txt
- name: Run ruff
run: |
ruff check .
- name: Run flake8
run: |
flake8 . || true
test-and-coverage:
name: Tests & Coverage
runs-on: ubuntu-latest
needs: [lint]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt || true
pip install -r requirements.dev.txt
- name: Run tests with coverage
run: |
# run pytest under coverage and fail if tests fail
coverage run -m pytest -q
coverage report -m --fail-under=75
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Optional: set CODECOV_TOKEN in repo secrets if needed for private repos

96
.github/workflows/propagate-changes.yml vendored Normal file
View File

@@ -0,0 +1,96 @@
name: Propagate Changes Between Branches
on:
push:
branches:
- main
- development
permissions:
contents: write
pull-requests: write
jobs:
propagate:
name: Create PR to synchronize branches
runs-on: ubuntu-latest
if: "\n github.actor != 'github-actions[bot]' && \
github.event.pusher != null\n "
steps:
- name: Set up Node (for github-script)
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Determine source and target branches
id: branches
run: |
echo "source=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_OUTPUT
if [ "${GITHUB_REF#refs/heads/}" = "main" ]; then
echo "target=development" >> $GITHUB_OUTPUT
else
echo "target=main" >> $GITHUB_OUTPUT
fi
- name: Create or update Pull Request
uses: actions/github-script@v7
with:
script: |
const source = process.env.SOURCE_BRANCH || process.env.GITHUB_REF.replace('refs/heads/','');
const target = process.env.TARGET_BRANCH || (source === 'main' ? 'development' : 'main');
const src = source;
const base = target;
// Do not create PR if source and base are same
if (src === base) {
core.info(`Source and base are the same (${src}); skipping.`);
return;
}
// Check for existing open PRs from src->base
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.repo.owner}:${src}`,
base: base,
});
if (pulls.length > 0) {
core.info(`Found existing PR(s) from ${src} to ${base}. Skipping creation.`);
return;
}
// Compare commits: only create PR if source is ahead of base
const compare = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: base,
head: src,
});
if (compare.data && compare.data.status === 'identical') {
core.info(`${src} and ${base} are identical. No PR needed.`);
return;
}
// Create PR
const title = `Propagate changes from ${src} into ${base}`;
const body = `Automated PR to propagate commits from ${src} into ${base}.\n\nTriggered by push by @${context.actor}.`;
const pr = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
head: src,
base,
body,
});
core.info(`Created PR #${pr.data.number}: ${pr.data.html_url}`);
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SOURCE_BRANCH: ${{ steps.branches.outputs.source }}
TARGET_BRANCH: ${{ steps.branches.outputs.target }}

28
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,28 @@
repos:
- repo: https://github.com/psf/black
rev: 24.3.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.15.0
hooks:
- id: ruff
args: ["--fix"]
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.12.0
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.6
hooks:
- id: mypy
additional_dependencies: []

38
Dockerfile Normal file
View File

@@ -0,0 +1,38 @@
# Generic multi-stage Dockerfile for a Python web backend (FastAPI example).
# Adapt this to your chosen stack (Go, Node, etc.) as needed.
# ---- Builder ----
FROM python:3.12-slim AS builder
WORKDIR /app
# Install build dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential gcc libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Copy only dependency files first to leverage cache
COPY requirements.txt requirements.dev.txt ./
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
# Copy source
COPY . .
# ---- Final image ----
FROM python:3.12-slim
WORKDIR /app
# Copy installed packages from builder
COPY --from=builder /usr/local/lib/python3.12 /usr/local/lib/python3.12
COPY --from=builder /usr/local/bin /usr/local/bin
# Copy application code
COPY --from=builder /app /app
ENV PYTHONUNBUFFERED=1
# Expose default port (change if needed)
EXPOSE 8000
# Default command - update to your actual app entrypoint
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Wikid82
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

36
README.md Normal file
View File

@@ -0,0 +1,36 @@
# CaddyProxyManager+
CaddyProxyManager+ is a modern web UI and management layer that brings Nginx Proxy Manager-style simplicity to Caddy, with extra security add-ons (CrowdSec, WAF, SSO, etc.).
This repository is the project scaffold and planning workspace.
Quick links
- Project board: https://github.com/users/Wikid82/projects/7
- Issues: https://github.com/Wikid82/CaddyProxyManagerPlus/issues
Getting started
1. Pick a stack (Go / Python / Node). This scaffold uses Python examples; adapt as needed.
2. Install development dependencies:
```bash
python -m pip install --upgrade pip
pip install -r requirements.dev.txt
```
3. Install pre-commit hooks:
```bash
pip install pre-commit
pre-commit install
pre-commit run --all-files
```
Development notes
- Branching model: `development` is the main working branch; create `feature/**` branches from `development`.
- CI enforces lint and coverage (75% fail-under) in `.github/workflows/ci.yml`.
Contributing
- See `CONTRIBUTING.md` (coming soon) for contribution guidelines.
License
- This project is released under the MIT License - see `LICENSE`.

1238
create_issues.sh Executable file

File diff suppressed because it is too large Load Diff

21
requirements.dev.txt Normal file
View File

@@ -0,0 +1,21 @@
# Development requirements
# Testing, linters, formatting, and security checks
# pytest-xdist is not used - tests run serially to reproduce a user's experience more accurately.
pytest>=7.4
pytest-cov>=4.1
black>=24.3
ruff>=0.15
isort>=5.12
mypy>=1.6
pre-commit>=3.4
bandit>=1.8
tox>=4.11
pytest-timeout==2.4.0
# Add more dev tools as required
# Coverage tooling and additional linters
coverage>=7.2
flake8>=6.1

15
requirements.txt Normal file
View File

@@ -0,0 +1,15 @@
# Base runtime requirements - adapt to your stack.
# Example for a Python FastAPI backend. Remove or replace if using Go/Node/etc.
fastapi>=0.100.0
uvicorn[standard]>=0.22.0
pydantic>=2.0
sqlalchemy>=2.0
alembic>=1.11
python-dotenv>=1.0
passlib[bcrypt]>=1.7
httpx>=0.24
requests>=2.31
python-multipart>=0.0.6
# Add additional runtime libs below