## Problem
The `danger-js` job in **CI Utils** has been failing across most PRs.
The failure is not a real Danger violation — it's a transient network
error fetching the PR diff/commits from the GitHub API:
```
Failed to fetch GitHub pull request files: FetchError: Invalid response body while trying to fetch
https://api.github.com/repos/twentyhq/twenty/pulls/XXXXX/files?page=1&per_page=100: Premature close
at Gunzip.<anonymous> (.../node_modules/node-fetch/lib/index.js:400:12)
errno: 'ERR_STREAM_PREMATURE_CLOSE',
code: 'ERR_STREAM_PREMATURE_CLOSE'
```
GitHub closes the gzipped HTTP response mid-stream, and Danger's bundled
`node-fetch` has **no retry** on a dropped connection — so any single
blip fails the whole check.
## Why is this happening now?
Nothing on our side changed at the boundary where failures started. The
Node 24.16 bump landed Jun 8 (the job stayed green for 2+ weeks after),
Danger has been pinned at `13.0.4` for months, and there are **zero
commits** to `.nvmrc`, `twenty-utils/package.json`, or the
`yarn-install` action since Jun 22.
What changed is GitHub's API reset rate, and it changed abruptly:
| Day | Failures | Successes | Failure rate |
|-----|----------|-----------|--------------|
| Jun 23 | 1 | 48 | ~2% (green) |
| Jun 24 | 38 | 204 | ~16% |
| Jun 25 | 23 | 25 | **~48%** |
The same PR passes on one run and fails on the next (e.g. one PR shows
up as both pass and fail; another failed 3 runs in a row) — a code bug
can't flip outcomes on identical input, only an infrastructure flake
can. When GitHub's connection-reset rate was ~0% we never noticed; now
that it's in the tens of percent, roughly half of all PRs trip it.
## Fix
Wrap the Danger invocation in a small retry loop (3 attempts, 5s
backoff) so the check absorbs these transient fetch errors instead of
red-flagging the PR. Applied to both the `danger-js` and `congratulate`
jobs since they share the same failure mode.
This is the correct mitigation rather than a code revert — there's no
change on our side to revert. 3 attempts drop a ~48% single-shot failure
rate to ~11%, and a less-degraded ~16% rate to well under 1%. If
GitHub's reliability recovers, the retries simply stop firing and cost
nothing.
This is a CI-only change — no application code is touched.
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22151?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## 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.
## Summary
- Fix expression injection vulnerabilities in composite actions
(`restore-cache`, `nx-affected`) and workflow files (`claude.yml`)
- Reduce overly broad permissions in `ci-utils.yaml` (Danger.js) and
`ci-breaking-changes.yaml`
- Restructure `preview-env-dispatch.yaml`: auto-trigger for members,
opt-in for contributor PRs via `preview-app` label (safe because
keepalive has no write tokens)
- Isolate all write-access operations (PR comments, cross-repo posting)
to a new dedicated
[`twentyhq/ci-privileged`](https://github.com/twentyhq/ci-privileged)
repo via `repository_dispatch`, so that workflows in twenty that execute
contributor code never have write tokens
- Create `post-ci-comments.yaml` (`workflow_run` bridge) to dispatch
breaking changes results to ci-privileged, solving the [fork PR comment
issue](https://github.com/twentyhq/twenty/pull/13713#issuecomment-3168999083)
- Delete 5 unused secrets and broken `i18n-qa-report` workflow
- Remove `TWENTY_DISPATCH_TOKEN` from twenty (moved to ci-privileged as
`CORE_TEAM_ISSUES_COMMENT_TOKEN`)
- Use `toJSON()` for all `client-payload` values to prevent JSON
injection
## Security model after this PR
| Workflow | Executes fork code? | Write tokens available? |
|----------|---------------------|------------------------|
| preview-env-keepalive | Yes | None (contents: read only) |
| preview-env-dispatch | No (base branch) | CI_PRIVILEGED_DISPATCH_TOKEN
only |
| ci-breaking-changes | Yes | None (contents: read only) |
| post-ci-comments (workflow_run) | No (default branch) |
CI_PRIVILEGED_DISPATCH_TOKEN only |
| claude.yml | No (base branch) | CI_PRIVILEGED_DISPATCH_TOKEN,
CLAUDE_CODE_OAUTH_TOKEN |
| ci-utils (Danger.js) | No (base branch) | GITHUB_TOKEN (scoped) |
All actual write tokens (`TWENTY_PR_COMMENT_TOKEN`,
`CORE_TEAM_ISSUES_COMMENT_TOKEN`) live in `twentyhq/ci-privileged` with
strict CODEOWNERS review and branch protection.
## Test plan
- [ ] Verify preview environment comments still appear on member PRs
- [ ] Verify adding `preview-app` label triggers preview for contributor
PRs
- [ ] Verify breaking changes reports still post on PRs (including fork
PRs)
- [ ] Verify Claude cross-repo responses still post on core-team-issues
- [ ] Confirm ci-privileged branch protection is enforced
Increased the timeout for the Danger JS job from 3 to 5 minutes to
prevent premature failures on slower runs. This ensures more reliable
execution of the workflow.
To unlock https://github.com/twentyhq/twenty/pull/11339
This Pull Request addresses the need to optimize our Continuous
Integration (CI) workflows for Playwright tests and release processes.
The changes implemented aim to reduce unnecessary resource usage by
conditionally executing jobs based on relevant file changes and
Implement https://github.com/tj-actions/changed-files step
## Changes logs
- Updated `ci-test-docker-compose.yaml , ci-chrome-extension.yaml ` to
check for changed files before running tests.
- Updated `ci-front.yaml , ci-utils.yaml , ci-website.yaml ,
ci-server.yaml` to check for changed files before running tests.
- Enhanced `playwright.yml` to skip unnecessary tests based on file
changes.
Closes#5097
- Uses "nx affected" to detect what projects need to be checked in the
current PR (for now, `ci-front` and `ci-server` workflows only).
- Caches results of certain tasks (`lint`, `typecheck`, `test`,
`storybook:build`) when a PR pipeline runs. The next runs of the same
PR's pipeline will then be able to reuse the PR's task cache to execute
tasks faster.
- Caches Yarn's cache folder to install dependencies faster in CI jobs.
- Rewrites the node modules cache/install steps as a custom, reusable
Github action.
- Distributes `ci-front` jobs with a "matrix" strategy.
- Sets common tasks config at the root `nx.json`. For instance, to
activate the `typecheck` task in a project, add `typecheck: {}` to its
`project.json` and it'll use the default config set in `nx.json` for the
`typecheck` task. Options can be overridden in each individual
`project.json` if needed.
- Adds "scope" tags to some projects: `scope:frontend`, `scope:backend`,
`scope:shared`. An eslint rule ensures that `scope:frontend` only
depends on `scope:frontent` or `scope:shared` projects, same for
`scope:backend`. These tags are used by `nx affected` to filter projects
by scope and generates different task cache keys according to the
requested scope.
- Enables checks for twenty-emails in the `ci-server` workflow.
As recommended on the repo of the action we were using
https://github.com/styfle/cancel-workflow-action, we should use
`concurrency.group` rather than a dedicated action.
Here is a PR to use it on all our workflows
* Fix CIs
* Fix docs
* Fix eslint-build
* Move file
* Move back
* Fix server ci
* Fix server ci
* Fix server ci
* Fix server ci
* Deactivate e2e tests
* Fix front
* Fix front
* Fix front
* Add twenty-zapier and twenty-utils to the yarn project
* fix
* fix
* Remove pull_request trigger