Skip to content
Merged
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
59 changes: 59 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false

- name: Set up pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
Expand Down Expand Up @@ -61,9 +64,20 @@ jobs:
- name: Lint
run: pnpm -w lint

- name: Find dead code and dependencies
run: pnpm -w knip

- name: Build
run: pnpm -w build

- name: Lint changed code strictly
env:
ESLINT_PLUGIN_DIFF_COMMIT: ${{ github.event.pull_request.base.sha || github.event.before || 'HEAD^' }}
run: pnpm -w lint:strict:ci

- name: Enforce dashboard bundle budgets
run: pnpm -w size

- name: Run PR runtime smoke tests
if: github.event_name == 'pull_request'
run: pnpm --filter @ultrafuzz/runtime test:pr-smoke:prebuilt
Expand All @@ -72,6 +86,39 @@ jobs:
if: github.event_name == 'pull_request'
run: pnpm --filter @ultrafuzz/cli test:pr-smoke:prebuilt

external-static-analysis:
name: External static analysis
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false

- name: Run Super-Linter
uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0
env:
ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT: false
MULTI_STATUS: false
VALIDATE_ALL_CODEBASE: false
VALIDATE_BASH: true
VALIDATE_BASH_EXEC: true
VALIDATE_CSS: true
VALIDATE_DOCKERFILE_HADOLINT: true
VALIDATE_ENV: true
VALIDATE_GITHUB_ACTIONS: true
VALIDATE_GITHUB_ACTIONS_ZIZMOR: true
VALIDATE_GITLEAKS: true
VALIDATE_HTML: true
VALIDATE_JSON: true
VALIDATE_JSONC: true
VALIDATE_MARKDOWN: true
VALIDATE_SHELL_SHFMT: true
VALIDATE_YAML: true

# The lane table lives in scripts/ci/release-validation-lanes.mjs so the
# pull-request policy is a tested artifact instead of an invisible `if:`.
# While this job was gated off pull requests, every runtime test reported
Expand All @@ -86,6 +133,8 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Select release validation lanes
id: select
Expand All @@ -98,6 +147,7 @@ jobs:
name: Full release validation (${{ matrix.description }})
needs:
- draft-and-build-gates
- external-static-analysis
- release-validation-lanes
runs-on: ubuntu-latest
timeout-minutes: ${{ matrix.timeout_minutes }}
Expand All @@ -113,6 +163,8 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Set up pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
Expand Down Expand Up @@ -166,6 +218,7 @@ jobs:
release-gates:
needs:
- draft-and-build-gates
- external-static-analysis
- release-validation-lanes
- release-validation
if: always()
Expand All @@ -177,13 +230,19 @@ jobs:
if: needs.draft-and-build-gates.result != 'success'
run: exit 1

- name: Require external static analysis
if: needs.external-static-analysis.result != 'success'
run: exit 1

- name: Require the release validation lane selection
if: needs.release-validation-lanes.result != 'success'
run: exit 1

- name: Check out repository
if: github.event_name != 'pull_request'
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Set up pnpm
if: github.event_name != 'pull_request'
Expand Down
12 changes: 12 additions & 0 deletions .size-limit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"name": "dashboard JavaScript",
"path": "packages/dashboard/dist/public/assets/*.js",
"limit": "250 kB"
},
{
"name": "dashboard CSS",
"path": "packages/dashboard/dist/public/assets/*.css",
"limit": "10 kB"
}
]
76 changes: 73 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import diff from "eslint-plugin-diff";
import globals from "globals";
import tseslint from "typescript-eslint";

const strictLint = process.env.ULTRAFUZZ_STRICT_LINT === "1";
const browserFiles = ["packages/dashboard/frontend/{public,src}/**/*.{js,ts,tsx}"];
const typescriptFiles = ["packages/**/*.{ts,tsx}", "scripts/**/*.{ts,tsx}"];
const typeCheckedFiles = ["packages/*/src/**/*.ts", "packages/dashboard/frontend/src/**/*.{ts,tsx}"];
const sourceFiles = ["packages/**/*.{js,mjs,cjs,ts,tsx}", "scripts/**/*.{js,mjs,cjs,ts,tsx}"];
const strictConfigs = strictLint
? [
...tseslint.configs.strict.map((config) => ({
...config,
files: typescriptFiles
})),
...tseslint.configs.strictTypeChecked.map((config) => ({
...config,
files: typeCheckedFiles
})),
{
files: typeCheckedFiles,
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname
}
}
},
{
files: sourceFiles,
rules: {
complexity: ["error", 20],
"max-depth": ["error", 4],
"max-lines": ["error", { max: 500, skipBlankLines: true, skipComments: true }],
"max-lines-per-function": ["error", { max: 80, skipBlankLines: true, skipComments: true }],
"max-nested-callbacks": ["error", 4],
"max-params": ["error", 5],
"max-statements": ["error", 40],
"no-console": "error",
"no-warning-comments": ["error", { terms: ["todo", "fixme"], location: "anywhere" }]
}
},
{
files: [
"**/{test,tests}/**/*.{js,mjs,cjs,ts,tsx}",
"**/*.test.{js,mjs,cjs,ts,tsx}",
"packages/runtime/src/templates/**/*.tsx"
],
rules: {
complexity: ["error", 25],
"max-lines": ["error", { max: 1000, skipBlankLines: true, skipComments: true }],
"max-lines-per-function": ["error", { max: 150, skipBlankLines: true, skipComments: true }],
"max-params": ["error", 6],
"max-statements": ["error", 80]
}
}
]
: [];

