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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Git
.git
.gitignore
.gitattributes

# CI/CD
.github

# Documentation
*.md
docs/

# Python
__pycache__
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
dist/
build/
*.egg

# Virtual Environments
venv/
env/
ENV/
.venv/
.virtualenv/

# IDE
.idea/
.vscode/
*.swp
*.swo
*~
.spyproject
.spyderproject

# Testing
.pytest_cache/
.coverage
coverage.xml
*.cover
htmlcov/
.tox/
.nox/

# Database (will be created in container or use external)
*.db
*.sqlite3
instance/

# Logs (will be created in container)
logs/
*.log

# Environment files (use Docker secrets/env vars instead)
.env
.env.*
*.env

# OS
.DS_Store
Thumbs.db

# Uploads (use volumes or external storage)
uploads/
media/

# Temporary files
*.tmp
*.temp
tmp/
temp/

# Security
*.pem
*.key
*.crt

# Docker
Dockerfile
docker-compose.yml
.dockerignore

# Backup files
*.backup
*.bak
*.old
95 changes: 95 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Bug Report
description: File a bug report to help us improve
title: "[Bug]: "
labels: ["bug", "triage"]
assignees: []

body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!

- type: textarea
id: what-happened
attributes:
label: What happened?
description: A clear and concise description of what the bug is
placeholder: Tell us what you see!
validations:
required: true

- type: textarea
id: reproduce
attributes:
label: Steps to Reproduce
description: Steps to reproduce the behavior
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen
validations:
required: true

- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem

- type: dropdown
id: deployment
attributes:
label: Deployment Method
description: How are you running the application?
options:
- Docker
- Docker Compose
- Heroku
- Render
- Railway
- Local Development
- VPS/Manual
- Other
validations:
required: true

- type: input
id: python-version
attributes:
label: Python Version
description: What version of Python are you using?
placeholder: "e.g., 3.11"
validations:
required: true

- type: input
id: os
attributes:
label: Operating System
description: What OS are you using?
placeholder: "e.g., Ubuntu 22.04, macOS 13, Windows 11"
validations:
required: true

- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output
render: shell

- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context about the problem here
62 changes: 62 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Feature Request
description: Suggest an idea for this project
title: "[Feature]: "
labels: ["enhancement"]
assignees: []

body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest a new feature!

- type: textarea
id: problem
attributes:
label: Is your feature request related to a problem?
description: A clear and concise description of what the problem is
placeholder: I'm always frustrated when...
validations:
required: true

- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered

- type: dropdown
id: priority
attributes:
label: Priority
description: How important is this feature to you?
options:
- Low - Nice to have
- Medium - Would be helpful
- High - Critical for my use case
validations:
required: true

- type: checkboxes
id: contribution
attributes:
label: Contribution
description: Are you willing to contribute to this feature?
options:
- label: I'm willing to submit a PR for this feature
- label: I can help test this feature
- label: I can help with documentation

- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context, mockups, or screenshots about the feature request here
142 changes: 142 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: CI/CD Pipeline

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
# Job 1: Lint and Test
test:
name: Lint and Test
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ['3.9', '3.10', '3.11']

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov flake8

- name: Lint with flake8
run: |
# Stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=venv,env,.venv,.git,__pycache__
# Exit-zero treats all errors as warnings
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=venv,env,.venv,.git,__pycache__

- name: Run tests
run: |
pytest tests/ -v --cov=app --cov-report=xml --cov-report=term
env:
FLASK_ENV: testing
SECRET_KEY: test-secret-key

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
fail_ci_if_error: false

# Job 2: Security Scan
security:
name: Security Scan
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install safety
run: pip install safety

- name: Run safety check
run: safety check --json || true
Comment on lines +69 to +73

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Safety step installs only safety itself and then runs safety check, so it will primarily scan the Safety package’s environment rather than your application dependencies. To get meaningful results, install the project requirements in this job (or run safety check -r requirements.txt / requirements-prod.txt).

Suggested change
- name: Install safety
run: pip install safety
- name: Run safety check
run: safety check --json || true
- name: Install dependencies for safety scan
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install safety
- name: Run safety check
run: safety check --json -r requirements.txt || true

Copilot uses AI. Check for mistakes.

- name: Run Bandit security scan
run: |
pip install bandit
bandit -r . -f json -o bandit-report.json || true

- name: Upload security reports
uses: actions/upload-artifact@v3
if: always()
with:
name: security-reports
path: |
bandit-report.json

# Job 3: Build Docker Image
build:
name: Build Docker Image
runs-on: ubuntu-latest
needs: [test, security]
if: github.event_name == 'push'

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.ref == 'refs/heads/main' }}
tags: |
${{ secrets.DOCKER_USERNAME }}/project-management:latest
${{ secrets.DOCKER_USERNAME }}/project-management:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Test Docker image
run: |
docker build -t project-management:test .
docker run -d -p 8000:8000 --name test-container project-management:test

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker image is run in production mode and the app requires SECRET_KEY and DATABASE_URL in production, but this workflow starts the container without either. This will likely cause the container to exit immediately and make the health curl fail. Pass required env vars (or override FLASK_ENV=testing and set a SQLite DATABASE_URL) when running the container in CI.

Suggested change
docker run -d -p 8000:8000 --name test-container project-management:test
docker run -d -p 8000:8000 \
-e FLASK_ENV=testing \
-e SECRET_KEY=ci-test-secret \
-e DATABASE_URL=sqlite:///test.db \
--name test-container project-management:test

Copilot uses AI. Check for mistakes.
sleep 10
curl http://localhost:8000/health || exit 1
docker stop test-container

# Job 4: Deploy to Render (optional)
deploy-render:
name: Deploy to Render
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'

steps:
- name: Trigger Render Deployment
if: secrets.RENDER_DEPLOY_HOOK_URL != ''
run: |
curl -X POST "${{ secrets.RENDER_DEPLOY_HOOK_URL }}"

- name: Deployment notification
run: echo "Deployment triggered to Render"
Loading