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
21 changes: 11 additions & 10 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@ on:

jobs:
pytest:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
run: uv sync --all-groups

- name: Lint python code
run: flake8 --ignore=E501,F401,E402,F811,E731,F403,E721 .
run: uv run flake8 --ignore=E501,F401,E402,F811,E731,F403,E721 --exclude=.git,*migrations*,ve,.venv .

- name: Run django checks
run: ./manage.py check
run: uv run ./manage.py check

- name: Check migrations
run: ./manage.py makemigrations --dry-run --check
run: uv run ./manage.py makemigrations --dry-run --check

- name: Run tests
run: FAKE_REDIS=1 DEBUG=1 py.test
run: FAKE_REDIS=1 DEBUG=1 uv run py.test
31 changes: 16 additions & 15 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,57 @@ env:

jobs:
pytest:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
run: uv sync --all-groups

- name: Lint python code
run: flake8 --ignore=E501,F401,E402,F811,E731,F403,E721 .
run: uv run flake8 --ignore=E501,F401,E402,F811,E731,F403,E721 --exclude=.git,*migrations*,ve,.venv .

- name: Run django checks
run: ./manage.py check
run: uv run ./manage.py check

- name: Check migrations
run: ./manage.py makemigrations --dry-run --check
run: uv run ./manage.py makemigrations --dry-run --check

- name: Run tests
run: FAKE_REDIS=1 DEBUG=1 py.test
run: FAKE_REDIS=1 DEBUG=1 uv run py.test

docker:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- uses: docker/build-push-action@v2
- uses: docker/build-push-action@v6
name: Build and push
with:
push: true
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ db.sqlite3

# env
.env*

.python-version
77 changes: 25 additions & 52 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,11 @@

## Setup your machine

The setup you need wildly depends on the OS you are running.
Here are instructions for some common OSes.

<details>
<summary>Ubuntu (or Mint)</summary>

```shell
sudo apt-get install python3-dev python3-setuptools python3-pip
sudo pip3 install virtualenv
```

</details>

<details>
<summary>Fedora</summary>

```shell
sudo dnf install python3-devel python3-setuptools python3-virtualenv
```

</details>

<details>
<summary>MacOS</summary>

```shell
brew install python3
pip3 install virtualenv
```

