Merge commit '416a35537f89b1c3ccd3d123289cea37b3309bba' into next-rc

This commit is contained in:
Stefan Benz
2025-07-29 18:15:55 +02:00
656 changed files with 45737 additions and 41051 deletions

View File

@@ -0,0 +1,16 @@
FROM mcr.microsoft.com/devcontainers/typescript-node:20-bookworm
ENV SHELL=/bin/bash \
DEBIAN_FRONTEND=noninteractive \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
CI=1 \
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 \
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

View File

@@ -0,0 +1,28 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "devcontainer",
"dockerComposeFile": "docker-compose.yml",
"service": "devcontainer",
"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": {}
},
"forwardPorts": [
3000,
3001,
4200,
8080
],
"onCreateCommand": "pnpm install -g sass@1.64.1",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
}
}

View File

@@ -0,0 +1,225 @@
services:
devcontainer:
container_name: devcontainer
build:
context: .
volumes:
- ../../:/workspaces:cached
- /tmp/.X11-unix:/tmp/.X11-unix:cached
- home-dir:/home/node:delegated
command: sleep infinity
working_dir: /workspaces
environment:
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_EXTERNALSECURE: false
db:
container_name: db
image: postgres:17.0-alpine3.19
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
PGUSER: postgres
POSTGRES_PASSWORD: postgres
healthcheck:
test: [ "CMD-SHELL", "pg_isready" ]
interval: "10s"
timeout: "30s"
retries: 5
start_period: "20s"
ports:
- "5432:5432"
mock-zitadel:
container_name: mock-zitadel
build:
context: ../../apps/login/integration/core-mock
ports:
- 22220:22220
- 22222:22222
login-integration:
container_name: login-integration
build:
context: ../..
dockerfile: build/login/Dockerfile
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
command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --config /zitadel.yaml --steps /zitadel.yaml'
volumes:
- ../../apps/login/acceptance/pat:/pat:delegated
- ../../apps/login/acceptance/zitadel.yaml:/zitadel.yaml:cached
network_mode: service:devcontainer
healthcheck:
test:
- CMD
- /app/zitadel
- ready
- --config
- /zitadel.yaml
depends_on:
db:
condition: "service_healthy"
configure-login:
container_name: configure-login
restart: no
build:
context: ../../apps/login/acceptance/setup
dockerfile: ../go-command.Dockerfile
entrypoint: "./setup.sh"
network_mode: service:devcontainer
environment:
PAT_FILE: /pat/zitadel-admin-sa.pat
ZITADEL_API_URL: http://localhost:8080
WRITE_ENVIRONMENT_FILE: /login-env/.env.test.local
SINK_EMAIL_INTERNAL_URL: http://sink:3333/email
SINK_SMS_INTERNAL_URL: http://sink:3333/sms
SINK_NOTIFICATION_URL: http://sink:3333/notification
LOGIN_BASE_URL: http://localhost:3000/ui/v2/login/
ZITADEL_API_DOMAIN: localhost
ZITADEL_ADMIN_USER: zitadel-admin@zitadel.localhost
volumes:
- ../../apps/login/acceptance/pat:/pat:cached # Read the PAT file from zitadels setup
- ../../apps/login:/login-env:delegated # Write the environment variables file for the login
depends_on:
zitadel:
condition: "service_healthy"
login-acceptance:
container_name: login
image: "${LOGIN_TAG:-ghcr.io/zitadel/zitadel-login:v4.0.0-rc.2}"
network_mode: service:devcontainer
volumes:
- ../../apps/login/.env.test.local:/env-files/.env:cached
depends_on:
configure-login:
condition: service_completed_successfully
mock-notifications:
container_name: mock-notifications
build:
context: ../../apps/login/acceptance/sink
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
environment:
PORT: '3333'
command:
- -port
- '3333'
- -email
- '/email'
- -sms
- '/sms'
- -notification
- '/notification'
ports:
- "3333:3333"
depends_on:
configure-login:
condition: "service_completed_successfully"
mock-oidcrp:
container_name: mock-oidcrp
build:
context: ../../apps/login/acceptance/oidcrp
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
network_mode: service:devcontainer
environment:
API_URL: 'http://localhost:8080'
API_DOMAIN: 'localhost'
PAT_FILE: '/pat/zitadel-admin-sa.pat'
LOGIN_URL: 'http://localhost:3000/ui/v2/login'
ISSUER: 'http://localhost:8000'
HOST: 'localhost'
PORT: '8000'
SCOPES: 'openid profile email'
volumes:
- ../../apps/login/acceptance/pat:/pat:cached
depends_on:
configure-login:
condition: "service_completed_successfully"
# mock-oidcop:
# container_name: mock-oidcop
# build:
# context: ../../apps/login/acceptance/idp/oidc
# dockerfile: ../../go-command.Dockerfile
# args:
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
# network_mode: service:devcontainer
# environment:
# API_URL: 'http://localhost:8080'
# API_DOMAIN: 'localhost'
# PAT_FILE: '/pat/zitadel-admin-sa.pat'
# SCHEMA: 'http'
# HOST: 'localhost'
# PORT: "8004"
# volumes:
# - "../apps/login/packages/acceptance/pat:/pat:cached"
# depends_on:
# configure-login:
# condition: "service_completed_successfully"
mock-samlsp:
container_name: mock-samlsp
build:
context: ../../apps/login/acceptance/samlsp
dockerfile: ../go-command.Dockerfile
args:
- LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
network_mode: service:devcontainer
environment:
API_URL: 'http://localhost:8080'
API_DOMAIN: 'localhost'
PAT_FILE: '/pat/zitadel-admin-sa.pat'
LOGIN_URL: 'http://localhost:3000/ui/v2/login'
IDP_URL: 'http://localhost:8080/saml/v2/metadata'
HOST: 'http://localhost:8001'
PORT: '8001'
volumes:
- "../apps/login/packages/acceptance/pat:/pat:cached"
depends_on:
configure-login:
condition: "service_completed_successfully"
# mock-samlidp:
# container_name: mock-samlidp
# build:
# context: ../../apps/login/acceptance/idp/saml
# dockerfile: ../../go-command.Dockerfile
# args:
# - LOGIN_TEST_ACCEPTANCE_GOLANG_TAG=${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
# network_mode: service:devcontainer
# environment:
# API_URL: 'http://localhost:8080'
# API_DOMAIN: 'localhost'
# PAT_FILE: '/pat/zitadel-admin-sa.pat'
# SCHEMA: 'http'
# HOST: 'localhost'
# PORT: "8003"
# volumes:
# - "../apps/login/packages/acceptance/pat:/pat"
# depends_on:
# configure-login:
# condition: "service_completed_successfully"
volumes:
postgres-data:
home-dir:

View File

@@ -1,22 +0,0 @@
{
"name": "zitadel",
"dockerComposeFile": "docker-compose.yml",
"service": "devcontainer",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/go:1": {
"version": "1.22"
},
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/guiyomh/features/golangci-lint:0": {},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/jungaretti/features/make:1": {}
},
"forwardPorts": [
3000,
4200,
8080
],
"onCreateCommand": "npm install -g sass@1.64.1"
}

View File

@@ -1,31 +0,0 @@
version: '3.8'
services:
devcontainer:
image: mcr.microsoft.com/devcontainers/base:ubuntu
volumes:
- ../..:/workspaces:cached
- /var/run/docker.sock:/var/run/docker.sock
network_mode: service:db
command: sleep infinity
environment:
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
ZITADEL_EXTERNALSECURE: false
db:
image: postgres:latest
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
PGUSER: postgres
POSTGRES_PASSWORD: postgres
volumes:
postgres-data:

View File

@@ -0,0 +1,21 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "login-integration-debug",
"dockerComposeFile": [
"../base/docker-compose.yml",
"docker-compose.yml"
],
"service": "login-integration-debug",
"runServices": ["login-integration-debug"],
"workspaceFolder": "/workspaces",
"forwardPorts": [3001],
"onCreateCommand": "pnpm install --recursive",
"postAttachCommand": "pnpm turbo daemon clean; pnpm turbo @zitadel/login#dev test:integration:login:debug",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
}
}

View File

@@ -0,0 +1,9 @@
services:
login-integration-debug:
extends:
file: ../base/docker-compose.yml
service: devcontainer
container_name: login-integration-debug
depends_on:
mock-zitadel:
condition: service_started

View File

@@ -0,0 +1,19 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "login-integration",
"dockerComposeFile": [
"../base/docker-compose.yml"
],
"service": "devcontainer",
"runServices": ["login-integration"],
"workspaceFolder": "/workspaces",
"forwardPorts": [3001],
"onCreateCommand": "pnpm install --frozen-lockfile --recursive && cd apps/login/packages/integration && pnpm cypress install && pnpm test:integration:login",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
}
}

View File

@@ -0,0 +1,21 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "turbo-lint-unit-debug",
"dockerComposeFile": [
"../base/docker-compose.yml",
"docker-compose.yml"
],
"service": "turbo-lint-unit-debug",
"runServices": ["turbo-lint-unit-debug"],
"workspaceFolder": "/workspaces",
"forwardPorts": [3001],
"onCreateCommand": "pnpm install --recursive",
"postAttachCommand": "pnpm turbo daemon clean; pnpm turbo watch lint test:unit",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
}
}

View File

@@ -0,0 +1,6 @@
services:
turbo-lint-unit-debug:
extends:
file: ../base/docker-compose.yml
service: devcontainer
container_name: turbo-lint-unit-debug

View File

@@ -0,0 +1,18 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "turbo-lint-unit",
"dockerComposeFile": [
"../base/docker-compose.yml"
],
"service": "devcontainer",
"runServices": ["devcontainer"],
"workspaceFolder": "/workspaces",
"postStartCommand": "pnpm install --frozen-lockfile --recursive && pnpm turbo lint test:unit",
"customizations": {
"jetbrains": {
"settings": {
"com.intellij:app:HttpConfigurable.use_proxy_pac": true
}
}
}
}

View File

