Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-build-missing-api-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codacy/codacy-cloud-cli": patch
---

Fix `npm run build` (and `npm test`, `npm run check-types`, `npm start`) failing with `Cannot find module '../api/client/**'` on a fresh clone. These scripts now auto-generate the gitignored API client via a new `ensure-api-client` `pre*` hook when `src/api/client/` is missing, instead of requiring `npm run update-api` to be run manually first.
5 changes: 5 additions & 0 deletions .changeset/free-planets-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codacy/codacy-cloud-cli": patch
---

Add support for proxy variables
5 changes: 5 additions & 0 deletions .changeset/old-peas-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codacy/codacy-cloud-cli": patch
---

Add support for proxy variables
5 changes: 5 additions & 0 deletions .changeset/proxy-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codacy/codacy-cloud-cli": minor
---

Add support for running behind an HTTP/HTTPS proxy via `HTTP_PROXY`/`HTTPS_PROXY` environment variables (with `NO_PROXY` bypass support).
2 changes: 2 additions & 0 deletions .changeset/proxy-tls-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
5 changes: 5 additions & 0 deletions .changeset/sunny-ads-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@codacy/codacy-cloud-cli": patch
---

Add proxy configurations
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
| Full API update | `npm run update-api` |
| Run tests | `npm test` |

`build`, `test`, `check-types`, and `start` auto-run `npm run update-api` on a fresh clone (via a `pre*` `ensure-api-client` hook) if `src/api/client/` doesn't exist yet, so no manual bootstrap step is required.

## Architecture & Project Structure

```
Expand Down Expand Up @@ -240,6 +242,9 @@
|---|---|---|
| `CODACY_API_TOKEN` | One of the two | Account API token. Get it from Codacy > Account > API Tokens |
| `CODACY_PROJECT_TOKEN` | One of the two | Repository (project) token, scoped to one repository. Get it from Codacy > Repository > Settings > Integrations > Project API token. **Outranks `CODACY_API_TOKEN`** — see `SPECS/repository-tokens.md` |
| `HTTPS_PROXY` / `HTTP_PROXY` | No | Route outbound API requests through an HTTP/HTTPS proxy (case-insensitive; `HTTPS_PROXY` takes precedence). Resolved by `src/utils/proxy.ts`, installed via `undici`'s `ProxyAgent`/`setGlobalDispatcher` in `src/index.ts` before any command runs. |
| `NO_PROXY` / `no_proxy` | No | Comma-separated hostnames (or `*`) to bypass the proxy for, checked against the Codacy API host. |
| `NODE_EXTRA_CA_CERTS` | No | Standard Node.js env var (not implemented by this CLI). Path to a PEM CA bundle to trust in addition to Node's built-in CAs. Fixes `UNABLE_TO_GET_LOCAL_ISSUER_CERT` errors behind TLS-intercepting corporate proxies. |

Check notice on line 247 in AGENTS.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

AGENTS.md#L247

Undefined acronym "PEM" — define on first use or add to glossary.

## Useful Context

Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ An explicit `--repository-token` wins outright, so a deliberately scoped run is

Passing `--repository-token` with an **empty** value is an error rather than a fallback. `--repository-token "$CODACY_PROJECT_TOKEN"` with the secret unset is a common CI mistake, and quietly falling back to an account token would run with much wider access than you asked for. An empty *environment variable*, by contrast, simply means "unset".

### Proxy Support

The CLI respects the standard `HTTPS_PROXY`/`HTTP_PROXY` (and lowercase `https_proxy`/`http_proxy`) environment variables, routing all outbound API requests through the configured proxy. `HTTPS_PROXY` takes precedence over `HTTP_PROXY` when both are set. `NO_PROXY`/`no_proxy` is honored to bypass the proxy for the Codacy API host. No proxy env vars set means no change in behavior.

```bash
HTTPS_PROXY=http://proxyhost:port codacy info
```

#### TLS Interception (MITM) Proxies

Some corporate proxies perform TLS interception (man-in-the-middle) using an internal root CA. Unlike `curl`, which trusts your OS certificate store, Node.js uses its own bundled CA list and doesn't read the OS trust store — so requests can fail with `unable to get local issuer certificate` / `UNABLE_TO_GET_LOCAL_ISSUER_CERT` even when `curl -x "$HTTPS_PROXY" -v https://app.codacy.com/api/v3/user` against the same host succeeds. That mismatch (curl works, the CLI doesn't) is the tell-tale sign of this issue.

