sonar-autofix 0.1.1 → 0.3.2
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
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var childProcess = require('node:child_process');
|
|
4
|
-
var util = require('node:util');
|
|
5
|
-
|
|
6
|
-
var execFile = util.promisify(childProcess.execFile);
|
|
7
|
-
|
|
8
|
-
var DEFAULT_COMMIT_MESSAGE =
|
|
9
|
-
'fix(sonar): automatically resolve Sonar issues\n\nGenerated by sonar-autofix';
|
|
10
|
-
|
|
11
|
-
class GitClient {
|
|
12
|
-
/**
|
|
13
|
-
* @param {object} [config]
|
|
14
|
-
* @param {object} [config.git]
|
|
15
|
-
* @param {string} [config.git.branch]
|
|
16
|
-
* @param {string} [config.git.token]
|
|
17
|
-
* @param {string} [config.git.username]
|
|
18
|
-
* @param {string} [config.git.remote='origin']
|
|
19
|
-
* @param {string} [cwd]
|
|
20
|
-
*/
|
|
21
|
-
constructor(config, cwd) {
|
|
22
|
-
this.config = config || {};
|
|
23
|
-
this.config.git = this.config.git || {};
|
|
24
|
-
|
|
25
|
-
this.config.git.branch =
|
|
26
|
-
this.config.git.branch || 'sonar-autofix';
|
|
27
|
-
|
|
28
|
-
this.config.git.remote =
|
|
29
|
-
this.config.git.remote || 'origin';
|
|
30
|
-
|
|
31
|
-
this.cwd = cwd || process.cwd();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Get Git authentication token.
|
|
36
|
-
*
|
|
37
|
-
* Priority:
|
|
38
|
-
* 1. config.git.token
|
|
39
|
-
* 2. GITHUB_TOKEN
|
|
40
|
-
* 3. GH_TOKEN
|
|
41
|
-
* 4. GIT_TOKEN
|
|
42
|
-
*
|
|
43
|
-
* @returns {string|undefined}
|
|
44
|
-
*/
|
|
45
|
-
_getToken() {
|
|
46
|
-
return (
|
|
47
|
-
this.config.git.token ||
|
|
48
|
-
process.env.GITHUB_TOKEN ||
|
|
49
|
-
process.env.GH_TOKEN ||
|
|
50
|
-
process.env.GIT_TOKEN
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Get Git username.
|
|
56
|
-
*
|
|
57
|
-
* @returns {string}
|
|
58
|
-
*/
|
|
59
|
-
_getUsername() {
|
|
60
|
-
return (
|
|
61
|
-
this.config.git.username ||
|
|
62
|
-
process.env.GIT_USERNAME ||
|
|
63
|
-
'x-access-token'
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Execute git command.
|
|
69
|
-
*
|
|
70
|
-
* Authentication is supplied through environment variables,
|
|
71
|
-
* never as command-line arguments.
|
|
72
|
-
*
|
|
73
|
-
* @param {string[]} args
|
|
74
|
-
* @returns {Promise<string>}
|
|
75
|
-
*/
|
|
76
|
-
async _execGit(args) {
|
|
77
|
-
try {
|
|
78
|
-
var env = Object.assign({}, process.env);
|
|
79
|
-
|
|
80
|
-
var token = this._getToken();
|
|
81
|
-
|
|
82
|
-
if (token) {
|
|
83
|
-
env.GIT_TERMINAL_PROMPT = '0';
|
|
84
|
-
|
|
85
|
-
/*
|
|
86
|
-
* GIT_ASKPASS prevents Git from prompting for credentials.
|
|
87
|
-
* The actual token is supplied through environment variables.
|
|
88
|
-
*/
|
|
89
|
-
env.GIT_USERNAME = this._getUsername();
|
|
90
|
-
env.GIT_PASSWORD = token;
|
|
91
|
-
|
|
92
|
-
env.GIT_ASKPASS = 'git-askpass-helper';
|
|
93
|
-
|
|
94
|
-
/*
|
|
95
|
-
* This is handled by the shell-independent askpass mechanism
|
|
96
|
-
* below when the executable is available.
|
|
97
|
-
*/
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
var result = await execFile('git', args, {
|
|
101
|
-
cwd: this.cwd,
|
|
102
|
-
env: env
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return (result.stdout || '').trim();
|
|
106
|
-
} catch (err) {
|
|
107
|
-
var command = 'git ' + args.join(' ');
|
|
108
|
-
var stderr = (err.stderr || '').trim();
|
|
109
|
-
|
|
110
|
-
throw new Error(
|
|
111
|
-
'Git command failed: ' +
|
|
112
|
-
command +
|
|
113
|
-
(stderr ? '\n' + stderr : '')
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Execute GitHub CLI command.
|
|
120
|
-
*
|
|
121
|
-
* Uses GH_TOKEN/GITHUB_TOKEN so gh never prompts interactively.
|
|
122
|
-
*
|
|
123
|
-
* @param {string[]} args
|
|
124
|
-
* @returns {Promise<string>}
|
|
125
|
-
*/
|
|
126
|
-
async _execGh(args) {
|
|
127
|
-
try {
|
|
128
|
-
var env = Object.assign({}, process.env);
|
|
129
|
-
var token = this._getToken();
|
|
130
|
-
|
|
131
|
-
if (token) {
|
|
132
|
-
env.GH_TOKEN = token;
|
|
133
|
-
env.GITHUB_TOKEN = token;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/*
|
|
137
|
-
* Prevent gh from falling back to an interactive login.
|
|
138
|
-
*/
|
|
139
|
-
env.GH_PROMPT_DISABLED = '1';
|
|
140
|
-
|
|
141
|
-
var result = await execFile('gh', args, {
|
|
142
|
-
cwd: this.cwd,
|
|
143
|
-
env: env
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
return (result.stdout || '').trim();
|
|
147
|
-
} catch (err) {
|
|
148
|
-
var stderr = (err.stderr || '').trim();
|
|
149
|
-
|
|
150
|
-
throw new Error(
|
|
151
|
-
'GitHub CLI command failed: ' +
|
|
152
|
-
['gh'].concat(args).join(' ') +
|
|
153
|
-
(stderr ? '\n' + stderr : '')
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Create and checkout a new branch.
|
|
160
|
-
*
|
|
161
|
-
* @param {string} [branchName]
|
|
162
|
-
* @returns {Promise<string>}
|
|
163
|
-
*/
|
|
164
|
-
async createBranch(branchName) {
|
|
165
|
-
var branch = branchName || this.config.git.branch;
|
|
166
|
-
|
|
167
|
-
try {
|
|
168
|
-
await this._execGit(['checkout', '-b', branch]);
|
|
169
|
-
} catch (err) {
|
|
170
|
-
if (
|
|
171
|
-
err.message &&
|
|
172
|
-
err.message.indexOf('already exists') !== -1
|
|
173
|
-
) {
|
|
174
|
-
await this._execGit(['checkout', branch]);
|
|
175
|
-
} else {
|
|
176
|
-
throw err;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return branch;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Checkout an existing branch.
|
|
185
|
-
*
|
|
186
|
-
* @param {string} branchName
|
|
187
|
-
* @returns {Promise<string>}
|
|
188
|
-
*/
|
|
189
|
-
async checkout(branchName) {
|
|
190
|
-
if (!branchName) {
|
|
191
|
-
throw new Error('Branch name is required for checkout');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return this._execGit(['checkout', branchName]);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Stage all changes and commit.
|
|
199
|
-
*
|
|
200
|
-
* @param {string} [message]
|
|
201
|
-
* @returns {Promise<string>}
|
|
202
|
-
*/
|
|
203
|
-
async commit(message) {
|
|
204
|
-
var commitMessage = message || DEFAULT_COMMIT_MESSAGE;
|
|
205
|
-
|
|
206
|
-
await this.stageAll();
|
|
207
|
-
|
|
208
|
-
return this._execGit([
|
|
209
|
-
'commit',
|
|
210
|
-
'-m',
|
|
211
|
-
commitMessage
|
|
212
|
-
]);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Push branch to remote.
|
|
217
|
-
*
|
|
218
|
-
* @param {string} [branchName]
|
|
219
|
-
* @param {boolean} [force=false]
|
|
220
|
-
* @returns {Promise<string>}
|
|
221
|
-
*/
|
|
222
|
-
async push(branchName, force) {
|
|
223
|
-
var branch = branchName || this.config.git.branch;
|
|
224
|
-
var remote = this.config.git.remote;
|
|
225
|
-
|
|
226
|
-
var args = ['push', remote, branch];
|
|
227
|
-
|
|
228
|
-
if (force) {
|
|
229
|
-
args.splice(1, 0, '--force');
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return this._execGit(args);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Restore a file from HEAD.
|
|
237
|
-
*
|
|
238
|
-
* @param {string} filePath
|
|
239
|
-
* @returns {Promise<string>}
|
|
240
|
-
*/
|
|
241
|
-
async restoreFile(filePath) {
|
|
242
|
-
if (!filePath) {
|
|
243
|
-
throw new Error(
|
|
244
|
-
'File path is required for restoreFile'
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return this._execGit([
|
|
249
|
-
'checkout',
|
|
250
|
-
'--',
|
|
251
|
-
filePath
|
|
252
|
-
]);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Git reset.
|
|
257
|
-
*
|
|
258
|
-
* @param {string} [mode='hard']
|
|
259
|
-
* @returns {Promise<string>}
|
|
260
|
-
*/
|
|
261
|
-
async reset(mode) {
|
|
262
|
-
var resetMode = mode || 'hard';
|
|
263
|
-
|
|
264
|
-
return this._execGit([
|
|
265
|
-
'reset',
|
|
266
|
-
'--' + resetMode
|
|
267
|
-
]);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Create a pull request using GitHub CLI.
|
|
272
|
-
*
|
|
273
|
-
* Authentication is provided through:
|
|
274
|
-
* config.git.token
|
|
275
|
-
* GITHUB_TOKEN
|
|
276
|
-
* GH_TOKEN
|
|
277
|
-
* GIT_TOKEN
|
|
278
|
-
*
|
|
279
|
-
* The token is passed through the environment and never
|
|
280
|
-
* appears in the command line.
|
|
281
|
-
*
|
|
282
|
-
* @param {string} title
|
|
283
|
-
* @param {string} body
|
|
284
|
-
* @param {string} [baseBranch='main']
|
|
285
|
-
* @returns {Promise<string>}
|
|
286
|
-
*/
|
|
287
|
-
async createPullRequest(title, body, baseBranch) {
|
|
288
|
-
if (!title) {
|
|
289
|
-
throw new Error(
|
|
290
|
-
'Title is required for createPullRequest'
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
var token = this._getToken();
|
|
295
|
-
|
|
296
|
-
if (!token) {
|
|
297
|
-
throw new Error(
|
|
298
|
-
'GitHub authentication token is required. ' +
|
|
299
|
-
'Set GITHUB_TOKEN, GH_TOKEN, GIT_TOKEN, ' +
|
|
300
|
-
'or provide config.git.token.'
|
|
301
|
-
);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
var base = baseBranch || 'main';
|
|
305
|
-
|
|
306
|
-
return this._execGh([
|
|
307
|
-
'pr',
|
|
308
|
-
'create',
|
|
309
|
-
'--title',
|
|
310
|
-
title,
|
|
311
|
-
'--body',
|
|
312
|
-
body || '',
|
|
313
|
-
'--base',
|
|
314
|
-
base
|
|
315
|
-
]);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Get the current branch name.
|
|
320
|
-
*
|
|
321
|
-
* @returns {Promise<string>}
|
|
322
|
-
*/
|
|
323
|
-
async getCurrentBranch() {
|
|
324
|
-
return this._execGit([
|
|
325
|
-
'rev-parse',
|
|
326
|
-
'--abbrev-ref',
|
|
327
|
-
'HEAD'
|
|
328
|
-
]);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Check if working tree has changes.
|
|
333
|
-
*
|
|
334
|
-
* @returns {Promise<boolean>}
|
|
335
|
-
*/
|
|
336
|
-
async hasChanges() {
|
|
337
|
-
var output = await this._execGit([
|
|
338
|
-
'status',
|
|
339
|
-
'--porcelain'
|
|
340
|
-
]);
|
|
341
|
-
|
|
342
|
-
return output.length > 0;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Stage all changes.
|
|
347
|
-
*
|
|
348
|
-
* @returns {Promise<string>}
|
|
349
|
-
*/
|
|
350
|
-
async stageAll() {
|
|
351
|
-
return this._execGit(['add', '-A']);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Get diff for a file or all files.
|
|
356
|
-
*
|
|
357
|
-
* @param {string} [filePath]
|
|
358
|
-
* @returns {Promise<string>}
|
|
359
|
-
*/
|
|
360
|
-
async diff(filePath) {
|
|
361
|
-
var args = ['diff'];
|
|
362
|
-
|
|
363
|
-
if (filePath) {
|
|
364
|
-
args.push('--', filePath);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return this._execGit(args);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
module.exports = GitClient;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@sonar-autofix/git-client",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "Git client for the Sonar Autofix tool",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"sonar",
|
|
11
|
-
"autofix",
|
|
12
|
-
"github",
|
|
13
|
-
"git"
|
|
14
|
-
],
|
|
15
|
-
"author": "Sonar Autofix Team",
|
|
16
|
-
"license": "MIT"
|
|
17
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
name: 'Sonar Autofix'
|
|
2
|
-
description: 'Automatically fix SonarQube/SonarCloud issues using LLMs'
|
|
3
|
-
author: 'Sonar Autofix Team'
|
|
4
|
-
|
|
5
|
-
inputs:
|
|
6
|
-
sonar-host:
|
|
7
|
-
description: 'SonarQube/SonarCloud host URL'
|
|
8
|
-
required: false
|
|
9
|
-
default: 'https://sonarcloud.io'
|
|
10
|
-
sonar-project:
|
|
11
|
-
description: 'Sonar project key'
|
|
12
|
-
required: true
|
|
13
|
-
sonar-token:
|
|
14
|
-
description: 'Sonar authentication token'
|
|
15
|
-
required: true
|
|
16
|
-
llm-provider:
|
|
17
|
-
description: 'LLM provider (lmstudio, openai, azure, anthropic, ollama, openrouter)'
|
|
18
|
-
required: false
|
|
19
|
-
default: 'lmstudio'
|
|
20
|
-
llm-endpoint:
|
|
21
|
-
description: 'LLM API endpoint URL'
|
|
22
|
-
required: true
|
|
23
|
-
llm-model:
|
|
24
|
-
description: 'LLM model name'
|
|
25
|
-
required: true
|
|
26
|
-
llm-api-key:
|
|
27
|
-
description: 'LLM API key'
|
|
28
|
-
required: false
|
|
29
|
-
default: ''
|
|
30
|
-
git-branch:
|
|
31
|
-
description: 'Branch name for autofix commits'
|
|
32
|
-
required: false
|
|
33
|
-
default: 'sonar-autofix'
|
|
34
|
-
max-iterations:
|
|
35
|
-
description: 'Maximum number of fix iterations'
|
|
36
|
-
required: false
|
|
37
|
-
default: '5'
|
|
38
|
-
max-retries:
|
|
39
|
-
description: 'Maximum retries per file fix'
|
|
40
|
-
required: false
|
|
41
|
-
default: '3'
|
|
42
|
-
dry-run:
|
|
43
|
-
description: 'Run without making changes'
|
|
44
|
-
required: false
|
|
45
|
-
default: 'false'
|
|
46
|
-
build-commands:
|
|
47
|
-
description: 'Build commands (JSON array)'
|
|
48
|
-
required: false
|
|
49
|
-
default: '["npm run build"]'
|
|
50
|
-
lint-commands:
|
|
51
|
-
description: 'Lint commands (JSON array)'
|
|
52
|
-
required: false
|
|
53
|
-
default: '["npm run lint"]'
|
|
54
|
-
test-commands:
|
|
55
|
-
description: 'Test commands (JSON array)'
|
|
56
|
-
required: false
|
|
57
|
-
default: '["npm test"]'
|
|
58
|
-
|
|
59
|
-
outputs:
|
|
60
|
-
files-fixed:
|
|
61
|
-
description: 'Number of files fixed'
|
|
62
|
-
iterations:
|
|
63
|
-
description: 'Number of iterations performed'
|
|
64
|
-
|
|
65
|
-
runs:
|
|
66
|
-
using: 'node20'
|
|
67
|
-
main: 'index.js'
|
|
68
|
-
|
|
69
|
-
branding:
|
|
70
|
-
icon: 'check-circle'
|
|
71
|
-
color: 'green'
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
// GitHub Action entry point for Sonar Autofix
|
|
2
|
-
const CoreOrchestrator = require('@sonar-autofix/core');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Read a GitHub Action input value.
|
|
6
|
-
* In a real GitHub Actions environment, inputs are exposed as INPUT_<NAME> environment variables.
|
|
7
|
-
*/
|
|
8
|
-
function getInput(name, required = false) {
|
|
9
|
-
const envKey = `INPUT_${name.replace(/-/g, '_').toUpperCase()}`;
|
|
10
|
-
const value = process.env[envKey] || '';
|
|
11
|
-
if (required && !value) {
|
|
12
|
-
throw new Error(`Missing required input: ${name}`);
|
|
13
|
-
}
|
|
14
|
-
return value;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Set a GitHub Action output value.
|
|
19
|
-
*/
|
|
20
|
-
function setOutput(name, value) {
|
|
21
|
-
if (process.env.GITHUB_OUTPUT) {
|
|
22
|
-
const fs = require('fs');
|
|
23
|
-
fs.appendFileSync(process.env.GITHUB_OUTPUT, `${name}=${value}\n`);
|
|
24
|
-
} else {
|
|
25
|
-
console.log(`::set-output name=${name}::${value}`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* GitHub Action entry point
|
|
31
|
-
*/
|
|
32
|
-
async function run() {
|
|
33
|
-
console.log('Sonar Autofix GitHub Action');
|
|
34
|
-
console.log('===================================');
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
// Read action inputs (from action.yml)
|
|
38
|
-
const config = {
|
|
39
|
-
sonar: {
|
|
40
|
-
host: getInput('sonar-host') || 'https://sonarcloud.io',
|
|
41
|
-
project: getInput('sonar-project', true),
|
|
42
|
-
token: getInput('sonar-token', true),
|
|
43
|
-
},
|
|
44
|
-
llm: {
|
|
45
|
-
provider: getInput('llm-provider') || 'lmstudio',
|
|
46
|
-
endpoint: getInput('llm-endpoint', true),
|
|
47
|
-
model: getInput('llm-model', true),
|
|
48
|
-
apiKey: getInput('llm-api-key') || undefined,
|
|
49
|
-
},
|
|
50
|
-
git: {
|
|
51
|
-
branch: getInput('git-branch') || 'sonar-autofix',
|
|
52
|
-
},
|
|
53
|
-
retry: {
|
|
54
|
-
maxIterations: parseInt(getInput('max-iterations') || '5', 10),
|
|
55
|
-
maxRetries: parseInt(getInput('max-retries') || '3', 10),
|
|
56
|
-
},
|
|
57
|
-
validation: {
|
|
58
|
-
build: JSON.parse(getInput('build-commands') || '["npm run build"]'),
|
|
59
|
-
lint: JSON.parse(getInput('lint-commands') || '["npm run lint"]'),
|
|
60
|
-
tests: JSON.parse(getInput('test-commands') || '["npm test"]'),
|
|
61
|
-
},
|
|
62
|
-
dryRun: getInput('dry-run') === 'true',
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const orchestrator = new CoreOrchestrator(config);
|
|
66
|
-
|
|
67
|
-
console.log('🚀 Starting Sonar Autofix GitHub Action...');
|
|
68
|
-
const summary = await orchestrator.run();
|
|
69
|
-
|
|
70
|
-
// Set outputs
|
|
71
|
-
setOutput('files-fixed', summary.totalFixed);
|
|
72
|
-
setOutput('iterations', summary.iterations);
|
|
73
|
-
|
|
74
|
-
console.log('✅ Done!');
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error(`::error::${error.message}`);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Run the GitHub Action if this file is executed directly
|
|
82
|
-
if (require.main === module) {
|
|
83
|
-
run();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
module.exports = { run };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@sonar-autofix/github-action",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "GitHub Action wrapper for the Sonar Autofix tool",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"sonar",
|
|
11
|
-
"autofix",
|
|
12
|
-
"github",
|
|
13
|
-
"action"
|
|
14
|
-
],
|
|
15
|
-
"author": "Sonar Autofix Team",
|
|
16
|
-
"license": "MIT"
|
|
17
|
-
}
|