fix(ci): fix sidebar tests + add registry publish + prod compose
- sidebar.test: expand category before asserting on module names (categories are collapsed by default since UI-Umbau) - ci.yml: replace build-deploy with publish job that pushes images to git.vicolab.de container registry - docker-compose.prod.yml: pull-only compose for server deployments using registry images Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+14
-6
@@ -47,15 +47,23 @@ jobs:
|
|||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: pnpm test
|
run: pnpm test
|
||||||
|
|
||||||
build-deploy:
|
publish:
|
||||||
name: Build & Deploy
|
name: Build & Publish Images
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: test
|
needs: test
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build Docker images
|
- name: Log in to Gitea Container Registry
|
||||||
run: docker compose build web api
|
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.vicolab.de -u ${{ gitea.actor }} --password-stdin
|
||||||
|
|
||||||
- name: Deploy services
|
- name: Build web image
|
||||||
run: docker compose up -d web api
|
run: docker build -t git.vicolab.de/schalli/tessera-ctl/web:latest -f apps/web/Dockerfile .
|
||||||
|
|
||||||
|
- name: Build api image
|
||||||
|
run: docker build -t git.vicolab.de/schalli/tessera-ctl/api:latest -f apps/api/Dockerfile .
|
||||||
|
|
||||||
|
- name: Push images
|
||||||
|
run: |
|
||||||
|
docker push git.vicolab.de/schalli/tessera-ctl/web:latest
|
||||||
|
docker push git.vicolab.de/schalli/tessera-ctl/api:latest
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ describe('Sidebar', () => {
|
|||||||
const Sidebar = await importSidebar();
|
const Sidebar = await importSidebar();
|
||||||
render(<Sidebar />);
|
render(<Sidebar />);
|
||||||
|
|
||||||
|
// Categories are collapsed by default — wait for category header, then expand
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Domain Tools')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
await userEvent.click(screen.getByText('Domain Tools'));
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Domaincheck')).toBeInTheDocument();
|
expect(screen.getByText('Domaincheck')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -156,8 +162,9 @@ describe('Sidebar', () => {
|
|||||||
const Sidebar = await importSidebar();
|
const Sidebar = await importSidebar();
|
||||||
const { rerender } = render(<Sidebar />);
|
const { rerender } = render(<Sidebar />);
|
||||||
|
|
||||||
|
// Wait for category header to confirm initial fetch completed
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Domaincheck')).toBeInTheDocument();
|
expect(screen.getByText('Domain Tools')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialCallCount = (globalThis.fetch as ReturnType<typeof vi.fn>).mock.calls.length;
|
const initialCallCount = (globalThis.fetch as ReturnType<typeof vi.fn>).mock.calls.length;
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: git.vicolab.de/schalli/tessera-ctl/web:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
HOSTNAME: "0.0.0.0"
|
||||||
|
NEXT_PUBLIC_API_URL: ${APP_URL:-http://localhost:3001}
|
||||||
|
API_INTERNAL_URL: "http://api:3001"
|
||||||
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
|
networks:
|
||||||
|
- frontend-net
|
||||||
|
- backend-net
|
||||||
|
depends_on:
|
||||||
|
api:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
api:
|
||||||
|
image: git.vicolab.de/schalli/tessera-ctl/api:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3001:3001"
|
||||||
|
networks:
|
||||||
|
- backend-net
|
||||||
|
- data-net
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: ${DATABASE_URL}
|
||||||
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
|
TESSERA_ADMIN_USER: ${TESSERA_ADMIN_USER:-admin}
|
||||||
|
TESSERA_ADMIN_EMAIL: ${TESSERA_ADMIN_EMAIL}
|
||||||
|
TESSERA_ADMIN_PASSWORD: ${TESSERA_ADMIN_PASSWORD}
|
||||||
|
TESSERA_FORCE_CHANGE: ${TESSERA_FORCE_CHANGE:-true}
|
||||||
|
TESSERA_SMTP_HOST: ${TESSERA_SMTP_HOST:-}
|
||||||
|
TESSERA_SMTP_PORT: ${TESSERA_SMTP_PORT:-587}
|
||||||
|
TESSERA_SMTP_SECURE: ${TESSERA_SMTP_SECURE:-false}
|
||||||
|
TESSERA_SMTP_USER: ${TESSERA_SMTP_USER:-}
|
||||||
|
TESSERA_SMTP_PASSWORD: ${TESSERA_SMTP_PASSWORD:-}
|
||||||
|
TESSERA_SMTP_FROM: ${TESSERA_SMTP_FROM:-Tessera <noreply@tessera.local>}
|
||||||
|
TESSERA_APP_URL: ${APP_URL:-http://localhost:3000}
|
||||||
|
CALENDAR_ENCRYPTION_KEY: ${CALENDAR_ENCRYPTION_KEY}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/health"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 20s
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- data-net
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: tessera
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_DB: tessera
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U tessera"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
networks:
|
||||||
|
frontend-net:
|
||||||
|
driver: bridge
|
||||||
|
backend-net:
|
||||||
|
driver: bridge
|
||||||
|
data-net:
|
||||||
|
driver: bridge
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
Reference in New Issue
Block a user