The fix is to point Node at your corporate CA bundle via the standard `NODE_EXTRA_CA_CERTS` environment variable:

```bash
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca-bundle.pem
codacy login
```

Ask your IT/security team for this bundle, or export it yourself from your OS/browser certificate trust store (PEM format).

## Usage

```bash
Expand Down
3 changes: 3 additions & 0 deletions SPECS/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,6 @@ _No pending tasks._ All commands implemented.
| 2026-07-28 | (OD-378) New `pull-requests` (`prs`) command — the plural counterpart to `pull-request`, listing PRs for a repository with the same analysis-gated table columns as `repository`'s "Open Pull Requests" section (reuses `buildGateStatus`/`formatStandards`/`formatPrIssues`/`formatPrCoverage`/`formatDelta`). `--search-text`/`-q` and `--branch`/`-b` map to the API's `textQuery`/`targetBranch` params added in OD-376; the classification param (`search`, Merged vs. last-updated) is deliberately not exposed — different axis, out of scope. `[provider] [org] [repo]` auto-detect via `resolveRepoArgs`, paginate-to-`--limit` loop matching `findings`. Registered in `src/index.ts` (10 new tests, 516 total) |
| 2026-07-30 | (OD-378, review follow-up) `pull-requests` table polish + a real data bug. **Bug:** Complexity rendered as "no data" on every PR because the API omits the flat top-level `deltaComplexity` and only returns `quality.deltaComplexity` (while still sending a top-level `deltaClonesCount`) — new shared `prQualityMetric(pr, key)` in `utils/formatting.ts` reads the nested `quality` value first and falls back to the flat field; also applied to `repository`'s Open PR table and `pull-request`'s Analysis section, which had the same bug. **Layout:** `✓` moved to the first column; metric order now matches `repositories` (issues → complexity → duplication → coverage); the Coverage column is dropped entirely when no listed PR has a coverage value (new `hasAnyPrCoverage()` — repos without coverage return `diffCoverage.cause` and no numbers on any PR); missing metric values now render as a dim `-` instead of `N/A` in `formatDelta`/`formatPrCoverage`/`formatPrIssues`, matching `formatStandards`/`formatCountCell`/`formatCoverageCell`; and a zero issue count renders as a bare `0` rather than `+0`/`-0` (`-0` read as a negative), matching what `pull-request`'s Files table and `formatDelta` already did. **JSON:** added `quality.resultReasons`/`coverage.resultReasons` (Codacy review suggestion — they drive the per-metric gate coloring, so consumers need them to see which gates passed/failed) plus the `quality.*` metric mirrors the table actually renders (23 new tests, 544 total) |
| 2026-08-11 | (OD-489) Repository (project) token support. New `--repository-token <token>` on every command (plus `CODACY_PROJECT_TOKEN`), sent as the `project-token` header; account tokens keep `api-token`. `src/utils/auth.ts` rewritten around a `RemoteAuth` discriminated union carrying both kind and source, replacing `checkApiToken()` with `resolveAuth(this)` / `resolveAccountAuth(this, why)` / `requireAccountToken(...)` / `fetchIfAccountToken(...)`. Precedence matches `codacy-analysis` exactly — flag > `CODACY_PROJECT_TOKEN` > `CODACY_API_TOKEN` > stored login — so `vitest.config.mts` now blanks `CODACY_PROJECT_TOKEN` (it outranks the account token and is exported job-wide by the coverage reporter, so tests would otherwise depend on the developer's shell). Codacy whitelists only 13 operations for repository tokens, so `tool`/`patterns`/`pattern` work unchanged, `issues` (incl. `--overview`) and `tools --import` work, and the 9 account-only commands plus `repository`'s 6 management flags, `issues --ignore`/`--ignored`, and `tools --import --force` (only when standards exist) **fail fast before any request** with a message naming the operation, the reason, and where the token came from. `repository`'s dashboard skips the two non-whitelisted calls: the table keeps the "Open Pull Requests" header with an explanatory line, and JSON keeps `pullRequests: []` (so `jq '.pullRequests[]'` still works) plus an additive `unavailable: ["pullRequests"]` — under an account token the payload is byte-identical. Also added the long-missing `.catch()` on the PR call so an account token lacking PR access degrades instead of losing the whole dashboard, and fixed `login`'s 401 message, which told repository-token users their token was "invalid" when it is rejected by `/user` by design. New `SPECS/repository-tokens.md` (whitelist + matrix, re-verify on every `npm run update-api`) and `SPECS/missing-endpoints.md` (ranked gaps for follow-up Linear tasks) (40 new tests, 606 total) |
| 2026-09-03 | HTTP/HTTPS proxy support. Node's built-in `fetch` (used by the generated API client) doesn't honor `HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY` automatically on the Node versions this CLI supports (`engines` requires Node ≥20; Node 24's `NODE_USE_ENV_PROXY` flag is experimental and version-specific). New `src/utils/proxy.ts`: `resolveProxyUrl(env)` reads `HTTPS_PROXY`/`HTTP_PROXY` (and lowercase forms, uppercase wins), `shouldBypassProxy(env, host)` checks `NO_PROXY`/`no_proxy` against the Codacy API host, and `configureProxyFromEnv(env)` installs an `undici.ProxyAgent` via `setGlobalDispatcher` when a proxy is resolved and not bypassed. Called from `src/index.ts` before `OpenAPI.BASE`/`OpenAPI.HEADERS` are set; no-op when no proxy env vars are set, so existing behavior is unchanged. Added `undici` as a direct dependency. Documented in `README.md` (new "Proxy Support" section) and `AGENTS.md` (Environment Variables table) (17 new tests) |
| 2026-09-03 | Fixed `npm run build` (and `npm test`, `npm run check-types`, `npm start`) failing on a fresh clone with `Cannot find module '../api/client/**'`: `src/api/client/` is gitignored/auto-generated and previously required a manual `npm run update-api` first. New `ensure-api-client` script wired as `pre*` hook on those four scripts runs `update-api` only when `src/api/client/` is missing (no-op in CI, which already generates it explicitly) |
| 2026-09-03 | Docs-only: documented `NODE_EXTRA_CA_CERTS` for users behind corporate proxies that perform TLS interception (MITM) with an internal root CA. Node's `fetch` uses its own bundled CA list rather than the OS trust store, so requests fail with `unable to get local issuer certificate` / `UNABLE_TO_GET_LOCAL_ISSUER_CERT` even when `curl -x "$HTTPS_PROXY" ...` against the same host succeeds. New "TLS Interception (MITM) Proxies" subsection under `README.md`'s "Proxy Support" section (fix, how to obtain the CA bundle, and the curl-vs-CLI diagnostic) plus a new row in `AGENTS.md`'s Environment Variables table. No source code changes — `NODE_EXTRA_CA_CERTS` is a standard Node.js env var, not implemented by this CLI |
1 change: 1 addition & 0 deletions SPECS/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- **Build output:** `dist/` (gitignored)
- **Build command:** `npm run build` (runs `tsc`)
- **Build tsconfig:** `tsconfig.build.json` (excludes test files, used for `prepublishOnly`)
- **API client bootstrap:** `src/api/client/` (gitignored, auto-generated) doesn't exist in a fresh clone. `build`, `test`, `check-types`, and `start` each have a `pre*` script (`ensure-api-client`) that runs `npm run update-api` automatically the first time, so these scripts work out of the box without a manual `npm run update-api` step. It's a no-op once `src/api/client/` exists (CI generates it explicitly beforehand, so this adds no extra fetch there).

## Global Flag

Expand Down
Loading