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:
18
.codecov.yml
Normal file
18
.codecov.yml
Normal 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
27
.dockerignore
Normal 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
70
.github/workflows/ci.yml
vendored
Normal 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
96
.github/workflows/propagate-changes.yml
vendored
Normal 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
28
.pre-commit-config.yaml
Normal 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
38
Dockerfile
Normal 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
21
LICENSE
Normal 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
36
README.md
Normal 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
1238
create_issues.sh
Executable file
File diff suppressed because it is too large
Load Diff
21
requirements.dev.txt
Normal file
21
requirements.dev.txt
Normal 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
15
requirements.txt
Normal 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
|
||||
Reference in New Issue
Block a user