|
| 1 | +# Contributing to yuque-open-cli |
| 2 | + |
| 3 | +Thanks for your interest in improving the Yuque CLI! This document covers the |
| 4 | +development workflow, the conventions the codebase enforces, and how releases |
| 5 | +are cut. |
| 6 | + |
| 7 | +> Working with an AI agent (or as one)? [AGENTS.md](./AGENTS.md) is the |
| 8 | +> authoritative architecture map and convention guide — it is kept in lockstep |
| 9 | +> with the code by tests. |
| 10 | +
|
| 11 | +## Development setup |
| 12 | + |
| 13 | +Requirements: Node.js ≥ 20. |
| 14 | + |
| 15 | +```bash |
| 16 | +git clone https://github.com/yuque/yuque-open-cli.git |
| 17 | +cd yuque-open-cli |
| 18 | +npm install |
| 19 | +npm run dev -- --help # run the CLI from source (tsx) |
| 20 | +``` |
| 21 | + |
| 22 | +To exercise commands against the real API you need a token from |
| 23 | +[Yuque Developer Settings](https://www.yuque.com/settings/tokens): |
| 24 | + |
| 25 | +```bash |
| 26 | +YUQUE_TOKEN=... npm run dev -- auth status |
| 27 | +``` |
| 28 | + |
| 29 | +## The check gate |
| 30 | + |
| 31 | +Every change must pass the single unified gate — the same command CI runs: |
| 32 | + |
| 33 | +```bash |
| 34 | +npm run check |
| 35 | +``` |
| 36 | + |
| 37 | +That is: ESLint, Prettier check, generated-types drift check, `tsc`, unit |
| 38 | +tests with coverage, build, packaged-CLI smoke test, and the mock-server e2e |
| 39 | +suite. If `npm run check` is green locally, CI will be green. |
| 40 | + |
| 41 | +Useful narrower loops while iterating: |
| 42 | + |
| 43 | +```bash |
| 44 | +npm test # unit tests once |
| 45 | +npm run test:watch # unit tests in watch mode |
| 46 | +npm run test:e2e # build + e2e against the bundled mock server |
| 47 | +``` |
| 48 | + |
| 49 | +## Spec-driven workflow |
| 50 | + |
| 51 | +The OpenAPI spec is the source of truth for the API surface: |
| 52 | + |
| 53 | +1. Edit `spec/yuque-openapi.yaml` — never edit `src/client/types.gen.ts` by |
| 54 | + hand. |
| 55 | +2. Run `npm run gen:types` to regenerate the types. |
| 56 | +3. Adapt the thin compatibility layer in `src/client/types.ts` if public type |
| 57 | + names changed. |
| 58 | + |
| 59 | +`npm run gen:types:check` (part of the check gate) fails if the generated |
| 60 | +file drifts from the spec. `tests/spec-coverage.test.ts` fails if a spec |
| 61 | +operation has no corresponding CLI command, so extending the spec means |
| 62 | +extending the command surface in the same change. |
| 63 | + |
| 64 | +## Code layout and conventions |
| 65 | + |
| 66 | +``` |
| 67 | +bin.ts → cli.ts (commander program, error → exit code) |
| 68 | + └── commands/<domain>.ts (flags, confirmation, rendering) |
| 69 | + └── client/api/<domain>.ts (typed calls, envelope unwrap) |
| 70 | + └── client/http.ts (auth header, retry/backoff, YuqueError) |
| 71 | +``` |
| 72 | + |
| 73 | +- One domain = one `src/commands/<domain>.ts` exporting a single |
| 74 | + `register<Domain>Commands` function, plus one thin `src/client/api/<domain>.ts`. |
| 75 | +- `src/client/http.ts` is the only HTTP exit; `src/errors.ts` is the only |
| 76 | + place exit codes are defined. |
| 77 | +- Destructive commands must go through `confirmDestructive` (`--yes` to skip). |
| 78 | +- Every command supports `--json`; human-readable output goes through the |
| 79 | + helpers in `src/output.ts`. |
| 80 | +- The full `--help` surface is pinned by a golden file — when you add or |
| 81 | + change flags, regenerate it as instructed by the failing test and review |
| 82 | + the diff. |
| 83 | + |
| 84 | +## Pull requests |
| 85 | + |
| 86 | +- Branch from `main`; keep PRs focused on one concern. |
| 87 | +- Update docs in the same PR: both `README.md` and `README.zh-CN.md` for any |
| 88 | + user-visible change, `AGENTS.md` for structural changes, and `CHANGELOG.md` |
| 89 | + under the upcoming version heading. |
| 90 | +- `npm run check` must pass. |
| 91 | + |
| 92 | +## Releasing (maintainers) |
| 93 | + |
| 94 | +Releases are tag-driven via `.github/workflows/release.yml`: |
| 95 | + |
| 96 | +1. Bump `version` in `package.json` and add the matching `## X.Y.Z` section |
| 97 | + at the top of `CHANGELOG.md`; land that on `main`. |
| 98 | +2. Tag and push: |
| 99 | + |
| 100 | + ```bash |
| 101 | + git tag vX.Y.Z && git push origin vX.Y.Z |
| 102 | + ``` |
| 103 | + |
| 104 | +The workflow re-runs the full check gate, publishes to npm with provenance, |
| 105 | +and creates the GitHub Release from the CHANGELOG section. It requires the |
| 106 | +`NPM_TOKEN` repository secret (an npm automation token with publish rights on |
| 107 | +`yuque-open-cli`). |
| 108 | + |
| 109 | +## Reporting security issues |
| 110 | + |
| 111 | +Please do not open public issues for vulnerabilities — see |
| 112 | +[SECURITY.md](./SECURITY.md). |
0 commit comments