sonar-autofix 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +164 -0
- package/README.md +2 -2
- package/config.example.json +3 -1
- package/package.json +6 -2
- package/scripts/publish-all.js +211 -0
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -197
- package/packages/cli/index.js +0 -132
- package/packages/cli/package.json +0 -23
- package/packages/core/index.js +0 -475
- package/packages/core/package.json +0 -22
- package/packages/git-client/index.js +0 -371
- package/packages/git-client/package.json +0 -17
- package/packages/github-action/action.yml +0 -71
- package/packages/github-action/index.js +0 -86
- package/packages/github-action/package.json +0 -17
- package/packages/llm-client/index.js +0 -419
- package/packages/llm-client/package.json +0 -17
- package/packages/sonar-client/index.js +0 -343
- package/packages/sonar-client/package.json +0 -20
- package/packages/validator/index.js +0 -170
- package/packages/validator/package.json +0 -17
package/AGENTS.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`sonar-autofix` is a Node.js monorepo (npm workspaces) that automatically fixes
|
|
8
|
+
code issues found by SonarQube/SonarCloud using LLMs. It runs Sonar analysis,
|
|
9
|
+
fetches open issues, prioritizes and groups them by file, asks an
|
|
10
|
+
OpenAI-compatible LLM to fix each file, validates the changes, then commits,
|
|
11
|
+
pushes a branch, and opens a PR. It ships both as a CLI (`sonar-autofix`) and a
|
|
12
|
+
GitHub Action.
|
|
13
|
+
|
|
14
|
+
Workflow (implemented in `@sonar-autofix/core`):
|
|
15
|
+
1. Create a working branch (default `sonar-autofix`); capture the base branch
|
|
16
|
+
for the PR first.
|
|
17
|
+
2. Run `sonar-scanner`, wait for the Quality Gate.
|
|
18
|
+
3. Fetch open issues (`OPEN`/`CONFIRMED` via `api/issues/search`).
|
|
19
|
+
4. Prioritize (severity BLOCKER > CRITICAL > MAJOR > MINOR > INFO, then type
|
|
20
|
+
BUG > VULNERABILITY > SECURITY_HOTSPOT > CODE_SMELL).
|
|
21
|
+
5. Group issues by file — one LLM call per file, not per issue.
|
|
22
|
+
6. Fix each file with up to `retry.maxRetries` attempts (default 3); on
|
|
23
|
+
exhausted retries, restore the original file content.
|
|
24
|
+
7. Repeat until no fixable issues remain or `retry.maxIterations` (default 5)
|
|
25
|
+
is reached.
|
|
26
|
+
8. Commit, push, and create a PR via the GitHub CLI.
|
|
27
|
+
|
|
28
|
+
## Repository Layout
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
sonar-autofix/
|
|
32
|
+
├── packages/
|
|
33
|
+
│ ├── core/ @sonar-autofix/core — orchestration only (CoreOrchestrator)
|
|
34
|
+
│ ├── sonar-client/ @sonar-autofix/sonar-client — Sonar REST API + sonar-scanner
|
|
35
|
+
│ ├── llm-client/ @sonar-autofix/llm-client — multi-provider LLM client
|
|
36
|
+
│ ├── git-client/ @sonar-autofix/git-client — git/gh subprocess wrapper
|
|
37
|
+
│ ├── validator/ @sonar-autofix/validator — runs build/lint/test commands
|
|
38
|
+
│ ├── cli/ @sonar-autofix/cli — `sonar-autofix` bin entry
|
|
39
|
+
│ └── github-action/ action.yml + index.js — thin GitHub Action wrapper
|
|
40
|
+
├── prompts/ fix-issues.md, retry-fix.md (Handlebars-style templates)
|
|
41
|
+
├── config.example.json
|
|
42
|
+
└── package.json workspaces: ["packages/*"]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Dependency chain: `cli → core → {sonar-client, llm-client, git-client}`;
|
|
46
|
+
`github-action → core`. `validator` is standalone.
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install # install all workspaces
|
|
52
|
+
npm test # runs node tests/core.test.js
|
|
53
|
+
node packages/cli/index.js --help # CLI help (also: --version, --dry-run)
|
|
54
|
+
node packages/cli/index.js --config config.example.json --dry-run
|
|
55
|
+
|
|
56
|
+
# Releasing (bumps every package, rewrites internal @sonar-autofix/* ranges,
|
|
57
|
+
# publishes in dependency order: leaves -> core -> cli/github-action -> root)
|
|
58
|
+
npm run publish:all -- --dry-run # preview the plan, change nothing
|
|
59
|
+
npm run publish:all # patch bump + publish (default)
|
|
60
|
+
npm run publish:all -- minor # minor (or `major`) bump + publish
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Notes:
|
|
64
|
+
- There is no build step and no TypeScript — packages are plain CommonJS run
|
|
65
|
+
directly with Node (Node 20+; the GitHub Action uses the `node20` runtime).
|
|
66
|
+
- `npm test` currently points at `tests/core.test.js`, which does not exist
|
|
67
|
+
yet; the root `test:structure` script likewise references a missing
|
|
68
|
+
`test-project.js`. Do not assume a working test suite exists; if you add
|
|
69
|
+
tests, place them at `tests/` and keep them runnable with plain `node`
|
|
70
|
+
(no test framework is installed).
|
|
71
|
+
- The only runtime dependency is `axios` (hoisted to the root). Avoid adding
|
|
72
|
+
new third-party dependencies.
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
All clients are config-driven. The config shape (see `config.example.json`):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"sonar": { "host": "...", "project": "<projectKey>", "token": "..." },
|
|
81
|
+
"llm": { "provider": "lmstudio", "endpoint": "...", "model": "...", "apiKey": "..." },
|
|
82
|
+
"validation": { "build": ["npm run build"], "lint": ["npm run lint"], "tests": ["npm test"] },
|
|
83
|
+
"git": { "branch": "sonar-autofix", "baseBranch": "", "token": "", "username": "" },
|
|
84
|
+
"retry": { "maxIterations": 5, "maxRetries": 3 },
|
|
85
|
+
"prompt": { "codingGuidelines": "", "projectInstructions": "" },
|
|
86
|
+
"dryRun": false,
|
|
87
|
+
"restoreOnFail": false,
|
|
88
|
+
"cwd": "."
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- LLM providers: `lmstudio` (default), `openai`, `azure`, `anthropic`,
|
|
93
|
+
`ollama`, `openrouter`. Provider-specific URL/header/body handling lives in
|
|
94
|
+
`llm-client/_resolveUrl`, `_buildHeaders`, `_buildBody`, `_extractResponse` —
|
|
95
|
+
keep all providers supported when touching them.
|
|
96
|
+
- The CLI (and GitHub Action) support env-var overrides:
|
|
97
|
+
`SONAR_HOST`, `SONAR_PROJECT`, `SONAR_TOKEN`, `LLM_PROVIDER`, `LLM_ENDPOINT`,
|
|
98
|
+
`LLM_MODEL`, `LLM_API_KEY`, `GIT_BRANCH`, `GIT_BASE_BRANCH`, `GITHUB_TOKEN`,
|
|
99
|
+
`GIT_USERNAME`. `git-client` also falls back to `GH_TOKEN`/`GIT_TOKEN`.
|
|
100
|
+
Env vars always override config file values.
|
|
101
|
+
- `dryRun: true` skips all git/sonar side effects and file writes.
|
|
102
|
+
|
|
103
|
+
## Code Style & Conventions
|
|
104
|
+
|
|
105
|
+
- CommonJS only: `require` / `module.exports`. Each package is a single
|
|
106
|
+
`index.js` that exports exactly one class (e.g. `module.exports = LLMClient;`).
|
|
107
|
+
- No TypeScript, no bundler, no lint config. Match the local style of the file
|
|
108
|
+
you edit (core/llm-client/validator use 2-space indent + `const`/`let`;
|
|
109
|
+
git-client uses 4-space indent + `var`/string concatenation — do not
|
|
110
|
+
reformat unrelated files).
|
|
111
|
+
- Public methods get JSDoc comments with `@param`/`@returns`.
|
|
112
|
+
- Logging uses `console.log` with status markers: `✓` success, `✗` failure,
|
|
113
|
+
`↻` retry. Errors are thrown as `new Error('Failed to <action>: <msg>')`
|
|
114
|
+
with context, and surfaced with `❌`/`::error::` at the CLI/Action boundary.
|
|
115
|
+
- `CoreOrchestrator` accepts optional injected clients
|
|
116
|
+
(`{ sonarClient, llmClient, gitClient, validator }`) and lazy-creates them —
|
|
117
|
+
use this dependency injection for testing instead of mocking modules.
|
|
118
|
+
- Plugin hooks: `beforeRun`, `beforeFile`, `afterFile`, `afterRun` (functions
|
|
119
|
+
in `config.hooks`).
|
|
120
|
+
- LLM responses must be parsed defensively: strip markdown code fences
|
|
121
|
+
(`CoreOrchestrator.extractCodeFromResponse`) before writing files, and treat
|
|
122
|
+
unchanged content as a failed attempt.
|
|
123
|
+
|
|
124
|
+
## Security Rules
|
|
125
|
+
|
|
126
|
+
- Never commit secrets. `config.example.json` and some `require.main ===
|
|
127
|
+
module` blocks in client packages contain example/placeholder Sonar tokens —
|
|
128
|
+
treat any `squ_*` string as a secret; do not copy real tokens into new code,
|
|
129
|
+
logs, or docs.
|
|
130
|
+
- Tokens are passed to git/gh only through environment variables (or
|
|
131
|
+
token-embedded HTTPS URLs for pushes), never as CLI arguments. Preserve this
|
|
132
|
+
in `git-client` and keep its `_redactSecrets` masking of tokens in error
|
|
133
|
+
output intact.
|
|
134
|
+
- Sonar auth uses the `Authorization: Bearer <token>` header; LLM clients set
|
|
135
|
+
provider-specific auth headers — don't print full request headers to logs.
|
|
136
|
+
|
|
137
|
+
## Known Gaps / Work-in-Progress
|
|
138
|
+
|
|
139
|
+
- The `validator` is implemented but **not wired into core**: the lazy
|
|
140
|
+
`validator` getter, the per-file validation in `fixFileWithRetry`, and the
|
|
141
|
+
batch validation step in `run()` are all commented out. Re-enabling them
|
|
142
|
+
changes the fix/retry behavior — verify the retry/restore flow still works.
|
|
143
|
+
- `prompts/fix-issues.md` and `prompts/retry-fix.md` exist as templates, but
|
|
144
|
+
`core` currently builds prompts inline in `requestFix()`; the two should
|
|
145
|
+
stay consistent.
|
|
146
|
+
- README references `USAGE.md` and `PROJECT.md`, which do not exist yet.
|
|
147
|
+
|
|
148
|
+
## When Making Changes
|
|
149
|
+
|
|
150
|
+
- Keep `core` orchestration-only — HTTP, git, and command execution belong in
|
|
151
|
+
the client packages.
|
|
152
|
+
- After editing, at minimum run `node --check <file>` on changed files; the
|
|
153
|
+
repo has no test harness to rely on yet.
|
|
154
|
+
- When touching `action.yml`, keep input names in sync with `getInput(...)`
|
|
155
|
+
calls in `packages/github-action/index.js` (kebab-case input →
|
|
156
|
+
`INPUT_KEBAB_CASE` env var).
|
|
157
|
+
- Releases are driven by `scripts/publish-all.js` (`npm run publish:all
|
|
158
|
+
[patch|minor|major]`, with `--dry-run` to preview). It bumps every package
|
|
159
|
+
by the same amount, re-points internal `@sonar-autofix/*` dependency ranges
|
|
160
|
+
at the new versions, and publishes dependees before dependents, ending with
|
|
161
|
+
the root package. Run `--dry-run` first and `npm login` before a real run.
|
|
162
|
+
Do not hand-bump `version` or dep ranges for a release — the script owns both.
|
|
163
|
+
(Note: 0.0.x caret ranges like `^0.0.3` match only `0.0.3`, so keeping
|
|
164
|
+
ranges in sync with published versions matters.)
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# sonar-autofix
|
|
1
|
+
# sonar-autofix (BETA)
|
|
2
2
|
|
|
3
3
|
This is a monorepo for the GitHub Sonar Autofix project, which automatically fixes code issues found by SonarQube/SonarCloud using LLMs.
|
|
4
4
|
|
|
@@ -65,7 +65,7 @@ Provider abstraction for various LLM providers:
|
|
|
65
65
|
- Reset
|
|
66
66
|
- Create Pull Request (GitHub CLI)
|
|
67
67
|
|
|
68
|
-
### validator
|
|
68
|
+
### validator (currently not used)
|
|
69
69
|
Runs configurable commands:
|
|
70
70
|
- npm run build
|
|
71
71
|
- npm run lint
|
package/config.example.json
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sonar-autofix",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"test": "node tests/core.test.js",
|
|
6
|
-
"test:structure": "node test-project.js"
|
|
6
|
+
"test:structure": "node test-project.js",
|
|
7
|
+
"publish:all": "node scripts/publish-all.js patch",
|
|
8
|
+
"publish:all:minor": "node scripts/publish-all.js minor",
|
|
9
|
+
"publish:all:major": "node scripts/publish-all.js major",
|
|
10
|
+
"publish:all:dry-run": "node scripts/publish-all.js --dry-run"
|
|
7
11
|
},
|
|
8
12
|
"publishConfig": {
|
|
9
13
|
"access": "public"
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* scripts/publish-all.js
|
|
6
|
+
*
|
|
7
|
+
* Bumps and publishes every @sonar-autofix workspace package — plus the
|
|
8
|
+
* root package — in dependency order:
|
|
9
|
+
*
|
|
10
|
+
* 1. leaf packages (sonar-client, llm-client, git-client, validator)
|
|
11
|
+
* 2. core (depends on the leaf clients)
|
|
12
|
+
* 3. cli + github-action (depend on core)
|
|
13
|
+
* 4. the root package.json
|
|
14
|
+
*
|
|
15
|
+
* Before anything is published, every package.json is rewritten with the
|
|
16
|
+
* bumped version and with internal (@sonar-autofix/*) dependency ranges
|
|
17
|
+
* pointing at the versions being published in this run.
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* node scripts/publish-all.js [patch|minor|major] [--dry-run]
|
|
21
|
+
*
|
|
22
|
+
* npm scripts:
|
|
23
|
+
* npm run publish:all patch bump + publish (default)
|
|
24
|
+
* npm run publish:all -- minor minor bump + publish
|
|
25
|
+
* npm run publish:all -- major major bump + publish
|
|
26
|
+
* npm run publish:all -- --dry-run preview only: no writes, no publish
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const { spawnSync } = require('node:child_process');
|
|
30
|
+
const fs = require('node:fs');
|
|
31
|
+
const path = require('node:path');
|
|
32
|
+
|
|
33
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
34
|
+
const SCOPE = '@sonar-autofix';
|
|
35
|
+
const BUMP_TYPES = ['patch', 'minor', 'major'];
|
|
36
|
+
|
|
37
|
+
function fail(message) {
|
|
38
|
+
console.error(`✗ ${message}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function readJson(file) {
|
|
43
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function writeJson(file, data) {
|
|
47
|
+
fs.writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function runNpm(args, { quiet = false } = {}) {
|
|
51
|
+
return spawnSync('npm', args, {
|
|
52
|
+
cwd: ROOT,
|
|
53
|
+
stdio: quiet ? ['ignore', 'pipe', 'pipe'] : 'inherit',
|
|
54
|
+
encoding: quiet ? 'utf8' : undefined,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseArgs(argv) {
|
|
59
|
+
const args = { bump: 'patch', dryRun: false };
|
|
60
|
+
for (const arg of argv) {
|
|
61
|
+
if (arg === '--dry-run') {
|
|
62
|
+
args.dryRun = true;
|
|
63
|
+
} else if (BUMP_TYPES.includes(arg)) {
|
|
64
|
+
args.bump = arg;
|
|
65
|
+
} else {
|
|
66
|
+
fail(`Unknown argument "${arg}". Expected ${BUMP_TYPES.join(' | ')} and/or --dry-run.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return args;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function bumpVersion(version, type, label) {
|
|
73
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version || '');
|
|
74
|
+
if (!match) fail(`Unsupported version "${version}" in ${label}`);
|
|
75
|
+
const [major, minor, patch] = [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
76
|
+
if (type === 'major') return `${major + 1}.0.0`;
|
|
77
|
+
if (type === 'minor') return `${major}.${minor + 1}.0`;
|
|
78
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function discoverWorkspaces(rootPkg) {
|
|
82
|
+
const found = [];
|
|
83
|
+
for (const pattern of rootPkg.workspaces || []) {
|
|
84
|
+
const baseDir = pattern.endsWith('/*') ? path.join(ROOT, pattern.slice(0, -2)) : null;
|
|
85
|
+
const entries = baseDir
|
|
86
|
+
? fs.readdirSync(baseDir)
|
|
87
|
+
.map((entry) => path.join(baseDir, entry))
|
|
88
|
+
.filter((dir) => fs.existsSync(path.join(dir, 'package.json')))
|
|
89
|
+
: [path.join(ROOT, pattern)];
|
|
90
|
+
for (const dir of entries) {
|
|
91
|
+
found.push({ name: readJson(path.join(dir, 'package.json')).name, dir });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return found.sort((a, b) => a.name.localeCompare(b.name));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function internalDepsOf(pkg) {
|
|
98
|
+
return Object.keys(pkg.dependencies || {}).filter((dep) => dep.startsWith(`${SCOPE}/`));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function topologicalOrder(names, depsOf) {
|
|
102
|
+
const remaining = new Set(names);
|
|
103
|
+
const order = [];
|
|
104
|
+
while (remaining.size > 0) {
|
|
105
|
+
const ready = names.filter(
|
|
106
|
+
(name) => remaining.has(name) && depsOf[name].every((dep) => !remaining.has(dep))
|
|
107
|
+
);
|
|
108
|
+
if (ready.length === 0) fail('Circular dependency detected between workspace packages.');
|
|
109
|
+
for (const name of ready) {
|
|
110
|
+
remaining.delete(name);
|
|
111
|
+
order.push(name);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return order;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isAlreadyPublished(name, version) {
|
|
118
|
+
const result = runNpm(['view', `${name}@${version}`, 'version'], { quiet: true });
|
|
119
|
+
return result.status === 0 && (result.stdout || '').includes(version);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function main() {
|
|
123
|
+
const { bump, dryRun } = parseArgs(process.argv.slice(2));
|
|
124
|
+
|
|
125
|
+
const rootPkg = readJson(path.join(ROOT, 'package.json'));
|
|
126
|
+
const workspaces = discoverWorkspaces(rootPkg);
|
|
127
|
+
if (workspaces.length === 0) fail('No workspace packages found.');
|
|
128
|
+
|
|
129
|
+
// Every package we manage: the workspace members plus the root (published last).
|
|
130
|
+
const packageInfos = workspaces.map((ws) => {
|
|
131
|
+
const file = path.join(ws.dir, 'package.json');
|
|
132
|
+
return { name: ws.name, version: readJson(file).version, file, isRoot: false };
|
|
133
|
+
});
|
|
134
|
+
packageInfos.push({
|
|
135
|
+
name: rootPkg.name,
|
|
136
|
+
version: rootPkg.version,
|
|
137
|
+
file: path.join(ROOT, 'package.json'),
|
|
138
|
+
isRoot: true,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const byName = new Map(packageInfos.map((info) => [info.name, info]));
|
|
142
|
+
|
|
143
|
+
// Internal dependency graph (only @sonar-autofix/* deps that we publish here).
|
|
144
|
+
const depsOf = {};
|
|
145
|
+
for (const info of packageInfos) {
|
|
146
|
+
const internal = internalDepsOf(readJson(info.file)).filter((dep) => byName.has(dep));
|
|
147
|
+
// The root has no internal deps of its own, but must publish last, so we
|
|
148
|
+
// pretend it depends on every workspace to force it to the end of the order.
|
|
149
|
+
depsOf[info.name] = info.isRoot ? workspaces.map((ws) => ws.name) : internal;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const names = packageInfos.map((info) => info.name);
|
|
153
|
+
const order = topologicalOrder(names, depsOf);
|
|
154
|
+
|
|
155
|
+
// New version for every package (all bumped by the same amount).
|
|
156
|
+
const newVersion = {};
|
|
157
|
+
for (const info of packageInfos) {
|
|
158
|
+
newVersion[info.name] = bumpVersion(info.version, bump, info.name);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log(`\nSonar Autofix publish plan — ${bump} bump${dryRun ? ' [DRY RUN]' : ''}\n`);
|
|
162
|
+
order.forEach((name, index) => {
|
|
163
|
+
console.log(` ${index + 1}. ${name}: ${byName.get(name).version} -> ${newVersion[name]}`);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (dryRun) {
|
|
167
|
+
console.log('\nDry run only — no files were modified and nothing was published.');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Rewrite every package.json: bumped version + internal dep ranges pointing
|
|
172
|
+
// at the versions we are about to publish (dependees are published first, so
|
|
173
|
+
// these ranges will resolve on the registry by the time the dependent ships).
|
|
174
|
+
for (const info of packageInfos) {
|
|
175
|
+
const pkg = readJson(info.file);
|
|
176
|
+
pkg.version = newVersion[info.name];
|
|
177
|
+
if (pkg.dependencies) {
|
|
178
|
+
for (const dep of Object.keys(pkg.dependencies)) {
|
|
179
|
+
if (byName.has(dep)) {
|
|
180
|
+
pkg.dependencies[dep] = `^${newVersion[dep]}`;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
writeJson(info.file, pkg);
|
|
185
|
+
}
|
|
186
|
+
console.log('\nUpdated package.json files with new versions and dependency ranges.');
|
|
187
|
+
|
|
188
|
+
const whoami = runNpm(['whoami'], { quiet: true });
|
|
189
|
+
if (whoami.status !== 0) {
|
|
190
|
+
fail('Not authenticated with npm. Run `npm login` and try again.');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
for (const name of order) {
|
|
194
|
+
const version = newVersion[name];
|
|
195
|
+
if (isAlreadyPublished(name, version)) {
|
|
196
|
+
fail(`${name}@${version} is already on the registry. Bump further or unpublish it first.`);
|
|
197
|
+
}
|
|
198
|
+
console.log(`\nPublishing ${name}@${version} ...`);
|
|
199
|
+
const args = byName.get(name).isRoot
|
|
200
|
+
? ['publish', '--access', 'public']
|
|
201
|
+
: ['publish', `--workspace=${name}`, '--access', 'public'];
|
|
202
|
+
const result = runNpm(args);
|
|
203
|
+
if (result.status !== 0) {
|
|
204
|
+
fail(`Publishing ${name}@${version} failed. Stopping — the remaining packages were not published.`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.log('\nAll packages published successfully.');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
main();
|
package/.idea/vcs.xml
DELETED
package/.idea/workspace.xml
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="AutoImportSettings">
|
|
4
|
-
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
|
-
</component>
|
|
6
|
-
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="2b435513-27c8-4fc6-b596-5368f46599ce" name="Changes" comment="package publishing changes">
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
9
|
-
<change beforePath="$PROJECT_DIR$/packages/cli/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/cli/package.json" afterDir="false" />
|
|
10
|
-
<change beforePath="$PROJECT_DIR$/packages/core/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/index.js" afterDir="false" />
|
|
11
|
-
<change beforePath="$PROJECT_DIR$/packages/core/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/package.json" afterDir="false" />
|
|
12
|
-
<change beforePath="$PROJECT_DIR$/packages/sonar-client/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/packages/sonar-client/index.js" afterDir="false" />
|
|
13
|
-
<change beforePath="$PROJECT_DIR$/packages/sonar-client/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/sonar-client/package.json" afterDir="false" />
|
|
14
|
-
</list>
|
|
15
|
-
<option name="SHOW_DIALOG" value="false" />
|
|
16
|
-
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
17
|
-
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
18
|
-
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
19
|
-
</component>
|
|
20
|
-
<component name="EmbeddingIndexingInfo">
|
|
21
|
-
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
|
22
|
-
</component>
|
|
23
|
-
<component name="Git.Settings">
|
|
24
|
-
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
25
|
-
</component>
|
|
26
|
-
<component name="GithubDefaultAccount">
|
|
27
|
-
<option name="defaultAccountId" value="6dade5ab-73e2-43de-8589-5680489ff109" />
|
|
28
|
-
</component>
|
|
29
|
-
<component name="McpProjectServerCommands">
|
|
30
|
-
<commands />
|
|
31
|
-
<urls />
|
|
32
|
-
</component>
|
|
33
|
-
<component name="NextEditCompletionFeaturesState">
|
|
34
|
-
<decayedCancelled>
|
|
35
|
-
<entry key="MS100" value="1.0" />
|
|
36
|
-
<entry key="MS500" value="1.0000096685874162" />
|
|
37
|
-
<entry key="S2" value="1.2053514605030213" />
|
|
38
|
-
<entry key="S5" value="3.5054075452577873" />
|
|
39
|
-
<entry key="S10" value="8.285153691522252" />
|
|
40
|
-
<entry key="S30" value="22.099915652269726" />
|
|
41
|
-
<entry key="S60" value="32.503558498086804" />
|
|
42
|
-
<entry key="M2" value="46.00668244909441" />
|
|
43
|
-
<entry key="M5" value="75.21966408675024" />
|
|
44
|
-
<entry key="M10" value="105.05174529605523" />
|
|
45
|
-
<entry key="M15" value="126.80949976552866" />
|
|
46
|
-
<entry key="M30" value="179.30193657490182" />
|
|
47
|
-
<entry key="H1" value="268.5100212929829" />
|
|
48
|
-
<entry key="H2" value="399.1900222888334" />
|
|
49
|
-
<entry key="H4" value="549.3576268473516" />
|
|
50
|
-
<entry key="D1" value="962.4386311481882" />
|
|
51
|
-
<entry key="W1" value="1139.0154724501535" />
|
|
52
|
-
</decayedCancelled>
|
|
53
|
-
<decayedSelected>
|
|
54
|
-
<entry key="MS100" value="2.486781009267054E-163" />
|
|
55
|
-
<entry key="MS500" value="3.013890769637781E-33" />
|
|
56
|
-
<entry key="S2" value="7.409380142936205E-9" />
|
|
57
|
-
<entry key="S5" value="5.596451582670592E-4" />
|
|
58
|
-
<entry key="S10" value="0.023656820612534327" />
|
|
59
|
-
<entry key="S30" value="0.2877167821835834" />
|
|
60
|
-
<entry key="S60" value="0.571795845487523" />
|
|
61
|
-
<entry key="M2" value="1.0008499332221734" />
|
|
62
|
-
<entry key="M5" value="1.8675369713255476" />
|
|
63
|
-
<entry key="M10" value="3.120725880242862" />
|
|
64
|
-
<entry key="M15" value="4.464030671385961" />
|
|
65
|
-
<entry key="M30" value="7.887012981030183" />
|
|
66
|
-
<entry key="H1" value="12.157858627695783" />
|
|
67
|
-
<entry key="H2" value="16.454162116620612" />
|
|
68
|
-
<entry key="H4" value="20.162257655545318" />
|
|
69
|
-
<entry key="D1" value="27.068485237392622" />
|
|
70
|
-
<entry key="W1" value="29.516199133476672" />
|
|
71
|
-
</decayedSelected>
|
|
72
|
-
<decayedShown>
|
|
73
|
-
<entry key="MS100" value="0.9592641193252643" />
|
|
74
|
-
<entry key="MS500" value="0.991726344920333" />
|
|
75
|
-
<entry key="S2" value="1.202935507981753" />
|
|
76
|
-
<entry key="S5" value="3.5032164599084017" />
|
|
77
|
-
<entry key="S10" value="8.302441666600823" />
|
|
78
|
-
<entry key="S30" value="22.36943934928447" />
|
|
79
|
-
<entry key="S60" value="33.057047712169364" />
|
|
80
|
-
<entry key="M2" value="46.990410072819984" />
|
|
81
|
-
<entry key="M5" value="77.07026261815581" />
|
|
82
|
-
<entry key="M10" value="108.15662354380419" />
|
|
83
|
-
<entry key="M15" value="131.2588743558754" />
|
|
84
|
-
<entry key="M30" value="187.17731809627006" />
|
|
85
|
-
<entry key="H1" value="280.65969612672166" />
|
|
86
|
-
<entry key="H2" value="415.6389430187304" />
|
|
87
|
-
<entry key="H4" value="569.5167208047027" />
|
|
88
|
-
<entry key="D1" value="989.5063431249184" />
|
|
89
|
-
<entry key="W1" value="1168.5315458022485" />
|
|
90
|
-
</decayedShown>
|
|
91
|
-
</component>
|
|
92
|
-
<component name="ProjectColorInfo">{
|
|
93
|
-
"associatedIndex": 0,
|
|
94
|
-
"fromUser": false
|
|
95
|
-
}</component>
|
|
96
|
-
<component name="ProjectId" id="3HYLMP5y2Kv5j83bVaucxd9Nu7S" />
|
|
97
|
-
<component name="ProjectViewState">
|
|
98
|
-
<option name="hideEmptyMiddlePackages" value="true" />
|
|
99
|
-
<option name="showLibraryContents" value="true" />
|
|
100
|
-
</component>
|
|
101
|
-
<component name="PropertiesComponent">{
|
|
102
|
-
"keyToString": {
|
|
103
|
-
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
|
104
|
-
"RunOnceActivity.MCP Project settings loaded": "true",
|
|
105
|
-
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
106
|
-
"RunOnceActivity.git.unshallow": "true",
|
|
107
|
-
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
|
108
|
-
"SONARLINT_PRECOMMIT_ANALYSIS": "true",
|
|
109
|
-
"codeWithMe.voiceChat.enabledByDefault": "false",
|
|
110
|
-
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
|
111
|
-
"git-widget-placeholder": "master",
|
|
112
|
-
"javascript.nodejs.core.library.configured.version": "24.18.0",
|
|
113
|
-
"javascript.nodejs.core.library.typings.version": "24.13.3",
|
|
114
|
-
"javascript.preferred.runtime.type.id": "node",
|
|
115
|
-
"junie.onboarding.icon.badge.shown": "true",
|
|
116
|
-
"last_opened_file_path": "/Users/divyaaditya/projects/sonar-autofix",
|
|
117
|
-
"node.js.detected.package.eslint": "true",
|
|
118
|
-
"node.js.detected.package.jshint": "true",
|
|
119
|
-
"node.js.detected.package.tslint": "true",
|
|
120
|
-
"node.js.selected.package.eslint": "(autodetect)",
|
|
121
|
-
"node.js.selected.package.jshint": "",
|
|
122
|
-
"node.js.selected.package.tslint": "(autodetect)",
|
|
123
|
-
"nodejs_interpreter_path": "node",
|
|
124
|
-
"nodejs_package_manager_path": "npm",
|
|
125
|
-
"settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
|
|
126
|
-
"to.speed.mode.migration.done": "true",
|
|
127
|
-
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external"
|
|
128
|
-
}
|
|
129
|
-
}</component>
|
|
130
|
-
<component name="RecentsManager">
|
|
131
|
-
<key name="CopyFile.RECENT_KEYS">
|
|
132
|
-
<recent name="$PROJECT_DIR$" />
|
|
133
|
-
</key>
|
|
134
|
-
</component>
|
|
135
|
-
<component name="SharedIndexes">
|
|
136
|
-
<attachedChunks>
|
|
137
|
-
<set>
|
|
138
|
-
<option value="bundled-js-predefined-d6986cc7102b-4abd2a77f808-JavaScript-WS-262.9437.145" />
|
|
139
|
-
</set>
|
|
140
|
-
</attachedChunks>
|
|
141
|
-
</component>
|
|
142
|
-
<component name="TaskManager">
|
|
143
|
-
<task active="true" id="Default" summary="Default task">
|
|
144
|
-
<changelist id="2b435513-27c8-4fc6-b596-5368f46599ce" name="Changes" comment="" />
|
|
145
|
-
<created>1786040006836</created>
|
|
146
|
-
<option name="number" value="Default" />
|
|
147
|
-
<option name="presentableId" value="Default" />
|
|
148
|
-
<updated>1786040006836</updated>
|
|
149
|
-
<workItem from="1786040007924" duration="6453000" />
|
|
150
|
-
<workItem from="1786046840005" duration="601000" />
|
|
151
|
-
<workItem from="1786830049128" duration="109000" />
|
|
152
|
-
<workItem from="1786830198912" duration="598000" />
|
|
153
|
-
<workItem from="1787769103566" duration="9226000" />
|
|
154
|
-
<workItem from="1787817536391" duration="61000" />
|
|
155
|
-
<workItem from="1787859060707" duration="1282000" />
|
|
156
|
-
<workItem from="1787860367363" duration="674000" />
|
|
157
|
-
<workItem from="1788016099431" duration="1199000" />
|
|
158
|
-
<workItem from="1788165341480" duration="4495000" />
|
|
159
|
-
<workItem from="1788169983174" duration="1684000" />
|
|
160
|
-
<workItem from="1788171725187" duration="4774000" />
|
|
161
|
-
<workItem from="1788177896634" duration="4501000" />
|
|
162
|
-
<workItem from="1788182750659" duration="1495000" />
|
|
163
|
-
<workItem from="1788184609891" duration="38000" />
|
|
164
|
-
<workItem from="1788186007862" duration="4274000" />
|
|
165
|
-
<workItem from="1788246235790" duration="407000" />
|
|
166
|
-
</task>
|
|
167
|
-
<task id="LOCAL-00001" summary="package publishing changes">
|
|
168
|
-
<option name="closed" value="true" />
|
|
169
|
-
<created>1788181949023</created>
|
|
170
|
-
<option name="number" value="00001" />
|
|
171
|
-
<option name="presentableId" value="LOCAL-00001" />
|
|
172
|
-
<option name="project" value="LOCAL" />
|
|
173
|
-
<updated>1788181949023</updated>
|
|
174
|
-
</task>
|
|
175
|
-
<task id="LOCAL-00002" summary="package publishing changes">
|
|
176
|
-
<option name="closed" value="true" />
|
|
177
|
-
<created>1788186558939</created>
|
|
178
|
-
<option name="number" value="00002" />
|
|
179
|
-
<option name="presentableId" value="LOCAL-00002" />
|
|
180
|
-
<option name="project" value="LOCAL" />
|
|
181
|
-
<updated>1788186558939</updated>
|
|
182
|
-
</task>
|
|
183
|
-
<option name="localTasksCounter" value="3" />
|
|
184
|
-
<servers />
|
|
185
|
-
</component>
|
|
186
|
-
<component name="TypeScriptGeneratedFilesManager">
|
|
187
|
-
<option name="version" value="3" />
|
|
188
|
-
</component>
|
|
189
|
-
<component name="VcsManagerConfiguration">
|
|
190
|
-
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
|
191
|
-
<ignored-roots>
|
|
192
|
-
<path value="$PROJECT_DIR$" />
|
|
193
|
-
</ignored-roots>
|
|
194
|
-
<MESSAGE value="package publishing changes" />
|
|
195
|
-
<option name="LAST_COMMIT_MESSAGE" value="package publishing changes" />
|
|
196
|
-
</component>
|
|
197
|
-
</project>
|