Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0093fdf
[lichess] Start working on the Lichess integration
olivierphi Sep 5, 2024
e7de888
[chore] After the switch to uv, fix some minor issues and improve the…
olivierphi Sep 5, 2024
0a20492
[lichess] We can now log in and log out from Lichess in the UI
olivierphi Sep 5, 2024
cf01eca
[chore] Better cookies management, with a HttpCookieAttributes struct
olivierphi Sep 6, 2024
9e045c5
[lichess] Check the CSRF state, rather than ignoring that aspect of O…
olivierphi Sep 6, 2024
61e07d7
[chore] misc uv-related fixes & improvements
olivierphi Sep 6, 2024
3be18be
[lichess] switch to async Views
olivierphi Sep 6, 2024
24769a5
[lichess] WIP: stop using Berserk, add integration to more endpoints
olivierphi Sep 6, 2024
39df04b
[lichess] We can now display (but not interact with) a Lichess game!
olivierphi Sep 9, 2024
0cb76fe
[lichess] Add some very basic tests
olivierphi Sep 9, 2024
3b4673d
[lichess] We can now select one of our pieces, via HTMX
olivierphi Sep 9, 2024
71b89d5
[chore] Use Uvicorn's logger in our app when using the "development" …
olivierphi Sep 9, 2024
0546a79
[lichess] We can now move one our pieces, via HTMX
olivierphi Sep 10, 2024
271219b
[lichess] Make sure we cannot play opponent's pieces during their turn
olivierphi Sep 10, 2024
a5b33f0
[lichess] Flip the chess board the other way if we're playing Black
olivierphi Sep 10, 2024
272b936
[chess] Use more immutable data structures
olivierphi Sep 11, 2024
a0097a0
[uv] Don't use the "package" mode, since this is an app
olivierphi Sep 11, 2024
284fad1
[django] Time has come to use the DatabaseCache
olivierphi Sep 11, 2024
3fa7101
[chore] Update `uv`
olivierphi Sep 11, 2024
6500d28
[fonts] Use `django-google-fonts` to mirror Google fonts
olivierphi Sep 11, 2024
15764e6
[lichess] Fix bug in `create_teams_and_piece_role_by_square_for_start…
olivierphi Sep 11, 2024
ee6981f
[lichess] Add some perf monitoring in `rebuild_game_from_starting_pos…
olivierphi Sep 11, 2024
11c732e
[lichess] Minor bugfixes related to pieces selection
olivierphi Sep 11, 2024
06d8c2d
[lichess] Use "game stream" endpoint instead of the "game export" one
olivierphi Sep 12, 2024
d796324
[lichess] Add a "Lichess account" modal, improve the UI a bit here an…
olivierphi Sep 13, 2024
fb6c687
[lichess] Making the UI a bit less ugly, bit by bit
olivierphi Sep 13, 2024
891e3e9
[Docker] Hotfix for the Gunicorn/Uvicorn setup
olivierphi Sep 13, 2024
bf3f8ac
[fix] Misc fixes after a first "pre-alpha" deploy to production
olivierphi Sep 13, 2024
bca6e34
[hotfix] Fix a bug in our Django Admin daily challenge edition UI
olivierphi Sep 15, 2024
d60de66
[hotfix] Fix a regression with the new "NamedTuples" management of Te…
olivierphi Sep 28, 2024
68282fa
[deps] Update "django-axes"
olivierphi Sep 28, 2024
1d60d71
[UI] Experiment with better (??) ways to display black pieces' symbol
olivierphi Sep 28, 2024
dd9f2be
[CI] Update the "orgoro/coverage" GH Action
olivierphi Sep 28, 2024
77f2009
[UI] Keep experimenting with better (??) ways to display black pieces…
olivierphi Sep 28, 2024
a9f8e49
[bugfix] Fix the wrong highlight of the king in check
olivierphi Nov 25, 2024
820c158
[cleaning] Remove the server-side chess engines
olivierphi Dec 7, 2024
0ca4188
[pre-commit] Add "fix-future-annotations" & "pyupgrade" hooks
olivierphi Dec 7, 2024
34a0378
[chore] Update `uv`, update Django version, some TLC for the GH Actions
olivierphi Dec 7, 2024
2b4c1e2
[UI] Start using atomic components, rather than shared classes
olivierphi Dec 7, 2024
aa210eb
[deps] Prevent `uv` from building a "zakuchess.egg-info" every time w…
olivierphi Dec 7, 2024
ec961d8
[UI] Now that we have "atoms", we can also start using "molecule" com…
olivierphi Dec 7, 2024
0eadccf
[lichess] We now have to confirm moves before they are actually sent …
olivierphi Dec 7, 2024
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
2 changes: 2 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# This file will never be used in production, so it's ok to commit this secret key :-)
SECRET_KEY=not-a-security-issue
DATABASE_URL=sqlite:///db.sqlite3

