Skip to content

Commit 9b96a28

Browse files
Merge pull request #85 from contentstack/feat/dx-5404-cursor-skills-rules
snyk fix and cursor rules
2 parents 90db914 + e1345fc commit 9b96a28

13 files changed

Lines changed: 742 additions & 241 deletions

File tree

.cursor/rules/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Cursor (optional)
2+
3+
**Cursor** users: start at the repo root **[`AGENTS.md`](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`** (universal for any editor or tool).
4+
5+
This folder **only** contains this **README** — no `.mdc` or other rule files — so nothing editor-specific duplicates the canonical docs.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Catches when developers forget to bump package.json for release-affecting changes.
2+
# App code changes (app.js, bin/, config/, routes/, views/, etc.) require a version bump vs latest tag.
3+
# Skips for: test-only, docs, .github (workflows/config), dependency-only bumps without app edits.
4+
name: Check Version Bump
5+
6+
on:
7+
pull_request:
8+
9+
jobs:
10+
version-bump:
11+
name: Version bump
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Detect changed files and version bump
20+
id: detect
21+
run: |
22+
if git rev-parse HEAD^2 >/dev/null 2>&1; then
23+
FILES=$(git diff --name-only HEAD^1 HEAD^2)
24+
else
25+
FILES=$(git diff --name-only HEAD~1 HEAD)
26+
fi
27+
VERSION_FILES_CHANGED=false
28+
echo "$FILES" | grep -qx 'package.json' && VERSION_FILES_CHANGED=true
29+
echo "version_files_changed=$VERSION_FILES_CHANGED" >> $GITHUB_OUTPUT
30+
# App source paths for this boilerplate (no lib/webpack/dist); .github/ and test/ do not count
31+
CODE_CHANGED=false
32+
echo "$FILES" | grep -qE '^app\.js$|^bin/|^config/|^middlewares/|^models/|^public/|^routes/|^views/|^schemaNentries/' && CODE_CHANGED=true
33+
echo "$FILES" | grep -qx 'package.json' && CODE_CHANGED=true
34+
echo "code_changed=$CODE_CHANGED" >> $GITHUB_OUTPUT
35+
36+
- name: Skip when only test/docs/.github changed
37+
if: steps.detect.outputs.code_changed != 'true'
38+
run: |
39+
echo "No release-affecting files changed (e.g. only test/docs/.github). Skipping version-bump check."
40+
exit 0
41+
42+
- name: Fail when version bump was missed
43+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed != 'true'
44+
run: |
45+
echo "::error::This PR has code changes but no version bump. Please bump the version in package.json."
46+
exit 1
47+
48+
- name: Setup Node
49+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true'
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: '22.x'
53+
54+
- name: Check version bump
55+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_changed == 'true'
56+
run: |
57+
set -e
58+
PKG_VERSION=$(node -p "require('./package.json').version.replace(/^v/, '')")
59+
if [ -z "$PKG_VERSION" ]; then
60+
echo "::error::Could not read version from package.json"
61+
exit 1
62+
fi
63+
git fetch --tags --force 2>/dev/null || true
64+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
65+
if [ -z "$LATEST_TAG" ]; then
66+
echo "No existing tags found. Skipping version-bump check (first release)."
67+
exit 0
68+
fi
69+
LATEST_VERSION="${LATEST_TAG#v}"
70+
LATEST_VERSION="${LATEST_VERSION%%-*}"
71+
if [ "$(printf '%s\n' "$LATEST_VERSION" "$PKG_VERSION" | sort -V | tail -1)" != "$PKG_VERSION" ]; then
72+
echo "::error::Version bump required: package.json version ($PKG_VERSION) is not greater than latest tag ($LATEST_TAG). Please bump the version in package.json."
73+
exit 1
74+
fi
75+
if [ "$PKG_VERSION" = "$LATEST_VERSION" ]; then
76+
echo "::error::Version bump required: package.json version ($PKG_VERSION) equals latest tag ($LATEST_TAG). Please bump the version in package.json."
77+
exit 1
78+
fi
79+
echo "Version bump check passed: package.json is at $PKG_VERSION (latest tag: $LATEST_TAG)."

.github/workflows/release.yml

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: Release
22

33
on:
4-
push:
5-
branches: [master]
4+
release:
5+
types: [created]
66

77
jobs:
88
build:
@@ -43,35 +43,13 @@ jobs:
4343
token: ${{ secrets.NPM_TOKEN }}
4444
# access: public # Uncomment this line if you want to publish the package as public for first time
4545

46-
# Auto-tag the new version if a change is detected
47-
- name: Auto-tag new version
48-
id: update_tag
49-
uses: Klemensas/action-autotag@stable
50-
with:
51-
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
52-
tag_prefix: "v"
53-
54-
# Create a new GitHub Release
55-
- name: Create GitHub Release
56-
if: steps.update_tag.outputs.tagname != ''
57-
uses: actions/create-release@v1
58-
id: create_release
59-
env:
60-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
61-
with:
62-
tag_name: ${{ steps.update_tag.outputs.tagname }}
63-
release_name: Release ${{ steps.update_tag.outputs.tagname }}
64-
draft: false
65-
prerelease: false
66-
67-
# Upload the packaged .tgz file as a release asset
46+
# Upload the packaged .tgz to the release that triggered this workflow
6847
- name: Upload Release Asset
69-
if: steps.update_tag.outputs.tagname != ''
7048
uses: actions/upload-release-asset@v1
7149
env:
7250
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7351
with:
74-
upload_url: ${{ steps.create_release.outputs.upload_url }}
52+
upload_url: ${{ github.event.release.upload_url }}
7553
asset_path: "./contentstack-datasync-mongodb-sdk-${{ steps.package.outputs.version }}.tgz"
7654
asset_name: "contentstack-datasync-mongodb-sdk-${{ steps.package.outputs.version }}.tgz"
7755
asset_content_type: application/tgz

.husky/post-checkout

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env sh
2+
# When switching to a branch that doesn't exist on remote (e.g. newly created),
3+
# pull and merge origin/main or origin/master into current branch. Does not push.
4+
5+
# Only run on branch checkout (not file checkout)
6+
if [ "$3" != "1" ]; then
7+
exit 0
8+
fi
9+
10+
# Skip if we don't have a remote
11+
if ! git rev-parse --verify origin 2>/dev/null; then
12+
exit 0
13+
fi
14+
15+
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
16+
17+
# Skip main/master - no need to merge base into these
18+
case "$CURRENT_BRANCH" in
19+
main|master) exit 0 ;;
20+
esac
21+
22+
# Only run when current branch does not exist on origin (treat as new local branch)
23+
if git ls-remote --heads origin "$CURRENT_BRANCH" 2>/dev/null | grep -q .; then
24+
echo "post-checkout: $CURRENT_BRANCH exists on origin, skipping merge."
25+
exit 0
26+
fi
27+
28+
# Prefer main, fallback to master
29+
if git rev-parse --verify origin/main 2>/dev/null; then
30+
BASE=origin/main
31+
elif git rev-parse --verify origin/master 2>/dev/null; then
32+
BASE=origin/master
33+
else
34+
exit 0
35+
fi
36+
37+
echo "New branch detected: merging latest $BASE into $CURRENT_BRANCH (local only, not pushing)..."
38+
git fetch origin
39+
git merge "$BASE" --no-edit --no-ff
40+
echo "Done. Merge is local only; push when ready."

AGENTS.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# AI agent docs — `@contentstack/datasync-mongodb-sdk`
2+
3+
You are working on the **Contentstack DataSync MongoDB SDK** — a library that queries **MongoDB** (or a Mongo-compatible store) holding content synced via **Contentstack DataSync**, **not** the Content **Delivery** (CDA) or **Management** (CMA) HTTP SDKs. Core behavior uses the **MongoDB driver** and queries against **persisted sync data**, not live stack REST calls for normal reads.
4+
5+
## Single source of truth
6+
7+
| Layer | Role |
8+
|-------|------|
9+
| **[`.cursor/rules/README.md`](.cursor/rules/README.md)** | Optional Cursor pointer (the **only** file under `.cursor/rules/`); links to **`AGENTS.md`** and **`skills/`** |
10+
| **`AGENTS.md`** (this file) | Universal entry: identity, out-of-scope, links, tech stack, commands, skills index |
11+
| **`skills/<name>/SKILL.md`** | Full conventions and checklists (source of truth for depth) |
12+
13+
**Flow:** [`.cursor/rules/README.md`](.cursor/rules/README.md)**`AGENTS.md`****`skills/<name>/SKILL.md`**
14+
15+
## Out of scope (unless comparing or documenting migration)
16+
17+
- **Not** the CDA or CMA **HTTP** client SDKs.
18+
- **Not** live Contentstack **REST** reads for normal query paths — this SDK targets **synced data in MongoDB**.
19+
20+
## Repository
21+
22+
| | |
23+
|--|--|
24+
| **npm** | `@contentstack/datasync-mongodb-sdk` |
25+
| **Git** | [https://github.com/contentstack/datasync-mongodb-sdk](https://github.com/contentstack/datasync-mongodb-sdk) |
26+
| **Product docs** | [Contentstack DataSync](https://www.contentstack.com/docs/guide/synchronization/contentstack-datasync) |
27+
28+
## Tech stack
29+
30+
| Area | Details |
31+
|------|---------|
32+
| Language | TypeScript `^4.9.5` (`package.json`); `tsc``dist/`, declarations `typings/` (`tsconfig.json`) |
33+
| Runtime | Node `>=8` (`engines`); README may suggest a newer Node for local dev |
34+
| Build | `npm run compile` (`tsc`); `npm run build-ts` (`clean` + `tsc`) |
35+
| Test | Jest `^29` + ts-jest, Node env, coverage on (`jest.config.js`). **`npm test` is `jest` only** — no `pretest` in `package.json` |
36+
| Lint | **TSLint**`npm run tslint` + `tslint.json` on `src/**/*.ts`. **No ESLint** / no `npm run lint` in this repo |
37+
| Runtime deps | `mongodb`, `lodash`, `sift` |
38+
| Docs | `npm run build-doc` (builds then JSDoc → `docs/`) |
39+
40+
## Source layout and public entry points
41+
42+
| Role | Path |
43+
|------|------|
44+
| Package entry | `dist/index.js` (`main`) |
45+
| Public API | `src/index.ts``Contentstack`, `Contentstack.Stack(config, db?)` |
46+
| Query / connection | `src/stack.ts` |
47+
| Defaults + validation | `src/config.ts`, `src/util.ts` |
48+
| Messages | `src/messages.ts` |
49+
| Tests + fixtures | `test/`, `test/data/` |
50+
| Declarations | `typings/*.d.ts` |
51+
| Example | `example/index.js` |
52+
53+
## Commands
54+
55+
| Command | Purpose |
56+
|---------|---------|
57+
| `npm run build-ts` | Clean `dist/`, `typings/`, `coverage/`, then `tsc` |
58+
| `npm run compile` | `tsc` only |
59+
| `npm test` | Jest (coverage per `jest.config.js`) |
60+
| `npm run tslint` | TSLint `src/**/*.ts` |
61+
| `npm run clean` | Rimraf `dist`, `typings`, `coverage` |
62+
| `npm run build-doc` | Full build + JSDoc to `docs/` |
63+
64+
## Test model and credentials
65+
66+
- **Integration-style** tests against a **real MongoDB** (`Stack.connect()`, inserts, queries, teardown). **Not** live Contentstack HTTP API calls.
67+
- Default URI from merged **`src/config.ts`** (e.g. `mongodb://localhost:27017`); tests often use **`test/config.ts`** (`dbName` e.g. `sync-test`).
68+
- **No** committed `.env` for tests; override via **`contentStore`** (including `url`) in code. **Do not** commit production Mongo URIs or secrets.
69+
- **No** Testcontainers or CI Mongo service defined in-repo — local MongoDB is the documented path for developers running tests.
70+
71+
## Skills index
72+
73+
Canonical detail lives under **`skills/<kebab-case>/SKILL.md`**. See **[`skills/README.md`](skills/README.md)**.
74+
75+
| Skill | `SKILL.md` |
76+
|-------|------------|
77+
| Dev workflow, hooks, CI | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) |
78+
| TypeScript / TSLint / `src/` layout | [`skills/typescript/SKILL.md`](skills/typescript/SKILL.md) |
79+
| DataSync MongoDB SDK behavior | [`skills/datasync-mongodb/SKILL.md`](skills/datasync-mongodb/SKILL.md) |
80+
| Testing | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) |
81+
| Code review | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) |
82+
83+
## Using Cursor
84+
85+
- Open **[`.cursor/rules/README.md`](.cursor/rules/README.md)** — the sole file in **`.cursor/rules/`** — for pointers to **`AGENTS.md`** and **`skills/`**.
86+
- Full guidance: **`skills/<name>/SKILL.md`** (attach or `@`-reference those paths in chat per your Cursor setup); there are **no** `.cursor/rules/*.mdc` files in this repo.
87+
88+
## Contributor workflow (concise)
89+
90+
- **`.husky/pre-commit`:** **Snyk** + **Talisman** when installed; `SKIP_HOOK=1` only if your team allows.
91+
- **CI:** `.github/workflows/` includes CodeQL, SCA, policy scans, **check-version-bump** — see each file for triggers.
92+
- **Version bump workflow** path filters may **not** list `src/`; maintainers may need to align the workflow with this layout (see [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md)).

0 commit comments

Comments
 (0)