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
9 changes: 9 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[flake8]
exclude = .git,__pycache__,build,dist,.venv,venv
max-line-length = 88
max-complexity = 10
# These rules conflict with black
ignore = E203,W503
per-file-ignores =
# imported but unused in __init__ files
__init__.py: F401
84 changes: 84 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CI

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

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4

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

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.8.3
virtualenvs-create: true
virtualenvs-in-project: true

- name: Cache Poetry dependencies
uses: actions/cache@v4
with:
path: .venv
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
run: poetry install

- name: Lint with flake8
run: |
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.venv,.git,__pycache__,build,dist
poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics --exclude=.venv,.git,__pycache__,build,dist

- name: Format check with black
run: poetry run black --check --exclude=\.venv --extend-exclude=main.py .

- name: Import sorting check with isort
run: poetry run isort --check --skip .venv --skip main.py .

- name: Test with pytest
run: |
if [ -d "src" ]; then
poetry run pytest --cov=src
else
echo "No src directory yet, skipping tests"
exit 0
fi

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false

release:
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
concurrency: release
permissions:
id-token: write
contents: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Python Semantic Release
uses: python-semantic-release/python-semantic-release@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
13 changes: 8 additions & 5 deletions .github/workflows/docker-build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,26 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

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

- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ghcr.io/offendingcommit/bingo:latest
tags: |
ghcr.io/offendingcommit/bingo:latest
ghcr.io/offendingcommit/bingo:${{ github.sha }}
${{ github.event_name == 'release' && format('ghcr.io/offendingcommit/bingo:{0}', github.ref_name) || '' }}
build-args: BUILD_ENVIRONMENT=production
4 changes: 2 additions & 2 deletions .github/workflows/helm-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v1
Expand All @@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Helm
uses: azure/setup-helm@v1
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ venv.bak/
*.log
logs/
.cache/
.coverage
.coverage.*
htmlcov/

# OS files
.DS_Store
Expand Down
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- Initial project structure
- Bingo board generation functionality
- Interactive UI with NiceGUI
- Board synchronization between views
- Testing framework with pytest
- Modular architecture with separate components
- Semantic versioning with python-semantic-release
- CI pipeline with GitHub Actions
- Developer setup script

## [0.1.0] - 2025-03-02

### Added
- Initial release
- Basic bingo board functionality
- Home and stream views
- Dynamic board generation
- Win pattern detection
164 changes: 164 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# BINGO Project Guide

## Build Commands
```bash
# Quick setup for development
./setup.sh

# Install dependencies
poetry install

# Run application (old monolithic structure)
poetry run python main.py

# Run application (new modular structure)
poetry run python app.py

# Run tests
poetry run pytest

# Run tests with coverage
poetry run pytest --cov=src --cov-report=html

# Lint code
poetry run flake8
poetry run black --check .
poetry run isort --check .

# Format code
poetry run black .
poetry run isort .

# Build Docker container
docker build -t bingo .

# Run Docker container
docker run -p 8080:8080 bingo

# Helm deployment
cd helm && ./package.sh && helm install bingo ./bingo

# Using Makefile
make install # Install dependencies
make run # Run application
make test # Run tests
make lint # Run linters
make format # Format code
make build # Build package
```

## Code Style Guidelines
- **Imports**: Standard library first, third-party second, local modules last
- **Formatting**: Use f-strings for string formatting
- **Constants**: Defined at top of file in UPPER_CASE
- **Naming**: snake_case for functions/variables, UPPER_CASE for constants
- **Error Handling**: Use try/except blocks with proper logging
- **UI Elements**: Define class constants for styling
- **Logging**: Use Python's logging module with descriptive messages
- **Comments**: Use docstrings for functions and descriptive comments
- **Line Length**: Max 88 characters (Black's default)
- **Code Formatting**: Use Black for code formatting and isort for import sorting

## Project Structure
- `app.py`: Main entry point for modular application
- `src/`: Source code directory
- `config/`: Configuration and constants
- `core/`: Core game logic
- `ui/`: User interface components
- `utils/`: Utility functions
- `phrases.txt`: Contains customizable bingo phrases
- `static/`: Static assets for fonts and styles
- `tests/`: Unit and integration tests
- `helm/`: Kubernetes deployment configuration
- `.github/workflows/`: CI pipeline configuration
- `CHANGELOG.md`: Release history tracking

## Git Workflow

### Branch Naming
- Use feature branches for each change: `feature/description-of-change`
- Use bugfix branches for bug fixes: `fix/description-of-bug`
- Use chore branches for maintenance: `chore/description-of-task`

### Commit Guidelines
Follow conventional changelog format:

```
<type>(<scope>): <subject>

<body>

<footer>
```

1. **Types**:
- `feat`: A new feature
- `fix`: A bug fix
- `docs`: Documentation only changes
- `style`: Changes that do not affect meaning (white-space, formatting)
- `refactor`: Code change that neither fixes a bug nor adds a feature
- `perf`: Change that improves performance
- `test`: Adding missing tests or correcting existing tests
- `chore`: Changes to the build process or auxiliary tools

2. **Scope** (optional): The module/component affected, e.g., `core`, `ui`, `board`

3. **Subject**: Short description in imperative, present tense (not past tense)
- Good: "add feature X" (not "added feature X")
- Use lowercase
- No period at the end

4. **Body** (optional): Detailed explanation of changes
- Use present tense
- Include motivation and context
- Explain "what" and "why" (not "how")

5. **Footer** (optional): Reference issues, PRs, breaking changes

### Example Commits:
```
feat(board): add color theme selector

Add ability for users to choose color themes for the bingo board

Resolves #123
```

```
fix(ui): resolve client disconnection issues

Handle race conditions during client disconnects to prevent
server exceptions and ensure smooth reconnection

Fixes #456
```

## Semantic Versioning

This project follows semantic versioning (SEMVER) principles:

- **MAJOR** version when making incompatible API changes (X.0.0)
- **MINOR** version when adding functionality in a backwards compatible manner (0.X.0)
- **PATCH** version when making backwards compatible bug fixes (0.0.X)

Version numbers are automatically updated by the CI/CD pipeline based on commit messages.
The project uses python-semantic-release to analyze commit messages and determine the appropriate
version bump according to the conventional commit format.

## CI/CD Pipeline

The project utilizes GitHub Actions for continuous integration and deployment:

1. **CI Job**:
- Runs on each push to main and pull request
- Installs dependencies
- Runs linters (flake8, black, isort)
- Runs all tests with pytest
- Uploads coverage reports

2. **Release Job**:
- Runs after successful CI job on the main branch
- Determines new version based on commit messages
- Updates CHANGELOG.md
- Creates Git tag for the release
- Publishes release on GitHub
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,17 @@ RUN --mount=type=cache,target=$POETRY_CACHE_DIR \
# Copy the rest of the project
COPY . /app

# Create a non-root user and switch to it
RUN adduser --disabled-password --gecos "" appuser && \
chown -R appuser:appuser /app
USER appuser

# Expose port 8080 (if required)
EXPOSE 8080

# Add healthcheck
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/ || exit 1

# Set the default command to run the application
CMD ["python", "main.py"]
Loading
Loading