</details>
Install [uv](https://docs.astral.sh/uv/getting-started/installation/):

```shell
curl -LsSf https://astral.sh/uv/install.sh | sh
```

## Get the code
```shell
Expand All @@ -41,40 +15,31 @@ cd incubator
```

## Initial setup
Now that you have the code we have to install the required Python dependencies.

We will use a virtualenv for this purpose. This allows us to install specific versions of the package for the incubator and avoid messing up with your system packages. If you don't know what is a virtualenv, it might be good to google it a bit or ask about it to members of the hackerspace, they will be happy to help.
Install dependencies (uv will automatically create a virtual environment):

```shell
python3 -m venv ve
source ve/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
uv sync --group dev
```

The last step is to create an empty database with the correct structure.
```shell
./manage.py migrate
uv run ./manage.py migrate
```

## Run the web server
Now that you are set up, you can fire up the Django web server:
```shell
./manage.py runserver
uv run ./manage.py runserver
```

And have a look at your local instance on [localhost:8000](http://localhost:8000)


## Next time
The next time you want to work on this code, you don't have to repeat the whole list of commands we just typed. You only have to activate the virtualenv (you have to activate it once for every new shell you open)

```shell
source ve/bin/activate
```
The next time you want to work on this code, just start the server:

And then start the server
```shell
./manage.py runserver
uv run ./manage.py runserver
```

# How to ?
Expand All @@ -84,7 +49,7 @@ And then start the server
You might need to create a user with admin rights on your local instance. Just run this command:

```shell
./manage.py createsuperuser
uv run ./manage.py createsuperuser
```

## Change the configuration
Expand Down Expand Up @@ -116,15 +81,23 @@ export SQL_PORT=<PORT>

## MQTT backend
```shell
pip install paho-mqtt
uv add paho-mqtt
```


## Adding new requirements

To add a requirement, add it with no version constraint (or as little as needed)
to `requirements.in` (or `requirements-dev.in` or `requirements-prod.in` if it is needed only in prod or dev). Then run `pip-compile` (or `pip-compile requirements-dev.in` or `pip-compile requirements-prod.in`).
To add a new dependency, use:

Never edit a `requirements-*.txt` file by hand !
```shell
uv add <dependency>
```

For dev-only or prod-only dependencies, use the `--group` flag:

```shell
uv add --group dev <dependency>
uv add --group prod <dependency>
```

In addition, we use [Dependabot](https://dependabot.com/) who will automatically submit Pull Requests to upgrade the python packages when a new version is available. This will only change the `requirement-*.txt`.
This will update both `pyproject.toml` and `uv.lock` automatically. Never edit `uv.lock` by hand!
21 changes: 13 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
FROM python:3.10-slim-buster
FROM python:3.10-slim-bookworm

COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

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

The Dockerfile pulls ghcr.io/astral-sh/uv using the mutable latest tag, which is a supply-chain risk. If that registry or tag is ever compromised, a malicious uv binary could be injected into your build, with the ability to influence dependency resolution and run in an environment that may have access to secrets or sensitive configuration. To reduce this risk, reference this image using an immutable identifier such as a specific version tag and preferably a content digest, and update it explicitly when you choose to upgrade.

Copilot uses AI. Check for mistakes.

WORKDIR /srv

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy

RUN apt update && apt install -y libpq-dev build-essential netcat && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends libpq-dev build-essential netcat-openbsd && rm -rf /var/lib/apt/lists/*

COPY ./requirements.txt .
COPY ./requirements-prod.txt .
COPY pyproject.toml uv.lock ./

RUN pip install --upgrade pip && pip install -r requirements.txt && pip install -r requirements-prod.txt
RUN uv sync --frozen --no-dev --group prod --no-install-project

COPY . .

RUN uv sync --frozen --no-dev --group prod --no-editable

ENTRYPOINT ["./entrypoint.sh"]
CMD ["gunicorn", "incubator.wsgi:application", "--bind", "0.0.0.0:8000"]
CMD ["uv", "run", "gunicorn", "incubator.wsgi:application", "--bind", "0.0.0.0:8000"]
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
git pull
docker pull ghcr.io/urlab/incubator:main
docker-compose up -d --build
docker-compose exec web python manage.py migrate --noinput
docker-compose exec web python manage.py collectstatic --no-input --clear
docker-compose exec web uv run python manage.py migrate --noinput
docker-compose exec web uv run python manage.py collectstatic --no-input --clear
docker-compose restart nginx
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
labels:
ofelia.enabled: "true"
ofelia.job-exec.autoclose.schedule: "0 0 4 * * *"
ofelia.job-exec.autoclose.command: "python3 manage.py close_space"
ofelia.job-exec.autoclose.command: "uv run python manage.py close_space"
restart: unless-stopped

redis:
Expand Down
17 changes: 8 additions & 9 deletions fabfile.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this file still relevant ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't even know what it's

Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
from fabric.api import run, cd
from fabric.context_managers import prefix


def deploy():
code_dir = '/home/www-data/incubator'
with cd(code_dir), prefix('source ve/bin/activate'):
run('sudo supervisorctl stop incubator')
code_dir = "/home/www-data/incubator"
with cd(code_dir):
run("sudo supervisorctl stop incubator")
run("./save_db.sh")
run("git pull")
run("pip install -r requirements.txt --upgrade -q")
run("./manage.py collectstatic --noinput -v 0")
run("./manage.py makemigrations")
run("./manage.py migrate")
run('sudo supervisorctl start incubator')
run("uv sync --frozen")
run("uv run ./manage.py collectstatic --noinput -v 0")
run("uv run ./manage.py makemigrations")
run("uv run ./manage.py migrate")
run("sudo supervisorctl start incubator")
64 changes: 64 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[project]
name = "incubator"
version = "0.1.0"
description = "UrLab's incubator – hackerspace management platform"
requires-python = ">=3.10"

dependencies = [
# Main packages
"django>=3,<4",

# Main Django apps
"djangorestframework",
"django-activity-stream",
"django-bootstrap4",
"django-constance",

Copilot AI Mar 6, 2026

Copy link

Choose a reason for hiding this comment

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

incubator/settings.py enables constance.backends.database and sets CONSTANCE_BACKEND to the database backend, but pyproject.toml depends on plain django-constance (no [database] extra) and the lockfile contains no django-picklefield. This is likely to break at runtime when Constance tries to use its DB backend. Add the django-constance[database] extra (or explicitly add whatever backend dependency the DB backend requires) so the installed deps match the configured backend.

Suggested change
"django-constance",
"django-constance[database]",

Copilot uses AI. Check for mistakes.
"django-crispy-forms",
"django-extensions",
"django-filter",
"django-simple-history",
"django-mptt",
"wiki",
"sorl-thumbnail<12.10",
"setuptools<78",

# Other Django
"django-jsonfield",
"django-jsonfield-compat",
"django-resized",

# Tooling
"influxdb",
"ipython",
"mypy-extensions",
"typing-extensions",

# Common Python packages
"ics",
"Markdown",
"Pillow",
"redis",
"requests",
"sentry-sdk",
]

[dependency-groups]
dev = [
"flake8",
"isort",
"pycodestyle",
"pyflakes",
"pylint",
"pytest",
"pytest-django",
]
prod = ["gunicorn", "psycopg2-binary"]

[tool.pytest.ini_options]
norecursedirs = "ve static media .git env venv v3 ve3 venv3 env3"
DJANGO_SETTINGS_MODULE = "incubator.settings"
addopts = "--reuse-db --nomigrations"

[tool.flake8]
exclude = ".git,*migrations*,ve,.venv"
max-line-length = 125
9 changes: 0 additions & 9 deletions requirements-dev.in

This file was deleted.

Loading