export default tseslint.config(
{
ignores: [
Expand All @@ -16,18 +72,31 @@ export default tseslint.config(
"coverage/**"
]
},
{
linterOptions: { reportUnusedDisableDirectives: "error" }
},
js.configs.recommended,
...tseslint.configs.recommended,
...strictConfigs,
{
files: ["**/*.{js,mjs,ts}"],
files: ["**/*.{js,mjs,cjs,ts,tsx}"],
ignores: browserFiles,
languageOptions: {
ecmaVersion: "latest",
globals: globals.node,
sourceType: "module"
}
},
{
files: ["**/*.ts"],
files: browserFiles,
languageOptions: {
ecmaVersion: "latest",
globals: globals.browser,
sourceType: "module"
}
},
{
files: ["**/*.{ts,tsx}"],
rules: {
"no-undef": "off",
"@typescript-eslint/consistent-type-imports": [
Expand All @@ -47,5 +116,6 @@ export default tseslint.config(
]
}
},
eslintConfigPrettier
eslintConfigPrettier,
...(strictLint ? diff.configs[process.env.CI ? "flat/ci" : "flat/diff"] : [])
);
28 changes: 28 additions & 0 deletions knip.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "https://unpkg.com/knip@6/schema.json",
"workspaces": {
".": { "entry": ["scripts/validate-audit-profile-package.mjs"] },
"packages/dashboard": {
"entry": ["frontend/public/theme-bootstrap.js"]
},
"packages/evals": {
"entry": ["src/index.ts", "test/append-eval-run-record-child.ts"]
},
"packages/evmbench": {
"entry": ["src/{index,cli,adapter-cli,update-lock}.ts"]
},
"packages/modal": {
"entry": [
"src/index.ts",
"scripts/prepare-smithers-seed.mjs",
"src/worker.ts",
"test/modal-download-helper-fixture.mjs"
]
},
"packages/runtime": {
"entry": ["src/templates/**/*.tsx"],
"ignoreDependencies": ["@moonshot-ai/kimi-code", "react"],
"ignoreUnresolved": ["^__ULTRAFUZZ_WORKFLOW_IMPORT__$", "^\\.\\./agents/index\\.ts$"]
}
}
}
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
"benchmark:check": "pnpm --filter @ultrafuzz/cli... build && pnpm -w benchmark:check:prebuilt",
"benchmark:check:prebuilt": "node packages/cli/dist/index.js eval history --check --project .",
"benchmark:history:check": "pnpm -w benchmark:check",
"ci": "pnpm -w format:check && pnpm -w lint && pnpm -w build && pnpm -w validate:release",
"ci": "pnpm -w format:check && pnpm -w lint && pnpm -w knip && pnpm -w build && pnpm -w lint:strict && pnpm -w size && pnpm -w validate:release",
"docs:audit-profiles": "node scripts/audit-profile-docs.mjs",
"docs:check": "node scripts/audit-profile-docs.mjs --check && node scripts/docs-check.mjs",
"format": "prettier --write .",
"format:check": "prettier --check .",
"lint": "eslint \"packages/**/*.{ts,js,mjs}\" \"scripts/**/*.{ts,js,mjs}\" \"*.{js,mjs}\"",
"lint:fix": "eslint \"packages/**/*.{ts,js,mjs}\" \"scripts/**/*.{ts,js,mjs}\" \"*.{js,mjs}\" --fix",
"knip": "pnpm dlx knip@6.33.0 --include files,dependencies,unlisted,unresolved --treat-config-hints-as-errors",
"lint": "eslint \"packages/**/*.{ts,tsx,js,mjs,cjs}\" \"scripts/**/*.{ts,tsx,js,mjs,cjs}\" \"*.{js,mjs,cjs}\"",
"lint:fix": "eslint \"packages/**/*.{ts,tsx,js,mjs,cjs}\" \"scripts/**/*.{ts,tsx,js,mjs,cjs}\" \"*.{js,mjs,cjs}\" --fix",
"lint:strict": "ULTRAFUZZ_STRICT_LINT=1 eslint \"packages/**/*.{ts,tsx,js,mjs,cjs}\" \"scripts/**/*.{ts,tsx,js,mjs,cjs}\" \"*.{js,mjs,cjs}\" --max-warnings 0",
"lint:strict:ci": "bash -o pipefail -c ': \"${ESLINT_PLUGIN_DIFF_COMMIT:?required}\"; git diff --name-only --diff-filter=ACMR -z \"$ESLINT_PLUGIN_DIFF_COMMIT\" -- \"*.js\" \"*.mjs\" \"*.cjs\" \"*.ts\" \"*.tsx\" | xargs -0 --no-run-if-empty env ULTRAFUZZ_STRICT_LINT=1 eslint --max-warnings 0'",
"security:dependency-advisories": "pnpm --filter @ultrafuzz/artifacts... build && node scripts/check-production-dependency-advisories.mjs",
"size": "size-limit",
"test": "pnpm run test:ci-scripts && pnpm -r test",
"test:ci-scripts": "pnpm --filter @ultrafuzz/modal... build && bun test --timeout 30000 scripts/ci/*.test.ts",
"validate:pack": "node scripts/validate-packed-install.mjs",
Expand All @@ -30,12 +34,15 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@size-limit/file": "13.0.3",
"@types/node": "^24.0.0",
"@ultrafuzz/modal": "workspace:*",
"eslint": "^10.6.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-diff": "2.1.7",
"globals": "^17.7.0",
"prettier": "^3.9.4",
"size-limit": "13.0.3",
"typescript": "^5.8.3",
"typescript-eslint": "^8.62.1",
"vitest": "^3.2.4",
Expand Down
Loading