chore: fix login integration (#10318)

# Which Problems Are Solved

Login integration tests are not executed in the pipeline

# How the Problems Are Solved

The login integration tests are fixed and added as a pipeline workflow.
It  tests against the built login docker image.
On pipeline failures, developers are guided on how to fix them using a
dev container configured for this purpose.

# Additional Changes

- email domains are replaced by example.com. In case the tests were
accidentally run against a cloud instance, it wouldn't cause bounces.
- pnpm is upgraded, because the --filter argument doesn't work for the
install command on the old version.
- The login Dockerfile is optimized for docker image builds

# Additional Changes From Review for
https://github.com/zitadel/zitadel/pull/10305

These changes were requested from @peintnermax 

- The base dev container starts without any services besides the
database and the dev container itself
- CONTRIBUTING.md is restructured
- To reproduce pipeline checks, only the devcontainer CLI and Docker are
needed. This is described in the CONTRIBUTING.md
- The convenience npm script "generate" is added

# Additional Context

- Follow-up for PR https://github.com/zitadel/zitadel/pull/10305
- Base for https://github.com/zitadel/zitadel/issues/10277
This commit is contained in:
Elio Bischof
2025-08-05 17:59:30 +02:00
committed by GitHub
parent 30175041c1
commit e210d0a16a
52 changed files with 11019 additions and 1746 deletions

View File

@@ -8,9 +8,13 @@ ENV SHELL=/bin/bash \
PNPM_HOME=/home/node/.local/share/pnpm \
PATH=/home/node/.local/share/pnpm:$PATH
RUN apt-get update && \
apt-get --no-install-recommends install -y \
# Cypress dependencies
libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb && \
apt-get clean && \
corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@9.1.2 --activate
corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@10.13.1 --activate
COPY --chown=node:node commands /commands
USER node

View File

@@ -0,0 +1,2 @@
*
!commands

View File

@@ -0,0 +1,39 @@
#!/bin/bash
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
set -e
fi
echo
echo
echo
echo -e "THANKS FOR CONTRIBUTING TO ZITADEL 🚀"
echo
echo "Your dev container is configured for fixing login integration tests."
echo "The login is running in a separate container with the same configuration."
echo "It calls the mock-zitadel container which provides a mocked Zitadel gRPC API."
echo
echo "Also the test suite is configured correctly."
echo "For example, run a single test file:"
echo "pnpm cypress run --spec integration/integration/login.cy.ts"
echo
echo "You can also run the test interactively."
echo "However, this is only possible from outside the dev container."
echo "On your host machine, run:"
echo "cd apps/login"
echo "pnpm cypress open"
echo
echo "If you want to change the login code, you can replace the login container by a hot reloading dev server."
echo "docker stop login-integration"
echo "pnpm turbo dev"
echo "Navigate to the page you want to fix, for example:"
echo "http://localhost:3001/ui/v2/login/verify?userId=221394658884845598&code=abc"
echo "Change some code and reload the page for instant feedback."
echo
echo "When you are done, make sure all integration tests pass:"
echo "pnpm cypress run"
echo
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
exit 0
fi

View File

@@ -0,0 +1,18 @@
#!/bin/bash
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
echo "Running in fail-on-errors mode"
set -e
fi
pnpm install --frozen-lockfile \
--filter @zitadel/login \
--filter @zitadel/client \
--filter @zitadel/proto \
--filter zitadel-monorepo
pnpm cypress install
pnpm test:integration:login
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
exit 0
fi

View File

@@ -0,0 +1,30 @@
#!/bin/bash
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
set -e
fi
echo
echo
echo
echo -e "THANKS FOR CONTRIBUTING TO ZITADEL 🚀"
echo
echo "Your dev container is configured for fixing linting and unit tests."
echo "No other services are running alongside this container."
echo
echo "To fix all auto-fixable linting errors, run:"
echo "pnpm turbo lint:fix"
echo
echo "To watch console linting errors, run:"
echo "pnpm turbo watch lint --filter console"
echo
echo "To watch @zitadel/client unit test failures, run:"
echo "pnpm turbo watch test:unit --filter @zitadel/client"
echo
echo "To watch @zitadel/login relevant unit tests and linting failures, run:"
echo "pnpm turbo watch lint test:unit --filter @zitadel/login..."
echo
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
exit 0
fi

View File

@@ -0,0 +1,12 @@
#!/bin/bash
if [ "$FAIL_COMMANDS_ON_ERRORS" == "true" ]; then
set -e
fi
pnpm install --frozen-lockfile --recursive
pnpm turbo lint test:unit
if [ "$FAIL_COMMANDS_ON_ERRORS" != "true" ]; then
exit 0
fi

View File

@@ -1,15 +1,15 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "devcontainer",
"dockerComposeFile": "docker-compose.yml",
"name": "Base: Build and Run the Components you need",
"dockerComposeFile": "docker-compose.yaml",
"service": "devcontainer",
"runServices": [
"devContainer",
"db"
],
"workspaceFolder": "/workspaces",
"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "1.24"
},
"ghcr.io/guiyomh/features/golangci-lint:0": {},
"ghcr.io/jungaretti/features/make:1": {}
"remoteEnv": {
"DISPLAY": ""
},
"forwardPorts": [
3000,
@@ -17,12 +17,13 @@
4200,
8080
],
"onCreateCommand": "pnpm install -g sass@1.64.1",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
"onCreateCommand": "pnpm install --frozen-lockfile --recursive --prefer-offline",
"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "1.24"
},
"ghcr.io/guiyomh/features/golangci-lint:0": {},
"ghcr.io/jungaretti/features/make:1": {},
"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
}
}
}