LICHESS_CLIENT_ID=zakuchess-local-dev
36 changes: 23 additions & 13 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,41 @@ jobs:
runs-on: "ubuntu-latest"

steps:
# Setup
- uses: "actions/checkout@v4"
- name: Set up uv
# Install a specific uv version using the installer
run: "curl -LsSf https://astral.sh/uv/${UV_VERSION}/install.sh | sh"
env:
UV_VERSION: "0.4.4"
- name: Set up Python
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "0.5.7"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Install Python, via uv
run: uv python install
- name: "Install dependencies via uv"
run: uv sync --all-extras
- name: "Install the project in 'editable' mode"
run: uv pip install --no-build -e .

# Code quality checks
- name: "Run linting checks: Ruff checker"
run: uv run ruff format --check --quiet src/
run: uv run --no-sync ruff format --check --quiet src/
- name: "Run linting checks: Ruff linter"
run: uv run ruff check --quiet src/
run: uv run --no-sync ruff check --quiet src/
- name: "Run linting checks: Mypy"
run: uv run mypy src/
run: uv run --no-sync mypy src/
- name: "Run linting checks: fix-future-annotations"
run: uv run --no-sync fix-future-annotations src/
- name: "Check that Django DB migrations are up to date"
run: uv run python manage.py makemigrations | grep "No changes detected"
run: uv run --no-sync python manage.py makemigrations --check

# Test suite & code coverage
- name: "Run tests"
# TODO: progressively increase minimum coverage to something closer to 80%
run: uv run pytest --cov=src --cov-report xml:coverage.xml
# TODO: progressively increase minimum coverage to something closer to 80%
run: uv run --no-sync pytest --cov=src --cov-report xml:coverage.xml
# --cov-fail-under=60 --> we'll actually do that with the "Report coverage" step
- name: "Report coverage"
# @link https://github.com/orgoro/coverage
uses: "orgoro/coverage@v3.1"
uses: "orgoro/coverage@v3.2"
continue-on-error: true
with:
coverageFile: coverage.xml
Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
# uv-related stuff:
/bin/uv
/bin/uvx
/.uv.env
/.uv.env.fish
*.egg-info

