Commit Graph

95 Commits

Author SHA1 Message Date
neo773
565995e715 security: harden CI against supply-chain attacks (#20476)
- Pin all third-party actions to SHA
- Gate claude.yml triggers to internal authors with Harden-Runner egress
audit
- Ignore fork-PR lifecycle scripts
- Narrow cross-repo dispatch payloads
- Add 7d npm release-age gate
- Add CODEOWNERS on .github/** and .yarnrc.yml

---------

Co-authored-by: prastoin <paul@twenty.com>
2026-05-12 12:20:29 +00:00
Paul Rastoin
1e7c1691f4 [CI] Prevent previous version upgrade sequence mutation (#20075)
# Introduction
Prevent any PR to target a previous already released twenty version by
mistake.

Especially useful for existing opened PR introducing commands into an
upgrade that has just been released leading to a
`TWENTY_CURRENT_VERSION` bump

<img width="3150" height="1158" alt="image"
src="https://github.com/user-attachments/assets/b83d211f-a061-4d63-ae7a-354d7851ec08"
/>

## Bypass
If intentional add `ci:allow-previous-version-upgrade-mutation` label to
the PR and re-run the failed job

<img width="3150" height="1158" alt="image"
src="https://github.com/user-attachments/assets/f94ee630-d87b-4477-9e50-bf6773a8a280"
/>

This will require a brand new ci from a commit introduced after the
label has been added
2026-04-27 11:15:49 +00:00
Félix Malfait
75848ff8ea feat: move admin panel to dedicated /admin-panel GraphQL endpoint (#19852)
## Summary

Splits admin-panel resolvers off the shared `/metadata` GraphQL endpoint
onto a dedicated `/admin-panel` endpoint. The backend plumbing mirrors
the existing `metadata` / `core` pattern (new scope, decorator, module,
factory), and admin types now live in their own
`generated-admin/graphql.ts` on the frontend — dropping 877 lines of
admin noise from `generated-metadata`.

## Why

- **Smaller attack surface on `/metadata`** — every authenticated user
hits that endpoint; admin ops don't belong there.
- **Independent complexity limits and monitoring** per endpoint.
- **Cleaner module boundaries** — admin is a cross-cutting concern that
doesn't match the "shared-schema configuration" meaning of `/metadata`.
- **Deploy / blast-radius isolation** — a broken admin query can't
affect `/metadata`.

Runtime behavior, auth, and authorization are unchanged — this is a
relocation, not a re-permissioning. All existing guards
(`WorkspaceAuthGuard`, `UserAuthGuard`,
`SettingsPermissionGuard(SECURITY)` at class level; `AdminPanelGuard` /
`ServerLevelImpersonateGuard` at method level) remain on
`AdminPanelResolver`.

## What changed

### Backend
- `@AdminResolver()` decorator with scope `'admin'`, naming parallels
`CoreResolver` / `MetadataResolver`.
- `AdminPanelGraphQLApiModule` + `adminPanelModuleFactory` registered at
`/admin-panel`, same Yoga hook set as the metadata factory (Sentry
tracing, error handler, introspection-disabling in prod, complexity
validation).
- Middleware chain on `/admin-panel` is identical to `/metadata`.
- `@nestjs/graphql` patch extended: `resolverSchemaScope?: 'core' |
'metadata' | 'admin'`.
- `AdminPanelResolver` class decorator swapped from
`@MetadataResolver()` to `@AdminResolver()` — no other changes.

### Frontend
- `codegen-admin.cjs` → `src/generated-admin/graphql.ts` (982 lines).
- `codegen-metadata.cjs` excludes admin paths; metadata file shrinks by
877 lines.
- `ApolloAdminProvider` / `useApolloAdminClient` follow the existing
`ApolloCoreProvider` / `useApolloCoreClient` pattern, wired inside
`AppRouterProviders` alongside the core provider.
- 37 admin consumer files migrated: imports switched to
`~/generated-admin/graphql` and `client: useApolloAdminClient()` is
passed to `useQuery` / `useMutation`.
- Three files intentionally kept on `generated-metadata` because they
consume non-admin Documents: `useHandleImpersonate.ts`,
`SettingsAdminApplicationRegistrationDangerZone.tsx`,
`SettingsAdminApplicationRegistrationGeneralToggles.tsx`.

### CI
- `ci-server.yaml` runs all three `graphql:generate` configurations and
diff-checks all three generated dirs.

## Authorization (unchanged, but audited while reviewing)

Every one of the 38 methods on `AdminPanelResolver` has a method-level
guard:
- `AdminPanelGuard` (32 methods) — requires `canAccessFullAdminPanel ===
true`
- `ServerLevelImpersonateGuard` (6 methods: user/workspace lookup + chat
thread views) — requires `canImpersonate === true`

On top of the class-level guards above. No resolver method is accessible
without these flags + `SECURITY` permission in the workspace.

## Test plan

- [ ] Dev server boots; `/graphql`, `/metadata`, `/admin-panel` all
mapped as separate GraphQL routes (confirmed locally during
development).
- [ ] `nx typecheck twenty-server` passes.
- [ ] `nx typecheck twenty-front` passes.
- [ ] `nx lint:diff-with-main twenty-server` and `twenty-front` both
clean.
- [ ] Manual smoke test: log in with a user who has
`canAccessFullAdminPanel=true`, open the admin panel at
`/settings/admin-panel`, verify each tab loads (General, Health, Config
variables, AI, Apps, Workspace details, User details, chat threads).
- [ ] Manual smoke test: log in with a user who has
`canImpersonate=false` and `canAccessFullAdminPanel=false`, hit
`/admin-panel` directly with a raw GraphQL request, confirm permission
error on every operation.
- [ ] Production deploy note: reverse proxy / ingress must route the new
`/admin-panel` path to the Nest server. If the proxy has an explicit
allowlist, infra change required before cutover.

## Follow-ups (out of scope here)

- Consider cutting over the three
`SettingsAdminApplicationRegistration*` components to admin-scope
versions of the app-registration operations so the admin page is fully
on the admin endpoint.
- The `renderGraphiQL` double-assignment in
`admin-panel.module-factory.ts` is copied from
`metadata.module-factory.ts` — worth cleaning up in both.
2026-04-19 20:55:10 +02:00
Paul Rastoin
c99db7d9c6 Fix server-validation ci pending instance command detection (#19558)
https://github.com/twentyhq/twenty/actions/runs/24246052659/job/70792870185
2026-04-10 13:53:56 +00:00
Paul Rastoin
e062343802 Refactor typeorm migration lifecycle and generation (#19275)
# Introduction

Typeorm migration are now associated to a given twenty-version from the
`UPGRADE_COMMAND_SUPPORTED_VERSIONS` that the current twenty core engine
handles

This way when we upgrade we retrieve the migrations that need to be run,
this will be useful for the cross-version incremental upgrade so we
preserve sequentiality

## What's new

To generate
```sh
npx nx database:migrate:generate twenty-server -- --name add-index-to-users
```

To apply all
```sh
npx nx database:migrate twenty-server
```

## Next
Introduce slow and fast typeorm migration in order to get rid of the
save point pattern in our code base
Create a clean and dedicated `InstanceUpgradeService` abstraction
2026-04-06 07:11:47 +00:00
Charles Bochet
ac8e0d4217 Replace twentycrm/twenty-postgres-spilo with official postgres:16 in CI (#19182)
## Summary
- Replaces `twentycrm/twenty-postgres-spilo` with the official
`postgres:16` image across all 7 CI workflow files
- Removes Docker Hub `credentials` blocks from all service containers
(postgres, redis, clickhouse)
- Removes the `Login to Docker Hub` step from the breaking changes
workflow

## Context
Fork PRs cannot access repository secrets/variables, causing `${{
vars.DOCKERHUB_USERNAME }}` and `${{ secrets.DOCKERHUB_PASSWORD }}` to
resolve to empty strings. GitHub Actions rejects empty credential values
at template validation time, failing the job before any step runs.

The custom spilo image was the original reason credentials were needed
(to avoid Docker Hub rate limits on non-official images). The only
Postgres extensions required in CI (`uuid-ossp`, `unaccent`) are built
into the official `postgres:16` image. Official Docker Hub images have
significantly higher pull rate limits and don't require authentication.
2026-03-31 21:41:42 +02:00
Charles Bochet
191a277ddf fix: invalidate rolesPermissions cache + add Docker Hub auth to CI (#19044)
## Summary

### Cache invalidation fix
- After migrating object/field permissions to syncable entities (#18609,
#18751, #18567), changes to `flatObjectPermissionMaps`,
`flatFieldPermissionMaps`, or `flatPermissionFlagMaps` no longer
triggered `rolesPermissions` cache invalidation
- This caused stale permission data to be served, leading to flaky
`permissions-on-relations` integration tests and potentially incorrect
permission enforcement in production after object permission upserts
- Adds the three permission-related flat map keys to the condition that
triggers `rolesPermissions` cache recomputation in
`WorkspaceMigrationRunnerService.getLegacyCacheInvalidationPromises`
- Clears memoizer after recomputation to prevent concurrent
`getOrRecompute` calls from caching stale data

### Docker Hub rate limit fix
- CI service containers (postgres, redis, clickhouse) and `docker
run`/`docker build` steps were pulling from Docker Hub
**unauthenticated**, hitting the 100-pull-per-6-hour rate limit on
shared GitHub-hosted runner IPs
- Adds `credentials` blocks to all service container definitions and
`docker/login-action` steps before `docker run`/`docker compose`
commands
- Uses `vars.DOCKERHUB_USERNAME` + `secrets.DOCKERHUB_PASSWORD`
(matching the existing twenty-infra convention)
- Affected workflows: ci-server, ci-merge-queue, ci-breaking-changes,
ci-zapier, ci-sdk, ci-create-app-e2e, ci-website,
ci-test-docker-compose, preview-env-keepalive, spawn-twenty-docker-image
action
2026-03-27 17:32:53 +01:00
Paul Rastoin
281bb6d783 Guard yarn database:migrate:prod (#19008)
## Motivations
A lot of self hosters hands up using the `yarn database:migrated:prod`
either manually or through AI assisted debug while they try to upgrade
an instance while their workspace is still blocked in a previous one
Leading to their whole database permanent corruption

## What happened
Replaced the direct call the the typeorm cli to a command calling it
programmatically, adding a layer of security in case a workspace seems
to be blocked in a previous version than the one just before the one
being installed ( e.g 1.0 when you try to upgrade from 1.1 to 1.2 )

For our cloud we still need a way to bypass this security explaining the
-f flag

## Remark
Centralized this logic and refactored creating new services
`WorkspaceVersionService` and `CoreEngineVersionService` that will
become useful for the upcoming upgrade refactor

Related to https://github.com/twentyhq/twenty-infra/pull/529
2026-03-27 14:39:18 +00:00
Paul Rastoin
4ea2e32366 Refactor twenty client sdk provisioning for logic function and front-component (#18544)
## 1. The `twenty-client-sdk` Package (Source of Truth)

The monorepo package at `packages/twenty-client-sdk` ships with:
- A **pre-built metadata client** (static, generated from a fixed
schema)
- A **stub core client** that throws at runtime (`CoreApiClient was not
generated...`)
- Both ESM (`.mjs`) and CJS (`.cjs`) bundles in `dist/`
- A `package.json` with proper `exports` map for
`twenty-client-sdk/core`, `twenty-client-sdk/metadata`, and
`twenty-client-sdk/generate`

## 2. Generation & Upload (Server-Side, at Migration Time)

**When**: `WorkspaceMigrationRunnerService.run()` executes after a
metadata schema change.

**What happens in `SdkClientGenerationService.generateAndStore()`**:
1. Copies the stub `twenty-client-sdk` package from the server's assets
(resolved via `SDK_CLIENT_PACKAGE_DIRNAME` — from
`dist/assets/twenty-client-sdk/` in production, or from `node_modules`
in dev)
2. Filters out `node_modules/` and `src/` during copy — only
`package.json` + `dist/` are kept (like an npm publish)
3. Calls `replaceCoreClient()` which uses `@genql/cli` to introspect the
**application-scoped** GraphQL schema and generates a real
`CoreApiClient`, then compiles it to ESM+CJS and overwrites
`dist/core.mjs` and `dist/core.cjs`
4. Archives the **entire package** (with `package.json` + `dist/`) into
`twenty-client-sdk.zip`
5. Uploads the single archive to S3 under
`FileFolder.GeneratedSdkClient`
6. Sets `isSdkLayerStale = true` on the `ApplicationEntity` in the
database

## 3. Invalidation Signal

The `isSdkLayerStale` boolean column on `ApplicationEntity` is the
invalidation mechanism:
- **Set to `true`** by `generateAndStore()` after uploading a new client
archive
- **Checked** by both logic function drivers before execution — if
`true`, they rebuild their local layer
- **Set back to `false`** by `markSdkLayerFresh()` after the driver has
successfully consumed the new archive

Default is `false` so existing applications without a generated client
aren't affected.

## 4a. Logic Functions — Local Driver

**`ensureSdkLayer()`** is called before every execution:
1. Checks if the local SDK layer directory exists AND `isSdkLayerStale`
is `false` → early return
2. Otherwise, cleans the local layer directory
3. Calls `downloadAndExtractToPackage()` which streams the zip from S3
directly to disk and extracts the full package into
`<tmpdir>/sdk/<workspaceId>-<appId>/node_modules/twenty-client-sdk/`
4. Calls `markSdkLayerFresh()` to set `isSdkLayerStale = false`

**At execution time**, `assembleNodeModules()` symlinks everything from
the deps layer's `node_modules/` **except** `twenty-client-sdk`, which
is symlinked from the SDK layer instead. This ensures the logic
function's `import ... from 'twenty-client-sdk/core'` resolves to the
generated client.

## 4b. Logic Functions — Lambda Driver

**`ensureSdkLayer()`** is called during `build()`:
1. Checks if `isSdkLayerStale` is `false` and an existing Lambda layer
ARN exists → early return
2. Otherwise, deletes all existing layer versions for this SDK layer
name
3. Calls `downloadArchiveBuffer()` to get the raw zip from S3 (no disk
extraction)
4. Calls `reprefixZipEntries()` which streams the zip entries into a
**new zip** with the path prefix
`nodejs/node_modules/twenty-client-sdk/` — this is the Lambda layer
convention path. All done in memory, no disk round-trip
5. Publishes the re-prefixed zip as a new Lambda layer via
`publishLayer()`
6. Calls `markSdkLayerFresh()`

**At function creation**, the Lambda is created with **two layers**:
`[depsLayerArn, sdkLayerArn]`. The SDK layer is listed last so it
overwrites the stub `twenty-client-sdk` from the deps layer (later
layers take precedence in Lambda's `/opt` merge).

## 5. Front Components

Front components are built by `app:build` with `twenty-client-sdk/core`
and `twenty-client-sdk/metadata` as **esbuild externals**. The stored
`.mjs` in S3 has unresolved bare import specifiers like `import {
CoreApiClient } from 'twenty-client-sdk/core'`.

SDK import resolution is split between the **frontend host** (fetching &
caching SDK modules) and the **Web Worker** (rewriting imports):

**Server endpoints**:
- `GET /rest/front-components/:id` —
`FrontComponentService.getBuiltComponentStream()` returns the **raw
`.mjs`** directly from file storage. No bundling, no SDK injection.
- `GET /rest/sdk-client/:applicationId/:moduleName` —
`SdkClientController` reads a single file (e.g. `dist/core.mjs`) from
the generated SDK archive via
`SdkClientGenerationService.readFileFromArchive()` and serves it as
JavaScript.

**Frontend host** (`FrontComponentRenderer` in `twenty-front`):
1. Queries `FindOneFrontComponent` which returns `applicationId`,
`builtComponentChecksum`, `usesSdkClient`, and `applicationTokenPair`
2. If `usesSdkClient` is `true`, renders
`FrontComponentRendererWithSdkClient` which calls the
`useApplicationSdkClient` hook
3. `useApplicationSdkClient({ applicationId, accessToken })` checks the
Jotai atom family cache for existing blob URLs. On cache miss, fetches
both SDK modules from `GET /rest/sdk-client/:applicationId/core` and
`/metadata`, creates **blob URLs** for each, and stores them in the atom
family
4. Once the blob URLs are cached, passes them as `sdkClientUrls`
(already blob URLs, not server URLs) to `SharedFrontComponentRenderer` →
`FrontComponentWorkerEffect` → worker's `render()` call via
`HostToWorkerRenderContext`

**Worker** (`remote-worker.ts` in `twenty-sdk`):
1. Fetches the raw component `.mjs` source as text
2. If `sdkClientUrls` are provided and the source contains SDK import
specifiers (`twenty-client-sdk/core`, `twenty-client-sdk/metadata`),
**rewrites** the bare specifiers to the blob URLs received from the host
(e.g. `'twenty-client-sdk/core'` → `'blob:...'`)
3. Creates a blob URL for the rewritten source and `import()`s it
4. Revokes only the component blob URL after the module is loaded — the
SDK blob URLs are owned and managed by the host's Jotai cache

This approach eliminates server-side esbuild bundling on every request,
caches SDK modules per application in the frontend, and keeps the
worker's job to a simple string rewrite.

## Summary Diagram

```
app:build (SDK)
  └─ twenty-client-sdk stub (metadata=real, core=stub)
       │
       ▼
WorkspaceMigrationRunnerService.run()
  └─ SdkClientGenerationService.generateAndStore()
       ├─ Copy stub package (package.json + dist/)
       ├─ replaceCoreClient() → regenerate core.mjs/core.cjs
       ├─ Zip entire package → upload to S3
       └─ Set isSdkLayerStale = true
              │
     ┌────────┴────────────────────┐
     ▼                             ▼
Logic Functions               Front Components
     │                             │
     ├─ Local Driver               ├─ GET /rest/sdk-client/:appId/core
     │   └─ downloadAndExtract     │    → core.mjs from archive
     │      → symlink into         │
     │        node_modules         ├─ Host (useApplicationSdkClient)
     │                             │    ├─ Fetch SDK modules
     └─ Lambda Driver              │    ├─ Create blob URLs
         └─ downloadArchiveBuffer  │    └─ Cache in Jotai atom family
            → reprefixZipEntries   │
            → publish as Lambda    ├─ GET /rest/front-components/:id
              layer                │    → raw .mjs (no bundling)
                                   │
                                   └─ Worker (browser)
                                        ├─ Fetch component .mjs
                                        ├─ Rewrite imports → blob URLs
                                        └─ import() rewritten source
```

## Next PR
- Estimate perf improvement by implementing a redis caching for front
component client storage ( we don't even cache front comp initially )
- Implem frontent blob invalidation sse event from server

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2026-03-24 18:10:25 +00:00
Paul Rastoin
75bb3a904d [SDK] Refactor clients (#18433)
# Intoduction

Closes https://github.com/twentyhq/core-team-issues/issues/2289

In this PR all the clients becomes available under `twenty-sdk/clients`,
this is a breaking change but generated was too vague and thats still
the now or never best timing to do so

## CoreClient
The core client is now shipped with a default stub empty class for both
the schema and the client
Allowing its import, will still raises typescript errors when consumed
as generated but not generated

## MetadataClient
The metadata client is workspace agnostic, it's now generated and
commited in the repo. added a ci that prevents any schema desync due to
twenty-server additions

Same behavior than for the twenty-front generated graphql schema
2026-03-09 15:32:13 +00:00
Charles Bochet
662de17644 ci: replace 4-core runners with ubuntu-latest (#18503)
## Summary

- Replace all `ubuntu-latest-4-cores` (paid larger runners) with
`ubuntu-latest` across CI workflows
- The free `ubuntu-latest` runner for public repos already provides **4
vCPUs + 16 GB RAM** — identical specs to the paid 4-core larger runner
- Affects 4 workflow files: `ci-server.yaml`, `ci-front.yaml`,
`ci-sdk.yaml`, `ci-zapier.yaml` (8 job definitions total, including the
10-shard integration test matrix)
- The `ubuntu-latest-8-cores` runners are intentionally **kept** for
memory-heavy jobs (frontend build, storybook build, E2E tests) where the
extra capacity (8 vCPUs, 32 GB RAM) is needed
2026-03-09 16:21:03 +01:00
Charles Bochet
ef499b6d47 Re-enable disabled lint rules and right-size CI runners (#18461)
## Summary

- Re-enable one lint rule that was temporarily disabled during the
ESLint-to-Oxlint migration:
- **`twenty/sort-css-properties-alphabetically`** in twenty-front — 578
violations auto-fixed across 390 files
- Document why **`typescript/consistent-type-imports`** cannot be
auto-fixed in twenty-server: NestJS relies on `emitDecoratorMetadata`
for DI, so converting constructor parameter imports to `import type`
erases them at compile time and breaks dependency injection at runtime
- Right-size CI runners, reducing 8-core usage from 18 jobs to 3:

| Change | Jobs | Rationale |
|--------|------|-----------|
| **Keep 8-core** | `ci-merge-queue/e2e-test`,
`ci-front/front-sb-build`, `ci-front/front-build` | Heavy builds needing
max CPU + memory (10GB NODE_OPTIONS, full Storybook webpack bundling) |
| **8-core → 4-core** | `ci-server` (build, lint-typecheck, validation,
test, integration-test), `ci-front/front-sb-test`,
`ci-zapier/server-setup`, `ci-sdk/sdk-e2e-test` | Already sharded into
10-12 parallel instances, I/O-bound (DB/Redis), or moderate single
builds |
| **8-core → 2-core** | `ci-emails/emails-test` | Trivially lightweight
(build + curl health check) |
| **Removed** | `ci-front/front-chromatic-deployment` | Dead code —
permanently disabled with `if: false` |

- Fix merge queue CI issues:
- **Concurrency**: Use `merge_group.base_ref` instead of unique merge
group ref so new queue entries cancel previous runs
- **Required status checks**: Add `merge_group` trigger to all 6
required CI workflows (front, server, shared, website, docker-compose,
sdk) with `changed-files-check` auto-skipped for merge_group events —
status check jobs auto-pass without re-running full CI
- **Build caching**: Add Nx build cache restore/save to E2E test job
with fallback to `main` branch cache for faster frontend and server
builds

## Test plan

- [ ] CI passes on this PR (verifies lint rule auto-fix works)
- [ ] Verify 4-core runner jobs complete within their 30-minute timeouts
- [ ] Verify merge queue status checks auto-pass (ci-front-status-check,
ci-server-status-check, etc.)
- [ ] Verify merge queue E2E concurrency cancels previous runs when a
new PR enters the queue
2026-03-06 13:33:02 +00:00
Charles Bochet
d37ed7e07c Optimize merge queue to only run E2E and integrate prettier into lint (#18459)
## Summary

- **Merge queue optimization**: Created a dedicated
`ci-merge-queue.yaml` workflow that only runs Playwright E2E tests on
`ubuntu-latest-8-cores`. Removed `merge_group` trigger from all 7
existing CI workflows (front, server, shared, website, sdk, zapier,
docker-compose). The merge queue goes from ~30+ parallel jobs to a
single focused E2E job.
- **Label-based merge queue simulation**: Added `run-merge-queue` label
support so developers can trigger the exact merge queue E2E pipeline on
any open PR before it enters the queue.
- **Prettier in lint**: Chained `prettier --check` into `lint` and
`prettier --write` into `lint --configuration=fix` across `nx.json`
defaults, `twenty-front`, and `twenty-server`. Prettier formatting
errors are now caught by `lint` and fixed by `lint:fix` /
`lint:diff-with-main --configuration=fix`.

## After merge (manual repo settings)

Update GitHub branch protection required status checks:
1. Remove old per-workflow merge queue checks (`ci-front-status-check`,
`ci-e2e-status-check`, `ci-server-status-check`, etc.)
2. Add `ci-merge-queue-status-check` as the required check for the merge
queue
2026-03-06 13:20:57 +01:00
Charles Bochet
364c944ca6 Improve build performance 2x (#18449)
## Summary

Front Before:
<img width="1199" height="670" alt="image"
src="https://github.com/user-attachments/assets/b978f67c-c0a6-49fc-bedd-a443f11c365d"
/>

Front After:
<img width="1199" height="670" alt="image"
src="https://github.com/user-attachments/assets/a4939dbb-a8b4-4c74-978c-daa7f27d00f3"
/>


Server Before:
<img width="1199" height="670" alt="image"
src="https://github.com/user-attachments/assets/da53e97f-ec65-4224-a656-ca41040aef6e"
/>


Server After:
<img width="1199" height="670" alt="image"
src="https://github.com/user-attachments/assets/8cdf3885-f515-4d6c-989f-a421a4e8206c"
/>


### CI Server Pipeline Restructuring
- Split monolithic `server-setup` job into three parallel jobs:
`server-build`, `server-lint-typecheck`, and `server-validation`
- `server-build` only handles build + Nx cache save (~1m vs old 3.5m),
unblocking downstream jobs faster
- `server-lint-typecheck` runs in parallel with no DB dependency
- `server-validation` handles DB setup, migration checks, and GraphQL
generation checks in parallel with tests
- Make `server-test` (unit tests) fully independent — no longer waits
for server-setup, builds its own artifacts
- Increase integration test shards from 8 to 10 for better parallelism
- Expected critical path reduction: ~10m → ~7m (~30% faster)

### CI Front Pipeline Improvements
- Use artifact upload/download for storybook build instead of rebuilding
in test shards
- Serve pre-built storybook via `http-server` in test jobs, with
`STORYBOOK_URL` env var
- Update `vitest.config.ts` to use `storybookUrl` when `STORYBOOK_URL`
is set
- Remove redundant `twenty-shared`, `twenty-ui`, `twenty-sdk` builds
from storybook test shards

### Vite Build Optimizations
- Conditionally enable `rollup-plugin-visualizer` behind `ANALYZE=true`
env var (not loaded by default)
- Broaden Istanbul coverage exclusions to skip test files, stories,
mocks, and decorators
- Remove `@tabler/icons-react` alias from twenty-front and storybook
configs
- Bundle `@tabler/icons-react` into twenty-ui instead of treating it as
an external dependency
- Add lazy loading with `React.lazy` + `Suspense` for all page-level
route components in `useCreateAppRouter`
2026-03-06 11:02:26 +01:00
Charles Bochet
9d57bc39e5 Migrate from ESLint to OxLint (#18443)
## Summary

Fully replaces ESLint with OxLint across the entire monorepo:

- **Replaced all ESLint configs** (`eslint.config.mjs`) with OxLint
configs (`.oxlintrc.json`) for every package: `twenty-front`,
`twenty-server`, `twenty-emails`, `twenty-ui`, `twenty-shared`,
`twenty-sdk`, `twenty-zapier`, `twenty-docs`, `twenty-website`,
`twenty-apps/*`, `create-twenty-app`
- **Migrated custom lint rules** from ESLint plugin format to OxLint JS
plugin system (`@oxlint/plugins`), including
`styled-components-prefixed-with-styled`, `no-hardcoded-colors`,
`sort-css-properties-alphabetically`,
`graphql-resolvers-should-be-guarded`,
`rest-api-methods-should-be-guarded`, `max-consts-per-file`, and
Jotai-related rules
- **Migrated custom rule tests** from ESLint `RuleTester` + Jest to
`oxlint/plugins-dev` `RuleTester` + Vitest
- **Removed all ESLint dependencies** from `package.json` files and
regenerated lockfiles
- **Updated Nx targets** (`lint`, `lint:diff-with-main`, `fmt`) in
`nx.json` and per-project `project.json` to use `oxlint` commands with
proper `dependsOn` for plugin builds
- **Updated CI workflows** (`.github/workflows/ci-*.yaml`) — no more
ESLint executor
- **Updated IDE setup**: replaced `dbaeumer.vscode-eslint` with
`oxc.oxc-vscode` extension, configured `source.fixAll.oxc` and
format-on-save with Prettier
- **Replaced all `eslint-disable` comments** with `oxlint-disable`
equivalents across the codebase
- **Updated docs** (`twenty-docs`) to reference OxLint instead of ESLint
- **Renamed** `twenty-eslint-rules` package to `twenty-oxlint-rules`

### Temporarily disabled rules (tracked in `OXLINT_MIGRATION_TODO.md`)

| Rule | Package | Violations | Auto-fixable |
|------|---------|-----------|-------------|
| `twenty/sort-css-properties-alphabetically` | twenty-front | 578 | Yes
|
| `typescript/consistent-type-imports` | twenty-server | 3814 | Yes |
| `twenty/max-consts-per-file` | twenty-server | 94 | No |

### Dropped plugins (no OxLint equivalent)

`eslint-plugin-project-structure`, `lingui/*`, `@stylistic/*`,
`import/order`, `prefer-arrow/prefer-arrow-functions`,
`eslint-plugin-mdx`, `@next/eslint-plugin-next`,
`eslint-plugin-storybook`, `eslint-plugin-react-refresh`. Partial
coverage for `jsx-a11y` and `unused-imports`.

### Additional fixes (pre-existing issues exposed by merge)

- Fixed `EmailThreadPreview.tsx` broken import from main rename
(`useOpenEmailThreadInSidePanel`)
- Restored truthiness guard in `getActivityTargetObjectRecords.ts`
- Fixed `AgentTurnResolver` return types to match entity (virtual
`fileMediaType`/`fileUrl` are resolved via `@ResolveField()`)

## Test plan

- [x] `npx nx lint twenty-front` passes
- [x] `npx nx lint twenty-server` passes
- [x] `npx nx lint twenty-docs` passes
- [x] Custom oxlint rules validated with Vitest: `npx nx test
twenty-oxlint-rules`
- [x] `npx nx typecheck twenty-front` passes
- [x] `npx nx typecheck twenty-server` passes
- [x] CI workflows trigger correctly with `dependsOn:
["twenty-oxlint-rules:build"]`
- [x] IDE linting works with `oxc.oxc-vscode` extension
2026-03-06 01:03:50 +01:00
Charles Bochet
d48c58640c Migrate CI runners from Depot back to GitHub-hosted runners (#18347)
## Summary
- Replaces all `depot-ubuntu-24.04` runners with `ubuntu-latest`
- Replaces all `depot-ubuntu-24.04-8` runners with
`ubuntu-latest-8-cores`
- Updates storybook build cache keys in ci-front.yaml to reflect the
runner name change

Reverts the temporary Depot migration introduced in #18163 / #18179
across all 23 workflow files.
2026-03-03 14:14:27 +01:00
Paul Rastoin
9e8024a07a Restore depot (#18179) 2026-02-24 09:59:54 +01:00
Charles Bochet
129d1ede86 Change runners temp (#18163)
Temporarily moving all ubuntu-latest 1 core to depot except ci-website
2026-02-23 10:53:31 +01:00
Félix Malfait
6faef19f64 chore: replace depot.dev runners with GitHub-hosted runners (#17641)
## Summary
- Replace all `depot-ubuntu-24.04-8` runner references with the
equivalent GitHub-hosted `ubuntu-latest-8-cores` runner
- Updated across 4 workflow files: `ci-front.yaml`, `ci-server.yaml`,
`ci-emails.yaml`, `ci-sdk.yaml`
- Also updated cache key names in `ci-front.yaml` that referenced the
depot runner name

## Test plan
- [ ] Verify CI workflows run successfully on the new GitHub-hosted
larger runners
- [ ] Confirm cache keys work correctly with the updated naming

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:30:13 +01:00
Marie
ceba0972cd Remove tests run on push on main (#16971)
Since tests are now run in the pre-merge queue with the latest main
version, they need not to be run again when merged into main, it would
be the exact same thing
2026-01-06 17:53:08 +00:00
Félix Malfait
21ff42074d feat: implement skills system for AI agents (#16865)
## Summary
This PR introduces a Skills system for AI agents, inspired by the [Agent
Skills specification](https://agentskills.io/specification).

## Changes

### Backend
- **SkillEntity**: New database entity with migration for storing skills
- **V2 Sync Mechanism**: Implemented FlatSkill, builders, validators,
and action handlers following the v2 flat entity pattern
- **Standard Skills**: Pre-defined skills (workflow-building,
data-manipulation, dashboard-building, metadata-building, research,
code-interpreter, xlsx, pdf, docx, pptx)
- **GraphQL API**: CRUD operations for skills with proper guards and
permissions
- **Workspace Cache**: Integrated skills into the workspace cache system

### Frontend  
- **Skills Table**: Searchable table in AI settings showing all skills
- **Skill Form**: Create/edit page with Label (primary), Description,
and Content (markdown editor)
- **API Name**: Following existing patterns, name is derived from label
with advanced settings toggle for custom API names
- **Standard vs Custom**: Standard skills are read-only, custom skills
can be edited/deleted

## Key Design Decisions
- Skills are stored in the database (Salesforce-like approach) rather
than files
- Name is derived from Label by default (isLabelSyncedWithName pattern)
- Skills reference functions/files via @ mentions in markdown content
rather than explicit relations
- Standard skills are synced from code, custom skills are created via UI

## Screenshots
Skills table and form UI follow existing settings patterns.

## Testing
- [x] Lint passes
- [x] Typecheck passes
- [ ] CI tests
2026-01-02 14:22:01 +00:00
Félix Malfait
e6491d6a80 feat(i18n): fix translation QA issues and add automation (#16756)
## Summary

This PR fixes translation QA issues and adds automation to prevent
future issues.

### Translation Fixes
- Fixed **escaped Unicode sequences** in translations (e.g.,
`\u62db\u5f85` → `招待`)
- Removed **corrupted control characters** from .po files (null bytes,
invalid characters)
- Fixed **missing/incorrect placeholders** in various languages
- Deleted **35 problematic translations** via Crowdin API that had
variable mismatches

### New Scripts (in `packages/twenty-utils/`)
- `fix-crowdin-translations.ts` - Auto-fixes encoding issues and syncs
to Crowdin
- `fix-qa-issues.ts` - Fixes specific QA issues via Crowdin API
- `translation-qa-report.ts` - Generates weekly QA report from Crowdin
API

### New Workflow
- `i18n-qa-report.yaml` - Weekly workflow that creates a PR with
translation QA issues for review

### Other Changes
- Moved GitHub Actions from `.github/workflows/actions/` to
`.github/actions/`
- Fixed `date-utils.ts` to avoid nested `t` macros in plural expressions
(root cause of confusing placeholders)

### QA Status After Fixes
| Category | Count | Status |
|----------|-------|--------|
| variables | 0  | Fixed |
| tags | 1 | Minor |
| empty | 0  | Fixed |
| spaces | 127 | Low priority |
| numbers | 246 | Locale-specific |
| special_symbols | 268 | Locale-specific |
2025-12-22 17:30:46 +01:00
Paul Rastoin
75bba5a8ee Standard Agent, Role, Role target (#16499)
# Introduction
In this pullrequest have been migrated to the flat standard entities:
Role, Agent and RoleTargets.

## What happens
- Removed createStandardMorph tool util in favor of dynamic typing of
`createMorphOrRelationStandardField`
- Implemented a command to remove standard agents and their role that
has been removed in https://github.com/twentyhq/twenty/pull/16513 also
added a default role target to data manipulator role to the only
remaining agent
- Implemented an agent deleteMany service handler
2025-12-16 14:17:31 +01:00
Félix Malfait
a2a7ff8b4b Upgrade NestJS from 9.x to 10.x (#15835)
## Overview
This PR upgrades all NestJS dependencies from version 9.x to 10.x,
following the [official migration
guide](https://docs.nestjs.com/v10/migration-guide). This is the first
step before upgrading to NestJS 11.x in a future PR.

## Changes

### Dependencies Updated
- `@nestjs/common`: 9.4.3 → 10.4.16
- `@nestjs/core`: 9.4.3 → 10.4.16
- `@nestjs/passport`: 9.0.3 → 10.0.3
- `@nestjs/platform-express`: 9.4.3 → 10.4.16
- `@nestjs/config`: 2.3.4 → 3.2.3
- `@nestjs/event-emitter`: 2.0.4 → 2.1.0
- `@nestjs/testing`: ^9.0.0 → ^10.4.16
- `@nestjs/schematics`: ^9.0.0 → ^10.1.0

### Code Changes
- Fixed `CacheModuleOptions` import from `@nestjs/common` to
`@nestjs/cache-manager` in cache-storage.module-factory.ts

## Breaking Changes Addressed
 **CacheModule Migration**: Already using `@nestjs/cache-manager`
package
 **TypeScript Version**: Using 5.9.2 (requires 4.8+)  
 **Node.js Version**: Using 24.5.0 (requires 16+)  
 **Deprecated APIs**: All v9 deprecations removed in v10 - standard
patterns in use

## Testing
All tests passing and build successful:
-  Health module: 38 tests passed
-  Auth module: 115 tests passed (critical - uses @nestjs/passport)
-  Admin panel: 30 tests passed
-  REST API: 90 tests passed (uses @nestjs/platform-express)
-  Feature flags: 17 tests passed
-  Workspace: 23 tests passed
-  GraphQL query runner: 17 tests passed
-  **Total: 330+ tests passing**
-  Build: 3,683 files compiled successfully
-  Type checking: Passed
-  Linting: Passed

## Verification
Tested critical NestJS functionality:
- Authentication & Security (JWT, OAuth, guards)
- HTTP Platform (Express integration, REST endpoints)
- Dependency Injection (Services, factories, providers)
- Cache Management (Redis with @nestjs/cache-manager)
- GraphQL (Query runners, resolvers)
- Configuration (Environment config)
- Event Emitters (Event-driven architecture)

## Next Steps
This upgrade positions the codebase for the next upgrade to NestJS 11.x,
which will be handled in a separate PR.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades NestJS to v10, fixes cache module import, and narrows CI
GraphQL generation diff to generated directories.
> 
> - **Backend**
> - **Dependencies**: Upgrade `@nestjs/common`, `@nestjs/core`,
`@nestjs/platform-express`, `@nestjs/passport`, `@nestjs/config`,
`@nestjs/event-emitter`, `@nestjs/testing`, and `@nestjs/schematics` to
v10-compatible versions in `packages/twenty-server/package.json`.
> - **Code**: Update `CacheModuleOptions` import to
`@nestjs/cache-manager` in
`src/engine/core-modules/cache-storage/cache-storage.module-factory.ts`.
> - **CI**
> - **GraphQL**: Restrict schema change detection to
`packages/twenty-front/src/generated` and
`packages/twenty-front/src/generated-metadata` in
`.github/workflows/ci-server.yaml`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f621230fcf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-15 23:06:13 +01:00
Abdullah.
14c66c942f fix: update tmp to a safer version. (#15554)
@charlesBochet had a conversation with Felix and he said we don't need
to spend time upgrading `zapier-platform-core` and `zapier-platform-cli`
since `twenty-zapier` will be deprecated anyway, making those packages
irrelevant.

I have updated tmp to a safer version elsewhere using `yarn up tmp
--recursive`. Also added `yarn.lock` to both server and front ci.

The massive changes in `yarn.lock` were introduced by
`zapier-platform-cli` version 17x - not sure if they caused those
breaking changes, but if they did and we still want update
zapier-related packages, I will take that up in another PR.
2025-11-04 08:53:33 +01:00
Paul Rastoin
72fd8ae8d2 ci(server): integration server increase shard (#15228) 2025-10-21 16:03:50 +02:00
Félix Malfait
5375a478db Fix: Make CI .env manipulation robust against missing trailing newlines (#15189)
## Problem

CI workflow started timing out on October 14, 2025 after commit
`d750df7fff` removed the trailing newline from `.env.example`.

## Root Cause

When `.env.example` lacks a trailing newline:
```bash
# Last line without newline
# CLICKHOUSE_URL=...twenty
```

And CI runs:
```bash
echo "NODE_PORT=3002" >> .env
```

Result:
```bash
# CLICKHOUSE_URL=...twentyNODE_PORT=3002  ← Commented out!
```

Server starts on default port 3000 instead of 3002, health check fails.

## Fix

1. **Restore trailing newline** to `.env.example`
2. **Make all CI `.env` operations robust** by adding `echo "" >> .env`
before appending
3. **Simplified `set_env_var`** function to always add newline first

Now works regardless of whether template files have trailing newlines.

## Files Changed

- 6 CI workflow files
- 1 .env.example file
2025-10-18 13:46:56 +02:00
Félix Malfait
d76abefdee Fix CI concurrency: prevent test cancellation on main branch (#15188)
## Problem
The concurrency rules in CI workflows were cancelling in-progress test
runs even on the main branch. This caused inconsistent check counts when
multiple commits were pushed in quick succession.

## Solution
Updated `cancel-in-progress` in all CI workflows to be conditional:
- **On main branch**: Tests run to completion (no cancellation)
- **On feature branches**: Tests are cancelled when new commits are
pushed (saves CI resources)

## Changes
Modified 11 workflow files to use:
```yaml
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
```

This ensures every commit to main gets fully tested while maintaining
efficiency on feature branches.
2025-10-18 10:50:54 +02:00
Etienne
c693c4d9cf Common API - create common find one query (#14720)
closes https://github.com/twentyhq/core-team-issues/issues/1418

Tested : 
- findOne on Rest and Gql

### Vision
#### Common
- Common is kind of renamed Gql base resolver
- Common handles args (filter, values, ...) validation
- Common accepts depth or raw gql selected fields to compute
selectedFields
- Common is directly called by each CommonQueries (findOne, ...)
service, which extend CommonBaseQuery service
- Common sequence : 
| - Parse & Validate args (args-handlers, to create)
| - Build query (query-parsers : currently in gql-query-parsers, to
move)
| - Execute query
| - Fetch relation + format
#### Rest
- Simple parsing (without metadata validation)
- Calling Common API
- Simple rest response formatting
#### Gql
- Calling Common API
2025-10-08 10:18:42 +00:00
Antoine Moreaux
93d55d1bc2 chore(workflows): update permissions across GitHub Actions workflows … (#14919)
…for consistency
2025-10-06 17:36:41 +02:00
Charles Bochet
a21daa2670 Optimize CI runner cost (#14628) 2025-09-20 12:14:29 +02:00
Félix Malfait
30a2164980 First Application POC (#14382)
Quick proof of concept for twenty-apps + twenty-cli, with local
development / hot reload

Let's discuss it!



https://github.com/user-attachments/assets/c6789936-cd5f-4110-a265-863a6ac1af2d
2025-09-10 15:12:38 +02:00
Charles Bochet
953f1e7207 Fix CI cache for storybook (#14038)
In this PR:
- Migrate twenty-ui to ES2020 (removing undesired type errors during
build)
- Make CI cache work again between `sb-build` and `sb-test` steps

(Note: also fixing a minor bug on Notes)

Total CI time: ~8min
<img width="1088" height="531" alt="image"
src="https://github.com/user-attachments/assets/0bd0a99a-c69e-491d-91b2-9ddf6622464a"
/>

Both node_modules and sb-build caches are being hit now
<img width="1154" height="722" alt="image"
src="https://github.com/user-attachments/assets/a5addcee-51d2-4f51-9ff6-d02cd25da49a"
/>
2025-08-22 09:34:35 +02:00
Félix Malfait
d29dbd473b Upgrade SWC Core and Storybook to v8 (#13799)
This is is a blocker for various sub-migrations
2025-08-11 12:02:33 +02:00
Antoine Moreaux
29f7b74756 fix(ci): reorganize workflow steps and move cache saving to correct s… (#13083)
…tage
2025-07-07 16:06:25 +00:00
Antoine Moreaux
0199d5f72a feat(ci): add GraphQL check workflow and update dependencies setup (#13075) 2025-07-07 14:51:18 +02:00
Paul Rastoin
3233734d2c [CI] Jest sharding integration tests (#12400)
# Introduction
Introducing jest sharding along github actions matrix in order to
fluidify the process

Note in case we will compute and guard coverage metrics we will need to
merge coverages reports such as we do for the frontend storybooks
integrations tests, from now this is overkill as unused

Related successful run
https://github.com/twentyhq/twenty/actions/runs/15585113583/job/43889477889
2025-06-11 16:05:40 +02:00
Charles Bochet
a68895189c Deprecate old relations completely (#12482)
# What

Fully deprecate old relations because we have one bug tied to it and it
make the codebase complex

# How I've made this PR:
1. remove metadata datasource (we only keep 'core') => this was causing
extra complexity in the refactor + flaky reset
2. merge dev and demo datasets => as I needed to update the tests which
is very painful, I don't want to do it twice
3. remove all code tied to RELATION_METADATA /
relation-metadata.resolver, or anything tied to the old relation system
4. Remove ONE_TO_ONE and MANY_TO_MANY that are not supported
5. fix impacts on the different areas : see functional testing below 

# Functional testing

## Functional testing from the front-end:
1. Database Reset 
2. Sign In 
3. Workspace sign-up 
5. Browsing table / kanban / show 
6. Assigning a record in a one to many / in a many to one 
7. Deleting a record involved in a relation  => broken but not tied to
this PR
8. "Add new" from relation picker  => broken but not tied to this PR
9. Creating a Task / Note, Updating a Task / Note relations, Deleting a
Task / Note (from table, show page, right drawer)  => broken but not
tied to this PR
10. creating a relation from settings (custom / standard x oneToMany /
manyToOne) 
11. updating a relation from settings should not be possible 
12. deleting a relation from settings (custom / standard x oneToMany /
manyToOne) 
13. Make sure timeline activity still work (relation were involved
there), espacially with Task / Note => to be double checked  => Cannot
convert undefined or null to object
14. Workspace deletion / User deletion  
15. CSV Import should keep working  
16. Permissions: I have tested without permissions V2 as it's still hard
to test v2 work and it's not in prod yet 
17. Workflows global test  

## From the API:
1. Review open-api documentation (REST)  
2. Make sure REST Api are still able to fetch relations ==> won't do, we
have a coupling Get/Update/Create there, this requires refactoring
3. Make sure REST Api is still able to update / remove relation => won't
do same

## Automated tests
1. lint + typescript 
2. front unit tests: 
3. server unit tests 2 
4. front stories: 
5. server integration: 
6. chromatic check : expected 0
7. e2e check : expected no more that current failures

## Remove // Todos
1. All are captured by functional tests above, nothing additional to do

## (Un)related regressions
1. Table loading state is not working anymore, we see the empty state
before table content
2. Filtering by Creator Tim Ap return empty results
3. Not possible to add Tasks / Notes / Files from show page

# Result

## New seeds that can be easily extended
<img width="1920" alt="image"
src="https://github.com/user-attachments/assets/d290d130-2a5f-44e6-b419-7e42a89eec4b"
/>

## -5k lines of code
## No more 'metadata' dataSource (we only have 'core)
## No more relationMetadata (I haven't drop the table yet it's not
referenced in the code anymore)
## We are ready to fix the 6 months lag between current API results and
our mocked tests
## No more bug on relation creation / deletion

---------

Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-06-10 16:45:27 +02:00
Paul Rastoin
f2691e53a0 [CI]: Increase status check timeout (#11896)
# Introduction
Some jobs start to fail because they exceed the timeout
Such as this job
https://github.com/twentyhq/twenty/actions/runs/14862320942/job/41730200276?pr=11881
2025-05-06 17:14:58 +02:00
Antoine Moreaux
587281a541 feat(analytics): add clickhouse (#11174) 2025-04-16 16:33:10 +00:00
Weiko
fc30ba57f8 Fix server integration tests 2 (#10818)
## Context
- Removing search* integration tests instead of fixing them because they
will be replaced by global search very soon
- Fixed billing + add missing seeds to make them work
- Fixed integration tests not using consistently the correct "test" db
- Fixed ci not running the with-db-reset configuration due to nx
configuration being used twice for different level of the command
- Enriched .env.test
- Fixed parts where exceptions were not thrown properly and not caught
by exception handler to convert to 400 when needed
- Refactored feature flag service that had 2 different implementations
in lab and admin panel + added tests
- Fixed race condition when migrations are created at the same timestamp
and doing the same type of operation, in this case object deletion could
break because table could be deleted earlier than its relations
- Fixed many integration tests that were not up to date since the CI has
been broken for a while

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-03-13 17:48:29 +01:00
Félix Malfait
dde70ee3b0 Add fields for admin panel access and workspace version (#10451)
Prepare for better version upgrade system + split admin panel into two
permissions + fix GraphQL generation detection

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-02-24 21:38:41 +01:00
Weiko
5cf0a71d12 fix server ci integration (#10296)
Now that the CI is running, I'm trying to fix the tests
2025-02-18 17:01:29 +01:00
Weiko
2ba9f2d0e5 Fix integration test ci (#10226)
## Context
Integration test ci was not running properly. This PR should fix that

Todo: This was not running for a while, many tests are not succeeding so
I'll try to fix them in this PR now that the action is running properly.
2025-02-17 11:45:44 +01:00
Félix Malfait
f40d7e2ba8 Deprecate message queue type (#10040)
Not removing all the code for now, maybe we should 🤔
2025-02-06 16:06:54 +01:00
shubham yadav
47c2c774e3 Add GraphQL Generation Check to CI Workflow (#9742)
This pull request addresses the issue of ensuring that npx nx run
twenty-front:graphql:generate and npx nx run
twenty-front:graphql:generate --configuration=metadata commands are run
to generate the necessary GraphQL files. This prevents changes from
being missed and ending up in subsequent unrelated PRs.

Changes:
Added a step in the ci-server.yml workflow to check for pending GraphQL
generation.
If any GraphQL changes are detected, the CI will fail, and an error
message will be displayed instructing the developer to run the necessary
commands and commit the changes.
This approach is similar to the existing TypeORM migration check and
helps maintain consistency and correctness in the codebase.

Issue Resolved: #9726

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-21 14:43:19 +01:00
Paul Rastoin
22ee77145a [CI] ci-server reorder twenty-shared build after cache restoration (#9672)
# Introduction
Unless I'm mistaken we can win few seconds `~12s` by reordering the
`twenty-shared` build step after the cache restoration in order for `nx`
to hit it if possible.

[Related
run](https://github.com/twentyhq/twenty/actions/runs/12809421832/job/35714544486)
2025-01-17 08:06:30 +01:00
Paul Rastoin
560f715c37 [CI][NITPICK]: Rename prerequisites jobs to changed-files-check (#9670)
Related to https://github.com/twentyhq/twenty/pull/9643

Renaming `prerequisites` jobs to a more accurate `changed-files-check`
2025-01-16 14:09:59 +01:00
Paul Rastoin
f8ddc02b8e [CI] Refactor changed files integration (#9643)
# BEFORE
[run](https://github.com/twentyhq/twenty/actions/runs/12806801953)

![image](https://github.com/user-attachments/assets/f0a8ffe3-3fc0-42ca-b2ee-8a980606b5dd)
# AFTER
[run](https://github.com/twentyhq/twenty/actions/runs/12807034402)

![image](https://github.com/user-attachments/assets/5117c680-6804-416b-a8c8-bf00614ca453)

## Motivations:
- less workflow to whitelist as blocking for PRs
- less if condition per step

cons:
- quite verbose
- need to manually sync the `ci-NAME-status-check` needs list to any
other existing and should be dep jobs

## Version migration
Migrated to the latest `changed-files@45` version, getting rid of the
`set-output` usage warnings

## Tests runs:

With mutation:
- [Success
flow](https://github.com/twentyhq/twenty/actions/runs/12791958651/job/35661546343)
- [server-setup failure
flow](https://github.com/twentyhq/twenty/actions/runs/12792225779)
- [Other job failure
flow](https://github.com/twentyhq/twenty/actions/runs/12792313463), one
of the `inner` job failed
- [Manual cancel
flow](https://github.com/twentyhq/twenty/actions/runs/12792313463)
`ci-server-status-check` also has the `cancelled` status
- [Matrix
failure](https://github.com/twentyhq/twenty/actions/runs/12806883553)

Without mutation:
- [Nothing to do
flow](https://github.com/twentyhq/twenty/actions/runs/12792098384),
skipped `inner` job but `ci-server-status-check` still succeeded

## Notes
### Linter
We should setup a `yml` prettier and linter for the `.github/worfklows`
folder
### Centralized `ci-NAME-status-check` logic
Unfortunately I couldn't achieve to either make a `composite` action or
a `reusable-workflow`, as I could not access the correct layer to run
the `always` but also acessing the `needs` context
2025-01-16 13:37:28 +01:00
Paul Rastoin
9ba510eb3f [CI] Always save cache agnostically of the actions/restore cache-hit output (#9635)
## Motivations
This is not because we've hit the `actions/cache/restore` cache that NX
won't be re-building sub commands.
Which means the grain to save or not the cache should be extracted from
nx sub commands and not from the `actions/cache` outputs.

We should investigate on the way to retrieve this granularity level

From the moment we will be saving everything, which could result
sometimes in duplicating cache instances.
We should keep in mind that our cache occurrences have a 1 day retention
date, is low cost and pretty fast to perform
2025-01-15 11:59:17 +01:00