@@ -19,7 +19,6 @@ permissions:
issues: write issues: write
pull-requests: write pull-requests: write
actions: write actions: write
id-token: write
jobs: jobs:
core: core:
@@ -32,6 +31,11 @@ jobs:
uses: ./.github/workflows/console.yml uses: ./.github/workflows/console.yml
with: with:
node_version: "20" node_version: "20"
docs:
uses: ./.github/workflows/docs.yml
with:
node_version: "20"
buf_version: "latest" buf_version: "latest"
version: version:
@@ -50,6 +54,8 @@ jobs:
console_cache_path: ${{ needs.console.outputs.cache_path }} console_cache_path: ${{ needs.console.outputs.cache_path }}
version: ${{ needs.version.outputs.version }} version: ${{ needs.version.outputs.version }}
node_version: "20" node_version: "20"
secrets:
DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }}
core-unit-test: core-unit-test:
needs: core needs: core
@@ -79,16 +85,6 @@ jobs:
core_cache_key: ${{ needs.core.outputs.cache_key }} core_cache_key: ${{ needs.core.outputs.cache_key }}
core_cache_path: ${{ needs.core.outputs.cache_path }} core_cache_path: ${{ needs.core.outputs.cache_path }}
login-quality:
needs: [compile]
uses: ./.github/workflows/login-quality.yml
permissions:
actions: write
id-token: write
with:
ignore-run-cache: ${{ github.event_name == 'workflow_dispatch' || fromJSON(github.run_attempt) > 1 }}
node_version: "20"
container: container:
needs: [compile] needs: [compile]
uses: ./.github/workflows/container.yml uses: ./.github/workflows/container.yml
@@ -101,13 +97,14 @@ jobs:
login-container: login-container:
uses: ./.github/workflows/login-container.yml uses: ./.github/workflows/login-container.yml
if: ${{ github.event_name == 'workflow_dispatch' }}
permissions: permissions:
packages: write packages: write
id-token: write id-token: write
with: with:
login_build_image_name: "ghcr.io/zitadel/zitadel-login-build" login_build_image_name: "ghcr.io/zitadel/zitadel-login-build"
node_version: "20" node_version: "20"
secrets:
DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }}
e2e: e2e:
uses: ./.github/workflows/e2e.yml uses: ./.github/workflows/e2e.yml
@@ -121,7 +118,15 @@ jobs:
issues: write issues: write
pull-requests: write pull-requests: write
needs: needs:
[version, core-unit-test, core-integration-test, lint, container, login-container, login-quality, e2e] [
version,
core-unit-test,
core-integration-test,
lint,
container,
login-container,
e2e,
]
if: ${{ github.event_name == 'workflow_dispatch' }} if: ${{ github.event_name == 'workflow_dispatch' }}
secrets: secrets:
GCR_JSON_KEY_BASE64: ${{ secrets.GCR_JSON_KEY_BASE64 }} GCR_JSON_KEY_BASE64: ${{ secrets.GCR_JSON_KEY_BASE64 }}

View File

@@ -21,6 +21,10 @@ on:
node_version: node_version:
required: true required: true
type: string type: string
secrets:
DEPOT_TOKEN:
required: true
jobs: jobs:
executable: executable:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -31,96 +35,57 @@ jobs:
goarch: [amd64, arm64] goarch: [amd64, arm64]
steps: steps:
- - uses: actions/checkout@v4
uses: actions/checkout@v4 - uses: actions/cache/restore@v4
- timeout-minutes: 1
uses: actions/cache/restore@v4 name: restore console
timeout-minutes: 1 with:
name: restore console path: ${{ inputs.console_cache_path }}
with: key: ${{ inputs.console_cache_key }}
path: ${{ inputs.console_cache_path }} fail-on-cache-miss: true
key: ${{ inputs.console_cache_key }} - uses: actions/cache/restore@v4
fail-on-cache-miss: true timeout-minutes: 1
- name: restore core
uses: actions/cache/restore@v4 with:
timeout-minutes: 1 path: ${{ inputs.core_cache_path }}
name: restore core key: ${{ inputs.core_cache_key }}
with: fail-on-cache-miss: true
path: ${{ inputs.core_cache_path }} - uses: actions/setup-go@v5
key: ${{ inputs.core_cache_key }} with:
fail-on-cache-miss: true go-version-file: "go.mod"
- - name: compile
uses: actions/setup-go@v5 timeout-minutes: 5
with: run: |
go-version-file: 'go.mod' GOOS="${{matrix.goos}}" \
- GOARCH="${{matrix.goarch}}" \
name: compile VERSION="${{ inputs.version }}" \
timeout-minutes: 5 COMMIT_SHA="${{ github.sha }}" \
run: | make compile_pipeline
GOOS="${{matrix.goos}}" \ - name: create folder
GOARCH="${{matrix.goarch}}" \ run: |
VERSION="${{ inputs.version }}" \ mkdir zitadel-${{ matrix.goos }}-${{ matrix.goarch }}
COMMIT_SHA="${{ github.sha }}" \ mv zitadel zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/
make compile_pipeline cp LICENSE zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/
- cp README.md zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/
name: create folder tar -czvf zitadel-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz zitadel-${{ matrix.goos }}-${{ matrix.goarch }}
run: | - uses: actions/upload-artifact@v4
mkdir zitadel-${{ matrix.goos }}-${{ matrix.goarch }} with:
mv zitadel zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/ name: zitadel-${{ matrix.goos }}-${{ matrix.goarch }}
cp LICENSE zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/ path: zitadel-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz
cp README.md zitadel-${{ matrix.goos }}-${{ matrix.goarch }}/
tar -czvf zitadel-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz zitadel-${{ matrix.goos }}-${{ matrix.goarch }}
-
uses: actions/upload-artifact@v4
with:
name: zitadel-${{ matrix.goos }}-${{ matrix.goarch }}
path: zitadel-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz
login:
runs-on: ubuntu-latest
steps:
-
uses: actions/checkout@v4
-
uses: depot/setup-action@v1
with:
oidc: true
-
run: make login_standalone_out
env:
# latest if branch is main, otherwise image version which is the pull request number
LOGIN_BAKE_CLI: depot bake
DEPOT_PROJECT_ID: w47wkxzdtw
NODE_VERSION: ${{ inputs.node_version }}
-
name: move files
run: |
cp login/LICENSE login/apps/login/standalone/
cp login/README.md login/apps/login/standalone/
tar -czvf login.tar.gz -C login/apps/login/standalone .
-
uses: actions/upload-artifact@v4
with:
name: login
path: login.tar.gz
checksums: checksums:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [executable, login] needs: [executable]
steps: steps:
- - uses: actions/download-artifact@v4
uses: actions/download-artifact@v4 with:
with: path: executables
path: executables - name: move files one folder up
- run: mv */*.tar.gz . && find . -type d -empty -delete
name: move files one folder up working-directory: executables
run: mv */*.tar.gz . && find . -type d -empty -delete - run: sha256sum * > checksums.txt
working-directory: executables working-directory: executables
- - uses: actions/upload-artifact@v4
run: sha256sum * > checksums.txt with:
working-directory: executables name: checksums.txt
- path: executables/checksums.txt
uses: actions/upload-artifact@v4
with:
name: checksums.txt
path: executables/checksums.txt

View File

@@ -6,14 +6,11 @@ on:
node_version: node_version:
required: true required: true
type: string type: string
buf_version:
required: true
type: string
outputs: outputs:
cache_key: cache_key:
value: ${{ jobs.build.outputs.cache_key }} value: ${{ jobs.build.outputs.cache_key }}
cache_path: cache_path:
value: ${{ jobs.build.outputs.cache_path }} value: ${{ jobs.build.outputs.cache_path }}
env: env:
cache_path: console/dist/console cache_path: console/dist/console
@@ -25,38 +22,32 @@ jobs:
cache_path: ${{ env.cache_path }} cache_path: ${{ env.cache_path }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- - uses: actions/checkout@v4
uses: actions/checkout@v4 - uses: actions/cache/restore@v4
- timeout-minutes: 1
uses: actions/cache/restore@v4 continue-on-error: true
timeout-minutes: 1 id: cache
continue-on-error: true with:
id: cache key: console-${{ hashFiles('console', 'proto', '!console/dist') }}
with: restore-keys: |
key: console-${{ hashFiles('console', 'proto', '!console/dist') }} console-
restore-keys: | path: ${{ env.cache_path }}
console- - if: ${{ steps.cache.outputs.cache-hit != 'true' }}
path: ${{ env.cache_path }} uses: pnpm/action-setup@v4
- - if: ${{ steps.cache.outputs.cache-hit != 'true' }}
if: ${{ steps.cache.outputs.cache-hit != 'true' }} uses: actions/setup-node@v4
uses: bufbuild/buf-setup-action@v1 with:
with: node-version: ${{ inputs.node_version }}
github_token: ${{ github.token }} cache: "pnpm"
version: ${{ inputs.buf_version }} cache-dependency-path: pnpm-lock.yaml
- - if: ${{ steps.cache.outputs.cache-hit != 'true' }}
if: ${{ steps.cache.outputs.cache-hit != 'true' }} name: Install dependencies
uses: actions/setup-node@v4 run: pnpm install --frozen-lockfile
with: - if: ${{ steps.cache.outputs.cache-hit != 'true' }}
node-version: ${{ inputs.node_version }} name: Build console with Turbo
cache: 'yarn' run: pnpm turbo build --filter=./console
cache-dependency-path: console/yarn.lock - if: ${{ steps.cache.outputs.cache-hit != 'true' }}
- uses: actions/cache/save@v4
if: ${{ steps.cache.outputs.cache-hit != 'true' }} with:
run: make console_build path: ${{ env.cache_path }}
- key: ${{ steps.cache.outputs.cache-primary-key }}
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: ${{ env.cache_path }}
key: ${{ steps.cache.outputs.cache-primary-key }}

View File

@@ -79,7 +79,7 @@ jobs:
context: . context: .
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
file: build/Dockerfile file: build/zitadel/Dockerfile
target: artifact target: artifact
platforms: linux/${{ matrix.arch }} platforms: linux/${{ matrix.arch }}
push: true push: true
@@ -94,7 +94,7 @@ jobs:
context: . context: .
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
file: build/Dockerfile file: build/zitadel/Dockerfile
target: final target: final
platforms: linux/${{ matrix.arch }} platforms: linux/${{ matrix.arch }}
push: true push: true

61
.github/workflows/docs.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: Build docs
on:
workflow_call:
inputs:
node_version:
required: true
type: string
buf_version:
required: true
type: string
outputs:
cache_key:
value: ${{ jobs.build.outputs.cache_key }}
cache_path:
value: ${{ jobs.build.outputs.cache_path }}
env:
cache_path: docs/build
jobs:
build:
outputs:
cache_key: ${{ steps.cache.outputs.cache-primary-key }}
cache_path: ${{ env.cache_path }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/cache/restore@v4
timeout-minutes: 1
continue-on-error: true
id: cache
with:
key: docs-${{ hashFiles('docs', 'proto', '!docs/build', '!docs/node_modules', '!docs/protoc-gen-connect-openapi') }}
restore-keys: |
docs-
path: ${{ env.cache_path }}
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: bufbuild/buf-setup-action@v1
with:
github_token: ${{ github.token }}
version: ${{ inputs.buf_version }}
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: pnpm/action-setup@v4
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node_version }}
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
name: Install dependencies
run: pnpm install
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
name: Build docs with Turbo
run: pnpm turbo build --filter=./docs
- if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@v4
with:
path: ${{ env.cache_path }}
key: ${{ steps.cache.outputs.cache-primary-key }}

