ira-review 3.1.2 → 3.1.4
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/dist/cli.js +27 -10
- package/dist/index.cjs +13 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -14,9 +14,10 @@ import {
|
|
|
14
14
|
|
|
15
15
|
// src/cli.ts
|
|
16
16
|
import { Command } from "commander";
|
|
17
|
-
import { existsSync as existsSync9 } from "fs";
|
|
17
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
18
18
|
import { readFile } from "fs/promises";
|
|
19
|
-
import { resolve as resolve3, join as join7 } from "path";
|
|
19
|
+
import { resolve as resolve3, join as join7, dirname } from "path";
|
|
20
|
+
import { fileURLToPath } from "url";
|
|
20
21
|
import { execSync as execSync5 } from "child_process";
|
|
21
22
|
|
|
22
23
|
// src/core/sonarClient.ts
|
|
@@ -1633,17 +1634,23 @@ var CommentTracker = class {
|
|
|
1633
1634
|
return keys;
|
|
1634
1635
|
}
|
|
1635
1636
|
async getBitbucketServerIraComments(pullRequestId) {
|
|
1637
|
+
const visit = (node, sink) => {
|
|
1638
|
+
if (!node) return;
|
|
1639
|
+
if (typeof node.text === "string" && isIraComment(node.text)) {
|
|
1640
|
+
const meta = node.text.match(IRA_META_RE);
|
|
1641
|
+
if (meta) sink.add(`${meta[1]}:${meta[2]}:${meta[3]}`);
|
|
1642
|
+
}
|
|
1643
|
+
if (Array.isArray(node.comments)) {
|
|
1644
|
+
for (const child of node.comments) visit(child, sink);
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1636
1647
|
const keys = /* @__PURE__ */ new Set();
|
|
1637
1648
|
let start = 0;
|
|
1638
1649
|
while (true) {
|
|
1639
|
-
const url = `${this.baseUrl}/rest/api/1.0/projects/${this.project}/repos/${this.bbServerRepoSlug}/pull-requests/${pullRequestId}/
|
|
1650
|
+
const url = `${this.baseUrl}/rest/api/1.0/projects/${this.project}/repos/${this.bbServerRepoSlug}/pull-requests/${pullRequestId}/activities?start=${start}&limit=100`;
|
|
1640
1651
|
const data = await this.fetchBitbucketServerPage(url);
|
|
1641
|
-
for (const
|
|
1642
|
-
if (
|
|
1643
|
-
const meta = comment.text.match(IRA_META_RE);
|
|
1644
|
-
if (meta) {
|
|
1645
|
-
keys.add(`${meta[1]}:${meta[2]}:${meta[3]}`);
|
|
1646
|
-
}
|
|
1652
|
+
for (const activity of data.values) {
|
|
1653
|
+
if (activity.action === "COMMENTED") visit(activity.comment, keys);
|
|
1647
1654
|
}
|
|
1648
1655
|
if (data.isLastPage) break;
|
|
1649
1656
|
start = data.nextPageStart ?? start + 100;
|
|
@@ -4078,8 +4085,18 @@ function logEnvironmentInfo(config) {
|
|
|
4078
4085
|
step("\u{1F510}", `SSL_CERT_FILE: ${sslCert}`);
|
|
4079
4086
|
}
|
|
4080
4087
|
}
|
|
4088
|
+
function readPackageVersion() {
|
|
4089
|
+
try {
|
|
4090
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
4091
|
+
const pkgPath = resolve3(here, "..", "package.json");
|
|
4092
|
+
const pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
|
|
4093
|
+
if (pkg.version) return pkg.version;
|
|
4094
|
+
} catch {
|
|
4095
|
+
}
|
|
4096
|
+
return "unknown";
|
|
4097
|
+
}
|
|
4081
4098
|
var program = new Command();
|
|
4082
|
-
program.name("ira-review").description("AI-powered PR review tool with SonarQube + GitHub/Bitbucket integration").version(
|
|
4099
|
+
program.name("ira-review").description("AI-powered PR review tool with SonarQube + GitHub/Bitbucket integration").version(readPackageVersion());
|
|
4083
4100
|
program.command("review").description("Run AI-powered review on a pull request").option("--sonar-url <url>", "SonarQube/SonarCloud base URL (or IRA_SONAR_URL)").option("--sonar-token <token>", "SonarQube API token (or IRA_SONAR_TOKEN)").option("--project-key <key>", "Sonar project key (or IRA_PROJECT_KEY)").option("--pr <id>", "Pull request ID (or IRA_PR)").option("--scm-provider <provider>", "SCM provider: bitbucket or github (or IRA_SCM_PROVIDER)").option("--bitbucket-token <token>", "Bitbucket API token (or IRA_BITBUCKET_TOKEN)").option("--repo <repo>", "Bitbucket workspace/repo-slug (Cloud) or PROJECT/repo-slug (Server) (or IRA_REPO)").option("--bitbucket-url <url>", "Bitbucket base URL (or IRA_BITBUCKET_URL)").option("--bitbucket-type <type>", "Bitbucket type: cloud or server (auto-detects from URL if omitted; or IRA_BITBUCKET_TYPE)").option("--github-token <token>", "GitHub API token (or IRA_GITHUB_TOKEN)").option("--github-repo <repo>", "GitHub owner/repo (or IRA_GITHUB_REPO)").option("--github-url <url>", "GitHub Enterprise URL (or IRA_GITHUB_URL)").option("--ai-provider <provider>", "AI provider").option("--ai-model <model>", "AI model to use").option("--dry-run", "Print comments to stdout instead of posting to SCM").option("--min-severity <level>", "Minimum severity to review (BLOCKER|CRITICAL|MAJOR|MINOR|INFO)").option("--jira-url <url>", "JIRA base URL (or IRA_JIRA_URL)").option("--jira-email <email>", "JIRA email (or IRA_JIRA_EMAIL)").option("--jira-token <token>", "JIRA API token (or IRA_JIRA_TOKEN)").option("--jira-type <type>", "JIRA type: cloud or server (auto-detects from URL if omitted)").option("--jira-ticket <key>", "JIRA ticket key (e.g. PROJ-123)").option("--jira-ac-field <field>", "Custom field ID for acceptance criteria").option("--jira-ac-source <source>", "Where to look for AC: customField, description, or both (default: customField)").option("--no-post-acs-to-jira", "Don't post AI-generated acceptance criteria back to the JIRA ticket when none exist; keep them in the PR summary only (or IRA_POST_ACS_TO_JIRA=false)").option("--slack-webhook <url>", "Slack webhook URL for notifications").option("--teams-webhook <url>", "Teams webhook URL for notifications").option("--notify-min-risk <level>", "Only notify when risk is at or above this level: low, medium, high, critical").option("--notify-on-ac-fail", "Send notification when JIRA acceptance criteria validation fails").option("--ai-base-url <url>", "AI provider base URL (Azure endpoint, Ollama URL)").option("--ai-api-key <key>", "AI API key (or IRA_AI_API_KEY / OPENAI_API_KEY)").option("--ai-api-version <version>", "Azure OpenAI API version").option("--ai-deployment <name>", "Azure OpenAI deployment name").option("--ai-model-critical <model>", "Stronger AI model for BLOCKER/CRITICAL issues").option("--generate-tests", "Generate test cases from JIRA acceptance criteria").option("--test-framework <framework>", "Test framework: jest, vitest, mocha, playwright, cypress, gherkin, pytest, junit (default: jest)").option("--config <path>", "Path to config file (default: auto-detect .irarc.json / ira.config.json)").option("--no-config-file", "Disable auto-loading config file from repo").option("--rules-url <url>", "Fetch .ira-rules.json from URL (raw HTTP) \u2014 useful when CI has no full checkout (or IRA_RULES_URL)").option("--comment-style <style>", "Comment formatter style: compact (default) or detailed (or IRA_COMMENT_STYLE)").action(async (opts) => {
|
|
4084
4101
|
try {
|
|
4085
4102
|
console.log(`
|
package/dist/index.cjs
CHANGED
|
@@ -2429,17 +2429,23 @@ var CommentTracker = class {
|
|
|
2429
2429
|
return keys;
|
|
2430
2430
|
}
|
|
2431
2431
|
async getBitbucketServerIraComments(pullRequestId) {
|
|
2432
|
+
const visit = (node, sink) => {
|
|
2433
|
+
if (!node) return;
|
|
2434
|
+
if (typeof node.text === "string" && isIraComment(node.text)) {
|
|
2435
|
+
const meta = node.text.match(IRA_META_RE);
|
|
2436
|
+
if (meta) sink.add(`${meta[1]}:${meta[2]}:${meta[3]}`);
|
|
2437
|
+
}
|
|
2438
|
+
if (Array.isArray(node.comments)) {
|
|
2439
|
+
for (const child of node.comments) visit(child, sink);
|
|
2440
|
+
}
|
|
2441
|
+
};
|
|
2432
2442
|
const keys = /* @__PURE__ */ new Set();
|
|
2433
2443
|
let start = 0;
|
|
2434
2444
|
while (true) {
|
|
2435
|
-
const url = `${this.baseUrl}/rest/api/1.0/projects/${this.project}/repos/${this.bbServerRepoSlug}/pull-requests/${pullRequestId}/
|
|
2445
|
+
const url = `${this.baseUrl}/rest/api/1.0/projects/${this.project}/repos/${this.bbServerRepoSlug}/pull-requests/${pullRequestId}/activities?start=${start}&limit=100`;
|
|
2436
2446
|
const data = await this.fetchBitbucketServerPage(url);
|
|
2437
|
-
for (const
|
|
2438
|
-
if (
|
|
2439
|
-
const meta = comment.text.match(IRA_META_RE);
|
|
2440
|
-
if (meta) {
|
|
2441
|
-
keys.add(`${meta[1]}:${meta[2]}:${meta[3]}`);
|
|
2442
|
-
}
|
|
2447
|
+
for (const activity of data.values) {
|
|
2448
|
+
if (activity.action === "COMMENTED") visit(activity.comment, keys);
|
|
2443
2449
|
}
|
|
2444
2450
|
if (data.isLastPage) break;
|
|
2445
2451
|
start = data.nextPageStart ?? start + 100;
|