@diplodoc/infra
v2.0.1
Published
Diplodoc platform infrastructure management — linting, CI workflows, and scaffolding
Keywords
Readme
@diplodoc/infra
Central infrastructure package for the Diplodoc platform. Manages linting configurations, CI workflows, Git hooks, and automated distribution of infrastructure updates across 30+ repositories.
Migration note: This package was formerly named
@diplodoc/lint. It also replaces the deprecated@diplodoc/eslint-configand@diplodoc/prettier-configpackages.
Features
- Unified linting — shared ESLint, Prettier, and Stylelint configurations
- Automated distribution — infrastructure updates delivered via PRs to all repos on release
- Blacklist support — per-repo exclusions for selective scaffolding
- Pre-release testing — scaffolding changes tested against real packages before release
- Auto-merge — PRs auto-merge when CI passes (configurable per repo)
- Git hooks — pre-commit and commit-msg hooks via Husky
- Pre-bundled esbuild — shared esbuild version via
@diplodoc/infra/esbuild
Installation
npm install --save-dev @diplodoc/infraQuick Start
First-Time Setup
npx @diplodoc/infra initThis will:
- Add
lint,lint:fix,pre-commit,preparescripts topackage.json - Create configuration files (
.eslintrc.js,.prettierrc.js,.stylelintrc.js, etc.) - Set up Git hooks via Husky
- Update ignore files (
.gitignore,.eslintignore, etc.) - Create GitHub Actions workflow templates
Linting
npm run lint # Check for issues
npm run lint:fix # Auto-fix issuesManual Infrastructure Update
npx @diplodoc/infra updateNote: In normal workflow, infrastructure updates are delivered automatically via PRs from the infra repo. Manual updates are for development and debugging only.
How Distribution Works
Infrastructure updates follow a push model:
- Changes are made to scaffolding files in this repo
integration-test.ymltests changes against 3 reference packages before merge- On release,
distribute-infra.ymlcreates PRs in all target repositories - PRs are auto-merged when CI passes (unless disabled for the repo)
@diplodoc/infra release
│
▼
distribute-infra.yml
│
├─→ cli (PR, manual review)
├─→ transform (PR, manual review)
├─→ cut-extension (PR, auto-merge)
├─→ tabs-extension (PR, auto-merge)
└─→ ... 26 more reposBlacklist (Exclusions)
Some files can be excluded from distribution for specific repos:
Centralized — in distribution.yml (this repo):
repos:
cli:
auto_merge: false
exclude:
- path: .github/workflows/tests.yml
reason: 'Custom E2E workflow'
- path: .github/workflows/release.yml
reason: 'Node.js 24 migration in progress'
until: '2026-07-01'Per-repo — in .infrarc.yml (target repo root):
exclude:
- path: .github/workflows/tests.yml
reason: 'Custom matrix build'
- .editorconfigBoth lists are merged during distribution. Entries with expired until dates are ignored.
Supported Tools
ESLint
- Configurations for TypeScript and JavaScript
- React support (via
eslint-config/client) - Node.js support (via
eslint-config/node) - Project-aware TypeScript parsing
- Uses
ESLINT_USE_FLAT_CONFIG=false(legacy ESLint 8-style config)
Prettier
- Unified formatting style for all packages
- Uses
@gravity-ui/prettier-configas base
Stylelint
- CSS and SCSS support
- Uses
@gravity-ui/stylelint-configas base
Husky
- Git hooks management
- Pre-commit hook runs
lint-staged
lint-staged
- Checks only changed files
- Fast pre-commit checking
- Runs unit tests when test/source files change
SonarCloud
Scaffolding provides optional SonarCloud integration:
sonar-project.properties— copied with{{PACKAGE_NAME}}substitution (scope removed, e.g.@diplodoc/foo→foo).github/workflows/sonarcloud.yml— runs analysis on push/PR tomaster/main(only whentest:coveragescript exists).github/workflows/coverage.yml— optional, runstest:coveragewhen script exists
To enable SonarCloud for a repository:
- Add the repository in SonarCloud (organization
diplodoc-platform) - Add the SONAR_TOKEN secret in GitHub repo settings
- Optionally add a
test:coveragescript (e.g.vitest run --coverage)
Commands
lint (linting only)
| Command | Description |
| ------------- | ----------------------------------------------- |
| lint | Run ESLint + Prettier + Stylelint in check mode |
| lint fix | Run all linters with auto-fix |
| lint init | Initialize infrastructure in current package |
| lint update | Update scaffolding files locally |
infra (infrastructure management)
| Command | Description |
| --------------------------------- | -------------------------------------- |
| infra sync --all | Create PRs in all target repos |
| infra sync --repo cli | Create PR in a specific repo |
| infra sync --dry-run --all | Preview changes without creating PRs |
| infra sync --target ./path | Apply scaffolding to a local directory |
| infra blacklist show --repo cli | Show exclusions for a repo |
| infra blacklist audit | List expired exclusions |
Configuration
⚠️ Important: Auto-Generated Files
The following configuration files are automatically generated and updated by @diplodoc/infra:
.eslintrc.js,.prettierrc.js,.stylelintrc.js,.lintstagedrc.js.eslintignore,.prettierignore,.stylelintignore.gitignore(patterns are added automatically).github/workflows/*.yml
⚠️ DO NOT EDIT THESE FILES MANUALLY — any changes will be overwritten on the next infrastructure update.
If you need to customize:
- Check if the customization can be done via package-level overrides (e.g.
src/.eslintrc.js) - If not, add the file to blacklist (
.infrarc.yml) and manage it manually - Or open a PR to
@diplodoc/infrato add the feature to templates
Configuration File Examples
.eslintrc.js:
module.exports = {
root: true,
extends: require.resolve('@diplodoc/infra/eslint-config'),
parserOptions: {
tsconfigRootDir: __dirname,
project: true,
},
};Packages can extend the configuration at src/ level, but should not override base settings.
.prettierrc.js:
module.exports = require('@diplodoc/infra/prettier-config');.stylelintrc.js:
module.exports = {
extends: require.resolve('@diplodoc/infra/stylelint-config'),
};Auto-Generated Files
The following files are created/updated by infra init and infra update:
| File | Purpose | Editable? |
| -------------------------- | ------------------------------------------------------- | ----------------------------------------- |
| .eslintrc.js | ESLint config (extends @diplodoc/infra/eslint-config) | No — use src/.eslintrc.js for overrides |
| .prettierrc.js | Prettier config | No |
| .stylelintrc.js | Stylelint config | No |
| .lintstagedrc.js | lint-staged config | No |
| .editorconfig | Editor settings | No |
| .husky/pre-commit | Pre-commit hook | No |
| .husky/commit-msg | Commit message validation | No |
| .github/workflows/*.yml | CI workflows | No — use blacklist to exclude |
| sonar-project.properties | SonarCloud config | No |
Do not edit these files manually — changes will be overwritten on the next infrastructure update.
Package Scripts
After infra init, the following scripts are added:
{
"lint": "lint",
"lint:fix": "lint fix",
"pre-commit": "lint-staged",
"prepare": "husky || true"
}Exports
// ESLint configurations
require('@diplodoc/infra/eslint-config'); // Common
require('@diplodoc/infra/eslint-config/client'); // Client-side (React)
require('@diplodoc/infra/eslint-config/node'); // Node.js
// Prettier
require('@diplodoc/infra/prettier-config');
// Stylelint
require('@diplodoc/infra/stylelint-config');
// Pre-bundled esbuild
import {build} from '@diplodoc/infra/esbuild';Pre-bundled esbuild
Use @diplodoc/infra/esbuild instead of adding esbuild as a direct dependency. This ensures all packages share the same version and native bindings:
import {build} from '@diplodoc/infra/esbuild';
build({
entryPoints: ['src/plugin/index.ts'],
outfile: 'build/plugin/index.js',
bundle: true,
platform: 'node',
packages: 'external',
});distribution.yml Reference
defaults:
auto_merge: true # PRs auto-merge when CI passes
exclude: [] # Global exclusions (applied to all repos)
repos:
cli:
auto_merge: false # Manual review required
exclude:
- .github/workflows/tests.yml # Exact path
- .github/workflows/*.yml # Glob pattern
- path: .github/workflows/release.yml # Extended format
reason: 'Custom release process' # Why excluded
until: '2026-07-01' # Auto-expiresMetapackage vs Standalone Usage
The package works in two modes:
In Metapackage (workspace mode)
When installed as part of the Diplodoc metapackage via npm workspaces:
- Located at
devops/infra/in the metapackage - Dependencies are resolved through shared
node_modules - Commands work through workspace links
package-lock.jsonis managed at the metapackage level
Standalone Mode
When used as an independent npm package:
- All dependencies are installed locally
- Commands work through
node_modules/.bin - For
package-lock.jsonmanagement, usenpm i --no-workspaces --package-lock-only
Both modes are supported automatically — path resolution uses require.resolve() which works in both contexts.
Development
Package Structure
@diplodoc/infra/
├── bin/
│ ├── lint.js # Linting CLI
│ ├── infra.js # Infrastructure CLI
│ ├── eslint # ESLint proxy
│ ├── prettier # Prettier proxy
│ └── ...
├── scripts/
│ ├── copy-scaffolding.js # Scaffolding with blacklist support
│ ├── modify-package.js # Adds scripts to consumer package.json
│ ├── modify-ignore.js # Updates .ignore files
│ └── modify-release-please.js
├── scaffolding/ # Template files distributed to consumers
├── distribution.yml # Repo list + blacklist + auto-merge config
├── *-config.js # Lint configuration files
└── test/
├── unit/
├── integration/
└── helpers/Testing
npm test # All tests
npm run test:unit # Unit tests only
npm run test:integration # Integration tests onlyCI Workflows (in this repo)
integration-test.yml— On PR: applies scaffolding to cli, transform, cut-extension; runs their full CI. Blocks merge if anything breaks.distribute-infra.yml— On release or manual trigger: creates PRs in all target repos withmax-parallel: 5.
Migration from @diplodoc/lint
For consumer packages:
- Replace
@diplodoc/lintwith@diplodoc/infraindevDependencies - Run
npx @diplodoc/infra init(or wait for the automated PR) - The auto-generated config files will be updated to reference
@diplodoc/infra/*
For import paths:
@diplodoc/lint/eslint-config→@diplodoc/infra/eslint-config@diplodoc/lint/prettier-config→@diplodoc/infra/prettier-config@diplodoc/lint/stylelint-config→@diplodoc/infra/stylelint-config@diplodoc/lint/esbuild→@diplodoc/infra/esbuild
License
MIT