View File

@@ -12,44 +12,47 @@ jobs:
browser: [firefox, chrome] browser: [firefox, chrome]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- - name: Checkout Repository
name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- - uses: actions/download-artifact@v4
uses: actions/download-artifact@v4
with: with:
path: .artifacts path: .artifacts
name: zitadel-linux-amd64 name: zitadel-linux-amd64
- - name: Unpack executable
name: Unpack executable
run: | run: |
tar -xvf .artifacts/zitadel-linux-amd64.tar.gz tar -xvf .artifacts/zitadel-linux-amd64.tar.gz
mv zitadel-linux-amd64/zitadel ./zitadel mv zitadel-linux-amd64/zitadel ./zitadel
- - name: Set up QEMU
name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- - name: Set up Docker Buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- - uses: pnpm/action-setup@v4
name: Start DB and ZITADEL - uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
- name: Install dependencies
run: pnpm install
- name: Install Cypress binary
run: cd ./e2e && pnpm exec cypress install
- name: Start DB and ZITADEL
run: | run: |
cd ./e2e cd ./e2e
ZITADEL_IMAGE=zitadel:local docker compose up --detach --wait ZITADEL_IMAGE=zitadel:local docker compose up --detach --wait
- - name: Cypress run
name: Cypress run
uses: cypress-io/github-action@v6 uses: cypress-io/github-action@v6
env: env:
CYPRESS_BASE_URL: http://localhost:8080/ui/console CYPRESS_BASE_URL: http://localhost:8080/ui/console
CYPRESS_WEBHOOK_HANDLER_HOST: host.docker.internal CYPRESS_WEBHOOK_HANDLER_HOST: host.docker.internal
CYPRESS_DATABASE_CONNECTION_URL: 'postgresql://root@localhost:26257/zitadel' CYPRESS_DATABASE_CONNECTION_URL: "postgresql://root@localhost:26257/zitadel"
CYPRESS_BACKEND_URL: http://localhost:8080 CYPRESS_BACKEND_URL: http://localhost:8080
with: with:
working-directory: e2e working-directory: e2e
browser: ${{ matrix.browser }} browser: ${{ matrix.browser }}
config-file: cypress.config.ts config-file: cypress.config.ts
- install: false
uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: always() if: always()
with: with:
name: production-tests-${{ matrix.browser }} name: production-tests-${{ matrix.browser }}

View File

@@ -20,7 +20,6 @@ on:
type: string type: string
jobs: jobs:
lint-skip: lint-skip:
name: lint skip name: lint skip
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -36,64 +35,50 @@ jobs:
continue-on-error: true continue-on-error: true
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
steps: steps:
- - uses: actions/checkout@v4
uses: actions/checkout@v4 - uses: bufbuild/buf-setup-action@v1
- with:
uses: bufbuild/buf-setup-action@v1 version: ${{ inputs.buf_version }}
with: github_token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ inputs.buf_version }} - name: lint
github_token: ${{ secrets.GITHUB_TOKEN }} uses: bufbuild/buf-lint-action@v1
- - uses: bufbuild/buf-breaking-action@v1
name: lint with:
uses: bufbuild/buf-lint-action@v1 against: "https://github.com/${{ github.repository }}.git#branch=${{ github.base_ref }}"
-
uses: bufbuild/buf-breaking-action@v1
with:
against: "https://github.com/${{ github.repository }}.git#branch=${{ github.base_ref }}"
console: turbo-lint-unit:
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
name: console name: turbo-lint-unit
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- - name: Checkout
name: Checkout uses: actions/checkout@v4
uses: actions/checkout@v4 - name: Run lint and unit tests in dev container
- uses: devcontainers/ci@v0.3
uses: actions/setup-node@v4 with:
with: push: never
node-version: ${{ inputs.node_version }} configFile: .devcontainer/turbo-lint-unit/devcontainer.json
cache: 'yarn' runCmd: echo "Successfully ran lint and unit tests in dev container postStartCommand"
cache-dependency-path: console/yarn.lock
-
run: cd console && yarn install
-
name: lint
run: make console_lint
core: core:
name: core name: core
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request' }} if: ${{ github.event_name == 'pull_request' }}
steps: steps:
- - name: Checkout
name: Checkout uses: actions/checkout@v4
uses: actions/checkout@v4 - uses: actions/setup-go@v5
- with:
uses: actions/setup-go@v5 go-version-file: "go.mod"
with: - uses: actions/cache/restore@v4
go-version-file: 'go.mod' timeout-minutes: 1
- name: restore core
uses: actions/cache/restore@v4 with:
timeout-minutes: 1 path: ${{ inputs.core_cache_path }}
name: restore core key: ${{ inputs.core_cache_key }}
with: fail-on-cache-miss: true
path: ${{ inputs.core_cache_path }} - uses: golangci/golangci-lint-action@v6
key: ${{ inputs.core_cache_key }} with:
fail-on-cache-miss: true version: ${{ inputs.go_lint_version }}
- github-token: ${{ github.token }}
uses: golangci/golangci-lint-action@v6 only-new-issues: true
with:
version: ${{ inputs.go_lint_version }}
github-token: ${{ github.token }}
only-new-issues: true

View File

@@ -14,6 +14,9 @@ on:
login_build_image: login_build_image:
description: 'The full image tag of the standalone login image' description: 'The full image tag of the standalone login image'
value: '${{ inputs.login_build_image_name }}:${{ github.sha }}' value: '${{ inputs.login_build_image_name }}:${{ github.sha }}'
secrets:
DEPOT_TOKEN:
required: true
permissions: permissions:
packages: write packages: write
@@ -27,15 +30,12 @@ env:
jobs: jobs:
login-container: login-container:
name: Build Login Container name: Build Login Container
runs-on: depot-ubuntu-22.04-8 runs-on: ubuntu-latest
permissions: permissions:
id-token: write
packages: write packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: depot/setup-action@v1 - uses: depot/setup-action@v1
with:
oidc: true
- name: Login meta - name: Login meta
id: login-meta id: login-meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
@@ -55,16 +55,16 @@ jobs:
- name: Bake login multi-arch - name: Bake login multi-arch
uses: depot/bake-action@v1 uses: depot/bake-action@v1
env: env:
DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }}
NODE_VERSION: ${{ inputs.node_version }} NODE_VERSION: ${{ inputs.node_version }}
with: with:
push: true push: true
provenance: true provenance: true
sbom: true sbom: true
targets: login-standalone targets: login-standalone
set: login-*.context=./login/
project: w47wkxzdtw project: w47wkxzdtw
files: | files: |
./login/docker-bake.hcl ./apps/login/docker-bake.hcl
./login/docker-bake-release.hcl ./apps/login/docker-bake-release.hcl
./docker-bake.hcl ./docker-bake.hcl
cwd://${{ steps.login-meta.outputs.bake-file }} cwd://${{ steps.login-meta.outputs.bake-file }}

View File

@@ -1,59 +0,0 @@
name: Login Quality
on:
workflow_call:
inputs:
ignore-run-cache:
description: 'Ignore run caches'
type: boolean
required: true
node_version:
required: true
type: string
jobs:
quality:
name: Ensure Quality
runs-on: depot-ubuntu-22.04-8
timeout-minutes: 30
permissions:
id-token: write
actions: write
env:
CACHE_DIR: /tmp/login-run-caches
steps:
- uses: actions/checkout@v4
- uses: depot/setup-action@v1
with:
oidc: true
- name: Restore Run Caches
uses: actions/cache/restore@v4
id: run-caches-restore
with:
path: ${{ env.CACHE_DIR }}
key: ${{ runner.os }}-login-run-caches-${{github.ref_name}}-${{ github.sha }}-${{github.run_attempt}}
restore-keys: |
${{ runner.os }}-login-run-caches-${{github.ref_name}}-${{ github.sha }}-
${{ runner.os }}-login-run-caches-${{github.ref_name}}-
${{ runner.os }}-login-run-caches-
- uses: actions/download-artifact@v4
with:
path: .artifacts
name: zitadel-linux-amd64
- name: Unpack executable
run: |
tar -xvf .artifacts/zitadel-linux-amd64.tar.gz
mv zitadel-linux-amd64/zitadel ./zitadel
- run: make login_quality
env:
# latest if branch is main, otherwise image version which is the pull request number
LOGIN_BAKE_CLI: depot bake
DEPOT_PROJECT_ID: w47wkxzdtw
IGNORE_RUN_CACHE: ${{ github.event.inputs.ignore-run-cache }}
NODE_VERSION: ${{ inputs.node_version }}
- name: Save Run Caches
uses: actions/cache/save@v4
with:
path: ${{ env.CACHE_DIR }}
key: ${{ steps.run-caches-restore.outputs.cache-primary-key }}
if: always()

View File

@@ -13,7 +13,7 @@ jobs:
Please make sure you tick the following checkboxes before marking this Pull Request (PR) as ready for review: Please make sure you tick the following checkboxes before marking this Pull Request (PR) as ready for review:
- [ ] I am happy with the code - [ ] I have reviewed my changes and would approve it
- [ ] Documentations and examples are up-to-date - [ ] Documentations and examples are up-to-date
- [ ] Logical behavior changes are tested automatically - [ ] Logical behavior changes are tested automatically
- [ ] No debug or dead code - [ ] No debug or dead code

View File