View File

@@ -1,20 +1,11 @@
x-build-cache: &build-cache
cache_from:
- type=gha
cache_to:
- type=gha,mode=max
services:
devcontainer:
container_name: devcontainer
build:
context: .
<<: *build-cache
context: ../base
volumes:
- ../../:/workspaces:cached
- /tmp/.X11-unix:/tmp/.X11-unix:cached
- home-dir:/home/node:delegated
command: sleep infinity
working_dir: /workspaces
environment:
@@ -39,34 +30,9 @@ services:
ports:
- "5432:5432"
mock-zitadel:
container_name: mock-zitadel
build:
context: ../../apps/login/integration/core-mock
<<: *build-cache
ports:
- 22220:22220
- 22222:22222
login-integration:
container_name: login-integration
build:
context: ../..
dockerfile: build/login/Dockerfile
<<: *build-cache
image: "${LOGIN_TAG:-zitadel-login:local}"
env_file: ../../apps/login/.env.test
network_mode: service:devcontainer
environment:
NODE_ENV: test
PORT: 3001
depends_on:
mock-zitadel:
condition: service_started
zitadel:
image: "${ZITADEL_TAG:-ghcr.io/zitadel/zitadel:v4.0.0-rc.2}"
container_name: zitadel
image: "${ZITADEL_TAG:-ghcr.io/zitadel/zitadel:latest}"
command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
volumes:
- ../../apps/login/acceptance/pat:/pat:delegated
@@ -89,7 +55,6 @@ services:
build:
context: ../../apps/login/acceptance/setup
dockerfile: ../go-command.Dockerfile
<<: *build-cache
entrypoint: "./setup.sh"
network_mode: service:devcontainer
environment:
@@ -111,7 +76,7 @@ services:
login-acceptance:
container_name: login
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:v4.0.0-rc.2}"
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:latest}"
network_mode: service:devcontainer
volumes:
- ../../apps/login/.env.test.local:/env-files/.env:cached
@@ -126,7 +91,6 @@ services:
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
<<: *build-cache
environment:
PORT: '3333'
command:
@@ -151,7 +115,6 @@ services:
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
<<: *build-cache
network_mode: service:devcontainer
environment:
API_URL: 'http://localhost:8080'
@@ -175,7 +138,6 @@ services:
# dockerfile: ../../go-command.Dockerfile
# args:
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
# <<: *build-cache
# network_mode: service:devcontainer
# environment:
# API_URL: 'http://localhost:8080'
@@ -197,7 +159,6 @@ services:
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
<<: *build-cache
network_mode: service:devcontainer
environment:
API_URL: 'http://localhost:8080'
@@ -219,7 +180,6 @@ services:
# dockerfile: ../../go-command.Dockerfile
# args:
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
# <<: *build-cache
# network_mode: service:devcontainer
# environment:
# API_URL: 'http://localhost:8080'
@@ -236,4 +196,3 @@ services:
volumes:
postgres-data:
home-dir: