Skip to content

Commit 440a57f

Browse files
claudiacodacyclaudealerizzo
authored
feat(issues): add --state ignored to list ignored issues OD-318 (#28)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Alejandro Rizzo <alerizzo@gmail.com>
1 parent 97942fc commit 440a57f

9 files changed

Lines changed: 620 additions & 22 deletions

File tree

‎.changeset/confirm-bulk-ignore.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@codacy/codacy-cloud-cli": minor
3+
---
4+
5+
`codacy issues --ignore` now asks for confirmation before bulk-ignoring. It
6+
prints how many issues match the current filters and only proceeds when you
7+
answer `y`, guarding against a mistyped or too-broad filter ignoring far more
8+
issues than intended. Pass `--skip-confirmation` (`-y`) to bypass the prompt in
9+
CI or scripts; in a non-interactive shell without that flag the command aborts
10+
without ignoring anything.

‎.changeset/list-ignored-issues.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@codacy/codacy-cloud-cli": minor
3+
---
4+
5+
Add `codacy issues --ignored` (`-i`) to list issues that were marked as ignored
6+
on Codacy. Without the flag, `codacy issues` behaves exactly as before; pass
7+
`--ignored` to see the ignored ones instead. The
8+
ignored listing accepts all the same filters as the normal search (`--branch`,
9+
`--severities`, `--categories`, `--tools`, `--patterns`, `--languages`, `--tags`,
10+
`--authors`, `--limit`, and `--false-positives`), and each ignored issue shows
11+
who ignored it, when, the reason, and any comment. It cannot be combined with
12+
`--overview` or `--ignore`. `--output json` emits an `ignoredIssues` array.
13+
Unignoring individual issues stays with `codacy issue <id> --unignore`.

‎.gemini/styleguide.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ concerns.
3030
versions (no `^`/`~`) for reproducibility and to avoid dependency-confusion
3131
risk. Flagging an unpinned range is correct; suggesting a range is not.
3232

33+
## CLI output / rendering
34+
- `src/utils/formatting.ts` has two issue-card renderers that differ **on
35+
purpose**: `printIgnoredIssueCard` omits the "Potential false positive"
36+
warning that `printIssueCard` shows, because an ignored issue already surfaces
37+
its ignore reason (usually `FalsePositive`) on the metadata line. Don't flag
38+
the missing warning as a parity gap. The shared header/message/file-line block
39+
is factored into `printIssueCardBody`; the trailing sections diverge by design.
40+
3341
## Generated files
3442
- `package-lock.json` and everything under `src/api/client/**` are generated.
3543
Complexity, duplication, and size findings on these are false positives.

‎SPECS/README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,6 @@ _No pending tasks._ All commands implemented.
7474
| 2026-06-24 | `findings` and `finding` now surface the vulnerable dependency's import chain from the new `dependencyChains` field: Direct (`Update <pkg> to <fixed>`) vs Transitive (`<chain> (Fixed in <fixed>)`), with the middle collapsed to `... N more ...` for 4+ packages. List shows the first chain + `... and X more`; detail shows all chains aligned under a single label. New helpers in `utils/formatting.ts` (`formatDependencyChain`, `formatDependencyChainsLine`, `formatDependencyChainsBlock`); `dependencyChains` added to both JSON projections (17 new tests, 390 total) |
7575
| 2026-06-30 | npm-style "update available" notice via `update-notifier@5`: one-time stderr hint when a newer version is published, gated to `--output table` (suppressed for `json`, when piped, in CI, under `npx`). Non-blocking daily background check; never auto-updates. New `src/version.ts` (single source of name/version) + `src/utils/update-check.ts` (`maybeNotifyUpdate`); `preAction` hook + `--no-update-notifier` flag wired in `index.ts`. Opt-outs: `CODACY_DISABLE_UPDATE_CHECK`, `NO_UPDATE_NOTIFIER`, `--no-update-notifier`. `package.json` `overrides` pin transitive `got@^11.8.6`/`package-json@^7` (CVE-2022-33987) (7 new tests, 409 total) |
7676
| 2026-07-07 | `ls` and `directories` commands: browse a repository's folders/files with quality metrics (Grade/Issues/Complexity/Duplication/Coverage). Auto-detect provider/org/repo and the cwd-relative path; `--path`/`--branch` options; `directories --plus-children` shows one extra level as a `└─` tree (header adds `, M subdirectories`). `--sort`/`--direction` (server-side; in `ls`, directories and files sorted independently), and `ls --search <term>` (files only; folds the path into the search as `<path>/%<term>` and shows full paths). Duplication uses `numberOfClones`; Complexity uses `complexity` (hotspots). Both fetch **all** pages (no pagination warning) via new `src/utils/repo-tree.ts` (path resolution + `resolveSort`/`resolveDirection` + `fetchAllDirectories`/`fetchAllFiles`). Row markers `▸` folder / dim `·` file (no emojis). Promoted `formatGrade` to `utils/formatting.ts` (now also colors E red) and added `formatCountCell`/`formatCoverageCell` (48 new tests, 457 total) |
77+
| 2026-07-16 | `issues --ignored` (`-i`): new read-only mode listing issues marked as ignored on Codacy, via the dedicated `searchRepositoryIgnoredIssues` endpoint. Boolean flag modeled on `--false-positives` for consistency (not a `--state <value>` selector). Reuses `buildFilterBody` (all existing filters + `--false-positives` pass through) and the paginate-to-`--limit` loop; errors when combined with `--overview`/`--ignore`. New `printIgnoredIssueCard` in `utils/formatting.ts` renders the ignore metadata line (`Ignored as <reason> by <name> · <date>` + optional comment) and the string `issueId` (ignored issues have no numeric `resultDataId`). Omitting the flag keeps existing behavior unchanged (10 new tests, 475 total) |
7778
| 2026-07-08 | `issues --overview` noise suggestions tuned to stop firing on low-volume repos: added a `NOISE_MIN_TOTAL` (200) floor on the repo's total issues that suppresses the whole "reduce noise" section below it, and a `NOISE_MIN_PATTERN` (100) absolute floor on each pattern's own count (AND-gated with the relative rules) so a long tail of tiny patterns can't drag the median down and make a ~9-issue pattern look noisy — the total floor is kept above the per-pattern floor so it isn't dead code; the ≥10% share rule now only applies with ≥11 distinct patterns (`NOISE_MIN_PATTERNS_FOR_SHARE` — an even split only drops below 10% once N > 10, so 8–10 balanced patterns would otherwise all be flagged); and the ≥3× multiple rule (`NOISE_MEDIAN_MULTIPLE`) now measures against the **median** (via new `medianOf()`) instead of the mean, so a single huge pattern can no longer inflate the baseline and mask smaller disproportionate patterns (5 new tests, 465 total) |
79+
| 2026-07-17 | `issues --ignore` now confirms before bulk-ignoring: `executeBulkIgnore` prints the match count then prompts via shared `confirmAction` (`utils/prompt.ts`), proceeding only on `y`. New `--skip-confirmation` (`-y`) bypasses the prompt for CI/scripts (same short flag as `tools --import --skip-approval`); non-TTY without the flag aborts rather than ignoring by accident. Confirmation runs after the fetch (count is shown) but before any `bulkIgnoreIssues` call (3 new tests, 478 total) |

‎SPECS/commands/issues.md‎

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ codacy is gh my-org my-repo --output json
1818
## API Endpoints
1919

2020
- [`searchRepositoryIssues`](https://api.codacy.com/api/api-docs#searchrepositoryissues) — `AnalysisService.searchRepositoryIssues(provider, org, repo, cursor, limit, body)`
21+
- [`searchRepositoryIgnoredIssues`](https://api.codacy.com/api/api-docs#searchrepositoryignoredissues) — `AnalysisService.searchRepositoryIgnoredIssues(provider, org, repo, cursor, limit, body)` (only when `--ignored` is given; accepts the same `SearchRepositoryIssuesBody`)
2122
- [`issuesOverview`](https://api.codacy.com/api/api-docs#issuesoverview) — `AnalysisService.issuesOverview(provider, org, repo, body)` (only when `--overview` is given)
2223
- [`listTools`](https://api.codacy.com/api/api-docs#listtools) — `ToolsService.listTools(cursor, limit)` (only when `--overview` surfaces noisy patterns, to map each pattern's `prefix` to its owning tool)
2324
- [`listRepositoryTools`](https://api.codacy.com/api/api-docs#listrepositorytools) — `AnalysisService.listRepositoryTools(provider, org, repo)` (only when `--overview` surfaces noisy patterns, to detect config-file-driven tools)
@@ -39,10 +40,12 @@ codacy is gh my-org my-repo --output json
3940
| `--tools <tools>` | `-T` | Comma-separated tool UUIDs or names |
4041
| `--limit <n>` | `-n` | Maximum number of issues (default: 100, max: 1000) |
4142
| `--overview` | `-O` | Show overview counts instead of list |
43+
| `--ignored` | `-i` | List issues marked as ignored instead of active ones |
4244
| `--false-positives [value]` | `-F` | Filter by potential false positives (true, false, or omit) |
4345
| `--ignore` | `-I` | Ignore all issues matching current filters |
4446
| `--ignore-reason <reason>` | `-R` | Reason for ignoring (AcceptedUse, FalsePositive, NotExploitable, TestCode, ExternalCode) |
4547
| `--ignore-comment <comment>` | `-m` | Optional comment when using --ignore |
48+
| `--skip-confirmation` | `-y` | Skip the confirmation prompt when using --ignore (for CI/scripts) |
4649

4750
## Output
4851

@@ -128,6 +131,50 @@ calls only run when at least one noisy pattern exists.
128131

129132
`--output json` is unaffected (raw counts only — no relabeling or suggestions).
130133

134+
### Ignored mode (`--ignored`)
135+
136+
Lists issues that were marked as ignored on Codacy, via the dedicated
137+
`searchRepositoryIgnoredIssues` endpoint. `--ignored` is a boolean flag (like
138+
`--false-positives`); without it, `codacy issues …` lists active issues as
139+
before, and passing `--ignored` switches to the ignored listing.
140+
141+
The endpoint accepts the same filter body as the active-issues search, so every
142+
filter (`--branch`, `--patterns`, `--tools`, `--severities`, `--categories`,
143+
`--languages`, `--tags`, `--authors`, `--limit`) and `--false-positives` apply.
144+
It cannot be combined with `--overview` (no ignored-issues overview exists) or
145+
`--ignore` (those issues are already ignored) — both error out.
146+
147+
Output is a card list sorted by severity, like the default list mode, plus an
148+
ignore-metadata line per issue:
149+
150+
```
151+
Critical | Security Injection <issueId>
152+
Potential SQL injection vulnerability
153+
154+
src/auth.ts:20
155+
db.query(`SELECT * FROM users WHERE id = ${id}`);
156+
157+
Ignored as FalsePositive by Jane Dev · 2026-06-01
158+
Comment: Reviewed, not exploitable
159+
```
160+
161+
Ignored issues carry the string `issueId` (there is no numeric `resultDataId`),
162+
and the `Comment:` line is shown only when a comment was recorded. Unignoring is
163+
not part of this mode — use `codacy issue <id> --unignore` (there is no
164+
bulk-unignore endpoint). `--output json` emits `{ ignoredIssues: [...] }`
165+
projected to the shown fields.
166+
167+
### Bulk ignore mode (`--ignore`)
168+
169+
Fetches every issue matching the current filters (all pages) and marks them all
170+
as ignored via `bulkIgnoreIssues` (batched at 100 IDs per call). Because this is
171+
destructive and applies to *all* matching issues, it prompts for confirmation
172+
after showing the count (`Ignore all N matching issues? …`) and only proceeds on
173+
an explicit `y`. `--skip-confirmation` (`-y`) bypasses the prompt for CI/scripts;
174+
in a non-interactive shell without that flag the prompt cannot be answered, so
175+
the command aborts without ignoring anything (rather than ignoring by accident).
176+
Cannot be combined with `--overview` or `--limit`.
177+
131178
## Tests
132179

133-
File: `src/commands/issues.test.ts` — 46 tests.
180+
File: `src/commands/issues.test.ts` — 64 tests.

‎src/commands/AGENTS.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,15 @@ Keeps the two command handlers thin: they only supply the API-specific callbacks
265265
- **`--ignore` mode** (`-I`): fetches all issues matching current filters (all pages), then calls `AnalysisService.bulkIgnoreIssues` in batches of 100
266266
- `-R, --ignore-reason`: `AcceptedUse` (default) | `FalsePositive` | `NotExploitable` | `TestCode` | `ExternalCode`
267267
- `-m, --ignore-comment`: optional free-text comment
268+
- **Confirmation** (`-y, --skip-confirmation`): the ignore is destructive and applies to *all* matching issues, so `executeBulkIgnore` prompts via `confirmAction` (shared `utils/prompt.ts`) after printing the count, and only proceeds on an explicit `y`. `--skip-confirmation` skips the prompt for CI/scripts. `confirmAction` returns `false` on a non-TTY, so a non-interactive run without the flag aborts rather than ignoring by accident. Same `-y` short flag as `tools --import`'s `--skip-approval`. Confirmation happens *after* fetching (so the count is shown) but *before* any `bulkIgnoreIssues` call
268269
- Cannot be combined with `--overview` or `--limit`
269270
- Works with any combination of filters; use `--false-positives --ignore` to ignore only FP issues
271+
- **`--ignored` mode** (`-i`): boolean flag that lists ignored issues instead of active ones. Modeled as a boolean flag for consistency with the other boolean filter, `--false-positives` (not a `--state <value>` selector). `-i` is the natural short flag; note it is distinct from `-I/--ignore` (the bulk-ignore *action*) — `-i` lists already-ignored issues, `-I` ignores matching active ones. Omitting the flag keeps the existing active-issues behavior unchanged
272+
- `--ignored` calls `AnalysisService.searchRepositoryIgnoredIssues` (dedicated `.../ignoredIssues/search` endpoint), reusing `buildFilterBody` — every base filter passes through unchanged — and the same paginate-to-`--limit` loop + pagination warning as list mode
273+
- Guards: errors when combined with `--overview` (no ignored-issues overview endpoint) or `--ignore` (those issues are already ignored). `--false-positives` is intentionally **allowed** — it's part of the shared filter body, so "ignored issues that are potential false positives" is a valid query
274+
- Rendered via `printIgnoredIssueCard` (in `utils/formatting.ts`): a variant of `printIssueCard` because `IgnoredIssue` has no numeric `resultDataId` (shows the string `issueId` instead) and carries ignore metadata — the trailing `Ignored as <reason> by <name> · <friendly date>` line plus an optional `Comment:` line
275+
- View-only: unignoring stays with `issue --unignore` (there is no bulk-unignore endpoint; it would be N per-issue `updateIssueState` calls — a possible fast-follow since `IgnoredIssue` carries the string `issueId`)
276+
- JSON: `{ ignoredIssues: [...] }`, each item projected via `pickDeep` (`issueId`, `reason`, `comment`, `ignoredByName`, `ignoredTimestamp`, `patternInfo.*`, `filePath`, `lineNumber`, `lineText`, `falsePositive*`)
270277

271278
## finding command (`finding.ts`)
272279

0 commit comments

Comments
 (0)