Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .snyk
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,6 @@ ignore:
reason: 'Transitive dependency in @azure/functions; upgrade path has type errors'
expires: '2026-07-28T00:00:00.000Z'
created: '2026-01-15T11:04:00.000Z'
'SNYK-JS-YAUZL-15467445':
- '* > yauzl@<3.2.1':
reason: 'Transitive dependency in @mongodb-memory-server; not exploitable in current usage.'
expires: '2026-03-26T00:00:00.000Z'
created: '2026-03-12T12:35:00.000Z'
'SNYK-JS-UUID-16133035':
- '* > uuid@8.3.2':
reason: 'Transitive dependency in Docusaurus and Azurite dev-only stacks; no compatible fix path available yet from upstream.'
Expand All @@ -71,11 +66,6 @@ ignore:
reason: 'Mongoose 8.22.1 has TypeScript constraint errors in type definitions (types/inferrawdoctype.d.ts, types/inferschematype.d.ts) that break compilation. Patch attempts failed due to external library type incompatibilities. Risk is Low: requires control of query field names and values.'
expires: '2026-11-07T00:00:00.000Z'
created: '2026-05-07T09:00:00.000Z'
'SNYK-JS-BABELPLUGINTRANSFORMMODULESSYSTEMJS-16624576':
- '* > @babel/plugin-transform-modules-systemjs@7.28.5':
reason: 'Transitive dependency in Docusaurus; not exploitable in current usage.'
expires: '2026-06-28T00:00:00.000Z'
created: '2026-05-11T10:00:00.000Z'
'SNYK-JS-AI-16734889':
- '@docusaurus/preset-classic@3.10.1 > * > ai@5.0.105':
reason: 'Transitive dependency in Docusaurus docsearch; Snyk reports no fixed upgrade or patch available.'
Expand All @@ -101,11 +91,6 @@ ignore:
reason: 'Transitive dependency in Docusaurus CSS optimization/build tooling; Snyk reports no fixed upgrade or patch available. Not exploitable at runtime because docs CSS is repository-controlled and processed at build time.'
expires: '2026-09-18T00:00:00.000Z'
created: '2026-06-08T00:00:00.000Z'
'SNYK-JS-SHELLQUOTE-17457810':
- '* > shell-quote@1.8.4':
reason: 'Transitive dependency in @docusaurus/core via webpack-dev-server > launch-editor; fixed in shell-quote@1.9.0 but no direct upgrade path available. Dev-time only; not exploitable in current usage.'
expires: '2026-12-31T00:00:00.000Z'
created: '2026-06-25T00:00:00.000Z'
'SNYK-JS-IMAGESIZE-17295814':
- '* > image-size@<=2.0.2':
reason: 'Transitive dependency in vitest@4.1.6; not exploitable in current usage.'
Expand Down
2 changes: 1 addition & 1 deletion apps/server-oauth2-mock/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { createMockOAuth2Manager, type MockOAuth2PortalConfig, normalizeBaseUrl, discoverPortalConfigs, type PortalOidcConfig, ensurePortInUrl, createFileUserStore } from '@cellix/server-oauth2-mock-seedwork';
import { createFileUserStore, createMockOAuth2Manager, discoverPortalConfigs, ensurePortInUrl, type MockOAuth2PortalConfig, normalizeBaseUrl, type PortalOidcConfig } from '@cellix/server-oauth2-mock-seedwork';
import { setupEnvironment } from './setup-environment.ts';

setupEnvironment();
Expand Down
6 changes: 3 additions & 3 deletions apps/ui-community/mock-oidc.users.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"username": "test@example.com",
"sub": "00000000-0000-4000-8000-000000000001",
"password": "password",
"oidcConfigName": "end-user",
"oidcConfigName": "end-user",
"claims": {
"email": "test@example.com",
"given_name": "Test",
Expand All @@ -15,7 +15,7 @@
"username": "john.doe@example.com",
"sub": "00000000-0000-4000-8000-000000000002",
"password": "password",
"oidcConfigName": "end-user",
"oidcConfigName": "end-user",
"claims": {
"email": "john.doe@example.com",
"given_name": "John",
Expand All @@ -27,7 +27,7 @@
"username": "owner@test.example",
"sub": "aaaaaaaa-bbbb-1ccc-9ddd-eeeeeeeeee01",
"password": "password",
"oidcConfigName": "end-user",
"oidcConfigName": "end-user",
"claims": {
"email": "owner@test.example",
"given_name": "Test",
Expand Down
2 changes: 1 addition & 1 deletion apps/ui-staff/mock-oidc.users.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"username": "staff@ownercommunity.onmicrosoft.com",
"sub": "10000000-0000-4000-8000-000000000001",
"password": "password",
"oidcConfigName": "staff-user",
"oidcConfigName": "staff-user",
"claims": {
"email": "staff@ownercommunity.onmicrosoft.com",
"given_name": "Staff",
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"!**/dist",
"!**/build",
"!**/deploy",
"!**/target",
"!**/target",
"!**/node_modules",
"!**/coverage",
"!**/.turbo",
Expand Down
37 changes: 37 additions & 0 deletions build-pipeline/scripts/verify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env node
/// <reference types="node" />

import { architectureTests, coverageMerge, e2eTests, knipCheck, pnpmAudit, pnpmScript, snykCodeScan, snykDependencyScan, sonarPullRequestAnalysis, sonarQualityGate, verificationSequence } from '@cellix/local-dev/silent-runners';

const snykOrgArgs = ['--org=cellixjs', '--remote-repo-url=https://github.com/CellixJs/cellixjs'];

const cellixVerify = verificationSequence
.addStep(pnpmScript('format:check'))
.addStep(architectureTests())
.addStep(coverageMerge())
.addStep(e2eTests())
.addStep(knipCheck())
.addStep(pnpmAudit({ auditLevel: 'high', dependencyType: 'prod', name: 'audit:prod' }))
.addStep(pnpmAudit({ auditLevel: 'critical', dependencyType: 'dev', name: 'audit:dev' }))
.addStep(
snykDependencyScan({
args: [...snykOrgArgs, '--policy-path=.snyk', '--file=package.json', '--severity-threshold=high'],
}),
)
.addStep(
snykCodeScan({
args: snykOrgArgs,
}),
)
.addStep(sonarPullRequestAnalysis())
.addStep(sonarQualityGate());

function runVerifyCommand(): void {
const result = cellixVerify.run();
if (result.status === 0) {
process.stdout.write('verify passed\n');
}
process.exitCode = result.status;
}

runVerifyCommand();
8 changes: 6 additions & 2 deletions knip.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"workspaces": {
".": {
"entry": ["build-pipeline/scripts/verify.ts"],
"project": ["build-pipeline/scripts/**/*.ts"]
},
"apps/api": {
"entry": ["src/index.ts", "start-*.mjs"],
"project": ["src/**/*.ts", "*.mjs"],
Expand Down Expand Up @@ -82,7 +86,7 @@
"entry": ["cucumber.js", "src/world.ts", "src/step-definitions/index.ts", "src/shared/abilities/index.ts"],
"project": ["src/**/*.ts"],
"ignoreBinaries": ["report"],
"ignoreUnresolved": ["progress-bar"]
"ignoreUnresolved": ["progress-bar"]
},
"packages/ocom-verification/acceptance-ui": {
"entry": ["cucumber.js", "src/world.ts", "src/step-definitions/index.ts"],
Expand All @@ -93,7 +97,7 @@
"packages/ocom-verification/e2e-tests": {
"entry": ["cucumber.js", "src/world.ts", "src/contexts/**/step-definitions/**/*.steps.ts", "src/shared/environment/**/*.ts", "src/shared/abilities/**/*.ts"],
"project": ["src/**/*.ts"],
"ignoreUnresolved": ["progress-bar"]
"ignoreUnresolved": ["progress-bar"]
},
"apps/server-oauth2-mock": {
"entry": ["src/index.ts"],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"sonar:pr": "export PR_NUMBER=$(node build-pipeline/scripts/get-pr-number.cjs) && sonar-scanner -Dsonar.pullrequest.key=$PR_NUMBER -Dsonar.pullrequest.branch=$(git branch --show-current) -Dsonar.pullrequest.base=main",
"sonar:pr-windows": "for /f %i in ('node build-pipeline/scripts/get-pr-number.cjs') do set PR_NUMBER=%i && sonar-scanner -Dsonar.pullrequest.key=%PR_NUMBER% -Dsonar.pullrequest.branch=%BRANCH_NAME% -Dsonar.pullrequest.base=main",
"check-sonar": "node build-pipeline/scripts/check-sonar-quality-gate.cjs",
"verify": "pnpm run format:check && pnpm run test:arch && pnpm run test:coverage:merge && pnpm run test:e2e:worktree && pnpm run knip && pnpm run audit && pnpm run snyk",
"verify": "node --conditions=source build-pipeline/scripts/verify.ts",
"knip": "knip",
"snyk": "pnpm run snyk:test && pnpm run snyk:code",
"snyk:report": "pnpm run snyk:monitor && pnpm run snyk:code:report",
Expand All @@ -73,6 +73,7 @@
"@ant-design/cli": "^6.3.5",
"@biomejs/biome": "2.4.10",
"@cellix/graphql-codegen": "workspace:*",
"@cellix/local-dev": "workspace:*",
"@graphql-codegen/cli": "^5.0.7",
"@graphql-codegen/introspection": "^4.0.3",
"@graphql-codegen/typed-document-node": "^5.1.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/cellix/local-dev/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/dist
/node_modules
119 changes: 119 additions & 0 deletions packages/cellix/local-dev/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# @cellix/local-dev

Local developer wrappers for Cellix verification commands.

This package is intentionally small on this branch. Other pull requests add
additional local-development modules to the same package; this change owns only
the silent command runner export and its portable tool wrappers.

## Install

In this monorepo, consumers use the workspace package directly:

```json
{
"devDependencies": {
"@cellix/local-dev": "workspace:*"
}
}
```

## Silent Runners

`runSilentCommand` captures stdout and stderr while a command is running. If the
command succeeds, nothing is printed. If it fails, whatever the command wrote to
stdout and stderr is replayed before the failing status is returned.

```js
import { runSilentCommand } from '@cellix/local-dev/silent-runners';

const result = runSilentCommand({
command: 'snyk',
args: ['test', '--all-projects'],
});

process.exitCode = result.status;
```

Use `runSilentCommandSequence` when a wrapper needs to run several commands in
order. Steps are silent by default; mark a step with `output: 'inherit'` only
when its live output is part of the intended consumer experience.

```js
import { runSilentCommandSequence } from '@cellix/local-dev/silent-runners';

const result = runSilentCommandSequence({
steps: [
{ name: 'format:check', command: 'pnpm', args: ['run', 'format:check'] },
{ name: 'test:e2e', command: 'pnpm', args: ['run', 'test:e2e'] },
],
});

process.exitCode = result.status;
```

For reusable verification workflows, use the fluent sequence builder:

```js
import { pnpmScript, verificationSequence } from '@cellix/local-dev/silent-runners';

const verify = verificationSequence
.addStep(pnpmScript('format:check'))
.addStep(pnpmScript('test'));

const result = verify.run();
process.exitCode = result.status;
```

Prefer the named tool wrappers when a command has a known CLI shape:

```js
import { knipCheck, pnpmAudit, runSilentCommandSequence, snykCodeScan, snykDependencyScan } from '@cellix/local-dev/silent-runners';

const result = runSilentCommandSequence({
steps: [
knipCheck(),
pnpmAudit({ auditLevel: 'high', dependencyType: 'prod' }),
snykDependencyScan({ args: ['--all-projects', '--org=my-org'] }),
snykCodeScan({ args: ['--org=my-org'] }),
],
});
```

## Public API

Exports are available from `@cellix/local-dev` and
`@cellix/local-dev/silent-runners`:

- `runSilentCommand`
- `runSilentCommandSequence`
- `CommandOutputMode`
- `CommandSequenceStep`
- `architectureTests`
- `coverageMerge`
- `e2eTests`
- `knipCheck`
- `livePnpmScript`
- `pnpmAudit`
- `pnpmScript`
- `SilentCommandOptions`
- `SilentCommandResult`
- `SilentCommandSequenceOptions`
- `SilentCommandSequenceResult`
- `SilentRunnerSpawnSync`
- `SilentRunnerStreams`
- `snykCodeScan`
- `snykDependencyScan`
- `snykIacScan`
- `sonarPullRequestAnalysis`
- `sonarQualityGate`
- `VerificationSequence`
- `VerificationSequenceOptions`
- `verificationSequence`

## Notes

- Tool wrappers encode reusable CLI shape; scripts still own project-specific arguments such as org names, paths, and CI policy.
- Success is silent; failure replays whatever the command wrote to stdout/stderr.
- Captured output defaults to 64 MiB and can be adjusted with `maxBuffer` for a command, sequence, or individual sequence step.
- Commands run without shell interpolation. Pass the executable as `command` and arguments as `args`.
75 changes: 75 additions & 0 deletions packages/cellix/local-dev/manifest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# manifest.md - @cellix/local-dev

## Purpose

Provide local developer wrappers for Cellix commands that should be quiet on
success and diagnostic on failure.

## Scope

This branch owns only the silent verification runner surface and portable tool
wrappers. Other local-dev modules from related pull requests will share this
package after the branches are merged.

## Non-goals

- Project-specific Snyk, Edgescan, or scanner policy such as org names,
repository URLs, token handling, or report publishing
- Worktree ports, app dev-server runners, URL transforms, or settings sync

## Public API shape

Published entrypoints:

- `@cellix/local-dev`
- `@cellix/local-dev/silent-runners`

Root entrypoint exports:

- `runSilentCommand(options)`
- `runSilentCommandSequence(options)`
- `VerificationSequence`
- `verificationSequence`
- tool-wrapper builders such as `knipCheck()`, `pnpmAudit(options)`,
`snykDependencyScan(options)`, `snykCodeScan(options)`, and
`sonarPullRequestAnalysis(options)`

## Core concepts

- Silent verification runners capture external command output, emit nothing on
success, and replay whatever the command wrote to stdout/stderr on failure.
- Silent command sequences run ordered verification steps, defaulting each step
to silent output while allowing explicit passthrough where live output is
intentionally part of the command contract.
- Fluent verification sequences provide a reusable `.addStep(...).run(...)`
object API over the same ordered, stop-on-failure behavior.
- Tool wrappers encode portable CLI shapes; root or app scripts own
project-specific arguments.
- Commands are spawned without shell interpolation.

## Package boundaries

- Do not encode project-specific Snyk, Edgescan, or scanner policy here.
- Keep this branch scoped to the silent runner module so it can merge cleanly
with other `@cellix/local-dev` modular exports.

## Dependencies / relationships

- Downstream consumers in this monorepo: the root `verify` script.

## Testing strategy

- Public-entrypoint tests prove success output is suppressed, failure output is
replayed, and the root verify sequence uses the expected tool wrappers while
remaining fully silent on success.

## Documentation obligations

- Keep README.md consumer-facing and focused on silent runners until the broader
local-dev package exports merge.
- Keep TSDoc aligned on the public runner API.

## Release-readiness standards

- Package build and package tests must pass.
- Root verification scripts should preserve their existing command arguments.
Loading
Loading