@@ -165,7 +165,7 @@ jobs:
run: | run: |
gh workflow -R zitadel/zitadel-charts run bump.yml gh workflow -R zitadel/zitadel-charts run bump.yml
typescript-packages: npm-packages:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: version needs: version
if: ${{ github.ref_name == 'next' }} if: ${{ github.ref_name == 'next' }}
@@ -184,7 +184,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
working-directory: login working-directory: login
run: pnpm install run: pnpm install --frozen-lockfile
- name: Create Release Pull Request - name: Create Release Pull Request
uses: changesets/action@v1 uses: changesets/action@v1
@@ -192,9 +192,10 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
version: ${{ needs.version.outputs.version }} version: ${{ needs.version.outputs.version }}
cwd: login cwd: packages
createGithubReleases: false
typescript-repo: login-repo:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: version needs: version
if: ${{ github.ref_name == 'next' }} if: ${{ github.ref_name == 'next' }}

11
.gitignore vendored
View File

@@ -7,6 +7,7 @@
# Test binary, build with `go test -c` # Test binary, build with `go test -c`
*.test *.test
!/**/.env.test
# Coverage # Coverage
coverage.txt coverage.txt
@@ -68,6 +69,7 @@ docs/docs/apis/proto
/internal/api/ui/login/static/resources/themes/zitadel/css/zitadel.css /internal/api/ui/login/static/resources/themes/zitadel/css/zitadel.css
/internal/api/ui/login/static/resources/themes/zitadel/css/zitadel.css.map /internal/api/ui/login/static/resources/themes/zitadel/css/zitadel.css.map
zitadel-*-* zitadel-*-*
!apps/**/zitadel-*-*
# local # local
build/local/*.env build/local/*.env
@@ -84,7 +86,14 @@ go.work.sum
.netlify .netlify
load-test/node_modules load-test/node_modules
load-test/yarn-error.log load-test/pnpm-debug.log
load-test/dist load-test/dist
load-test/output/* load-test/output/*
.vercel .vercel
# Turbo
.turbo/
**/.turbo/
# PNPM
.pnpm-store

2
.npmrc Normal file
View File

@@ -0,0 +1,2 @@
auto-install-peers = true
ignore-scripts = "postman-code-generators"

View File

