diff --git a/.env.example b/.env.example index 7fcd471..ea8465d 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,11 @@ INTEGRATION_ENCRYPTION_KEY= # ─── Optional ───────────────────────────────────────────────────────────────── +# Image tag pulled from ghcr.io for the api + web services. Pin to a release +# tag for reproducible upgrades; using `latest` can pull breaking changes on +# the next `docker compose pull`. Switch deliberately, never silently. +TESTJAM_VERSION=v1.0.0 + # Database — only override if you need non-default user/db name. POSTGRES_USER=testjam POSTGRES_DB=testjam diff --git a/backend/pyproject.toml b/backend/pyproject.toml index b5b1922..4eae58f 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "testjam-api" -version = "0.1.0" +version = "1.0.0" description = "Testjam test management platform — backend API" requires-python = ">=3.14" dependencies = [ diff --git a/docker-compose.yml b/docker-compose.yml index 4b8d5b7..13f9fc3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,9 +24,9 @@ services: retries: 5 api: - build: - context: ./backend - dockerfile: Dockerfile.prod + # Pin TESTJAM_VERSION in .env (default v1.0.0); avoid `latest` in prod — + # a `docker compose pull` could drag in a breaking release without warning. + image: ghcr.io/jamofer/testjam-api:${TESTJAM_VERSION:-v1.0.0} environment: DATABASE_URL: postgresql://${POSTGRES_USER:-testjam}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-testjam} SECRET_KEY: ${SECRET_KEY} @@ -48,9 +48,7 @@ services: retries: 6 web: - build: - context: ./frontend - dockerfile: Dockerfile.prod + image: ghcr.io/jamofer/testjam-web:${TESTJAM_VERSION:-v1.0.0} ports: - "${APP_PORT:-8080}:80" depends_on: diff --git a/docs/manual/getting-started.es.md b/docs/manual/getting-started.es.md index e5da95f..ab5b1d8 100644 --- a/docs/manual/getting-started.es.md +++ b/docs/manual/getting-started.es.md @@ -10,21 +10,24 @@ Esta página te lleva desde una máquina en blanco hasta una UI de Testjam con s - Salida HTTPS al exterior para descargar las imágenes oficiales (o un mirror configurado). - (Opcional) Un reverse proxy con terminación TLS — Caddy, nginx, Cloudflare Tunnel, … — apuntando al `APP_PORT` expuesto. -El stack arranca tres contenedores principales: +El stack arranca tres contenedores principales, todos descargados del GitHub Container Registry público: -| Contenedor | Imagen | Rol | -|------------|------------------------|--------------------------------------------------------------------| -| `db` | `postgres:18.3-alpine` | Base de datos persistente, montada en un volumen nombrado. | -| `api` | `testjam-api` | FastAPI + Uvicorn, ejecuta las migraciones Alembic al arrancar. | -| `web` | `testjam-frontend` | Nginx que sirve la UI compilada y hace proxy de `/api/` al backend.| +| Contenedor | Imagen | Rol | +|------------|----------------------------------------------|--------------------------------------------------------------------| +| `db` | `postgres:18.3-alpine` | Base de datos persistente, montada en un volumen nombrado. | +| `api` | `ghcr.io/jamofer/testjam-api:v1.0.0` | FastAPI + Uvicorn, ejecuta las migraciones Alembic al arrancar. | +| `web` | `ghcr.io/jamofer/testjam-web:v1.0.0` | Nginx que sirve la UI compilada y hace proxy de `/api/` al backend.| Sólo `web` expone puerto al host (`APP_PORT`, por defecto `8080`). -## 1 · Clonar y configurar +## 1 · Descargar compose + ejemplo de env + +No hace falta clonar — sólo dos archivos: ```bash -git clone https://github.com/Jamofer/testjam.git -cd testjam +mkdir testjam && cd testjam +curl -fsSLO https://raw.githubusercontent.com/Jamofer/testjam/v1.0.0/docker-compose.yml +curl -fsSLO https://raw.githubusercontent.com/Jamofer/testjam/v1.0.0/.env.example cp .env.example .env ``` @@ -33,10 +36,12 @@ Edita `.env` y rellena al menos: ```dotenv POSTGRES_PASSWORD=por-favor-cambialo SECRET_KEY=$(openssl rand -hex 32) +INTEGRATION_ENCRYPTION_KEY=$(python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())") +TESTJAM_VERSION=v1.0.0 APP_PORT=8080 ``` -`SECRET_KEY` firma los JWT — si lo rotas, invalidas todas las sesiones activas. +`SECRET_KEY` firma los JWT — si lo rotas, invalidas todas las sesiones activas. `TESTJAM_VERSION` fija el tag de imagen descargado de GHCR; **evita `latest` en producción** porque el siguiente `docker compose pull` podría traer una release con cambios incompatibles sin avisar. ## 2 · Arrancar el stack @@ -95,7 +100,18 @@ SITE_URL=https://testjam.example.com `SITE_URL` se interpola en los enlaces de los emails; apuntarlo al dominio equivocado rompe el flujo en silencio. -## 6 · Siguientes pasos +## 6 · Actualizar + +Cambia `TESTJAM_VERSION` en `.env` al tag nuevo (consulta [releases](https://github.com/Jamofer/testjam/releases)) y luego: + +```bash +docker compose pull +docker compose up -d +``` + +`alembic upgrade head` se ejecuta automáticamente en el nuevo contenedor `api`, así que las migraciones de schema se aplican antes de que el código nuevo empiece a servir. + +## 7 · Siguientes pasos - Crea tu primer proyecto → [Proyectos](projects.es.md). - Engancha tu CI → [Listener Robot](robot-listener.es.md). diff --git a/docs/manual/getting-started.md b/docs/manual/getting-started.md index 8892d8e..c57ed97 100644 --- a/docs/manual/getting-started.md +++ b/docs/manual/getting-started.md @@ -10,21 +10,24 @@ This page walks you from a blank machine to a logged-in Testjam UI. - Outbound HTTPS to pull the official images (or a mirror configured on the host). - (Optional) A reverse proxy with TLS termination — Caddy, nginx, Cloudflare Tunnel, … — pointing at the exposed `APP_PORT`. -The bundled stack ships three long-running containers: +The bundled stack ships three long-running containers, all pulled from the public GitHub Container Registry: -| Container | Image | Role | -|-----------|------------------------|-----------------------------------------------------------------| -| `db` | `postgres:18.3-alpine` | Persistent database, mounted on a named volume. | -| `api` | `testjam-api` | FastAPI + Uvicorn, runs Alembic migrations on start. | -| `web` | `testjam-frontend` | Nginx serving the built UI and proxying `/api/` to the backend. | +| Container | Image | Role | +|-----------|---------------------------------------------|-----------------------------------------------------------------| +| `db` | `postgres:18.3-alpine` | Persistent database, mounted on a named volume. | +| `api` | `ghcr.io/jamofer/testjam-api:v1.0.0` | FastAPI + Uvicorn, runs Alembic migrations on start. | +| `web` | `ghcr.io/jamofer/testjam-web:v1.0.0` | Nginx serving the built UI and proxying `/api/` to the backend. | Only the `web` container exposes a host port (`APP_PORT`, default `8080`). -## 1 · Clone & configure +## 1 · Download compose + env example + +No clone required — only two files: ```bash -git clone https://github.com/Jamofer/testjam.git -cd testjam +mkdir testjam && cd testjam +curl -fsSLO https://raw.githubusercontent.com/Jamofer/testjam/v1.0.0/docker-compose.yml +curl -fsSLO https://raw.githubusercontent.com/Jamofer/testjam/v1.0.0/.env.example cp .env.example .env ``` @@ -33,10 +36,12 @@ Edit `.env` and fill in **at least** the following entries: ```dotenv POSTGRES_PASSWORD=please-change-me SECRET_KEY=$(openssl rand -hex 32) +INTEGRATION_ENCRYPTION_KEY=$(python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())") +TESTJAM_VERSION=v1.0.0 APP_PORT=8080 ``` -`SECRET_KEY` signs JWTs — once issued, rotating it invalidates every active session. +`SECRET_KEY` signs JWTs — once issued, rotating it invalidates every active session. `TESTJAM_VERSION` pins the image tag pulled from GHCR; **avoid `latest` in production** since the next `docker compose pull` could drag in a breaking release without warning. ## 2 · Start the stack @@ -95,7 +100,18 @@ SITE_URL=https://testjam.example.com `SITE_URL` is interpolated into the reset-password link templates; pointing it at the wrong domain breaks the flow silently. -## 6 · Next steps +## 6 · Upgrading + +Bump `TESTJAM_VERSION` in `.env` to the new release tag (browse [releases](https://github.com/Jamofer/testjam/releases)) then: + +```bash +docker compose pull +docker compose up -d +``` + +`alembic upgrade head` runs automatically on the new `api` container, so schema migrations are applied before the new code starts serving. + +## 7 · Next steps - Build your first project → [Projects](projects.md). - Hook your CI → [Robot listener](robot-listener.md). diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ff669e5..61ae41f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "testjam-frontend", - "version": "0.1.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "testjam-frontend", - "version": "0.1.0", + "version": "1.0.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", diff --git a/frontend/package.json b/frontend/package.json index d0108b4..eb2df9f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "testjam-frontend", "private": true, - "version": "0.1.0", + "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", diff --git a/testjam-client/pyproject.toml b/testjam-client/pyproject.toml index 1acfd15..4fdf235 100644 --- a/testjam-client/pyproject.toml +++ b/testjam-client/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "testjam-client" -version = "0.1.0" +version = "1.0.0" description = "Python SDK and Robot Framework listener for the Testjam test management server." requires-python = ">=3.14" dependencies = [