Skip to content

chore(deps): bump react-grid-layout from 1.5.2 to 1.5.4 #261

chore(deps): bump react-grid-layout from 1.5.2 to 1.5.4

chore(deps): bump react-grid-layout from 1.5.2 to 1.5.4 #261

Workflow file for this run

name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
merge_group:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
lint-typecheck:
name: Lint & Typecheck
runs-on: ${{ github.actor == 'dependabot[bot]' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64"]') }}
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
- name: Build shared
run: npx nx build twenty-shared
- name: Build oxlint plugin
run: npx nx build twenty-oxlint-rules
- name: Typecheck frontend
run: npx nx typecheck twenty-front
- name: Typecheck server
run: npx nx typecheck twenty-server
- name: Lint frontend
run: npx nx lint twenty-front
- name: Lint server (oxlint)
# oxlint has an intermittent thread panic on large codebases — treat as warning
run: cd packages/twenty-server && npx oxlint --type-aware -c .oxlintrc.json src/ || echo "::warning::oxlint exited non-zero (possible thread panic — known issue)"
continue-on-error: true
- name: Lint server (prettier)
run: cd packages/twenty-server && npx prettier src/ --check
brand-drift:
name: Brand drift check
runs-on: ${{ github.actor == 'dependabot[bot]' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64"]') }}
timeout-minutes: 5
if: github.event_name == 'pull_request'
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Detect "twenty" in PR-added lines
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
ALLOWLIST_FILE: .brand-drift-allowlist.txt
SCAN_PATHS: 'packages/ README.md NOTICE'
run: |
set -euo pipefail
if [ ! -f "${ALLOWLIST_FILE}" ]; then
echo "::error::Missing ${ALLOWLIST_FILE} at repo root."
exit 1
fi
mapfile -t ALLOWED < <(grep -vE '^\s*(#|$)' "${ALLOWLIST_FILE}" || true)
is_allowed() {
local candidate="$1"
for entry in "${ALLOWED[@]}"; do
if [ "${candidate}" = "${entry}" ]; then
return 0
fi
done
return 1
}
MERGE_BASE=$(git merge-base "${BASE_SHA}" "${HEAD_SHA}")
# shellcheck disable=SC2086
CHANGED_FILES=$(git diff --name-only --diff-filter=AM \
"${MERGE_BASE}" "${HEAD_SHA}" -- ${SCAN_PATHS} || true)
if [ -z "${CHANGED_FILES}" ]; then
echo "No files in scope changed in this PR."
exit 0
fi
violations=0
while IFS= read -r file; do
[ -z "${file}" ] && continue
if is_allowed "${file}"; then
echo "skip (allowlisted): ${file}"
continue
fi
added=$(git diff -U0 "${MERGE_BASE}" "${HEAD_SHA}" -- "${file}" \
| grep -E '^\+[^+]' || true)
if [ -z "${added}" ]; then
continue
fi
# Exclude package imports (twenty-shared, twenty-ui, etc.) — those are legitimate
filtered=$(echo "${added}" | grep -ivE "from ['\"]twenty-|require\(['\"]twenty-" || true)
if [ -n "${filtered}" ] && echo "${filtered}" | grep -iqE 'twenty'; then
echo "::error file=${file}::Brand drift: PR adds 'twenty' to ${file}."
echo "${added}" | grep -iE 'twenty' | sed 's/^/ /'
violations=$((violations + 1))
fi
done <<< "${CHANGED_FILES}"
if [ "${violations}" -gt 0 ]; then
echo "::error::${violations} file(s) introduced 'twenty' outside the brand-drift allowlist."
exit 1
fi
echo "Brand drift check passed."
# MAIN LANE — full Linux server test coverage, unchanged, but now runs ONLY
# on push to main. PRs and the merge queue get the same suite on the mac
# runner via `server-tests-mac` below (the PR-lane primary gate). Linux test
# coverage is NOT lost — every merge to main still runs this full job on the
# existing [self-hosted, linux, x64] runners.
server-tests:
name: Server unit tests
if: github.event_name == 'push'
runs-on: ${{ github.actor == 'dependabot[bot]' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64"]') }}
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
- name: Build shared
run: npx nx build twenty-shared
- name: Run server tests
# Fail closed: a non-zero exit from the test run must fail the job so
# release green-CI gates cannot pass while server tests fail.
#
# Root cause of the previous (removed) `continue-on-error: true`:
# jest.config.mjs enforced global coverage thresholds (30/20/25/30) and
# the codebase currently sits below them (~27% statements). jest then
# exited non-zero *even when every test passed*, so CI swallowed the
# exit code — which ALSO masked genuine test failures. Coverage
# enforcement is now opt-in (JEST_ENFORCE_COVERAGE, see jest.config.mjs),
# so this step's exit code reflects test pass/fail only: a failing test
# (and only a failing test) fails the job.
# `^build` (nx targetDefaults) builds workspace deps (twenty-emails /
# twenty-client-sdk) first so they resolve in the jest module context;
# `--configuration=ci` pins maxWorkers=1 for deterministic runs.
run: npx nx test twenty-server --configuration=ci -- --passWithNoTests
# PR LANE (primary test gate) — runs the SAME server unit test suite on the
# dedicated self-hosted macOS runner (mac-m4-exe-crm, M4 / 16 cores). Check
# context: "Server unit tests (mac)". Runs ONLY on pull_request + merge_group
# (merge queue requires protection-required contexts to report on merge_group
# or the queue stalls).
#
# Why: the Linux build-my runners share one overloaded host — the full yarn
# workspace install + jest run took 30+ min there and queued behind other
# jobs. The mac runner is a dedicated 16-core box.
#
# `--maxWorkers=6` overrides the `--configuration=ci` pin of maxWorkers=1
# (nx CLI args take precedence over configuration values). maxWorkers=1 on
# Linux exists to avoid core thrash on the SHARED build-my host; the mac
# runner runs only this job, so 6 workers on 16 cores is safe headroom while
# leaving cores for the dev box's own load.
#
# macOS notes: no Docker on this runner (docker-dependent jobs stay on
# Linux — see security-scan); setup-node cache keys include runner OS+arch,
# so the macOS-arm64 yarn cache never collides with the Linux-x64 one.
server-tests-mac:
name: Server unit tests (mac)
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
runs-on: ${{ github.actor == 'dependabot[bot]' && 'ubuntu-latest' || fromJSON('["self-hosted", "macOS", "ARM64", "mac-fast"]') }}
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
- name: Build shared
run: npx nx build twenty-shared
- name: Run server tests
# Same fail-closed semantics as the main-lane `server-tests` job above
# (see its comment for the coverage-threshold / continue-on-error
# history). KEEP THE TWO COMMANDS IN SYNC apart from --maxWorkers.
run: npx nx test twenty-server --configuration=ci --maxWorkers=6 -- --passWithNoTests
security-scan:
name: Security scan (secrets, deps, container config)
runs-on: ${{ github.actor == 'dependabot[bot]' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64"]') }}
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --immutable
# Secret scan (open-source gitleaks binary via its pinned-by-digest image;
# the gitleaks GitHub Action requires a paid license for org repos, the CLI
# does not). --no-git scans the current checkout. Fails closed on findings.
- name: Secret scan (gitleaks)
run: |
docker run --rm -v "$PWD:/repo" \
ghcr.io/gitleaks/gitleaks:v8.21.2@sha256:0e99e8821643ea5b235718642b93bb32486af9c8162c8b8731f7cbdc951a7f46 \
detect --source=/repo --no-git --redact --no-banner --verbose \
--config=/repo/.gitleaks.toml
# Production dependency vulnerability scan. The required gate audits only
# production dependencies at CRITICAL severity; dev-dependency and HIGH
# advisory signals are surfaced by the non-blocking informational step below.
- name: Dependency scan (yarn npm audit, production, critical gate)
run: yarn npm audit --recursive --environment production --severity critical
- name: Dependency scan (yarn npm audit, production, latest high advisory signal)
run: yarn npm audit --all --recursive --environment production --severity high
continue-on-error: true
# Container / IaC misconfiguration scan of the production Docker stack
# (Dockerfile + docker-compose) AND the helm/ + k8s/ orchestration
# manifests (hardened in bug be6e91fe — securityContext, non-root,
# read-only rootfs, cap drops). Complements the full image vulnerability
# scan run at release time (.github/workflows/release-stack-image.yml).
# Fails closed on HIGH+.
- name: Container config scan (Trivy)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: config
scan-ref: packages/twenty-docker
format: table
exit-code: '1'
severity: CRITICAL,HIGH