@@ -1,4 +1,5 @@
# Contributing to ZITADEL # Contributing to Zitadel
## Introduction ## Introduction
@@ -12,24 +13,29 @@ If you want to give an answer or be part of discussions please be kind. Treat ot
## What can I contribute? ## What can I contribute?
For people who are new to ZITADEL: We flag issues which are a good starting point to start contributing. You find them [here](https://github.com/zitadel/zitadel/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) For people who are new to Zitadel: We flag issues which are a good starting point to start contributing.
You find them [here](https://github.com/zitadel/zitadel/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
We add the label "good first issue" for problems we think are a good starting point to contribute to Zitadel.
Make ZITADEL more popular and give it a ⭐ - [Issues for first time contributors](https://github.com/zitadel/zitadel/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
- [All issues](https://github.com/zitadel/zitadel/issues)
Help shaping the future of ZITADEL: Help shaping the future of Zitadel:
- Join our [chat](https://zitadel.com/chat) and discuss with us or others. - Join our [chat](https://zitadel.com/chat) and discuss with us or others.
- Ask or answer questions in the [issues section](https://github.com/zitadel/zitadel/issues) - Ask or answer questions in the [issues section](https://github.com/zitadel/zitadel/issues)
- Share your thoughts and ideas in the [discussions section](https://github.com/zitadel/zitadel/discussions) - Share your thoughts and ideas in the [discussions section](https://github.com/zitadel/zitadel/discussions)
Make Zitadel more popular and give it a ⭐
Follow [@zitadel](https://twitter.com/zitadel) on twitter
[Contribute](#how-to-contribute) [Contribute](#how-to-contribute)
- [Contribute code](#contribute) - [Contribute code](#contribute)
- If you found a mistake on our [docs page](https://zitadel.com/docs) or something is missing please read [the docs section](#contribute-docs) - If you found a mistake on our [docs page](https://zitadel.com/docs) or something is missing please read [the docs section](contribute-docs)
- [Translate](#contribute-internationalization) and improve texts - [Translate](#contribute-internationalization) and improve texts
Follow [@zitadel](https://twitter.com/zitadel) on twitter
## How to contribute ## How to contribute
We strongly recommend to [talk to us](https://zitadel.com/contact) before you start contributing to streamline our and your work. We strongly recommend to [talk to us](https://zitadel.com/contact) before you start contributing to streamline our and your work.
@@ -40,6 +46,21 @@ If you are unfamiliar with git have a look at Github's documentation on [creatin
Please draft the pull request as soon as possible. Please draft the pull request as soon as possible.
Go through the following checklist before you submit the final pull request: Go through the following checklist before you submit the final pull request:
### Components
The code consists of the following parts:
| name | description | language | where to find | Development Guide |
| --------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------- |
| backend | Service that serves the grpc(-web) and RESTful API | [go](https://go.dev) | [API implementation](./internal/api/grpc) | [Contribute to Backend](contribute-backend) |
| API definitions | Specifications of the API | [Protobuf](https://developers.google.com/protocol-buffers) | [./proto/zitadel](./proto/zitadel) | [Contribute to Backend](contribute-backend) |
| console | Frontend the user interacts with after log in | [Angular](https://angular.io), [Typescript](https://www.typescriptlang.org) | [./console](./console) | [Contribute to Frontend](contribute-frontend) |
| login | Modern authentication UI built with Next.js | [Next.js](https://nextjs.org), [React](https://reactjs.org), [TypeScript](https://www.typescriptlang.org) | [./login](./login) | [Contribute to Frontend](contribute-frontend) |
| docs | Project documentation made with docusaurus | [Docusaurus](https://docusaurus.io/) | [./docs](./docs) | [Contribute to Frontend](contribute-frontend) |
| translations | Internationalization files for default languages | YAML | [./console](./console) and [./internal](./internal) | [Contribute Translations](contribute-translations) |
Please follow the guides to validate and test the code before you contribute.
### Submit a pull request (PR) ### Submit a pull request (PR)
1. [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the [zitadel/zitadel](https://github.com/zitadel/zitadel) repository on GitHub 1. [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the [zitadel/zitadel](https://github.com/zitadel/zitadel) repository on GitHub
@@ -104,25 +125,6 @@ Please make sure you cover your changes with tests before marking a Pull Request
- [ ] Integration tests ensure that certain commands emit expected events that trigger notifications. - [ ] Integration tests ensure that certain commands emit expected events that trigger notifications.
- [ ] Integration tests ensure that certain events trigger expected notifications. - [ ] Integration tests ensure that certain events trigger expected notifications.
## Contribute
The code consists of the following parts:
| name | description | language | where to find |
| --------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------- | -------------------------------------------------- |
| backend | Service that serves the grpc(-web) and RESTful API | [go](https://go.dev) | [API implementation](./internal/api/grpc) |
| console | Frontend the user interacts with after log in | [Angular](https://angular.io), [Typescript](https://www.typescriptlang.org) | [./console](./console) |
| login | Server side rendered frontend the user interacts with during login | [go](https://go.dev), [go templates](https://pkg.go.dev/html/template) | [./internal/api/ui/login](./internal/api/ui/login) |
| API definitions | Specifications of the API | [Protobuf](https://developers.google.com/protocol-buffers) | [./proto/zitadel](./proto/zitadel) |
| docs | Project documentation made with docusaurus | [Docusaurus](https://docusaurus.io/) | [./docs](./docs) |
Please validate and test the code before you contribute.
We add the label "good first issue" for problems we think are a good starting point to contribute to ZITADEL.
- [Issues for first time contributors](https://github.com/zitadel/zitadel/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
- [All issues](https://github.com/zitadel/zitadel/issues)
### General Guidelines ### General Guidelines
#### Gender Neutrality and Inclusive Language #### Gender Neutrality and Inclusive Language
@@ -143,34 +145,62 @@ Choose alternative words depending on the context.
### API ### API
ZITADEL follows an API first approach. This means all features can not only be accessed via the UI but also via the API. Zitadel follows an API first approach. This means all features can not only be accessed via the UI but also via the API.
The API is designed to be used by different clients, such as web applications, mobile applications, and other services. The API is designed to be used by different clients, such as web applications, mobile applications, and other services.
Therefore, the API is designed to be easy to use, consistent, and reliable. Therefore, the API is designed to be easy to use, consistent, and reliable.
Please check out the dedicated [API guidelines](./API_DESIGN.md) page when contributing to the API. Please check out the dedicated [API guidelines](./API_DESIGN.md) page when contributing to the API.
### Developing ZITADEL with Dev Containers
Follow the instructions provided by your code editor/IDE to initiate the development container. This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers". The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container) #### <a name="dev-containers"></>Developing Zitadel with Dev Containers
When you are connected to the container run the following commands to start ZITADEL. You can use dev containers if you'd like to make sure you have the same development environment like the corresponding GitHub PR checks use.
The following dev containers are available:
- **.devcontainer/base/devcontainer.json**: Contains everything you need to run whatever you want.
- **.devcontainer/turbo-lint-unit/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
- **.devcontainer/turbo-lint-unit-debug/devcontainer.json**: Runs a dev container that executes frontent linting and unit tests in watch mode. You can fix the errors right away and have immediate feedback.
- **.devcontainer/login-integration/devcontainer.json**: Runs a dev container that executes login integration tests and then exits. This is useful to reproduce the corresponding GitHub PR check.
- **.devcontainer/login-integration-debug/devcontainer.json**: Runs a dev container that spins up the login in a hot-reloading dev server and executes login integration tests interactively. You can fix the errors right away and have immediate feedback.
You can also run the GitHub PR checks locally in dev containers without having to connect to a dev container.
The following pnpm commands use the [devcontainer CLI](https://github.com/devcontainers/cli/) and exit when the checks are done.
The minimal system requirements are having Docker and the devcontainers CLI installed.
If you don't have the node_modules installed already, you need to install the devcontainers CLI manually. Run `npm i -g @devcontainers/cli`. Alternatively, the [official Microsoft VS Code extension for Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) offers a command `Dev Containers: Install devcontainer CLI`
```bash
npm run devcontainer:lint-unit
npm run devcontainer:integration:login
```
If you don't have NPM installed, copy and execute the scripts from the package.json directly.
To connect to a dev container to have full IDE support, follow the instructions provided by your code editor/IDE to initiate the dev container.
This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers".
The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container)
For example, to build and run the Zitadel binary in a dev container, connect your IDE to the dev container described in .devcontainer/base/devcontainer.json.
Run the following commands inside the container to start Zitadel.
```bash ```bash
make compile && ./zitadel start-from-init --masterkey MasterkeyNeedsToHave32Characters --tlsMode disabled make compile && ./zitadel start-from-init --masterkey MasterkeyNeedsToHave32Characters --tlsMode disabled
``` ```
ZITADEL serves traffic as soon as you can see the following log line: Zitadel serves traffic as soon as you can see the following log line:
`INFO[0001] server is listening on [::]:8080` `INFO[0001] server is listening on [::]:8080`
### Backend/login ## <a name="backend"></a>Contribute Backend Code
By executing the commands from this section, you run everything you need to develop the ZITADEL backend locally. By executing the commands from this section, you run everything you need to develop the Zitadel backend locally.
Using [Docker Compose](https://docs.docker.com/compose/), you run a [PostgreSQL](https://www.postgresql.org/download/) on your local machine. Using [Docker Compose](https://docs.docker.com/compose/), you run a [PostgreSQL](https://www.postgresql.org/download/) on your local machine.
With [make](https://www.gnu.org/software/make/), you build a debuggable ZITADEL binary and run it using [delve](https://github.com/go-delve/delve). With [make](https://www.gnu.org/software/make/), you build a debuggable Zitadel binary and run it using [delve](https://github.com/go-delve/delve).
Then, you test your changes via the console your binary is serving at http://<span because="breaks the link"></span>localhost:8080 and by verifying the database. Then, you test your changes via the console your binary is serving at http://<span because="breaks the link"></span>localhost:8080 and by verifying the database.
Once you are happy with your changes, you run end-to-end tests and tear everything down. Once you are happy with your changes, you run end-to-end tests and tear everything down.
ZITADEL uses [golangci-lint](https://golangci-lint.run) for code quality checks. Please use [this configuration](.golangci.yaml) when running `golangci-lint`. We recommend to set golangci-lint as linter in your IDE. Zitadel uses [golangci-lint](https://golangci-lint.run) for code quality checks. Please use [this configuration](.golangci.yaml) when running `golangci-lint`. We recommend to set golangci-lint as linter in your IDE.
The commands in this section are tested against the following software versions: The commands in this section are tested against the following software versions:
@@ -199,10 +229,10 @@ make compile
> Build the binary: `make compile` > Build the binary: `make compile`
You can now run and debug the binary in .artifacts/zitadel/zitadel using your favourite IDE, for example GoLand. You can now run and debug the binary in .artifacts/zitadel/zitadel using your favourite IDE, for example GoLand.
You can test if ZITADEL does what you expect by using the UI at http://localhost:8080/ui/console. You can test if Zitadel does what you expect by using the UI at http://localhost:8080/ui/console.
Also, you can verify the data by running `psql "host=localhost dbname=zitadel sslmode=disable"` and running SQL queries. Also, you can verify the data by running `psql "host=localhost dbname=zitadel sslmode=disable"` and running SQL queries.
#### Run Local Unit Tests ### Run Local Unit Tests
To test the code without dependencies, run the unit tests: To test the code without dependencies, run the unit tests:
@@ -210,11 +240,11 @@ To test the code without dependencies, run the unit tests:
make core_unit_test make core_unit_test
``` ```
#### Run Local Integration Tests ### Run Local Integration Tests
Integration tests are run as gRPC clients against a running ZITADEL server binary. Integration tests are run as gRPC clients against a running Zitadel server binary.
The server binary is typically [build with coverage enabled](https://go.dev/doc/build-cover). The server binary is typically [build with coverage enabled](https://go.dev/doc/build-cover).
It is also possible to run a ZITADEL sever in a debugger and run the integrations tests like that. In order to run the server, a database is required. It is also possible to run a Zitadel sever in a debugger and run the integrations tests like that. In order to run the server, a database is required.
In order to prepare the local system, the following will bring up the database, builds a coverage binary, initializes the database and starts the sever. In order to prepare the local system, the following will bring up the database, builds a coverage binary, initializes the database and starts the sever.
@@ -237,7 +267,7 @@ To run all available integration tests:
make core_integration_test_packages make core_integration_test_packages
``` ```
When you change any ZITADEL server code, be sure to rebuild and restart the server before the next test run. When you change any Zitadel server code, be sure to rebuild and restart the server before the next test run.
```bash ```bash
make core_integration_server_stop core_integration_server_start make core_integration_server_stop core_integration_server_start
@@ -251,69 +281,83 @@ make core_integration_server_stop core_integration_db_down
The test binary has the race detector enabled. `core_core_integration_server_stop` checks for any race logs reported by Go and will print them along a `66` exit code when found. Note that the actual race condition may have happened anywhere during the server lifetime, including start, stop or serving gRPC requests during tests. The test binary has the race detector enabled. `core_core_integration_server_stop` checks for any race logs reported by Go and will print them along a `66` exit code when found. Note that the actual race condition may have happened anywhere during the server lifetime, including start, stop or serving gRPC requests during tests.
#### Run Local End-to-End Tests ### Run Local End-to-End Tests
To test the whole system, including the console UI and the login UI, run the E2E tests. To test the whole system, including the console UI and the login UI, run the E2E tests.
```bash ```bash
# Build the production docker image # Build the production docker image
export ZITADEL_IMAGE=zitadel:local GOOS=linux export Zitadel_IMAGE=zitadel:local GOOS=linux
make docker_image make docker_image
# If you made changes in the e2e directory, make sure you reformat the files # If you made changes in the e2e directory, make sure you reformat the files
make console_lint pnpm turbo lint:fix --filter=e2e
# Run the tests # Run the tests
docker compose --file ./e2e/config/host.docker.internal/docker-compose.yaml run --service-ports e2e docker compose --file ./e2e/docker-compose.yaml run --service-ports e2e
``` ```
When you are happy with your changes, you can cleanup your environment. When you are happy with your changes, you can cleanup your environment.
```bash ```bash
# Stop and remove the docker containers for zitadel and the database # Stop and remove the docker containers for zitadel and the database
docker compose --file ./e2e/config/host.docker.internal/docker-compose.yaml down docker compose --file ./e2e/docker-compose.yaml down
``` ```
#### Run Local End-to-End Tests Against Your Dev Server Console ### Run Local End-to-End Tests Against Your Dev Server Console
If you also make [changes to the console](#console), you can run the test suite against your locally built backend code and frontend server. If you also make [changes to the console](#console), you can run the test suite against your locally built backend code and frontend server.
But you will have to install the relevant node dependencies.
```bash ```bash
# Install dependencies # Install dependencies (from repository root)
(cd ./e2e && npm install) pnpm install
# Run the tests interactively # Run the tests interactively
(cd ./e2e && npm run open:golangangular) pnpm run open:golangangular
# Run the tests non-interactively # Run the tests non-interactively
(cd ./e2e && npm run e2e:golangangular) pnpm run e2e:golangangular
``` ```
When you are happy with your changes, you can cleanup your environment. When you are happy with your changes, you can cleanup your environment.
```bash ```bash
# Stop and remove the docker containers for zitadel and the database # Stop and remove the docker containers for zitadel and the database
docker compose --file ./e2e/config/host.docker.internal/docker-compose.yaml down docker compose --file ./e2e/docker-compose.yaml down
``` ```
### Console ## Contribute Frontend Code
By executing the commands from this section, you run everything you need to develop the console locally. This repository uses **pnpm** as package manager and **Turbo** for build orchestration.
Using [Docker Compose](https://docs.docker.com/compose/), you run [PostgreSQL](https://www.postgresql.org/download/) and the [latest release of ZITADEL](https://github.com/zitadel/zitadel/releases/latest) on your local machine. All frontend packages are managed as a monorepo with shared dependencies and optimized builds:
You use the ZITADEL container as backend for your console.
The console is run in your [Node](https://nodejs.org/en/about/) environment using [a local development server for Angular](https://angular.io/cli/serve#ng-serve), so you have fast feedback about your changes.
We use angular-eslint/Prettier for linting/formatting, so please run `yarn lint:fix` before committing. (VSCode users, check out [this ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [this Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) to fix lint and formatting issues in development) - [apps/login](contribute-login) (depends on packages/zitadel-client and packages/zitadel-proto)
- apps/login/integration
- apps/login/acceptance
- [console](contribute-console) (depends on packages/zitadel-client)
- packages/zitadel-client
- packages/zitadel-proto
- [docs](contribute-docs)
Once you are happy with your changes, you run end-to-end tests and tear everything down. ### <a name="frontend-dev-requirements"></a>Frontend Development Requirements
The frontend components are run in a [Node](https://nodejs.org/en/about/) environment and are managed using the pnpm package manager and the Turborepo orchestrator.
> [!INFO]
> Some [dev containers are available](dev-containers) for remote development with docker and pipeline debugging in isolated environments.
> If you don't want to use one of the dev containers, you can develop the frontend components directly on your local machine.
> To do so, proceed with installing the necessary dependencies.
We use **pnpm** as package manager and **Turbo** for build orchestration. Use angular-eslint/Prettier for linting/formatting.
VSCode users, check out [this ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [this Prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) to fix lint and formatting issues during development.
The commands in this section are tested against the following software versions: The commands in this section are tested against the following software versions:
- [Docker version 20.10.17](https://docs.docker.com/engine/install/) - [Docker version 20.10.17](https://docs.docker.com/engine/install/)
- [Node version v16.17.0](https://nodejs.org/en/download/) - [Node version v20.x](https://nodejs.org/en/download/)
- [npm version 8.18.0](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) - [pnpm version 9.x](https://pnpm.io/installation)
- [Cypress runtime dependencies](https://docs.cypress.io/guides/continuous-integration/introduction#Dependencies)
To run tests with Cypress, ensure you have installed the required [Cypress runtime dependencies](https://docs.cypress.io/guides/continuous-integration/introduction#Dependencies)
<details> <details>
<summary>Note for WSL2 on Windows 10</summary> <summary>Note for WSL2 on Windows 10</summary>
@@ -325,97 +369,165 @@ The commands in this section are tested against the following software versions:
4. When starting XLaunch, make sure to disable access control 4. When starting XLaunch, make sure to disable access control
</details> </details>
### <a name="contribute-login"></a>Contribute to Login
The Login UI is a Next.js application that provides the user interface for authentication flows.
It's located in the `apps/login` directory and uses pnpm and Turbo for development.
To start developing the login, make sure your system has the [required system dependencies](frontend-dev-requirements) installed.
#### Development Setup
```bash
# Start from the root of the repository
# Start the database and Zitadel backend
docker compose --file ./apps/login/acceptance/docker-compose.yaml up --detach zitadel
# Install dependencies
pnpm install
# Option 1: Run login development server with Turbo (recommended)
pnpm turbo dev --filter=@zitadel/login
# Option 2: Build and serve login (production build)
pnpm turbo build --filter=@zitadel/login
cd ./login && pnpm start
```
The login UI is available at http://localhost:3000.
#### Login Architecture
The login application consists of multiple packages:
- `@zitadel/login` - Main Next.js application
- `@zitadel/client` - TypeScript client library for Zitadel APIs
- `@zitadel/proto` - Protocol buffer definitions and generated code
The build process uses Turbo to orchestrate dependencies:
1. Proto generation (`@zitadel/proto#generate`)
2. Client library build (`@zitadel/client#build`)
3. Login application build (`@zitadel/login#build`)
#### Pass Quality Checks
Reproduce the pipelines linting and testing for the login.
```bash
pnpm turbo quality --filter=./apps/login/* --filter=./packages/*
```
Fix the [quality checks](troubleshoot-frontend), add new checks that cover your changes and mark your pull request as ready for review when the pipeline checks pass.
### <a name="contribute-console"></a>Contribute to Console
To start developing the console, make sure your system has the [required system dependencies](frontend-dev-requirements) installed.
Then, you need to decide which Zitadel instance you would like to target.
- The easiest starting point is to [configure your environment](console-dev-existing-zitadel) to use a [Zitadel cloud](https://zitadel.com) instance.
- Alternatively, you can [start a local Zitadel instance from scratch and develop against it](console-dev-local-zitadel).
#### <a name="console-dev-existing-zitadel"></a>Develop against an already running Zitadel instance
By default, `pnpm dev --filter=console` targets a Zitadel API running at http://localhost:8080.
To change this, export the link to your environment.json in your environment variables.
```bash
export ENVIRONMENT_JSON_URL=https://my-cloud-instance-abcdef.us1.zitadel.cloud/ui/console/assets/environment.json
```
Proceed [with configuring your console redirect URIs](console-redirect).
#### <a name="console-dev-local-zitadel"></a>Develop against a local Zitadel instance from scratch
By executing the commands from this section, you run everything you need to develop the console locally.
Using [Docker Compose](https://docs.docker.com/compose/), you run [PostgreSQL](https://www.postgresql.org/download/) and the [latest release of Zitadel](https://github.com/zitadel/zitadel/releases/latest) on your local machine.
You use the Zitadel container as backend for your console.
Run the database and the latest backend locally. Run the database and the latest backend locally.
```bash ```bash
# Change to the console directory # Start from the root of the repository
cd ./console
# You just need the db and the zitadel services to develop the console against. # You just need the db and the zitadel services to develop the console against.
docker compose --file ../e2e/docker-compose.yaml up --detach zitadel docker compose --file ./e2e/docker-compose.yaml up --detach zitadel
``` ```
When the backend is ready, you have the latest zitadel exposed at http://localhost:8080. When Zitadel accepts traffic, navigate to http://localhost:8080/ui/console/projects?login_hint=zitadel-admin@zitadel.localhost and log in with _Password1!_.
You can now run a local development server with live code reloading at http://localhost:4200.
To allow console access via http://localhost:4200, you have to configure the ZITADEL backend.
1. Navigate to <http://localhost:8080/ui/console/projects>. Proceed [with configuring your console redirect URIs](console-redirect).
2. When prompted, login with _zitadel-admin@<span because="breaks the mailto"></span>zitadel.localhost_ and _Password1!_
3. Select the _ZITADEL_ project. #### <a name="console-redirect"></a> Configure Console redirect URI
To allow console access via http://localhost:4200, you have to configure the Zitadel backend.
1. Navigate to /ui/console/projects in your target Zitadel instance.
3. Select the _Zitadel_ project.
4. Select the _Console_ application. 4. Select the _Console_ application.
5. Select _Redirect Settings_ 5. Select _Redirect Settings_
6. Add _http://<span because="breaks the link"></span>localhost:4200/auth/callback_ to the _Redirect URIs_ 6. Add _http://<span because="breaks the link"></span>localhost:4200/auth/callback_ to the _Redirect URIs_
7. Add _http://<span because="breaks the link"></span>localhost:4200/signedout_ to the _Post Logout URIs_ 7. Add _http://<span because="breaks the link"></span>localhost:4200/signedout_ to the _Post Logout URIs_
8. Select the _Save_ button 8. Select the _Save_ button
You can run the local console development server now. #### Develop
Run the local console development server.
```bash ```bash
# Install npm dependencies # Install dependencies (from repository root)
yarn install pnpm install
# Generate source files from Protos # Option 1: Run console development server with live reloading and dependency rebuilds
yarn generate pnpm turbo dev --filter=console
# Start the server # Option 2: Build and serve console (production build)
yarn start pnpm turbo build --filter=console
pnpm turbo serve --filter=console
# If you don't want to develop against http://localhost:8080, you can use another environment
ENVIRONMENT_JSON_URL=https://my-cloud-instance-abcdef.zitadel.cloud/ui/console/assets/environment.json yarn start
``` ```
Navigate to http://localhost:4200/. Navigate to http://localhost:4200/.
Make some changes to the source code and see how the browser is automatically updated. Make some changes to the source code and see how the browser is automatically updated.
After making changes to the code, you should run the end-to-end-tests.
Open another shell. #### Pass Quality Checks
Reproduce the pipelines linting and testing for the console.
```bash ```bash
# Reformat your console code pnpm turbo quality --filter=console --filter=e2e
yarn lint:fix
# Change to the e2e directory
cd .. && cd e2e/
# If you made changes in the e2e directory, make sure you reformat the files here too
npm run lint:fix
# Install npm dependencies
npm install
# Run all e2e tests
npm run e2e:angular -- --headed
``` ```
You can also open the test suite interactively for fast feedback on specific tests. Fix the [quality checks](troubleshoot-frontend), add new checks that cover your changes and mark your pull request as ready for review when the pipeline checks pass.
### <a name="contribute-docs"></a>Contribute to Docs
Project documentation is made with Docusaurus and is located under [./docs](./docs). The documentation uses **pnpm** and **Turbo** for development and build processes.
#### Local Development
```bash ```bash
# Run tests interactively # Install dependencies (from repository root)
npm run open:angular pnpm install
# Option 1: Run docs development server with Turbo (recommended)
pnpm turbo dev --filter=zitadel-docs
# Option 2: Build and serve docs (production build)
pnpm turbo build --filter=zitadel-docs
cd ./docs && pnpm serve
``` ```
If you also make [changes to the backend code](#backend--login), you can run the test against your locally built backend code and frontend server The docs build process automatically:
```bash 1. Downloads required protoc plugins
npm run open:golangangular 2. Generates gRPC documentation from proto files
npm run e2e:golangangular 3. Generates API documentation from OpenAPI specs
``` 4. Copies configuration files
5. Builds the Docusaurus site
When you are happy with your changes, you can format your code and cleanup your environment #### Local testing
```bash The documentation server will be available at http://localhost:3000 with live reload for fast development feedback.
# Stop and remove the docker containers for zitadel and the database
docker compose down
```
## Contribute docs #### Style guide
Project documentation is made with docusaurus and is located under [./docs](./docs).
### Local testing
Please refer to the [README](./docs/README.md) for more information and local testing.
### Style guide
- **Code with variables**: Make sure that code snippets can be used by setting environment variables, instead of manually replacing a placeholder. - **Code with variables**: Make sure that code snippets can be used by setting environment variables, instead of manually replacing a placeholder.
- **Embedded files**: When embedding mdx files, make sure the template ist prefixed by "\_" (lowdash). The content will be rendered inside the parent page, but is not accessible individually (eg, by search). - **Embedded files**: When embedding mdx files, make sure the template ist prefixed by "\_" (lowdash). The content will be rendered inside the parent page, but is not accessible individually (eg, by search).
@@ -431,14 +543,54 @@ The style guide covers a lot of material, so their [highlights](https://develope
- Use active voice: make clear who's performing the action. - Use active voice: make clear who's performing the action.
- Use descriptive link text. - Use descriptive link text.
### Docs pull request #### Docs pull request
When making a pull request use `docs(<scope>): <short summary>` as title for the semantic release. When making a pull request use `docs(<scope>): <short summary>` as title for the semantic release.
Scope can be left empty (omit the brackets) or refer to the top navigation sections. Scope can be left empty (omit the brackets) or refer to the top navigation sections.
## Contribute internationalization #### Pass Quality Checks
ZITADEL loads translations from four files: Reproduce the pipelines linting checks for the docs.
```bash
pnpm turbo quality --filter=docs
```
Fix the [quality checks](troubleshoot-frontend), add new checks that cover your changes and mark your pull request as ready for review when the pipeline checks pass.
### <a name="troubleshoot-frontend"></a>Troubleshoot Frontend Quality Checks
To debug and fix failing tasks, execute them individually using the `--filter` flag.
We recommend to use [one of the dev containers](dev-containers) to reproduce pipeline issues.
```bash
# to reproduce linting error in the console:
pnpm lint --filter=console
# To fix them:
pnpm lint:fix --filter=console
```
More tasks that are runnable on-demand.
Some tasks have variants like `pnpm test:e2e:angulargolang`,
others support arguments and flags like `pnpm test:integration run --spec apps/login/integration/integration/login.cy.ts`.
For the turbo commands, check your options with `pnpm turbo --help`
| Command | Description | Example |
| ------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm turbo run generate` | Generate stubs from Proto files | Generate API docs: `pnpm turbo run generate --filter zitadel-docs` |
| `pnpm turbo build` | Build runnable JavaScript code | Regenerate the proto stubs and build the @zitadel/client package: `pnpm turbo build --filter @zitadel/client` |
| `pnpm turbo quality` | Reproduce the pipeline quality checks | Run login-related quality checks `pnpm turbo quality --filter './apps/login/*' --filter './packages/*'` |
| `pnpm turbo lint` | Check linting issues | Check login-related linting issues for differences with main `pnpm turbo lint --filter=[main...HEAD] --filter .'/apps/login/**/*' --filter './packages/*'` |
| `pnpm turbo lint:fix` | Fix linting issues | Fix console-relevant linting issues `pnpm turbo lint:fix --filter console --filter './packages/*' --filter zitadel-e2e` |
| `pnpm turbo test:unit` | Run unit tests. Rerun on file changes | Run unit tests in all packages in and watch for file changes `pnpm turbo watch test:unit` |
| `pnpm turbo test:e2e` | Run the Cypress CLI for console e2e tests | Test interactively against the console in a local dev server and Zitadel in a container: `pnpm turbo test:e2e:angular open` |
| `pnpm turbo down` | Remove containers and volumes | Shut down containers from the integration test setup `pnpm turbo down` |
| `pnpm turbo clean` | Remove downloaded dependencies and other generated files | Remove generated docs `pnpm turbo clean --filter zitadel-docs` |
## <a name="contribute-translations"></a>Contribute Translations
Zitadel loads translations from four files:
- [Console texts](./console/src/assets/i18n) - [Console texts](./console/src/assets/i18n)
- [Login interface](./internal/api/ui/login/static/i18n) - [Login interface](./internal/api/ui/login/static/i18n)
@@ -450,12 +602,13 @@ Please make sure that the languages within the files remain in their own languag
If you have added support for a new language, please also ensure that it is added in the list of languages in all the other language files. If you have added support for a new language, please also ensure that it is added in the list of languages in all the other language files.
You also have to add some changes to the following files: You also have to add some changes to the following files:
- [Register Local File](./console/src/app/app.module.ts) - [Register Local File](./console/src/app/app.module.ts)
- [Add Supported Language](./console/src/app/utils/language.ts) - [Add Supported Language](./console/src/app/utils/language.ts)
- [Customized Text Docs](./docs/docs/guides/manage/customize/texts.md) - [Customized Text Docs](./docs/docs/guides/manage/customize/texts.md)
- [Add language option](./internal/api/ui/login/static/templates/external_not_found_option.html) - [Add language option](./internal/api/ui/login/static/templates/external_not_found_option.html)
## Want to start ZITADEL? ## Want to start Zitadel?
You can find an installation guide for all the different environments here: You can find an installation guide for all the different environments here:
[https://zitadel.com/docs/self-hosting/deploy/overview](https://zitadel.com/docs/self-hosting/deploy/overview) [https://zitadel.com/docs/self-hosting/deploy/overview](https://zitadel.com/docs/self-hosting/deploy/overview)
@@ -466,14 +619,14 @@ You can find an installation guide for all the different environments here:
## Product management ## Product management
The ZITADEL Team works with an agile product management methodology. The Zitadel Team works with an agile product management methodology.
You can find all the issues prioritized and ordered in the [product board](https://github.com/orgs/zitadel/projects/2/views/1). You can find all the issues prioritized and ordered in the [product board](https://github.com/orgs/zitadel/projects/2/views/1).
### Sprint ### Sprint
We want to deliver a new release every second week. So we plan everything in two-week sprints. We want to deliver a new release every second week. So we plan everything in two-week sprints.
Each Tuesday we estimate new issues and on Wednesday the last sprint will be reviewed and the next one will be planned. Each Tuesday we estimate new issues and on Wednesday the last sprint will be reviewed and the next one will be planned.
After a sprint ends a new version of ZITADEL will be released, and publish to [ZITADEL Cloud](https://zitadel.cloud) the following Monday. After a sprint ends a new version of Zitadel will be released, and publish to [Zitadel Cloud](https://zitadel.cloud) the following Monday.
If there are some critical or urgent issues we will have a look at it earlier, than the two weeks. If there are some critical or urgent issues we will have a look at it earlier, than the two weeks.
To show the community the needed information, each issue gets attributes and labels. To show the community the needed information, each issue gets attributes and labels.
@@ -493,15 +646,16 @@ The state should reflect the progress of the issue and what is going on right no
- **🔖 Ready**: The issue is ready to take into a sprint. Difference to "prioritized..." is that the complexity is defined by the team. - **🔖 Ready**: The issue is ready to take into a sprint. Difference to "prioritized..." is that the complexity is defined by the team.
- **📋 Sprint backlog**: The issue is scheduled for the current sprint. - **📋 Sprint backlog**: The issue is scheduled for the current sprint.
- **🏗 In progress**: Someone is working on this issue right now. The issue will get an assignee as soon as it is in progress. - **🏗 In progress**: Someone is working on this issue right now. The issue will get an assignee as soon as it is in progress.
- **❌ Blocked**: The issue is blocked until another issue is resolved/done.
- **👀 In review**: The issue is in review. Please add someone to review your issue or let us know that it is ready to review with a comment on your pull request. - **👀 In review**: The issue is in review. Please add someone to review your issue or let us know that it is ready to review with a comment on your pull request.
- **✅ Done**: The issue is implemented and merged to main. - **✅ Done**: The issue is implemented and merged to main.
#### Priority #### Priority
Priority shows you the priority the ZITADEL team has given this issue. In general the higher the demand from customers and community for the feature, the higher the priority. Priority shows you the priority the Zitadel team has given this issue. In general the higher the demand from customers and community for the feature, the higher the priority.
- **🌋 Critical**: This is a security issue or something that has to be fixed urgently, because the software is not usable or highly vulnerable. - **🌋 Critical**: This is a security issue or something that has to be fixed urgently, because the software is not usable or highly vulnerable.
- **🏔 High**: These are the issues the ZITADEL team is currently focusing on and will be implemented as soon as possible. - **🏔 High**: These are the issues the Zitadel team is currently focusing on and will be implemented as soon as possible.
- **🏕 Medium**: After all the high issues are done these will be next. - **🏕 Medium**: After all the high issues are done these will be next.
- **🏝 Low**: This is low in priority and will probably not be implemented in the next time or just if someone has some time in between. - **🏝 Low**: This is low in priority and will probably not be implemented in the next time or just if someone has some time in between.
@@ -516,18 +670,18 @@ Everything that is higher than 8 should be split in smaller parts.
There are a few general labels that don't belong to a specific category. There are a few general labels that don't belong to a specific category.
- **good first issue**: This label shows contributors, that it is an easy entry point to start developing on ZITADEL. - **good first issue**: This label shows contributors, that it is an easy entry point to start developing on Zitadel.
- **help wanted**: The author is seeking help on this topic, this may be from an internal ZITADEL team member or external contributors. - **help wanted**: The author is seeking help on this topic, this may be from an internal Zitadel team member or external contributors.
#### Category #### Category
The category shows which part of ZITADEL is affected. The category shows which part of Zitadel is affected.
- **category: backend**: The backend includes the APIs, event store, command and query side. This is developed in golang. - **category: backend**: The backend includes the APIs, event store, command and query side. This is developed in golang.
- **category: ci**: ci is all about continues integration and pipelines. - **category: ci**: ci is all about continues integration and pipelines.
- **category: design**: All about the ux/ui of ZITADEL - **category: design**: All about the ux/ui of Zitadel
- **category: docs**: Adjustments or new documentations, this can be found in the docs folder. - **category: docs**: Adjustments or new documentations, this can be found in the docs folder.
- **category: frontend**: The frontend concerns on the one hand the ZITADEL management console (Angular) and on the other hand the login (gohtml) - **category: frontend**: The frontend concerns on the one hand the Zitadel management console (Angular) and on the other hand the login (gohtml)
- **category: infra**: Infrastructure does include many different parts. E.g Terraform-provider, docker, metrics, etc. - **category: infra**: Infrastructure does include many different parts. E.g Terraform-provider, docker, metrics, etc.
- **category: translation**: Everything concerning translations or new languages - **category: translation**: Everything concerning translations or new languages

View File

@@ -23,6 +23,7 @@ The following files and directories, including their subdirectories, are license
``` ```
login/ login/
clients/
``` ```
## Community Contributions ## Community Contributions

View File

@@ -27,7 +27,7 @@ docker_image:
else \ else \
echo "Reusing precompiled zitadel binary"; \ echo "Reusing precompiled zitadel binary"; \
fi fi
DOCKER_BUILDKIT=1 docker build -f build/Dockerfile -t $(ZITADEL_IMAGE) . DOCKER_BUILDKIT=1 docker build -f build/zitadel/Dockerfile -t $(ZITADEL_IMAGE) .
.PHONY: compile_pipeline .PHONY: compile_pipeline
compile_pipeline: console_move compile_pipeline: console_move
@@ -97,18 +97,11 @@ console_move:
.PHONY: console_dependencies .PHONY: console_dependencies
console_dependencies: console_dependencies:
cd console && \ npx pnpm install --frozen-lockfile --filter=./console
yarn install --immutable
.PHONY: console_client
console_client:
cd console && \
yarn generate
.PHONY: console_build .PHONY: console_build
console_build: console_dependencies console_client console_build: console_dependencies
cd console && \ npx pnpm turbo build --filter=./console
yarn build
.PHONY: clean .PHONY: clean
clean: clean:
@@ -166,8 +159,7 @@ core_integration_test: core_integration_server_start core_integration_test_packa
.PHONY: console_lint .PHONY: console_lint
console_lint: console_lint:
cd console && \ npx pnpm turbo lint --filter=./console
yarn lint
.PHONY: core_lint .PHONY: core_lint
core_lint: core_lint:
@@ -179,14 +171,21 @@ core_lint:
.PHONY: login_pull .PHONY: login_pull
login_pull: login_ensure_remote login_pull: login_ensure_remote
@echo "Pulling changes from the 'login' subtree on remote $(LOGIN_REMOTE_NAME) branch $(LOGIN_REMOTE_BRANCH)" @echo "Pulling changes from the 'apps/login' subtree on remote $(LOGIN_REMOTE_NAME) branch $(LOGIN_REMOTE_BRANCH)"
git fetch $(LOGIN_REMOTE_NAME) git fetch $(LOGIN_REMOTE_NAME) $(LOGIN_REMOTE_BRANCH)
git subtree pull --prefix=login $(LOGIN_REMOTE_NAME) $(LOGIN_REMOTE_BRANCH) git merge -s ours --allow-unrelated-histories $(LOGIN_REMOTE_NAME)/$(LOGIN_REMOTE_BRANCH) -m "Synthetic merge to align histories"
git push
.PHONY: login_push .PHONY: login_push
login_push: login_ensure_remote login_push: login_ensure_remote
@echo "Pushing changes to the 'login' subtree on remote $(LOGIN_REMOTE_NAME) branch $(LOGIN_REMOTE_BRANCH)" @echo "Pushing changes to the 'apps/login' subtree on remote $(LOGIN_REMOTE_NAME) branch $(LOGIN_REMOTE_BRANCH)"
git subtree push --prefix=login $(LOGIN_REMOTE_NAME) $(LOGIN_REMOTE_BRANCH) git subtree split --prefix=apps/login -b login-sync-tmp
git checkout login-sync-tmp
git fetch $(LOGIN_REMOTE_NAME) main
git merge -s ours --allow-unrelated-histories $(LOGIN_REMOTE_NAME)/main -m "Synthetic merge to align histories"
git push $(LOGIN_REMOTE_NAME) login-sync-tmp:$(LOGIN_REMOTE_BRANCH)
git checkout -
git branch -D login-sync-tmp
login_ensure_remote: login_ensure_remote:
@if ! git remote get-url $(LOGIN_REMOTE_NAME) > /dev/null 2>&1; then \ @if ! git remote get-url $(LOGIN_REMOTE_NAME) > /dev/null 2>&1; then \
@@ -195,22 +194,3 @@ login_ensure_remote:
else \ else \
echo "Remote $(LOGIN_REMOTE_NAME) already exists."; \ echo "Remote $(LOGIN_REMOTE_NAME) already exists."; \
fi fi
@if [ ! -d login ]; then \
echo "Adding subtree for 'login' from branch $(LOGIN_REMOTE_BRANCH)"; \
git subtree add --prefix=login $(LOGIN_REMOTE_NAME) $(LOGIN_REMOTE_BRANCH); \
else \
echo "Subtree 'login' already exists."; \
fi
export LOGIN_DIR := ./login/
export LOGIN_BAKE_CLI_ADDITIONAL_ARGS := --set login-*.context=./login/ --file ./docker-bake.hcl
export ZITADEL_TAG ?= $(ZITADEL_IMAGE)
include login/Makefile
# Intentional override of login_test_acceptance_build
login_test_acceptance_build: docker_image
@echo "Building login test acceptance environment with the local zitadel image"
$(MAKE) login_test_acceptance_build_compose login_test_acceptance_build_bake
login_dev: docker_image typescript_generate login_test_acceptance_build_compose login_test_acceptance_cleanup login_test_acceptance_setup_dev
@echo "Starting login test environment with the local zitadel image"

21
apps/login/.dockerignore Normal file
View File

@@ -0,0 +1,21 @@
*
!constants
!scripts
!src
!public
!locales
!next.config.mjs
!next-env-vars.d.ts
!next-env.d.ts
!tailwind.config.js
!tsconfig.json
!package.json
!pnpm-lock.yaml
**/*.md
**/*.png
**/node_modules
**/.turbo
**/*.test.ts
**/*.test.tsx

5
apps/login/.env.test Normal file
View File

@@ -0,0 +1,5 @@
NEXT_PUBLIC_BASE_PATH="/ui/v2/login"
ZITADEL_API_URL=http://mock-zitadel:22222
ZITADEL_SERVICE_USER_TOKEN="yolo"
EMAIL_VERIFICATION=true
DEBUG=true

24
apps/login/.eslintrc.cjs Normal file
View File

@@ -0,0 +1,24 @@
module.exports = {
parser: "@typescript-eslint/parser",
extends: ["next", "prettier"],
plugins: ["@typescript-eslint"],
rules: {
"@next/next/no-html-link-for-pages": "off",
"@next/next/no-img-element": "off",
"react/no-unescaped-entities": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_" ,
varsIgnorePattern: "^_" ,
}],
"no-undef": "off",
},
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
project: "./tsconfig.json",
},
};

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -0,0 +1,39 @@
name: Auto-close PRs and guide to correct repo
on:
workflow_dispatch:
pull_request_target:
types: [opened]
jobs:
auto-close:
runs-on: ubuntu-latest
if: github.repository_id == '622995060' && github.ref_name != 'mirror-zitadel-repo'
steps:
- name: Comment and close PR
uses: actions/github-script@v7
with:
script: |
const message = `
👋 **Thanks for your contribution @${{ github.event.pull_request.user.login }}!**
This repository \`${{ github.repository }}\` is a read-only mirror of the git subtree at [\`zitadel/zitadel/login\`](https://github.com/zitadel/zitadel).
Therefore, we close this pull request automatically.
Your changes are not lost. Submitting them to the main repository is easy:
1. [Fork zitadel/zitadel](https://github.com/zitadel/zitadel/fork)
2. Clone your Zitadel fork \`git clone https://github.com/<your-owner>/zitadel.git\`
3. Change directory to your Zitadel forks root.
4. Pull your changes into the Zitadel fork by running \`make login_pull LOGIN_REMOTE_URL=https://github.com/<your-owner>/typescript.git LOGIN_REMOTE_BRANCH=<your-typescript-fork-branch>\`.
5. Push your changes and [open a pull request to zitadel/zitadel](https://github.com/zitadel/zitadel/compare)
`.trim();
await github.rest.issues.createComment({
...context.repo,
issue_number: context.issue.number,
body: message
});
await github.rest.pulls.update({
...context.repo,
pull_number: context.issue.number,
state: "closed"
});

View File

@@ -1,3 +1,8 @@
custom-config.js
.env*.local
standalone
tsconfig.tsbuildinfo
.DS_Store .DS_Store
node_modules node_modules
.turbo .turbo
@@ -7,12 +12,5 @@ dist
dist-ssr dist-ssr
*.local *.local
.env .env
server/dist
public/dist
.vscode .vscode
.idea
.vercel
.env*.local
/blob-report/ /blob-report/
/out
/docker

View File

@@ -0,0 +1,5 @@
*
!constants
!src
!locales
!scripts/healthcheck.js

View File

@@ -20,6 +20,18 @@ you have [more contact options on our Website](https://zitadel.com/contact).
## Pull Requests ## Pull Requests
The repository zitadel/typescript is a read-only mirror of the git subtree at zitadel/zitadel/login.
To submit changes, please open a Pull Request [in the zitadel/zitadel repository](https://github.com/zitadel/zitadel/compare).
If you already made changes based on the zitadel/typescript repository, these changes are not lost.
Submitting them to the main repository is easy:
1. [Fork zitadel/zitadel](https://github.com/zitadel/zitadel/fork)
1. Clone your Zitadel fork git clone https://github.com/<your-owner>/zitadel.git
1. Change directory to your Zitadel forks root.
1. Pull your changes into the Zitadel fork by running make login_pull LOGIN_REMOTE_URL=https://github.com/<your-owner>/typescript.git LOGIN_REMOTE_BRANCH=<your-typescript-fork-branch>.
1. Push your changes and [open a pull request to zitadel/zitadel](https://github.com/zitadel/zitadel/compare)
Please consider the following guidelines when creating a pull request. Please consider the following guidelines when creating a pull request.
- The latest changes are always in `main`, so please make your pull request against that branch. - The latest changes are always in `main`, so please make your pull request against that branch.

36
apps/login/Dockerfile Normal file
View File

@@ -0,0 +1,36 @@
FROM node:20-alpine AS base
FROM base AS build
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && COREPACK_ENABLE_DOWNLOAD_PROMPT=0 corepack prepare pnpm@9.1.2 --activate && \
apk update && apk add --no-cache && \
rm -rf /var/cache/apk/*
WORKDIR /app
COPY pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm fetch --frozen-lockfile
COPY package.json ./
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store pnpm install --frozen-lockfile --prod
COPY . .
RUN pnpm build:login:standalone
FROM scratch AS build-out
COPY --from=build /app/.next/standalone /
COPY --from=build /app/.next/static /.next/static
COPY --from=build /app/public /public
FROM base AS login-standalone
WORKDIR /runtime
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# If /.env-file/.env is mounted into the container, its variables are made available to the server before it starts up.
RUN mkdir -p /.env-file && touch /.env-file/.env && chown -R nextjs:nodejs /.env-file
COPY ./scripts/ ./
COPY --chown=nextjs:nodejs --from=build-out / ./
USER nextjs
ENV HOSTNAME="0.0.0.0"
ENV PORT=3000
# TODO: Check healthy, not ready
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD ["/bin/sh", "-c", "node ./healthcheck.js http://localhost:${PORT}/ui/v2/login/healthy"]
ENTRYPOINT ["./entrypoint.sh"]

View File

@@ -0,0 +1,10 @@
module.exports = {
root: true,
// Use basic ESLint config since the login app has its own detailed config
extends: ["eslint:recommended"],
settings: {
next: {
rootDir: ["apps/*/"],
},
},
};

View File

@@ -2,9 +2,10 @@
"name": "login-test-acceptance", "name": "login-test-acceptance",
"private": true, "private": true,
"scripts": { "scripts": {
"test:acceptance": "dotenv -e ../login/.env.test.local pnpm exec playwright", "test:acceptance": "dotenv -e ../login/.env.test.local playwright",
"test:acceptance:setup": "cd ../.. && make login_test_acceptance_setup_env && NODE_ENV=test pnpm exec turbo run test:acceptance:setup:dev", "test:acceptance:setup": "cd ../.. && make login_test_acceptance_setup_env && NODE_ENV=test turbo run test:acceptance:setup:dev",
"test:acceptance:setup:dev": "cd ../.. && make login_test_acceptance_setup_dev" "test:acceptance:setup:dev": "cd ../.. && make login_test_acceptance_setup_dev",
"clean": "rm -rf .turbo node_modules"
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^9.7.0", "@faker-js/faker": "^9.7.0",
@@ -12,6 +13,7 @@
"@otplib/plugin-crypto": "^12.0.0", "@otplib/plugin-crypto": "^12.0.0",
"@otplib/plugin-thirty-two": "^12.0.0", "@otplib/plugin-thirty-two": "^12.0.0",
"@playwright/test": "^1.52.0", "@playwright/test": "^1.52.0",
"dotenv-cli": "^8.0.0",
"gaxios": "^7.1.0", "gaxios": "^7.1.0",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }

View File

@@ -1,2 +1,3 @@
* *
!.gitignore
!.gitkeep !.gitkeep

View File

@@ -1,2 +1,3 @@
* *
!.gitignore
!.gitkeep !.gitkeep

View File

@@ -1,2 +1,3 @@
* *
!.gitignore
!.gitkeep !.gitkeep

Some files were not shown because too many files have changed in this diff Show More