Skip to content

Commit 6de6d1e

Browse files
chore: fix issue with reading environment varibles (#914)
1. add new cli options: - 'request-max-retries' - 'request-retry-delay' 2. Fix reading CF_ARG_* envs 3. Add Claude context file
1 parent 260f11d commit 6de6d1e

3 files changed

Lines changed: 133 additions & 4 deletions

File tree

CLAUDE.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project
6+
7+
`codefresh` — the Codefresh command-line tool. A Node.js CLI built on `yargs` that talks to the Codefresh API through an OpenAPI-driven SDK (`codefresh-sdk`) and also wraps several external binaries (Stevedore, Venona, gitops controllers) on the user's machine.
8+
9+
Node `^24.0.0` is required (see [.nvmrc](.nvmrc)). Package manager is `yarn@1.22` with `--frozen-lockfile` in CI.
10+
11+
## Common commands
12+
13+
```bash
14+
yarn install # install deps (use --frozen-lockfile in CI)
15+
yarn test # jest, runs every *.spec.js with --coverage
16+
yarn test path/to/file.spec.js # run a single spec file
17+
yarn test -t "pattern" # run tests whose name matches pattern
18+
yarn eslint # lint + autofix lib/logic/**
19+
yarn e2e # bash-driven scenarios in e2e/scenarios/*.sh (needs an authenticated CLI)
20+
yarn generate-completion # rebuilds lib/interface/cli/completion/tree.js — required by Dockerfile
21+
yarn build-local-docs # generate Hugo docs into ./temp
22+
yarn serve-docs # serve them locally; ALLOW_BETA_COMMANDS=true also includes beta cmds
23+
yarn pkg # build native binaries with @yao-pkg/pkg (alpine/macos/linux/win, x64+arm64)
24+
node lib/interface/cli/codefresh <cmd> # run the CLI directly from a clone (skipping the global `codefresh` install)
25+
```
26+
27+
Jest setup is configured in [package.json](package.json) (`jest.setupFiles`[test-setup.js](test-setup.js)). The setup mocks `Output`, `whoami`, and `request-promise`, and exposes `configureSdk()` / `verifyResponsesReturned()` as globals used throughout `*.sdk.spec.js`.
28+
29+
## Architecture
30+
31+
### Entry point and command discovery
32+
33+
`lib/interface/cli/codefresh` (the `bin` entry) delegates to [commad-line-interface.js](lib/interface/cli/commad-line-interface.js) (note the spelling). On startup it:
34+
35+
1. Recursively reads every `*.cmd.js` file under [lib/interface/cli/commands/](lib/interface/cli/commands/).
36+
2. Loads SDK config (`codefresh-sdk` + bundled [openapi.json](openapi.json) + cfconfig auth) — unless the invocation is `config use-context`, which is the only context-less path.
37+
3. Registers only commands where `isRoot()` is true. Subcommands attach to their parent via the `parent:` option in their constructor (see below).
38+
39+
Beta commands are filtered at this top level by `context.isBetaFeatEnabled()`. The on-prem flag is filtered per-subcommand inside `Command._createBuilderFunction`.
40+
41+
### The `Command` class
42+
43+
[lib/interface/cli/Command.js](lib/interface/cli/Command.js) wraps yargs. Conventions every command file follows:
44+
45+
- Each file exports a single `new Command({...})` instance (file name `*.cmd.js`).
46+
- Root commands set `root: true`; subcommands set `parent: require('../some/parent.cmd')` — that call also auto-registers the child via `setParentCommand`.
47+
- `requiresAuthentication` defaults to `true` for roots; subcommands inherit unless they override. Auth is enforced in [helpers/general.js#wrapHandler](lib/interface/cli/helpers/general.js) which also implements `--watch` (loop + `draftlog`) and the consecutive-error tolerance for watch mode.
48+
- `betaCommand: true` / `onPremCommand: true` gate the command behind context feature flags.
49+
- `webDocs: { category, title, weight }` feeds the Hugo docs generator ([docs/index.js](docs/index.js)) via `prepareDocs()`.
50+
- Handlers receive parsed `argv`; values can also be supplied through `CF_ARG_*` env vars (set in `commad-line-interface.js` via `yargs.env('CF_ARG_')`).
51+
52+
When adding a new command, follow the surrounding directory's pattern — most resources have a `get.cmd.js` / `create.cmd.js` / `delete.cmd.js` triple, and bash completion is generated from sibling `*.completion.js` files.
53+
54+
### SDK layer
55+
56+
[lib/logic/sdk/index.js](lib/logic/sdk/index.js) exports a single shared `Codefresh` SDK instance. It is configured once at startup from `openapi.json`; downstream code does `const { sdk } = require('../../logic')` and calls methods like `sdk.pipelines.get({...})` whose names come straight from the OpenAPI spec.
57+
58+
To add a new API endpoint there is usually no manual SDK wiring — regenerate/bump `openapi.json` and the method appears on `sdk`.
59+
60+
### Output and entities
61+
62+
`Output.print(data)` ([lib/output/Output.js](lib/output/Output.js)) dispatches by `--output` flag to a renderer in [lib/output/types/](lib/output/types/) (`json`, `yaml`, `table` (default + wide), `id`, `name`, `jsonArray`, `yamlArray`). When `--watch` is set, output goes through `draftlog` to overwrite in place.
63+
64+
Domain objects under [lib/logic/entities/](lib/logic/entities/) extend [Entity.js](lib/logic/entities/Entity.js). Each entity declares `defaultColumns` / `wideColumns`; renderers call `toDefault()` / `toWide()` / `toJson()` / `toYaml()` / `toName()` / `toId()`. Table column styling (colors, status badges) lives in matching files under [lib/output/formatters/](lib/output/formatters/). `fromResponse` is the constructor convention used by command handlers.
65+
66+
### Config storage
67+
68+
Two distinct config files:
69+
70+
- `~/.cfconfig` (override with `--cfconfig`) — auth contexts; managed entirely by `codefresh-sdk`.
71+
- `~/.Codefresh/cli-config/config.yaml` — CLI profile/preferences (request timeout, retries, pagination), managed by [lib/logic/cli-config/Manager.js](lib/logic/cli-config/Manager.js) with a JSON schema at [lib/logic/cli-config/schema.json](lib/logic/cli-config/schema.json).
72+
73+
### External binaries
74+
75+
The CLI shells out to several other binaries (Stevedore for cluster integration, Venona, argocd-agent, cf-gitops-controller). [lib/binary/](lib/binary/) holds:
76+
77+
- [components.js](lib/binary/components.js) — registry of binary metadata (local dir, remote repo, version file).
78+
- [downloader.js](lib/binary/downloader.js) — fetches the right release from GitHub into `~/.Codefresh/<dir>/`.
79+
- [runner.js](lib/binary/runner.js)`child_process.spawn` wrapper that pipes stdio through.
80+
81+
`codefresh components update` (run inside the Docker image build) pre-populates the binaries.
82+
83+
### Bash completion
84+
85+
`lib/interface/cli/completion/tree.js` is **generated** by `yarn generate-completion` ([completion/generate](lib/interface/cli/completion/generate)). When `process.argv` includes `--get-yargs-completions`, [codefresh](lib/interface/cli/codefresh) takes a fast path that loads only completion logic — do not add work to the startup path that would break this. The Dockerfile runs `yarn generate-completion` during image build; the file is `.gitignored`.
86+
87+
## Default CLI values
88+
89+
Defaults live in two places — check both when changing or referencing them:
90+
91+
- [lib/interface/cli/defaults.js](lib/interface/cli/defaults.js) — code-level constants exported as `DEFAULTS` (API URL, cfconfig path, pagination limits, watch interval, engine image, `~/.Codefresh` path, debug pattern). Used directly from command builders/handlers.
92+
- [lib/logic/cli-config/schema.json](lib/logic/cli-config/schema.json) — JSON-Schema for the user-editable profile config at `~/.Codefresh/cli-config/config.yaml`. The `default` field of each property is the fallback applied by [Manager.js](lib/logic/cli-config/Manager.js) (covers `output.pretty`, `output.dateFormat`, `request.timeout`/`maxAttempts`/`retryDelay`, `logs.fallback.*`).
93+
94+
## Testing conventions
95+
96+
- Unit tests: `*.spec.js`, plain jest.
97+
- SDK-backed integration tests: `*.sdk.spec.js`. These rely on the mocked [__mocks__/requestretry.js](__mocks__/requestretry.js) (use `request.__setResponse` / `request.__queueResponses`) and the global `verifyResponsesReturned([...])` helper from `test-setup.js`. They also call `await configureSdk()` in `beforeEach` to bind the SDK to the bundled `openapi.json` instead of a live server.
98+
- Jest mocks `Output`, `whoami`, and `request-promise` globally; do not assume they are real in tests.
99+
100+
## Lint
101+
102+
ESLint uses `airbnb-base` with overrides in [.eslintrc.js](.eslintrc.js): 4-space indent, `max-len: 140`, `no-console` and `no-underscore-dangle` disabled. Only `lib/logic/**` is wired into `yarn eslint`.
103+
104+
## Release flow
105+
106+
- Bumping `version` in [package.json](package.json) on `master` triggers [.github/workflows/create-release.yaml](.github/workflows/create-release.yaml), which uses `release-drafter` to publish a GitHub release.
107+
- Native binaries are produced with `yarn pkg` (configured under `pkg` in `package.json`).
108+
- The Docker image (see [Dockerfile](Dockerfile)) installs prod-only deps, runs `generate-completion`, then `npm uninstall -g corepack npm` for hardening, and symlinks `codefresh` into `/usr/local/bin/`.
109+
110+
## Useful environment variables
111+
112+
- `CF_ARG_<flag>` — alternative to passing `--flag` on the CLI (e.g. `CF_ARG_OUTPUT=json`).
113+
- `DEBUG=codefresh*` — print error stacks instead of the friendly message (see [defaults.js](lib/interface/cli/defaults.js)).
114+
- `ENGINE_IMAGE` — overrides the default `codefresh/engine:master` used by local pipeline runs.
115+
- `STEVEDORE` / `VENONACTL` — point components at an `alternateBinary` path instead of the auto-downloaded one.
116+
- `ALLOW_BETA_COMMANDS=true` — include beta commands when generating docs.
117+
- `NODE_TLS_REJECT_UNAUTHORIZED=0` — implicitly set when `--insecure` is passed.

lib/interface/cli/commad-line-interface.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,20 @@ const openapi = require('../../../openapi');
1111
const sdk = require('../../logic/sdk');
1212
const cliConfHelpers = require('./helpers/cli-config');
1313

14-
const PROCESS_ARGV = require('yargs-parser')(process.argv);
14+
const PROCESS_ARGV = require('yargs-parser')(process.argv, {
15+
number: ['request-timeout', 'request-max-retries', 'request-retry-delay'],
16+
envPrefix: 'CF_ARG_',
17+
});
1518

1619
const cliConfig = configManager.config();
17-
1820
async function getConfigForSdk(options = {}) {
1921
const configOptions = {
2022
configPath: PROCESS_ARGV.cfconfig,
2123
spec: { json: openapi },
2224
request: _.defaultsDeep({
2325
timeout: PROCESS_ARGV.requestTimeout,
26+
maxAttempts: PROCESS_ARGV.requestMaxRetries,
27+
retryDelay: PROCESS_ARGV.requestRetryDelay,
2428
headers: {
2529
'User-Agent': `codefresh-cli-v${version}`,
2630
'Codefresh-User-Agent-Type': 'cli',
@@ -76,7 +80,15 @@ async function startCommandLine() {
7680
},
7781
})
7882
.option('request-timeout', {
79-
describe: `Request timeout (default: ${cliConfig.request.timeout})`,
83+
describe: `Request timeout in ms (default: ${cliConfig.request.timeout})`,
84+
global: false,
85+
})
86+
.option('request-max-retries', {
87+
describe: `Request max retries (default: ${cliConfig.request.maxAttempts})`,
88+
global: false,
89+
})
90+
.option('request-retry-delay', {
91+
describe: `Request attempts delay in ms (default: ${cliConfig.request.retryDelay})`,
8092
global: false,
8193
})
8294
.demandCommand(1, 'You need at least one command before moving on')

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codefresh",
3-
"version": "1.1.4",
3+
"version": "1.2.1",
44
"description": "Codefresh command line utility",
55
"main": "index.js",
66
"preferGlobal": true,

0 commit comments

Comments
 (0)