Contributing to google-sheet-cli ========================================= I welcome all contributions to google-sheet-cli Issues ------ Feel free to submit issues and enhancement requests. Contributing ------------ Please refer to each project's style guidelines and guidelines for submitting patches and additions. In general, I follow the "fork-and-pull" Git workflow. 1. **Fork** the repo on GitHub 2. **Clone** the project to your own machine 3. **Commit** changes to your own branch 4. **Push** your work back up to your fork 5. Submit a **Pull request** so that we can review your changes NOTE: Be sure to merge the latest from "upstream" before making a pull request! Before you push --------------- Node 22 or newer (`.nvmrc` pins v24, which is what CI releases on). Run `npm run build && npm run test:unit`. `test:unit` is the offline suite - it needs no Google credentials, because `test/fake-sheets.ts` answers the Sheets API over an intercepted `https.request` and `test/commands/offline.test.ts` replaces the client through `src/lib/factory`. It is the only test gate a pull request gets, so it is the one that has to catch a regression before merge. `npm test` is the full suite. It additionally runs `test/google-sheet.test.ts` and `test/commands/**`, which talk to the one shared test spreadsheet and need `GSHEET_CLIENT_EMAIL`, `GSHEET_PRIVATE_KEY` and `TEST_SPREADSHEET_ID` in the environment. Those cases skip themselves without the credentials. On CI they run only on pushes to `master` and `2.x`, never on a pull request, so a fork PR never needs a secret. `README.md`'s `` and `` blocks and everything in `docs/` are generated by `oclif readme --multi` from the command classes. Never edit them by hand. The husky pre-commit hook runs `npm run build && npm run version`, which regenerates them, rewrites the in-repo `v0.0.0` links back to `master` with `bin/clean.sh`, and stages the result - so a flag or description change arrives in the docs on its own. Everything outside those two blocks, the migration notes included, is written by hand. Two things in the tree are frozen on purpose -------------------------------------------- `src/lib/table.ts` is `@oclif/core@2.8.11`'s `ux.table`, carried here because core 5 dropped it and has no successor that contributes `data:get`'s eight table flags. Its output was compared byte for byte, ANSI escapes included, against the real thing across eleven flag combinations. Treat it as frozen: it exists to keep 2.x output identical, not to grow. `js-yaml` is pinned to the 3.x line for the same reason - that table calls `safeDump`, which 4.x renamed to `dump`. 3.14.1 is end of life, so this looks like neglect and is not. Dependabot will open the 4.x major as its own pull request; taking it means porting the call *and* re-running the output comparison recorded in `test-docs/revive-v3.md`, not just changing the version. Adding a dependency ------------------- After `npm install `, check what it did to the lockfile: `git diff --numstat package-lock.json`. The second column is removed lines - it should be `0`. npm sometimes drops optional peer entries it decides this machine does not need, which leaves the lockfile internally inconsistent. Nothing complains locally; it surfaces as `npm ci` failing in CI with "Missing: … from lock file". If there are removals, restore the lockfile, re-add the dependency, and keep only the additions. A new runtime dependency is also a new entry in the published tarball and, for anything reachable from `src/lib/google-sheet.ts`, in the module graph of the `google-sheet-cli/sheet` subpath, which exists precisely to stay small and side-effect free. Dependabot ---------- One grouped pull request a month for minor and patch updates, plus a separate PR per major, for npm and for the pinned GitHub Actions. Third-party actions are pinned to commit SHAs with the tag in a comment; the `github-actions` ecosystem is what keeps those pins moving, so do not replace a pin with a floating tag to make a bump easier. `actions/checkout` and `actions/setup-node` are on v5 and `codeql-action` on v3 while newer majors exist, deliberately: the sibling `gsheet.action` repository runs the same commits, and those two should move together rather than one repository at a time. Commit messages --------------- Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/): `(): `, with `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `perf`, `build` or `ci` as the type. This is not cosmetic - releases are cut automatically from `master` by semantic-release, which reads these messages to decide the version. A `fix:` becomes a patch, a `feat:` a minor, and a `!` after the type or a `BREAKING CHANGE:` footer a major. Anything else releases nothing. If a pull request is squash-merged, the squash message is the only one semantic-release sees. A branch full of `feat!:` commits squashed under a `chore:` subject releases nothing at all.