From 5c46015a55a41204ab7d965b0519882941d062f1 Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Tue, 14 Apr 2026 11:40:52 +0530 Subject: [PATCH 1/5] chore:Refactor documentation in AGENTS.md and remove redundant Cursor rules --- .cursor/rules/README.md | 27 +----- .cursor/rules/code-review.mdc | 41 --------- .cursor/rules/dev-workflow.md | 38 -------- .cursor/rules/testing.mdc | 38 -------- .../rules/typescript-contentstack-utils.mdc | 34 ------- .cursor/rules/typescript.mdc | 34 ------- .gitignore | 3 +- AGENTS.md | 90 +++++++++---------- skills/README.md | 11 --- skills/code-review/SKILL.md | 58 +++++++----- skills/contentstack-utils/SKILL.md | 58 ++++++++++++ skills/dev-workflow/SKILL.md | 46 ++++++++++ skills/testing/SKILL.md | 52 +++++++---- skills/typescript-contentstack-utils/SKILL.md | 45 ---------- skills/typescript/SKILL.md | 39 ++++++++ 15 files changed, 262 insertions(+), 352 deletions(-) delete mode 100644 .cursor/rules/code-review.mdc delete mode 100644 .cursor/rules/dev-workflow.md delete mode 100644 .cursor/rules/testing.mdc delete mode 100644 .cursor/rules/typescript-contentstack-utils.mdc delete mode 100644 .cursor/rules/typescript.mdc delete mode 100644 skills/README.md create mode 100644 skills/contentstack-utils/SKILL.md create mode 100644 skills/dev-workflow/SKILL.md delete mode 100644 skills/typescript-contentstack-utils/SKILL.md create mode 100644 skills/typescript/SKILL.md diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md index b4b2107..b145041 100644 --- a/.cursor/rules/README.md +++ b/.cursor/rules/README.md @@ -1,26 +1,5 @@ -# Cursor rules — `@contentstack/utils` +# Cursor (optional) -This folder holds project-specific rules for AI assistants working in **contentstack-utils-javascript**. For the full project overview, see **[`AGENTS.md`](../../AGENTS.md)** at the repository root. +**Cursor** users: start at **[`AGENTS.md`](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`**. -## How rules are picked up - -Each rule is a `.md`/`.mdc` file. Files with YAML frontmatter can set `description`, `globs`, and `alwaysApply`. Cursor uses these to decide when a rule is included in context. - -### Referencing rules in chat - -In Cursor, you can **`@`-mention** a rule file (e.g. type `@` and choose the rule from the list) to force its guidance into the conversation. The file name (without extension) is the usual handle, e.g. **`typescript`**, **`testing`**, **`code-review`**. - -## Rule index - -| File | `alwaysApply` | Globs | When it applies | -|------|----------------|-------|------------------| -| [`dev-workflow.md`](dev-workflow.md) | no | *(none)* | Branching, CI alignment, commits, releases, and day-to-day commands for this repo. | -| [`typescript.mdc`](typescript.mdc) | no | `src/**/*.ts`, `__test__/**/*.ts` | TypeScript version, layout, ESLint/Prettier, strictness, imports. | -| [`typescript-contentstack-utils.mdc`](typescript-contentstack-utils.mdc) | no | `src/**/*.ts` | Delivery-oriented utils only: RTE rendering, GQL helpers, endpoints JSON, Live Preview tags—**not** full CDA/CMA SDK surface. | -| [`testing.mdc`](testing.mdc) | no | `__test__/**/*.ts` | Jest, jsdom, mocks, coverage output paths, no live-test env. | -| [`code-review.mdc`](code-review.mdc) | **yes** | *(global)* | PR checklist: public API docs, compatibility, errors, dependencies, terminology (utils + delivery context). | - -## Related - -- **[`AGENTS.md`](../../AGENTS.md)** — Single entry point (package purpose, stack, commands). -- **[`skills/README.md`](../../skills/README.md)** — Longer-form skill docs for the same themes. +This folder only points contributors to **`AGENTS.md`** so editor-specific config does not duplicate the canonical docs. diff --git a/.cursor/rules/code-review.mdc b/.cursor/rules/code-review.mdc deleted file mode 100644 index 0e5fc27..0000000 --- a/.cursor/rules/code-review.mdc +++ /dev/null @@ -1,41 +0,0 @@ ---- -description: PR review checklist for @contentstack/utils — API docs, compatibility, security, testing -alwaysApply: true ---- - -# Code review checklist — `@contentstack/utils` - -Use severity labels (**Blocker / Major / Minor**) when triaging findings. - -## Public API and documentation - -- **Blocker/Major:** New or changed **exports** from `src/index.ts` need accurate **JSDoc** (or clear type names) matching runtime behavior. -- **Major:** README / CHANGELOG updates when behavior is user-visible or migration is needed. - -## Backward compatibility - -- **Blocker:** Unplanned breaking changes to **function signatures** or **default behavior** consumed by Delivery SDK integrations or documented `renderOption` contracts. -- **Major:** Stricter throwing on inputs that previously passed (especially `getContentstackEndpoint`, RTE traversals). - -## Errors - -- This package uses **plain `Error`** (e.g. `endpoints.ts`); new code should keep messages actionable. **Major:** Silent failures where callers need to detect bad input. - -## Null safety and RTE edge cases - -- **Major:** Missing guards on **null/undefined** node or entry fragments (historically sensitive in `entry-editable` / RTE paths). -- **Minor:** Align with **`strictNullChecks: false`** legacy but avoid widening undefined leaks into public types. - -## Dependencies and SCA - -- **Major:** New runtime deps are rare—justify any addition; **`prepublishOnly`** and hooks assume **`npm test`** and Snyk-friendly trees. -- Use **`npm audit` / Snyk** expectations per org policy. - -## Tests - -- **Blocker:** Behavioral fixes or new branches without **`__test__`** coverage when risk is high (RTE nesting, GQL URL rewriting, endpoint resolution). -- **Minor:** Snapshot-only tests where a small assertion would be clearer. - -## Terminology - -- **Major:** Docs/comments must describe this as **utils** alongside **CDA / Delivery / JSON RTE / GraphQL**, not as **CMA** unless the change is explicitly management-related. diff --git a/.cursor/rules/dev-workflow.md b/.cursor/rules/dev-workflow.md deleted file mode 100644 index 0453f3c..0000000 --- a/.cursor/rules/dev-workflow.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -description: Branching, CI, local commands, commit hooks, and release flow for contentstack-utils-javascript -alwaysApply: false ---- - -# Dev workflow — `@contentstack/utils` - -## Branches and PRs - -- **CI** (`Unit-Test-CI`) runs on **push/PR** to `development`, `staging`, and `master` (see `.github/workflows/ci.yml`). -- **Branch protection:** A workflow fails PRs that target **`staging`** when the head branch is **not** `development` (see `.github/workflows/check-branch.yml`). Prefer **`development`** as the integration branch when contributing upstream. -- Target the branch your team uses for integration; align with maintainers if unsure. - -## Local development - -| Task | Command / note | -|------|----------------| -| Build | `npm run build` (runs `prebuild`: clean `dist`, `download-regions`, then `tsc` + Rollup) | -| Test | `npm test` (includes `pretest` → build; Jest + coverage; `reports/`) | -| Format | `npm run format` (Prettier: `src/**/*.ts`) | -| ESLint | No `lint` script in `package.json`; run e.g. `npx eslint src __test__` using `eslint.config.js` | - -## Git hooks (Husky) - -- **`commit-msg`:** [Conventional Commits](https://www.conventionalcommits.org/) via **`commitlint`** (`.commitlintrc.json`). -- **`pre-commit`:** Requires **Snyk** (`snyk test --all-projects`) and **Talisman** installed locally. Set `SKIP_HOOK=1` to bypass (documented in the hook). - -## PR expectations - -- **`npm test`** passes (build + unit tests). -- **CHANGELOG.md** updated for user-visible changes when maintainers expect it. -- **Dependencies:** Be mindful of Snyk/SCA workflows; security-relevant bumps should be justified. - -## Releases and versioning - -- **Package version** lives in **`package.json`** (also reflected in **`CHANGELOG.md`**). -- **`prepublishOnly`** runs **`npm test`** before publish. -- **NPM / GitHub Packages:** Publishing is driven by **GitHub release `created`** (`.github/workflows/npm-publish.yml`); requires maintainer secrets (`NPM_TOKEN`, `GIT_TOKEN`). Bump version and changelog in the same change set as the release your team uses. diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc deleted file mode 100644 index 1b7f67e..0000000 --- a/.cursor/rules/testing.mdc +++ /dev/null @@ -1,38 +0,0 @@ ---- -description: Jest tests, mocks, reports, and environments for @contentstack/utils -globs: - - __test__/**/*.ts -alwaysApply: false ---- - -# Testing — `@contentstack/utils` - -## Framework - -- **Jest 29** with **`ts-jest`** preset (`jest.config.ts`). -- **Environment:** **`jsdom`** (suitable for HTML string assertions and DOM-related behavior). - -## Discovery and naming - -- **Pattern:** `**/__test__/**/?(*.)+(spec|test).[jt]s?(x)` — this repo uses `*.test.ts` under **`__test__/`**. -- **Mocks / fixtures:** `__test__/mock/*.ts` — follow existing mock naming (`*-mock.ts`). - -## Coverage and reports - -- **Coverage** is collected from `src/**` excluding `src/index.ts` (`collectCoverageFrom`). -- Outputs: **`reports/coverage/`**, **`reports/html/`** (jest-html-reporters), **`reports/junit/`** (jest-junit), **`reports/report.json`** (from `npm test` script). - -## Running tests - -| Command | Behavior | -|---------|----------| -| `npm test` | Runs **`pretest` → build** then Jest (CI-aligned). | -| `npm run test:debug` | Watch mode, `--runInBand`. | - -## Integration / live tests - -- **None** in this repo. No `.env` or stack credentials required for **`npm test`**. - -## Build dependency - -- **`npm test` always builds first** (`pretest`). Ensure **`src/assets/regions.json`** exists or can be downloaded so `endpoints` tests pass. diff --git a/.cursor/rules/typescript-contentstack-utils.mdc b/.cursor/rules/typescript-contentstack-utils.mdc deleted file mode 100644 index 70f23c6..0000000 --- a/.cursor/rules/typescript-contentstack-utils.mdc +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: Contentstack utils package patterns — RTE, embedded items, GQL, endpoints (delivery-oriented companion, not CDA/CMA SDK) -globs: - - src/**/*.ts -alwaysApply: false ---- - -# `@contentstack/utils` — domain patterns - -This repository implements **companion utilities** for Contentstack **content consumption** scenarios (typically with the **Delivery SDK** and **CDA / GraphQL** responses). It does **not** implement stack configuration, delivery tokens, or HTTP clients—callers fetch entry JSON elsewhere and pass it into these helpers. - -## Mental model - -| Area | Source anchors | Notes | -|------|----------------|-------| -| Render options / callbacks | `src/options/`, `src/render-embedded-objects.ts` | `RenderOption`-style maps: node types, marks, `block` / `inline` embeds, `reference`, `display`, `default`. | -| JSON RTE → HTML | `src/json-to-html.ts`, `src/nodes/*`, `src/helper/*` | Supercharged RTE path uses `paths` arrays for nested fields (see `README.md`). | -| Embedded object types | `src/Models/embedded-object.ts`, `src/Models/json-rte-model.ts` | Align typings with shapes coming from **delivery** entry JSON, not management APIs. | -| GraphQL | `src/gql.ts`, `src/updateAssetURLForGQL.ts` | Docs/comments describe use **after** GraphQL fetches; asset URL rewriting is response-shape specific. | -| Live Preview / CSLP tags | `src/entry-editable.ts` | `addTags` / exported `addEditableTags` — preserve existing attribute and locale behavior when changing tag generation. | -| Region endpoints | `src/endpoints.ts` | **`getContentstackEndpoint(region, service?, omitHttps?)`** reads **`src/assets/regions.json`**; throws plain `Error` with human-readable messages on bad region/service. | - -## Terminology - -- Prefer **CDA / Delivery / JSON RTE / GraphQL** vocabulary when describing behavior—**not** CMA unless you are explicitly discussing something management-only (rare here). -- **“SDK”** in docs often means **this utils package** or the **Delivery SDK** together—disambiguate in user-facing text. - -## Concurrency / IO - -- Pure synchronous transforms dominate; no retry or rate-limit layer. Do not add HTTP clients without an explicit product requirement. - -## Official docs alignment - -- Behavior should stay consistent with current **Content Delivery** / **Live Preview** / **JSON RTE** documentation. When in doubt, cite the relevant Contentstack doc set in PR descriptions rather than guessing CMS semantics. diff --git a/.cursor/rules/typescript.mdc b/.cursor/rules/typescript.mdc deleted file mode 100644 index ad2d6fb..0000000 --- a/.cursor/rules/typescript.mdc +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: TypeScript conventions for @contentstack/utils (src and tests) -globs: - - src/**/*.ts - - __test__/**/*.ts -alwaysApply: false ---- - -# TypeScript — `@contentstack/utils` - -## Tooling - -- **TypeScript ~4.9** (`package.json`, `tsconfig.json`). -- **Bundler output:** `tsc` emits to `dist/lib` with declarations in `dist/types`; **Rollup** produces `dist/index.es.js` (`rollup.config.js`). -- **Strict mode** is on with **`strictNullChecks: false`** — new code should still minimize unnecessary null/undefined gaps when touching APIs. - -## Layout - -- **Library code:** `src/**/*.ts` only (`tsconfig.json` `include`); **tests** are under `__test__/` (excluded from `tsc` program but type-checked via Jest/tsconfig paths). -- **Public exports:** Maintain **`src/index.ts`** as the single export surface unless intentionally adding secondary entry points. - -## Style and lint - -- Match existing naming (PascalCase types, camelCase functions, existing file layout under `Models/`, `nodes/`, `helper/`, `options/`). -- **ESLint** flat config: `eslint.config.js` — `@typescript-eslint` recommended for `__test__`; source files use `js.configs.recommended` baseline. -- **Prettier:** `npm run format` scopes `src/**/*.ts`; keep formatting consistent when editing tests too. - -## JSON / assets - -- **`src/assets/regions.json`:** Consumed by `src/endpoints.ts`; populated by **`npm run download-regions`** during `prebuild`. Do not assume the file is committed (see root `.gitignore`). - -## Logging - -- No shared logger dependency; avoid introducing `console` noise in library paths unless consistent with nearby code. diff --git a/.gitignore b/.gitignore index 582c800..21a9cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ coverage/ .dccache snyk_output.log talisman_output.log -regions.json \ No newline at end of file +regions.json +.vscode/settings.json \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 0798e0e..2b82ff8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,52 +1,52 @@ -# Agent guidance — `@contentstack/utils` +# Contentstack Utils JavaScript – Agent guide -## What this package is +**Universal entry point** for anyone automating or assisting work in this repo—AI agents (Cursor, Copilot, CLI tools), reviewers, and contributors. Conventions and detailed guidance live in **`skills/*/SKILL.md`**, not in editor-specific config, so the same instructions apply whether or not you use Cursor. -**[@contentstack/utils](https://www.npmjs.com/package/@contentstack/utils)** (`contentstack-utils-javascript`) is a **JavaScript/TypeScript utilities library** for Contentstack. It is **not** the Content Delivery API (CDA) SDK or the Content Management API (CMA) SDK. It focuses on **JSON RTE / Supercharged RTE** rendering (`jsonToHTML`), **embedded entry and asset** rendering (`render`, `renderContent`), **GraphQL-oriented helpers** (`GQL`, `updateAssetURLForGQL`), **Live Preview–style editable tags** (`addEditableTags` / `addTags`), and **region endpoint lookup** (`getContentstackEndpoint`). Typical usage is **alongside** the Delivery SDK (see repository `README.md` examples with `@contentstack/delivery-sdk`). +## What this repo is -- **Repository:** [github.com/contentstack/contentstack-utils-javascript](https://github.com/contentstack/contentstack-utils-javascript) +- **Name:** [`@contentstack/utils`](https://www.npmjs.com/package/@contentstack/utils) — [contentstack/contentstack-utils-javascript](https://github.com/contentstack/contentstack-utils-javascript) +- **Purpose:** TypeScript/JavaScript **utilities** for Contentstack: JSON RTE / Supercharged RTE to HTML (`jsonToHTML`), embedded entry and asset rendering (`render`, `renderContent`), GraphQL helpers (`GQL`, `updateAssetURLForGQL`), Live Preview–style editable tags (`addEditableTags`), region endpoint lookup (`getContentstackEndpoint`), and variant-related helpers (`getVariantAliases`, `getVariantMetadataTags`). Used **with** the [Content Delivery API](https://www.contentstack.com/docs/developers/apis/content-delivery-api/) and delivery-shaped JSON (see root `README.md` and [`@contentstack/delivery-sdk`](https://www.npmjs.com/package/@contentstack/delivery-sdk) usage patterns). +- **Out of scope:** This package does **not** ship HTTP clients, stack credentials, or the full CDA/CMA SDK surface. Apps fetch content with the Delivery SDK or other clients, then pass entry JSON into these helpers. Runtime API calls are **not** part of the library; `regions.json` for endpoint lookup is a **build-time** asset. -## Tech stack +## Tech stack (at a glance) | Area | Details | |------|---------| -| Language | TypeScript **4.9** (`tsconfig.json`, `strict: true`, `strictNullChecks: false`) | -| Build | **TypeScript** (`tsc`) → `dist/lib`; **Rollup** (`rollup -c`) → `dist/index.es.js`; types in `dist/types/` | -| Test | **Jest 29** + **ts-jest**, **jsdom** environment (`jest.config.ts`) | -| Lint / format | **ESLint 9** flat config (`eslint.config.js`); **Prettier 3** (`npm run format`) — there is **no** `lint` npm script; use `npx eslint` as needed | -| Runtime HTTP / JSON for API calls | **None** in library code; `regions.json` is a **build-time** asset (see below) | - -## Source layout and public API - -| Role | Path | -|------|------| -| Public entry (sources) | `src/index.ts` | -| Options / render types | `src/options/` | -| RTE / node model | `src/Models/`, `src/nodes/` | -| Helpers | `src/helper/` | -| GQL + asset URL rewrite | `src/gql.ts`, `src/updateAssetURLForGQL.ts` | -| Endpoints helper | `src/endpoints.ts` + `src/assets/regions.json` (generated; see build) | -| Published bundle | `dist/` (per `package.json` `main` / `types`) | - -## Common commands - -| Command | Purpose | -|---------|---------| -| `npm run build` | Cleans `dist`, ensures `src/assets/regions.json` (download or warning), runs `tsc` + Rollup | -| `npm test` | Runs `pretest` → **build**, then Jest with coverage; outputs under `reports/` | -| `npm run test:debug` | Jest watch, in-band | -| `npm run format` | Prettier on `src/**/*.ts` | -| `npm run download-regions` | Fetches `regions.json` only (used by `prebuild`) | - -**Tests:** Unit tests only, under `__test__/**/*.test.ts`, with mocks in `__test__/mock/`. There are **no** live/integration tests requiring stack credentials in this repository. - -## Credentials / environment - -- **Unit tests:** No API keys or `.env` required. -- **Build:** `download-regions` calls a public URL (`artifacts.contentstack.com`); offline builds may warn and rely on an existing `src/assets/regions.json`. Note `regions.json` is listed in `.gitignore`; clones may need a successful `npm run build` (or manual file) before tests pass. -- **Publish:** GitHub release workflow uses `NPM_TOKEN` / `GIT_TOKEN` secrets (maintainers only). - -## More detail for AI / IDE rules - -- [`.cursor/rules/README.md`](.cursor/rules/README.md) — Cursor rules index (`alwaysApply`, globs, when to use). -- [`skills/README.md`](skills/README.md) — Topic skills (testing, code review, package mental model). +| Language | TypeScript **4.9** (`tsconfig.json`: `strict: true`, `strictNullChecks: false`) | +| Build | `tsc` → `dist/lib` + declarations in `dist/types/`; **Rollup** → `dist/index.es.js` (`rollup.config.js`). `prebuild` runs `download-regions` for `src/assets/regions.json`. | +| Tests | **Jest 29** + **ts-jest**, **jsdom** (`jest.config.ts`). Tests under **`__test__/**/*.test.ts`**, mocks in **`__test__/mock/`**. | +| Lint / coverage | **ESLint 9** flat config (`eslint.config.js`); **Prettier 3** (`npm run format`). Coverage under `reports/coverage/` when running `npm test`. | +| Runtime | No HTTP client dependency; pure transforms + bundled `regions.json` for endpoints. | + +## Commands (quick reference) + +```bash +npm run build && npm test +npx eslint src __test__ +npm run format +npm run download-regions # regions.json only (also run as part of prebuild) +``` + +`npm test` runs **`pretest` → `npm run build`**, then Jest with coverage; outputs under **`reports/`**. Use **`npm run test:debug`** for Jest watch mode (`--runInBand`). + +**CI:** `.github/workflows/ci.yml` (unit tests / coverage on `development`, `staging`, `master`). Branch rules: `.github/workflows/check-branch.yml`. Publish: `.github/workflows/npm-publish.yml` (on GitHub release). + +Install: `npm i @contentstack/utils` — see root **`README.md`** and **`package.json`** for the current version. + +## Where the real documentation lives: skills + +Read these **`SKILL.md` files** for full conventions—**this is the source of truth** for implementation and review: + +| Skill | Path | What it covers | +|-------|------|----------------| +| **Development workflow** | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Branches, CI, build/test/lint, Husky (Snyk/Talisman, commitlint), PR expectations, releases | +| **TypeScript (layout & tooling)** | [`skills/typescript/SKILL.md`](skills/typescript/SKILL.md) | Compiler settings, `src/` layout, ESLint/Prettier, `regions.json` / `.gitignore` | +| **Contentstack Utils (package)** | [`skills/contentstack-utils/SKILL.md`](skills/contentstack-utils/SKILL.md) | Public API and domain: exports from `src/index.ts`, RTE/embed/GQL/endpoints/Live Preview/variants—not the full CDA/CMA SDK; no network layer | +| **Testing** | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | Jest, mocks, coverage/report paths, `pretest` build, offline unit tests (no stack credentials) | +| **Code review** | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR checklist (API docs, compatibility, errors, deps/SCA, tests), Blocker/Major/Minor, terminology | + +There is **no** `skills/framework/` folder: this repo does not ship a shared HTTP client, retry layer, or native build system beyond npm/TypeScript/Rollup. + +## Using Cursor + +If you use **Cursor**, [`.cursor/rules/README.md`](.cursor/rules/README.md) only points to **`AGENTS.md`**—same source of truth as everyone else; no separate `.mdc` rule files. diff --git a/skills/README.md b/skills/README.md deleted file mode 100644 index 72354af..0000000 --- a/skills/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Skills — `@contentstack/utils` - -Short-form guides for humans and agents. Root context: **[`AGENTS.md`](../AGENTS.md)**. Cursor rule index: **[`.cursor/rules/README.md`](../.cursor/rules/README.md)**. - -| Skill | When to use | -|-------|--------------| -| [`code-review/`](code-review/SKILL.md) | Before opening or approving a PR; expanded checklist (API docs, compatibility, errors, tests, terminology). | -| [`testing/`](testing/SKILL.md) | Running Jest, understanding `pretest`/build, mocks, reports, and why no live API tests exist here. | -| [`typescript-contentstack-utils/`](typescript-contentstack-utils/SKILL.md) | Mental map of RTE/embed/GQL/endpoints/Live Preview code paths and where to change behavior safely. | - -There is **no** separate `framework` skill: this repo has **no** shared HTTP client or retry layer. diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md index 066047c..3e58dd9 100644 --- a/skills/code-review/SKILL.md +++ b/skills/code-review/SKILL.md @@ -1,44 +1,56 @@ -# Skill: Code review — `@contentstack/utils` +--- +name: code-review +description: PR checklist for @contentstack/utils — public API docs, compatibility, errors, tests, terminology, Blocker/Major/Minor +--- + +# Code review – @contentstack/utils ## When to use -Final pass before merge, or when authoring a PR to self-check against team expectations. +- Final pass before merge, or self-review while authoring a PR. + +## Instructions -## Checklist (expanded) +Use severity labels (**Blocker / Major / Minor**) when triaging findings. -### Public API and docs +### Public API and documentation -- Exported symbols from **`src/index.ts`** stay coherent: names match behavior, types match real JSON RTE / entry shapes from **delivery** content. -- **JSDoc** on public functions (`getContentstackEndpoint`, `jsonToHTML`, `render`, GQL helpers, etc.) matches parameters, throws, and return shapes. -- **README.md** examples remain valid for **`@contentstack/delivery-sdk`** + **`Contentstack.Utils`** style usage when touching those flows. +- **Blocker/Major:** New or changed **exports** from `src/index.ts` need accurate **JSDoc** (or clear type names) matching runtime behavior. +- **Major:** **README** / **CHANGELOG** updates when behavior is user-visible or migration is needed. ### Backward compatibility -- Avoid breaking **`RenderOption`** callback contracts or default HTML output without a major version plan and **CHANGELOG** entry. -- Changes to **`regions.json`** / endpoint keys must stay aligned with upstream region definitions. +- **Blocker:** Unplanned breaking changes to **function signatures** or **default behavior** consumed by Delivery SDK integrations or documented `renderOption` contracts. +- **Major:** Stricter throwing on inputs that previously passed (especially `getContentstackEndpoint`, RTE traversals). ### Errors -- Prefer clear **`Error`** messages for invalid regions, missing services, or malformed internal state—callers often log these verbatim. +- This package uses **plain `Error`** (e.g. `endpoints.ts`); new code should keep messages actionable. +- **Major:** Silent failures where callers need to detect bad input. -### Security and dependencies +### Null safety and RTE edge cases -- New **npm dependencies** need justification (`package.json` is dev-heavy already). -- No secrets or tokens in code; **Talisman** pre-commit enforces secret scanning locally for contributors with hooks installed. +- **Major:** Missing guards on **null/undefined** node or entry fragments (historically sensitive in `entry-editable` / RTE paths). +- **Minor:** Align with **`strictNullChecks: false`** legacy but avoid widening undefined leaks into public types. -### Tests +### Dependencies and SCA -- **`npm test`** must pass (includes full **build**). -- Add or update **`__test__`** cases for RTE edge cases, GQL URL rewriting, and endpoint error paths when logic changes. +- **Major:** New runtime deps are rare—justify any addition; **`prepublishOnly`** and hooks assume **`npm test`** and Snyk-friendly trees. +- Follow org policy for **`npm audit` / Snyk**. -### Severity rubric (optional) +### Tests -| Level | Examples | -|-------|-----------| -| **Blocker** | Breaks published API, break consumers without semver major, removes tests on critical path | -| **Major** | Missing docs for new export, behavior change without tests, confusing error surfaces | -| **Minor** | Naming nits, internal refactors with equivalent coverage | +- **Blocker:** Behavioral fixes or new branches without **`__test__`** coverage when risk is high (RTE nesting, GQL URL rewriting, endpoint resolution). +- **Minor:** Snapshot-only tests where a small assertion would be clearer. ### Terminology -- Use **delivery / CDA / JSON RTE / GraphQL / Live Preview** context—not **CMA**—unless the work truly relates to management APIs. +- **Major:** Docs/comments must describe this as **utils** alongside **CDA / Delivery / JSON RTE / GraphQL**, not as **CMA** unless the change is explicitly management-related. + +### Severity rubric (examples) + +| Level | Examples | +|-------|-----------| +| **Blocker** | Breaks published API; removes critical-path tests; ships breaking change without semver plan | +| **Major** | Missing docs for new export; behavior change without tests; confusing errors | +| **Minor** | Naming nits; internal refactors with equivalent coverage | diff --git a/skills/contentstack-utils/SKILL.md b/skills/contentstack-utils/SKILL.md new file mode 100644 index 0000000..0d4e24a --- /dev/null +++ b/skills/contentstack-utils/SKILL.md @@ -0,0 +1,58 @@ +--- +name: contentstack-utils +description: Public API, delivery-oriented domain model, and where to change JSON RTE, embeds, GQL, endpoints, and Live Preview tags +--- + +# @contentstack/utils (package domain) – Agent guide + +## When to use + +- Designing or reviewing changes to exports, RTE rendering, embeddings, GraphQL helpers, region endpoints, or Live Preview tags. +- Clarifying how this package relates to CDA/CMA/Delivery SDK. + +## Instructions + +### What this package is + +**`@contentstack/utils`** is a **utility library**, not the **CDA** or **CMA** SDK. It transforms **entry JSON** already obtained via **Content Delivery** (REST or **GraphQL**) into HTML or enriched structures. It does **not** configure stacks, tokens, or HTTP—callers fetch JSON elsewhere and pass it in. + +### Public entry (sources) + +| Role | Path | +|------|------| +| Exports | `src/index.ts` | +| Render options / types | `src/options/` | +| RTE nodes / document | `src/nodes/`, `src/Models/` | +| Helpers | `src/helper/` | +| JSON RTE → HTML | `src/json-to-html.ts` | +| Embedded rendering | `src/render-embedded-objects.ts` | +| GraphQL | `src/gql.ts`, `src/updateAssetURLForGQL.ts` | +| Live Preview / CSLP-style tags | `src/entry-editable.ts` | +| Region endpoints | `src/endpoints.ts` + `src/assets/regions.json` | +| Entry variants (aliases / metadata tags) | `src/variant-aliases.ts` | + +**Exported symbols** (see `src/index.ts`) include: `jsonToHTML`, `render`, `renderContent`, `GQL`, `updateAssetURLForGQL`, `addEditableTags` (from `addTags` in `entry-editable`), `getContentstackEndpoint`, `getVariantAliases`, `getVariantMetadataTags`, node/mark/document types, `RenderOption`, and related models. + +### Domain anchors + +| Area | Where | Notes | +|------|--------|--------| +| Render callbacks | `src/options/`, `src/render-embedded-objects.ts` | `RenderOption` maps: nodes, marks, `block` / `inline`, `reference`, `display`, `default`. | +| Supercharged RTE | `src/json-to-html.ts`, `src/nodes/*`, `src/helper/*` | Nested fields via `paths` arrays (see root `README.md`). | +| Embedded types | `src/Models/embedded-object.ts`, `src/Models/json-rte-model.ts` | Align with **delivery** entry JSON shapes. | +| GraphQL | `src/gql.ts`, `src/updateAssetURLForGQL.ts` | Intended for use **after** GraphQL responses; asset URL rewriting matches response shape. | +| Live Preview | `src/entry-editable.ts` | Preserve attribute/locale behavior when changing tag generation. | +| Endpoints | `src/endpoints.ts` | `getContentstackEndpoint(region, service?, omitHttps?)` reads bundled JSON; throws plain **`Error`** with clear messages for invalid region/service. | + +### Terminology + +- Use **delivery / CDA / JSON RTE / GraphQL / Live Preview** in docs—not **CMA** unless the change is explicitly management-related. +- Disambiguate “SDK”: this **utils** package vs **`@contentstack/delivery-sdk`**. + +### I/O model + +- Mostly **synchronous** transforms; **no** retry/rate-limit layer. Do not add HTTP clients without an explicit product decision. + +### Official docs + +- Align behavior with Contentstack **Delivery**, **Live Preview**, and **JSON RTE** documentation; cite docs in PRs when semantics are ambiguous. diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md new file mode 100644 index 0000000..184230b --- /dev/null +++ b/skills/dev-workflow/SKILL.md @@ -0,0 +1,46 @@ +--- +name: dev-workflow +description: Branches, CI, build/test/lint commands, git hooks, PR expectations, and releases for contentstack-utils-javascript +--- + +# Dev workflow – @contentstack/utils + +## When to use + +- Choosing a base branch or opening a PR. +- Running build/tests locally or debugging CI. +- Cutting releases or bumping versions. + +## Instructions + +### Branches and PRs + +- **CI** (`Unit-Test-CI`) runs on **push/PR** to `development`, `staging`, and `master` (`.github/workflows/ci.yml`). +- **Branch check:** PRs **into `staging`** from a head branch other than **`development`** fail (`.github/workflows/check-branch.yml`). Prefer **`development`** as the integration branch when aligning with upstream. +- Confirm target branch with maintainers if unsure. + +### Commands + +| Task | Command / note | +|------|----------------| +| Build | `npm run build` — `prebuild`: clean `dist`, `download-regions`, then `tsc` + Rollup | +| Test | `npm test` — `pretest` → build, then Jest + coverage → `reports/` | +| Format | `npm run format` — Prettier on `src/**/*.ts` | +| ESLint | No `npm run lint`; use e.g. `npx eslint src __test__` (`eslint.config.js`) | + +### Git hooks (Husky) + +- **`commit-msg`:** [Conventional Commits](https://www.conventionalcommits.org/) via **commitlint** (`.commitlintrc.json`). +- **`pre-commit`:** **Snyk** (`snyk test --all-projects`) and **Talisman** must be available locally, or set `SKIP_HOOK=1` to bypass (see hook script). + +### PR expectations + +- `npm test` passes (full build + unit tests). +- **CHANGELOG.md** for user-visible changes when maintainers expect it. +- Dependency changes: consider Snyk/SCA workflows. + +### Releases + +- Version in **`package.json`** and **`CHANGELOG.md`**. +- **`prepublishOnly`** runs **`npm test`**. +- **npm / GitHub Packages:** `.github/workflows/npm-publish.yml` on **release `created`**; secrets `NPM_TOKEN`, `GIT_TOKEN` (maintainers). diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md index 0f8b834..309b8b1 100644 --- a/skills/testing/SKILL.md +++ b/skills/testing/SKILL.md @@ -1,31 +1,47 @@ -# Skill: Testing — `@contentstack/utils` +--- +name: testing +description: Jest setup, test layout and mocks, coverage reports, pretest build, and no live API tests +--- + +# Testing – @contentstack/utils ## When to use -Setting up locally, debugging failures, or adding tests. +- Running or debugging tests, adding new tests, or understanding why `npm test` runs a build first. + +## Instructions + +### Framework and config + +- **Jest 29** + **ts-jest** (`jest.config.ts`). +- **Environment:** `jsdom` (HTML/DOM-oriented assertions where relevant). + +### Commands + +| Command | Behavior | +|---------|----------| +| `npm test` | Runs **`pretest`** → **`npm run build`**, then Jest with coverage; reports under **`reports/`** | +| `npm run test:debug` | Jest `--watchAll` with `--runInBand` | -## Commands +### Discovery and naming -- **`npm test`** — Runs **`pretest`** (→ **`npm run build`**) then **Jest** with coverage. Builds **`dist/`** and ensures `regions.json` flow runs. -- **`npm run test:debug`** — Jest **`--watchAll`** in **`--runInBand`** mode. +- **Match:** `**/__test__/**/?(*.)+(spec|test).[jt]s?(x)` — this repo uses **`__test__/**/*.test.ts`**. +- **Mocks / fixtures:** **`__test__/mock/`** (e.g. `entry-mock.ts`, `json-element-mock.ts`). -## Environment +### Coverage and reports -- **No API keys or `.env`** for tests—all **unit** tests with fixtures under **`__test__/mock/`**. -- First-time or clean machines: if **`src/assets/regions.json`** is missing, **`prebuild`** attempts **`download-regions`**; failures print a warning—see **`AGENTS.md`** / **package.json** `download-regions`. +- **Coverage** from `src/**` excluding `src/index.ts` (`collectCoverageFrom` in `jest.config.ts`). +- Outputs: **`reports/coverage/`**, **`reports/html/`**, **`reports/junit/`**, **`reports/report.json`** (from the `npm test` script). -## Naming and layout +### Credentials and integration tests -- Tests live in **`__test__/**/*.test.ts`** (see **`jest.config.ts` `testMatch`**). -- Reuse **`__test__/mock/`** patterns (`entry-mock.ts`, `json-element-mock.ts`, etc.). +- **No API keys or `.env`** for unit tests. +- **No** live/integration tests against a stack in this repository. -## Reports +### Build dependency -- **Coverage:** `reports/coverage/` -- **HTML summary:** `reports/html/` -- **JUnit:** `reports/junit/` -- **CI** consumes junit / coverage patterns in `.github/workflows/ci.yml` and `code.cov.yml`. +- **`pretest` always builds** — ensure **`src/assets/regions.json`** exists or can be downloaded (`download-regions` in `prebuild`) so `endpoints` and related tests behave consistently. -## Mocks +### Mocks -- Prefer explicit mock objects over live fetches—this package does not ship an HTTP client; do not introduce network calls in tests unless the project later adds gated integration tests. +- Prefer explicit objects over network calls—this library does not ship an HTTP client; avoid introducing network I/O in tests unless the project adds gated integration tests later. diff --git a/skills/typescript-contentstack-utils/SKILL.md b/skills/typescript-contentstack-utils/SKILL.md deleted file mode 100644 index 41115cc..0000000 --- a/skills/typescript-contentstack-utils/SKILL.md +++ /dev/null @@ -1,45 +0,0 @@ -# Skill: TypeScript — `@contentstack/utils` mental model - -## When to use - -Onboarding, feature design, or refactors touching RTE rendering, embeddings, GQL, or endpoints. - -## What this package is - -**`@contentstack/utils`** is a **TypeScript utility library**, not the **CDA** or **CMA** SDK. It transforms **entry JSON** already fetched via **Content Delivery** (REST or **GraphQL**) into HTML or enriched structures. - -## Where to change things - -| Goal | Start here | -|------|------------| -| Supercharged RTE / JSON → HTML | `src/json-to-html.ts`, `src/nodes/`, `src/helper/` | -| Custom element / embed rendering | `src/options/`, `src/render-embedded-objects.ts` | -| GraphQL-specific RTE or assets | `src/gql.ts`, `src/updateAssetURLForGQL.ts` | -| Live Preview / `data-cslp`-style tags | `src/entry-editable.ts` | -| Region → base URL lookup | `src/endpoints.ts`, `src/assets/regions.json` (build) | -| Public surface | `src/index.ts` only | - -## Data flow (conceptual) - -```mermaid -flowchart LR - subgraph external [Caller] - Delivery[Delivery SDK or GraphQL client] - end - subgraph utils [@contentstack/utils] - JSON[RTE JSON / entry object] - HTML[HTML string or tagged entry] - end - Delivery --> JSON - JSON --> HTML -``` - -## Conventions - -- Match existing **options** patterns (`RenderOption`, path arrays for nested fields). -- Preserve **pure** transform style—no hidden network I/O. -- Terminology in comments should say **delivery / JSON RTE / GraphQL**, not **CMA**, unless you explicitly touch management concerns (unlikely in this repo). - -## Docs - -- **Contentstack** product docs for **Delivery**, **Live Preview**, and **Rich Text / JSON RTE** are the authority for expected JSON shapes. diff --git a/skills/typescript/SKILL.md b/skills/typescript/SKILL.md new file mode 100644 index 0000000..6555b77 --- /dev/null +++ b/skills/typescript/SKILL.md @@ -0,0 +1,39 @@ +--- +name: typescript +description: TypeScript version, src layout, ESLint and Prettier, strictness, and build-time assets for @contentstack/utils +--- + +# TypeScript – @contentstack/utils + +## When to use + +- Editing or adding `.ts` under `src/` or `__test__/`. +- Changing compiler options, lint rules, or formatting scope. + +## Instructions + +### Tooling + +- **TypeScript ~4.9** (`package.json`, `tsconfig.json`). +- **Emit:** `tsc` → `dist/lib`, declarations → `dist/types/`; **Rollup** → `dist/index.es.js` (`rollup.config.js`). +- **Strict:** `strict: true` with **`strictNullChecks: false`** — avoid unnecessary null/undefined leaks in public APIs when touching types. + +### Layout + +- **Library:** `src/**/*.ts` only (`tsconfig.json` `include`). +- **Tests:** `__test__/` (excluded from `tsc` `include`; Jest/ts-jest type-checks test files). +- **Public API:** single barrel — **`src/index.ts`** unless you intentionally add another entry. + +### Style and lint + +- Match existing naming (PascalCase types, camelCase functions; folders `Models/`, `nodes/`, `helper/`, `options/`). +- **ESLint:** `eslint.config.js` — `@typescript-eslint` recommended rules for `__test__/`; `js.configs.recommended` for other TS files. +- **Prettier:** `npm run format` covers `src/**/*.ts`; keep tests consistently formatted when you edit them. + +### Build-time JSON + +- **`src/assets/regions.json`:** Used by `src/endpoints.ts`; filled by **`npm run download-regions`** in `prebuild`. Listed in **`.gitignore`** — clones may need a successful build (or a local file) before tests pass. + +### Logging + +- No shared logger; avoid noisy `console` in library code unless consistent with nearby patterns. From 2bdb70121fe07fd54bd0ce34836950820d2d065e Mon Sep 17 00:00:00 2001 From: raj pandey Date: Tue, 28 Apr 2026 17:36:58 +0530 Subject: [PATCH 2/5] fix: Modified github workflows for release and remove check-branch workflow --- .github/workflows/back-merge-pr.yml | 59 +++++++++++++++++ .github/workflows/check-branch.yml | 20 ------ .github/workflows/check-version-bump.yml | 82 ++++++++++++++++++++++++ .github/workflows/ci.yml | 4 +- .github/workflows/npm-publish.yml | 7 +- AGENTS.md | 2 +- CONTRIBUTING.md | 4 +- skills/dev-workflow/SKILL.md | 6 +- 8 files changed, 153 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/back-merge-pr.yml delete mode 100644 .github/workflows/check-branch.yml create mode 100644 .github/workflows/check-version-bump.yml diff --git a/.github/workflows/back-merge-pr.yml b/.github/workflows/back-merge-pr.yml new file mode 100644 index 0000000..cec0f26 --- /dev/null +++ b/.github/workflows/back-merge-pr.yml @@ -0,0 +1,59 @@ +# Opens a PR from master → development after changes land on master (back-merge). +# +# Org/repo Settings → Actions → General → Workflow permissions: read and write +# (so GITHUB_TOKEN can create pull requests). Or use a PAT in secret GH_TOKEN. + +name: Back-merge master to development + +on: + push: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +jobs: + open-back-merge-pr: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Open back-merge PR if needed + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + git fetch origin development master + + MASTER_SHA=$(git rev-parse origin/master) + DEV_SHA=$(git rev-parse origin/development) + + if [ "$MASTER_SHA" = "$DEV_SHA" ]; then + echo "master and development are at the same commit; nothing to back-merge." + exit 0 + fi + + EXISTING=$(gh pr list --repo "${{ github.repository }}" \ + --base development \ + --head master \ + --state open \ + --json number \ + --jq 'length') + + if [ "$EXISTING" -gt 0 ]; then + echo "An open PR from master to development already exists; skipping." + exit 0 + fi + + gh pr create --repo "${{ github.repository }}" \ + --base development \ + --head master \ + --title "chore: back-merge master into development" \ + --body "Automated back-merge after changes landed on \`master\`. Review and merge to keep \`development\` in sync." + + echo "Created back-merge PR master → development." diff --git a/.github/workflows/check-branch.yml b/.github/workflows/check-branch.yml deleted file mode 100644 index c63e084..0000000 --- a/.github/workflows/check-branch.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: 'Check Branch' - -on: - pull_request: - -jobs: - check_branch: - runs-on: ubuntu-latest - steps: - - name: Comment PR - if: github.base_ref == 'staging' && github.head_ref != 'development' - uses: thollander/actions-comment-pull-request@v2 - with: - message: | - We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the development branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch. - - name: Check branch - if: github.base_ref == 'staging' && github.head_ref != 'development' - run: | - echo "ERROR: We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the development branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch." - exit 1 \ No newline at end of file diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml new file mode 100644 index 0000000..620af85 --- /dev/null +++ b/.github/workflows/check-version-bump.yml @@ -0,0 +1,82 @@ +name: Check Version Bump + +on: + pull_request: + branches: [main, master] + +jobs: + check-version-bump: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Validate version and changelog updates + shell: bash + run: | + set -euo pipefail + + VERSION_FILE="package.json" + CHANGELOG_FILE="CHANGELOG.md" + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + + mapfile -t CHANGED_FILES < <(git diff --name-only "$BASE_SHA" "$HEAD_SHA") + if [ "${#CHANGED_FILES[@]}" -eq 0 ]; then + echo "No changed files detected." + exit 0 + fi + + is_ignored_change() { + local f="$1" + [[ "$f" =~ ^docs/ ]] && return 0 + [[ "$f" =~ ^\.github/ ]] && return 0 + [[ "$f" =~ (^|/)tests?/ ]] && return 0 + [[ "$f" =~ (^|/)__tests__/ ]] && return 0 + [[ "$f" =~ \.md$ ]] && [[ ! "$f" =~ (^|/)CHANGELOG\.md$ ]] && return 0 + return 1 + } + + has_release_impact=false + for file in "${CHANGED_FILES[@]}"; do + if ! is_ignored_change "$file"; then + has_release_impact=true + break + fi + done + + if [ "$has_release_impact" = false ]; then + echo "Skipping docs/test-only PR." + exit 0 + fi + + changed_file() { + local target="$1" + for file in "${CHANGED_FILES[@]}"; do + if [ "$file" = "$target" ]; then + return 0 + fi + done + return 1 + } + + changed_file "$VERSION_FILE" || { echo "Version bump required in $VERSION_FILE."; exit 1; } + changed_file "$CHANGELOG_FILE" || { echo "Matching changelog update required in $CHANGELOG_FILE."; exit 1; } + + head_version=$(node -e "console.log(require('./package.json').version)") + CHANGELOG_HEAD=$(sed -nE 's/^## v?([^[:space:]]+).*/\1/p' "$CHANGELOG_FILE" | head -1) + + [ -n "$CHANGELOG_HEAD" ] || { echo "::error::Could not find a top changelog heading like '## vX.Y.Z' in $CHANGELOG_FILE."; exit 1; } + [ "$CHANGELOG_HEAD" = "$head_version" ] || { echo "::error::$CHANGELOG_FILE top version ($CHANGELOG_HEAD) does not match project version ($head_version)."; exit 1; } + + base_version=$(git show "$BASE_SHA:$VERSION_FILE" | node -e "let d=''; process.stdin.on('data', c => d += c); process.stdin.on('end', () => console.log(JSON.parse(d).version));") + latest_tag=$(git tag --list 'v*' --sort=-version:refname | sed -n '1p') + latest_version="${latest_tag#v}" + [ -n "$latest_version" ] || latest_version="0.0.0" + + version_gt() { + python3 -c 'import sys;v=lambda s:[int(x) if x.isdigit() else 0 for x in (s.strip().lstrip("v").split("-",1)[0].split("+",1)[0].split(".")+["0","0","0"])[:3]];print("true" if v(sys.argv[1])>v(sys.argv[2]) else "false")' "$1" "$2" + } + + [ "$(version_gt "$head_version" "$base_version")" = "true" ] || { echo "Version must be greater than base version ($base_version). Found $head_version."; exit 1; } + [ "$(version_gt "$head_version" "$latest_version")" = "true" ] || { echo "Version must be greater than latest tag version ($latest_version). Found $head_version."; exit 1; } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33b9343..ac17520 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: Unit-Test-CI on: push: - branches: [ master, staging, development ] + branches: [ master, development ] pull_request: - branches: [ master, staging, development ] + branches: [ master, development ] jobs: build-test: diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index eab0907..d92c746 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,10 +1,11 @@ -# This workflow will publish a package to GitHub Packages when a release is created +# This workflow publishes packages when a release tag is pushed # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Publish package to NPM repository on: - release: - types: [created] + push: + tags: + - 'v*' jobs: publish-npm: diff --git a/AGENTS.md b/AGENTS.md index 2b82ff8..c50707c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,7 +29,7 @@ npm run download-regions # regions.json only (also run as part of prebuild) `npm test` runs **`pretest` → `npm run build`**, then Jest with coverage; outputs under **`reports/`**. Use **`npm run test:debug`** for Jest watch mode (`--runInBand`). -**CI:** `.github/workflows/ci.yml` (unit tests / coverage on `development`, `staging`, `master`). Branch rules: `.github/workflows/check-branch.yml`. Publish: `.github/workflows/npm-publish.yml` (on GitHub release). +**CI:** `.github/workflows/ci.yml` (unit tests / coverage on `development`, `master`). Publish: `.github/workflows/npm-publish.yml` (on tag push `v*`). Back-merge automation: `.github/workflows/back-merge-pr.yml`. Install: `npm i @contentstack/utils` — see root **`README.md`** and **`package.json`** for the current version. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 477c426..3364d13 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ Thank you for your interest in contributing to Contentstack Utils JavaScript. Th **All pull requests must be raised against the `development` branch.** -Do not open PRs against `master` or `staging`. Create your feature or fix branch from `development`, and open your PR to merge into `development`. Maintainers will handle promotion to other branches after review. +Feature/fix PRs should merge into `development`. Release PRs are raised by maintainers directly from `development` to `master`. ## Getting Started @@ -92,7 +92,7 @@ Husky is used for Git hooks. Before each commit, the pre-commit hook runs. Ensur git rebase upstream/development ``` -2. **Open a Pull Request** against the **`development`** branch (not `master` or `staging`). +2. **Open a Pull Request** against the **`development`** branch for feature/fix work. Maintainers handle release PRs from `development` to `master`. 3. **Fill out the PR template** (if one exists) and provide: - A clear title and description of the change diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md index 184230b..7ad13fa 100644 --- a/skills/dev-workflow/SKILL.md +++ b/skills/dev-workflow/SKILL.md @@ -15,8 +15,8 @@ description: Branches, CI, build/test/lint commands, git hooks, PR expectations, ### Branches and PRs -- **CI** (`Unit-Test-CI`) runs on **push/PR** to `development`, `staging`, and `master` (`.github/workflows/ci.yml`). -- **Branch check:** PRs **into `staging`** from a head branch other than **`development`** fail (`.github/workflows/check-branch.yml`). Prefer **`development`** as the integration branch when aligning with upstream. +- **CI** (`Unit-Test-CI`) runs on **push/PR** to `development` and `master` (`.github/workflows/ci.yml`). +- Feature/fix PRs should target **`development`**. Release PRs are raised directly from **`development`** to **`master`**. - Confirm target branch with maintainers if unsure. ### Commands @@ -43,4 +43,4 @@ description: Branches, CI, build/test/lint commands, git hooks, PR expectations, - Version in **`package.json`** and **`CHANGELOG.md`**. - **`prepublishOnly`** runs **`npm test`**. -- **npm / GitHub Packages:** `.github/workflows/npm-publish.yml` on **release `created`**; secrets `NPM_TOKEN`, `GIT_TOKEN` (maintainers). +- **npm / GitHub Packages:** `.github/workflows/npm-publish.yml` on **tag push (`v*`)**; secrets `NPM_TOKEN`, `GIT_TOKEN` (maintainers). From ac486268fa536674aa19c998206b1e7b1b727bdd Mon Sep 17 00:00:00 2001 From: raj pandey Date: Wed, 29 Apr 2026 12:11:43 +0530 Subject: [PATCH 3/5] Fixed: the release createion based on the tag --- .github/workflows/npm-publish.yml | 13 +++++++++---- AGENTS.md | 2 +- skills/dev-workflow/SKILL.md | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index d92c746..3f8b11c 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,17 +1,19 @@ -# This workflow publishes packages when a release tag is pushed +# This workflow publishes packages when a GitHub Release is created for a version tag. # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Publish package to NPM repository on: - push: - tags: - - 'v*' + release: + types: [created] jobs: publish-npm: + if: ${{ startsWith(github.event.release.tag_name, 'v') && !github.event.release.draft }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name }} - uses: actions/setup-node@v4 with: node-version: '22.x' @@ -21,9 +23,12 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} publish-git: + if: ${{ startsWith(github.event.release.tag_name, 'v') && !github.event.release.draft }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name }} - uses: actions/setup-node@v4 with: node-version: '22.x' diff --git a/AGENTS.md b/AGENTS.md index c50707c..ee75585 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,7 +29,7 @@ npm run download-regions # regions.json only (also run as part of prebuild) `npm test` runs **`pretest` → `npm run build`**, then Jest with coverage; outputs under **`reports/`**. Use **`npm run test:debug`** for Jest watch mode (`--runInBand`). -**CI:** `.github/workflows/ci.yml` (unit tests / coverage on `development`, `master`). Publish: `.github/workflows/npm-publish.yml` (on tag push `v*`). Back-merge automation: `.github/workflows/back-merge-pr.yml`. +**CI:** `.github/workflows/ci.yml` (unit tests / coverage on `development`, `master`). Publish: `.github/workflows/npm-publish.yml` (GitHub **Release** created for tag `v*`; draft releases are skipped). Back-merge automation: `.github/workflows/back-merge-pr.yml`. Install: `npm i @contentstack/utils` — see root **`README.md`** and **`package.json`** for the current version. diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md index 7ad13fa..93923d0 100644 --- a/skills/dev-workflow/SKILL.md +++ b/skills/dev-workflow/SKILL.md @@ -43,4 +43,4 @@ description: Branches, CI, build/test/lint commands, git hooks, PR expectations, - Version in **`package.json`** and **`CHANGELOG.md`**. - **`prepublishOnly`** runs **`npm test`**. -- **npm / GitHub Packages:** `.github/workflows/npm-publish.yml` on **tag push (`v*`)**; secrets `NPM_TOKEN`, `GIT_TOKEN` (maintainers). +- **npm / GitHub Packages:** `.github/workflows/npm-publish.yml` on **`release: types: [created]`** for tag **`v*`** (draft releases skipped); secrets `NPM_TOKEN`, `GIT_TOKEN` (maintainers). From 2108ce0e7d5ceead7aefe3c80437fd1e6180d947 Mon Sep 17 00:00:00 2001 From: raj pandey Date: Thu, 30 Apr 2026 11:59:13 +0530 Subject: [PATCH 4/5] fix: check-version bump triggered for all the PR --- .github/workflows/check-version-bump.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml index 620af85..5799ae8 100644 --- a/.github/workflows/check-version-bump.yml +++ b/.github/workflows/check-version-bump.yml @@ -2,7 +2,6 @@ name: Check Version Bump on: pull_request: - branches: [main, master] jobs: check-version-bump: From 8d733658c9bd20582d77a7d19413cd206bc4b438 Mon Sep 17 00:00:00 2001 From: raj pandey Date: Thu, 30 Apr 2026 15:10:37 +0530 Subject: [PATCH 5/5] ci: gate version-bump on src paths; validate semver vs latest tag only --- .github/workflows/check-version-bump.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml index 5799ae8..51e052c 100644 --- a/.github/workflows/check-version-bump.yml +++ b/.github/workflows/check-version-bump.yml @@ -1,3 +1,5 @@ +# Runs only when production code under src/ changes. Version must be > latest v* tag (not vs base branch). + name: Check Version Bump on: @@ -26,26 +28,21 @@ jobs: exit 0 fi - is_ignored_change() { + is_production_source_change() { local f="$1" - [[ "$f" =~ ^docs/ ]] && return 0 - [[ "$f" =~ ^\.github/ ]] && return 0 - [[ "$f" =~ (^|/)tests?/ ]] && return 0 - [[ "$f" =~ (^|/)__tests__/ ]] && return 0 - [[ "$f" =~ \.md$ ]] && [[ ! "$f" =~ (^|/)CHANGELOG\.md$ ]] && return 0 - return 1 + [[ "$f" == src/* ]] } - has_release_impact=false + has_source_changes=false for file in "${CHANGED_FILES[@]}"; do - if ! is_ignored_change "$file"; then - has_release_impact=true + if is_production_source_change "$file"; then + has_source_changes=true break fi done - if [ "$has_release_impact" = false ]; then - echo "Skipping docs/test-only PR." + if [ "$has_source_changes" = false ]; then + echo "Skipping: no src/ production code changes." exit 0 fi @@ -68,7 +65,6 @@ jobs: [ -n "$CHANGELOG_HEAD" ] || { echo "::error::Could not find a top changelog heading like '## vX.Y.Z' in $CHANGELOG_FILE."; exit 1; } [ "$CHANGELOG_HEAD" = "$head_version" ] || { echo "::error::$CHANGELOG_FILE top version ($CHANGELOG_HEAD) does not match project version ($head_version)."; exit 1; } - base_version=$(git show "$BASE_SHA:$VERSION_FILE" | node -e "let d=''; process.stdin.on('data', c => d += c); process.stdin.on('end', () => console.log(JSON.parse(d).version));") latest_tag=$(git tag --list 'v*' --sort=-version:refname | sed -n '1p') latest_version="${latest_tag#v}" [ -n "$latest_version" ] || latest_version="0.0.0" @@ -77,5 +73,4 @@ jobs: python3 -c 'import sys;v=lambda s:[int(x) if x.isdigit() else 0 for x in (s.strip().lstrip("v").split("-",1)[0].split("+",1)[0].split(".")+["0","0","0"])[:3]];print("true" if v(sys.argv[1])>v(sys.argv[2]) else "false")' "$1" "$2" } - [ "$(version_gt "$head_version" "$base_version")" = "true" ] || { echo "Version must be greater than base version ($base_version). Found $head_version."; exit 1; } [ "$(version_gt "$head_version" "$latest_version")" = "true" ] || { echo "Version must be greater than latest tag version ($latest_version). Found $head_version."; exit 1; }