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
22 changes: 22 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM mcr.microsoft.com/devcontainers/python:1-3.12

# Install uv from the official image (recommended by Astral)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# Install Task (https://taskfile.dev)
RUN curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b /usr/local/bin

# The base image ships a Yarn apt source with an expired/missing GPG key, which breaks
# apt-get for any devcontainer feature (e.g. docker-in-docker). Remove it before apt installs.
# Use docker-ce-cli (not docker.io): the host daemon is bind-mounted and Docker 29+ requires API 1.44+.
RUN rm -f /etc/apt/sources.list.d/yarn*.list 2>/dev/null || true \
&& install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \
&& chmod a+r /etc/apt/keyrings/docker.asc \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends docker-ce-cli \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

ENV UV_LINK_MODE=copy
52 changes: 52 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Dev Container — EcoIndex Python

## Prerequisites (machine running Docker)

- [Docker](https://docs.docker.com/get-docker/) (daemon running)
- Cursor with the **Dev Containers** extension (Anysphere)

Nothing to install on a Windows PC for **uv**: everything is in the image / `post-create`.

## Cursor error: `path must be of type string. Received undefined`

Known Cursor bug with **Remote SSH → Dev Container** (the Docker build succeeds; the failure happens when installing the Cursor server inside the container).

Reference: [Cursor forum](https://forum.cursor.com/t/failed-to-install-cursor-server-the-path-argument-must-be-of-type-string-received-undefined/155076)

### Recommended workaround

On the remote machine (where the repo lives, e.g. over SSH):

```bash
cd /path/to/EcoIndex_python
./.devcontainer/up.sh
```

Then in Cursor:

1. **Command Palette** → `Dev Containers: Attach to Running Container` → container **`ecoindex-python-dev`**
2. **File → Open Folder…** → `/workspaces/<project-folder-name>` (e.g. `/workspaces/EcoIndex_python` — the `up.sh` script prints the exact path)

Without step 2, the explorer stays empty: **Attach** does not open the project folder automatically (SSH workaround).

Alternative: `Dev Containers: Open Folder in Container…` (same path).

Avoid for now: **Reopen in Container** / **Rebuild and Reopen in Container** (often triggers the bug).

### Checks on the SSH host

```bash
echo "$HOME" # must not be empty
test -f ~/.gitconfig && echo "gitconfig OK"
```

If `$HOME` is empty, add to `~/.bashrc` or `~/.zshrc`:

```bash
export HOME=/home/your_username
```

### Cursor extensions

- Keep **Dev Containers** (Anysphere)
- Disable **Dev Containers** (Microsoft) if both are installed (possible conflicts)
9 changes: 9 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "2.17.0",
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c",
"integrity": "sha256:25b9f05705ffba7dbe503230ac76081419306f8c8bc88e0ce78c4ecd99a0c78c"
}
}
}
23 changes: 16 additions & 7 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
{
"name": "EcoIndex Python",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12",
"features": {
"ghcr.io/audacioustux/devcontainers/taskfile": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"runArgs": ["--name=ecoindex-python-dev"],
"containerEnv": {
"UV_LINK_MODE": "copy"
},
"customizations": {
"vscode": {
Expand All @@ -17,7 +25,8 @@
"mhutchie.git-graph"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true,
"python.formatting.provider": "black",
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
Expand All @@ -28,6 +37,6 @@
}
}
},
"postCreateCommand": "pipx install poetry==1.8.5 && poetry self add poetry-multiproject-plugin && poetry self add poetry-polylith-plugin",
"postCreateCommand": "bash .devcontainer/post-create.sh",
"remoteUser": "vscode"
}
}
14 changes: 14 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail

# Allow the vscode user to talk to the host Docker daemon (socket is bind-mounted).
if [ -S /var/run/docker.sock ]; then
DOCKER_GID="$(stat -c '%g' /var/run/docker.sock)"
if ! getent group docker >/dev/null; then
sudo groupadd --gid "${DOCKER_GID}" docker
fi
sudo usermod -aG docker vscode
fi

uv sync --all-groups
uv run playwright install chromium --with-deps
18 changes: 18 additions & 0 deletions .devcontainer/up.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Start the dev container without relying on Cursor's "Reopen in Container" (SSH workaround).
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${ROOT}"
echo "Starting dev container for ${ROOT} ..."
npx --yes @devcontainers/cli@latest up \
--workspace-folder "${ROOT}" \
--remove-existing-container
echo ""
WORKSPACE_IN_CONTAINER="/workspaces/$(basename "${ROOT}")"
echo "Container started. Workspace is mounted at: ${WORKSPACE_IN_CONTAINER}"
echo ""
echo "In Cursor:"
echo " 1. Dev Containers → Attach to Running Container → ecoindex-python-dev"
echo " 2. File → Open Folder… → ${WORKSPACE_IN_CONTAINER}"
echo ""
echo "Or use: Dev Containers → Open Folder in Container… (same path)"
53 changes: 41 additions & 12 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,57 @@
ci/cd:
- .github/workflows/*
'ci/cd':
- any:
- changed-files:
- any-glob-to-any-file:
- '.github/workflows/**'

documentation:
- README.md
- ./**/*.md
- any:
- changed-files:
- any-glob-to-any-file:
- 'README.md'
- '**/*.md'

tooling:
- ./**/*TaskFile.yml
- any:
- changed-files:
- any-glob-to-any-file:
- '**/*TaskFile.yml'
- '**/*Taskfile.yml'

tests:
- test/**
- any:
- changed-files:
- any-glob-to-any-file:
- 'test/**'
- 'tests/**'

compute:
- components/ecoindex/compute/**
- any:
- changed-files:
- any-glob-to-any-file:
- 'components/ecoindex/compute/**'

scraper:
- components/ecoindex/scraper/**
- any:
- changed-files:
- any-glob-to-any-file:
- 'components/ecoindex/scraper/**'

cli:
- bases/ecoindex/cli/**
- any:
- changed-files:
- any-glob-to-any-file:
- 'bases/ecoindex/cli/**'

api:
- bases/ecoindex/backend/**
- bases/ecoindex/worker/**
- any:
- changed-files:
- any-glob-to-any-file:
- 'bases/ecoindex/backend/**'
- 'bases/ecoindex/worker/**'

components:
- components
- any:
- changed-files:
- any-glob-to-any-file:
- 'components/**'
Loading
Loading