/.docker/*
!/.docker/.gitkeep
Expand Down
25 changes: 23 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:

# -------------- MyPy: type checking
# Although MyPy has limited abilities in a pre-commit context, as it can only
# type-check each file in isolation, it can still catch errors.
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
hooks:
- id: mypy
additional_dependencies: [types-requests==2.31.0.2]
additional_dependencies: [ types-requests==2.31.0.2 ]
exclude: "^scripts/load_testing/.*\\.py$"

# -------------- Ruff: linter & "à la Black" formatter
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.6.3
hooks:
# Run the formatter.
- id: ruff-format
# Run the linter.
- id: ruff
args: ["--fix"]
args: [ "--fix" ]
exclude: "^src/project/settings/.*\\.py$"

# -------------- pyupgrade: make sure we're using the latest Python features
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
hooks:
- id: pyupgrade
args: [ "--py311-plus" ]

# -------------- fix-future-annotations: upgrade the typing annotations syntax to PEP 585 and PEP 604.
- repo: https://github.com/frostming/fix-future-annotations
rev: 0.5.0 # a released version tag
hooks:
- id: fix-future-annotations

# -------------- validate-pyproject: does what it says on the tin ^_^
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.19
hooks:
Expand Down
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ COPY src/apps/chess/static-src ./src/apps/chess/static-src
# so that Tailwind see the classes used in them:
COPY src/apps/chess/components ./src/apps/chess/components
COPY src/apps/daily_challenge/components ./src/apps/daily_challenge/components
COPY src/apps/lichess_bridge/components ./src/apps/lichess_bridge/components
COPY src/apps/webui/components ./src/apps/webui/components
# We're going to use our Makefile to build the assets:
COPY Makefile ./
Expand Down Expand Up @@ -74,7 +75,7 @@ EOT

# Install uv.
# https://docs.astral.sh/uv/guides/integration/docker/
COPY --from=ghcr.io/astral-sh/uv:0.4.4 /uv /usr/local/bin/uv
COPY --from=ghcr.io/astral-sh/uv:0.5.7 /uv /usr/local/bin/uv

RUN mkdir -p /app
WORKDIR /app
Expand Down Expand Up @@ -115,8 +116,8 @@ FROM python:3.11-slim-bookworm AS assets_download
# By having a separate build stage for downloading assets, we can cache them
# as long as the `download_assets.py` doesn't change.

# should preferably be the same as in `poetry.lock`:
ENV PYTHON_HTTPX_VERSION=0.26.0
# should preferably be the same as in `uv.lock`:
ENV PYTHON_HTTPX_VERSION=0.27.2

RUN pip install -U pip httpx==${PYTHON_HTTPX_VERSION}

Expand Down Expand Up @@ -159,7 +160,6 @@ COPY --chown=1001:1001 --from=frontend_build /app/src/apps/chess/static src/apps

COPY --chown=1001:1001 --from=backend_build /app/.venv .venv

COPY --chown=1001:1001 --from=assets_download /app/src/apps/webui/static/webui/fonts/OpenSans.woff2 src/apps/webui/static/webui/fonts/OpenSans.woff2
COPY --chown=1001:1001 --from=assets_download /app/src/apps/chess/static/chess/js/bot src/apps/chess/static/chess/js/bot
COPY --chown=1001:1001 --from=assets_download /app/src/apps/chess/static/chess/units src/apps/chess/static/chess/units
COPY --chown=1001:1001 --from=assets_download /app/src/apps/chess/static/chess/symbols src/apps/chess/static/chess/symbols
Expand All @@ -179,7 +179,7 @@ EXPOSE 8080

ENV DJANGO_SETTINGS_MODULE=project.settings.production

ENV GUNICORN_CMD_ARGS="--bind 0.0.0.0:8080 --workers 2 --max-requests 120 --max-requests-jitter 20 --timeout 8"
ENV GUNICORN_CMD_ARGS="--bind 0.0.0.0:8080 --workers 4 -k uvicorn_worker.UvicornWorker --max-requests 120 --max-requests-jitter 20 --timeout 8"

RUN chmod +x scripts/start_server.sh
# See <https://hynek.me/articles/docker-signals/>.
Expand Down
76 changes: 61 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PYTHON_BINS ?= ./.venv/bin
PYTHON ?= ${PYTHON_BINS}/python
DJANGO_SETTINGS_MODULE ?= project.settings.development
SUB_MAKE = ${MAKE} --no-print-directory
UV ?= bin/uv

.DEFAULT_GOAL := help

Expand All @@ -10,15 +11,14 @@ help:
@grep -P '^[.a-zA-Z/_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: install
install: bin/uv .venv ./node_modules ## Install the Python and frontend dependencies
bin/uv sync --all-extras
${PYTHON_BINS}/pre-commit install
${SUB_MAKE} .venv/bin/black
install: backend/install frontend/install ## Install the Python and frontend dependencies


.PHONY: dev
dev: .env.local db.sqlite3
dev: ## Start Django in "development" mode, as well as our frontend assets compilers in "watch" mode
@${SUB_MAKE} frontend/img
${UV} pip install --no-build -e .
@./node_modules/.bin/concurrently --names "django,css,js" --prefix-colors "blue,yellow,green" \
"${SUB_MAKE} backend/watch" \
"${SUB_MAKE} frontend/css/watch" \
Expand All @@ -31,19 +31,49 @@ download_assets: download_assets_opts ?=
download_assets:
${PYTHON_BINS}/python scripts/download_assets.py ${download_assets_opts}

.PHONY: backend/install
backend/install: uv_sync_opts ?= --all-extras
backend/install: bin/uv .venv ## Install the Python dependencies (via uv) and install pre-commit
# Install Python dependencies:
${UV} sync ${uv_sync_opts}
# Install the project in editable mode, so we don't have to add "src/" to the Python path:
${UV} pip install --no-build -e .
# Install pre-commit hooks:
${PYTHON_BINS}/pre-commit install
# Create a shim for Black (actually using Ruff), so the IDE can use it:
@${SUB_MAKE} .venv/bin/black
# Create the database if it doesn't exist:
@${SUB_MAKE} db.sqlite3
# Make sure the SQLite database is up-to-date:
@${SUB_MAKE} django/manage cmd='createcachetable'

.PHONY: backend/watch
backend/watch: env_vars ?=
backend/watch: address ?= localhost
backend/watch: port ?= 8000
backend/watch: dotenv_file ?= .env.local
backend/watch: ## Start the Django development server
@${SUB_MAKE} django/manage cmd='runserver ${address}:${port}'
backend/watch: uvicorn_opts ?= --use-colors --access-log
backend/watch: ## Start Django via Uvicorn, in "watch" mode
@DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE} ${env_vars} \
${UV} run uvicorn \
--reload --reload-dir src/ \
--host ${address} --port ${port} \
--env-file ${dotenv_file} \
${uvicorn_opts} \
project.asgi:application

.PHONY: backend/resetdb
backend/resetdb: dotenv_file ?= .env.local
backend/resetdb: # Destroys the SQLite database and recreates it from scratch
backend/resetdb: .confirm # Destroys the SQLite database and recreates it from scratch
rm -f db.sqlite3
@${SUB_MAKE} db.sqlite3

.PHONY: backend/backupdb
backend/backupdb: backup_name ?= $$(date --iso-8601=seconds | cut -d + -f 1)
backend/backupdb: # Creates a backup of the SQLite database
@sqlite3 db.sqlite3 ".backup 'db.local.${backup_name}.backup.sqlite3'"
@echo "Backup created as 'db.local.${backup_name}.backup.sqlite3'"


.PHONY: backend/createsuperuser
backend/createsuperuser: dotenv_file ?= .env.local
backend/createsuperuser: email ?= [email protected]
Expand All @@ -61,7 +91,7 @@ test: ## Launch the pytest tests suite
${PYTHON_BINS}/pytest ${pytest_opts}

.PHONY: code-quality/all
code-quality/all: code-quality/ruff_check code-quality/ruff_lint code-quality/mypy ## Run all our code quality tools
code-quality/all: code-quality/ruff_check code-quality/ruff_lint code-quality/mypy code-quality/fix-future-annotations ## Run all our code quality tools

.PHONY: code-quality/ruff_check
code-quality/ruff_check: ruff_opts ?=
Expand All @@ -81,10 +111,20 @@ code-quality/mypy: ## Python's equivalent of TypeScript
# @link https://mypy.readthedocs.io/en/stable/
@${PYTHON_BINS}/mypy src/ ${mypy_opts}

.PHONY: code-quality/fix-future-annotations
code-quality/fix-future-annotations: fix_future_annotations_opts ?=
code-quality/fix-future-annotations: ## Make sure we're using PEP 585 and PEP 604
# @link https://github.com/frostming/fix-future-annotations
@${PYTHON_BINS}/fix-future-annotations ${fix_future_annotations_opts} src/

# Here starts the frontend stuff

.PHONY: frontend/install
frontend/install: ## Install the frontend dependencies (via npm)
npm install

.PHONY: frontend/watch
frontend/watch: ## Compile the CSS & JS assets of our various Django apps, in 'watch' mode
frontend/watch: ./node_modules ## Compile the CSS & JS assets of our various Django apps, in 'watch' mode
@./node_modules/.bin/concurrently --names "img,css,js" --prefix-colors "yellow,green" \
"${SUB_MAKE} frontend/img" \
"${SUB_MAKE} frontend/css/watch" \
Expand Down Expand Up @@ -143,14 +183,14 @@ frontend/img/copy_assets:

# Here starts the "misc util targets" stuff

bin/uv: uv_version ?= 0.4.4
bin/uv: uv_version ?= 0.5.7
bin/uv: # Install `uv` and `uvx` locally in the "bin/" folder
curl -LsSf "https://astral.sh/uv/${uv_version}/install.sh" | \
CARGO_DIST_FORCE_INSTALL_DIR="$$(pwd)" INSTALLER_NO_MODIFY_PATH=1 sh
UV_INSTALL_DIR="$$(pwd)/bin" UV_NO_MODIFY_PATH=1 sh
@echo "We'll use 'bin/uv' to manage Python dependencies."

.venv: ## Initialises the Python virtual environment in a ".venv" folder, via uv
bin/uv venv
${UV} venv

.env.local:
cp .env.dist .env.local
Expand All @@ -171,6 +211,7 @@ django/manage: env_vars ?=
django/manage: dotenv_file ?= .env.local
django/manage: cmd ?= --help
django/manage: .venv .env.local ## Run a Django management command
@echo "Running Django management command: ${cmd}"
@DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE} ${env_vars} \
${PYTHON_BINS}/dotenv -f '${dotenv_file}' run -- \
${PYTHON} manage.py ${cmd}
Expand All @@ -179,8 +220,13 @@ django/manage: .venv .env.local ## Run a Django management command

./node_modules: frontend/install

frontend/install:
npm install

# Here starts the "Internal Makefile utils" stuff

.PHONY: .confirm
.confirm:
# https://www.alexedwards.net/blog/a-time-saving-makefile-for-your-go-projects
@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]

# Here starts the "Lichess database" stuff

Expand Down
2 changes: 1 addition & 1 deletion dev-start.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export DJANGO_SETTINGS_MODULE=project.settings.development
alias run_in_dotenv='dotenv -f .env.local run -- '

alias uv='bin/uv'
alias djm='run_in_dotenv python src/manage.py'
alias djm='run_in_dotenv python manage.py'
alias test='DJANGO_SETTINGS_MODULE=project.settings.test run_in_dotenv pytest -x --reuse-db'
alias test-no-reuse='DJANGO_SETTINGS_MODULE=project.settings.test run_in_dotenv pytest -x'

Expand Down
Loading
Loading