chore: reproducible pipeline with dev containers (#10305)

# Which Problems Are Solved

- The previous monorepo in monorepo structure for the login app and its
related packages was fragmented, complicated and buggy.
- The process for building and testing the login container was
inconsistent between local development and CI.
- Lack of clear documentation as well as easy and reliable ways for
non-frontend developers to reproduce and fix failing PR checks locally.

# How the Problems Are Solved

- Consolidated the login app and its related npm packages by moving the
main package to `apps/login/apps/login` and merging
`apps/login/packages/integration` and `apps/login/packages/acceptance`
into the main `apps/login` package.
- Migrated from Docker Compose-based test setups to dev container-based
setups, adding support for multiple dev container configurations:
  - `.devcontainer/base`
  - `.devcontainer/turbo-lint-unit`
  - `.devcontainer/turbo-lint-unit-debug`
  - `.devcontainer/login-integration`
  - `.devcontainer/login-integration-debug`
- Added npm scripts to run the new dev container setups, enabling exact
reproduction of GitHub PR checks locally, and updated the pipeline to
use these containers.
- Cleaned up Dockerfiles and docker-bake.hcl files to only build the
production image for the login app.
- Cleaned up compose files to focus on dev environments in dev
containers.
- Updated `CONTRIBUTING.md` with guidance on running and debugging PR
checks locally using the new dev container approach.
- Introduced separate Dockerfiles for the login app to distinguish
between using published client packages and building clients from local
protos.
- Ensured the login container is always built in the pipeline for use in
integration and acceptance tests.
- Updated Makefile and GitHub Actions workflows to use
`--frozen-lockfile` for installing pnpm packages, ensuring reproducible
installs.
- Disabled GitHub release creation by the changeset action.
- Refactored the `/build` directory structure for clarity and
maintainability.
- Added a `clean` command to `docks/package.json`.
- Experimentally added `knip` to the `zitadel-client` package for
improved linting of dependencies and exports.

# Additional Changes

- Fixed Makefile commands for consistency and reliability.
- Improved the structure and clarity of the `/build` directory to
support seamless integration of the login build.
- Enhanced documentation and developer experience for running and
debugging CI checks locally.

# Additional Context

- See updated `CONTRIBUTING.md` for new local development and debugging
instructions.
- These changes are a prerequisite for further improvements to the CI
pipeline and local development workflow.
- Closes #10276
This commit is contained in:
Elio Bischof
2025-07-24 14:22:32 +02:00
committed by GitHub
parent af66c9844a
commit b10455b51f
430 changed files with 2869 additions and 4108 deletions
+99
View File
@@ -0,0 +1,99 @@
"use client";
import { CheckCircleIcon } from "@heroicons/react/24/solid";
import { clsx } from "clsx";
import {
ChangeEvent,
DetailedHTMLProps,
forwardRef,
InputHTMLAttributes,
ReactNode,
} from "react";
export type TextInputProps = DetailedHTMLProps<
InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
> & {
label: string;
suffix?: string;
placeholder?: string;
defaultValue?: string;
error?: string | ReactNode;
success?: string | ReactNode;
disabled?: boolean;
onChange?: (value: ChangeEvent<HTMLInputElement>) => void;
onBlur?: (value: ChangeEvent<HTMLInputElement>) => void;
};
const styles = (error: boolean, disabled: boolean) =>
clsx({
"h-[40px] mb-[2px] rounded p-[7px] bg-input-light-background dark:bg-input-dark-background transition-colors duration-300 grow": true,
"border border-input-light-border dark:border-input-dark-border hover:border-black hover:dark:border-white focus:border-primary-light-500 focus:dark:border-primary-dark-500": true,
"focus:outline-none focus:ring-0 text-base text-black dark:text-white placeholder:italic placeholder-gray-700 dark:placeholder-gray-700": true,
"border border-warn-light-500 dark:border-warn-dark-500 hover:border-warn-light-500 hover:dark:border-warn-dark-500 focus:border-warn-light-500 focus:dark:border-warn-dark-500":
error,
"pointer-events-none text-gray-500 dark:text-gray-800 border border-input-light-border dark:border-input-dark-border hover:border-light-hoverborder hover:dark:border-hoverborder cursor-default":
disabled,
});
// eslint-disable-next-line react/display-name
export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
(
{
label,
placeholder,
defaultValue,
suffix,
required = false,
error,
disabled,
success,
onChange,
onBlur,
...props
},
ref,
) => {
return (
<label className="relative flex flex-col text-12px text-input-light-label dark:text-input-dark-label">
<span
className={`mb-1 leading-3 ${
error ? "text-warn-light-500 dark:text-warn-dark-500" : ""
}`}
>
{label} {required && "*"}
</span>
<input
suppressHydrationWarning
ref={ref}
className={styles(!!error, !!disabled)}
defaultValue={defaultValue}
required={required}
disabled={disabled}
placeholder={placeholder}
autoComplete={props.autoComplete ?? "off"}
onChange={(e) => onChange && onChange(e)}
onBlur={(e) => onBlur && onBlur(e)}
{...props}
/>
{suffix && (
<span className="absolute bottom-[22px] right-[3px] z-30 translate-y-1/2 transform rounded-sm bg-background-light-500 p-2 dark:bg-background-dark-500">
@{suffix}
</span>
)}
<div className="leading-14.5px h-14.5px flex flex-row items-center text-12px text-warn-light-500 dark:text-warn-dark-500">
<span>{error ? error : " "}</span>
</div>
{success && (
<div className="text-md mt-1 flex flex-row items-center text-green-500">
<CheckCircleIcon className="h-4 w-4" />
<span className="ml-1">{success}</span>
</div>
)}
</label>
);
},
);