From f2c40bdc4565f521f6347c6a4320e59c8e44c8bc Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:29:38 +0530 Subject: [PATCH 01/20] sca-scan.yml From f1cd281c492693ceb8fcbe78ddb90510adfb90fa Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:29:51 +0530 Subject: [PATCH 02/20] jira.yml --- .github/workflows/jira.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml index caa4bbd..250abc7 100644 --- a/.github/workflows/jira.yml +++ b/.github/workflows/jira.yml @@ -21,7 +21,7 @@ jobs: project: ${{ secrets.JIRA_PROJECT }} issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} summary: | - ${{ github.event.pull_request.title }} + Snyk | Vulnerability | ${{ github.event.repository.name }} | ${{ github.event.pull_request.title }} description: | PR: ${{ github.event.pull_request.html_url }} From aa6a7b37da6f22d5acfc4799284540f177b5e145 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:29:52 +0530 Subject: [PATCH 03/20] sast-scan.yml From d52a684a89f1865c30dd4816c8f61419a5c0cd27 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:29:56 +0530 Subject: [PATCH 04/20] Updated codeowners --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 0773923..1be7e0d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @contentstack/security-admin \ No newline at end of file +* @contentstack/security-admin From 7873b44488e19818c876ad0b7bf1c6f11364c28f Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:56:53 +0530 Subject: [PATCH 05/20] policy-scan.yml --- .github/workflows/policy-scan.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/policy-scan.yml diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml new file mode 100644 index 0000000..13bd362 --- /dev/null +++ b/.github/workflows/policy-scan.yml @@ -0,0 +1,27 @@ +name: Checks the security policy and configurations +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-policy: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for SECURITY.md policy file + run: | + if ! [[ -f "SECURITY.md" || -f ".github/SECURITY.md" ]]; then exit 1; fi + security-license: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for License file + run: | + if ! [[ -f "LICENSE" || -f "License.txt" || -f "LICENSE.md" ]]; then exit 1; fi \ No newline at end of file From af978b3e752e9684416be65f5ac9621a8637a569 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:57:03 +0530 Subject: [PATCH 06/20] issues-jira.yml --- .github/workflows/issues-jira.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/issues-jira.yml diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml new file mode 100644 index 0000000..7bf0469 --- /dev/null +++ b/.github/workflows/issues-jira.yml @@ -0,0 +1,31 @@ +name: Create Jira Ticket for Github Issue + +on: + issues: + types: [opened] + +jobs: + issue-jira: + runs-on: ubuntu-latest + steps: + + - name: Login to Jira + uses: atlassian/gajira-login@master + env: + JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + - name: Create Jira Issue + id: create_jira + uses: atlassian/gajira-create@master + with: + project: ${{ secrets.JIRA_PROJECT }} + issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} + summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} + description: | + *GitHub Issue:* ${{ github.event.issue.html_url }} + + *Description:* + ${{ github.event.issue.body }} + fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file From 6b79426b5f74af4ec6d39f849f95fd5b0debacc3 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:57:04 +0530 Subject: [PATCH 07/20] Delete jira.yml --- .github/workflows/jira.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/jira.yml diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml deleted file mode 100644 index 250abc7..0000000 --- a/.github/workflows/jira.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Create JIRA ISSUE -on: - pull_request: - types: [opened] -jobs: - security-jira: - if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'snyk-bot' || contains(github.event.pull_request.head.ref, 'snyk-fix-') || contains(github.event.pull_request.head.ref, 'snyk-upgrade-')}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Login into JIRA - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Create a JIRA Issue - id: create - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: | - Snyk | Vulnerability | ${{ github.event.repository.name }} | ${{ github.event.pull_request.title }} - description: | - PR: ${{ github.event.pull_request.html_url }} - - fields: "${{ secrets.JIRA_FIELDS }}" - - name: Transition issue - uses: atlassian/gajira-transition@v3 - with: - issue: ${{ steps.create.outputs.issue }} - transition: ${{ secrets.JIRA_TRANSITION }} From 2959f1c576a1a28f4c70b58fdec328a3d4fbf21e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:57:04 +0530 Subject: [PATCH 08/20] Delete sast-scan.yml --- .github/workflows/sast-scan.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/workflows/sast-scan.yml diff --git a/.github/workflows/sast-scan.yml b/.github/workflows/sast-scan.yml deleted file mode 100644 index 3b9521a..0000000 --- a/.github/workflows/sast-scan.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: SAST Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-sast: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Semgrep Scan - run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}:/src" returntocorp/semgrep semgrep scan --config auto \ No newline at end of file From 65e092c192a3cd011a42b300a442886356d36b3c Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:57:09 +0530 Subject: [PATCH 09/20] Updated codeowners From 7edb97d73231828edae6ade3d4c2d40440ce2d24 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 23 Apr 2025 21:43:17 +0530 Subject: [PATCH 10/20] policy-scan.yml --- .github/workflows/policy-scan.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml index 13bd362..ff25923 100644 --- a/.github/workflows/policy-scan.yml +++ b/.github/workflows/policy-scan.yml @@ -24,4 +24,23 @@ jobs: - uses: actions/checkout@master - name: Checks for License file run: | - if ! [[ -f "LICENSE" || -f "License.txt" || -f "LICENSE.md" ]]; then exit 1; fi \ No newline at end of file + expected_license_files=("LICENSE" "LICENSE.txt" "LICENSE.md" "License.txt") + license_file_found=false + current_year=$(date +"%Y") + + for license_file in "${expected_license_files[@]}"; do + if [ -f "$license_file" ]; then + license_file_found=true + # check the license file for the current year, if not exists, exit with error + if ! grep -q "$current_year" "$license_file"; then + echo "License file $license_file does not contain the current year." + exit 2 + fi + break + fi + done + + if [ "$license_file_found" = false ]; then + echo "No license file found. Please add a license file to the repository." + exit 1 + fi \ No newline at end of file From d824c8d4cdb0d8fc9b9d6810e029fdb36679b377 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:17:18 +0530 Subject: [PATCH 11/20] policy-scan.yml From 4d86caefe643c7ed504c1b9a3789fcaeba0f1032 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:17:26 +0530 Subject: [PATCH 12/20] issues-jira.yml From b61035bccc94d806475103b80be1473680b784e8 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:17:26 +0530 Subject: [PATCH 13/20] secrets-scan.yml --- .github/workflows/secrets-scan.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/secrets-scan.yml diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml new file mode 100644 index 0000000..049c02f --- /dev/null +++ b/.github/workflows/secrets-scan.yml @@ -0,0 +1,29 @@ +name: Secrets Scan +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-secrets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: '2' + ref: '${{ github.event.pull_request.head.ref }}' + - run: | + git reset --soft HEAD~1 + - name: Install Talisman + run: | + # Download Talisman + wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman + + # Checksum verification + checksum=$(sha256sum ./talisman | awk '{print $1}') + if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi + + # Make it executable + chmod +x talisman + - name: Run talisman + run: | + # Run Talisman with the pre-commit hook + ./talisman --githook pre-commit \ No newline at end of file From bd45a0f19cf8b8c817284fc5734e5a11cfc89c06 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:17:31 +0530 Subject: [PATCH 14/20] Updated codeowners From 669d87c6ba6db4f1e49a4919a01ca6a2682bf8e4 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 23:37:37 +0530 Subject: [PATCH 15/20] talismanrc file updated --- .talismanrc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.talismanrc b/.talismanrc index 8953f7d..85a10d9 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,7 @@ fileignoreconfig: +- filename: .github/workflows/secrets-scan.yml + ignore_detectors: + - filecontent - filename: composer.lock checksum: 3e19a34da8e50af426a1b648f3fb067592c3df08274fa553b7204fd4d326e1df - filename: README.md From 3d11ed15cc4e9d035a6c08b838fe223d8cb85017 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 8 Sep 2025 22:20:31 +0530 Subject: [PATCH 16/20] Delete secrets-scan.yml --- .github/workflows/secrets-scan.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .github/workflows/secrets-scan.yml diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml deleted file mode 100644 index 049c02f..0000000 --- a/.github/workflows/secrets-scan.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Secrets Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-secrets: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: '2' - ref: '${{ github.event.pull_request.head.ref }}' - - run: | - git reset --soft HEAD~1 - - name: Install Talisman - run: | - # Download Talisman - wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman - - # Checksum verification - checksum=$(sha256sum ./talisman | awk '{print $1}') - if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi - - # Make it executable - chmod +x talisman - - name: Run talisman - run: | - # Run Talisman with the pre-commit hook - ./talisman --githook pre-commit \ No newline at end of file From 1ea51d72a32361e3d1a2ce58d25b5d36fc747fb0 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 8 Sep 2025 22:20:35 +0530 Subject: [PATCH 17/20] Updated codeowners --- CODEOWNERS | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 1be7e0d..785adb4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1,9 @@ -* @contentstack/security-admin +* @contentstack/devex-pr-reviewers + +.github/workflows/sca-scan.yml @contentstack/security-admin + +**/.snyk @contentstack/security-admin + +.github/workflows/policy-scan.yml @contentstack/security-admin + +.github/workflows/issues-jira.yml @contentstack/security-admin From 6c268c5de46ef4277336470474ca675dc9cb0378 Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Wed, 8 Apr 2026 15:02:11 +0530 Subject: [PATCH 18/20] Add agent guide, skills overview, and development workflow instructions. --- .cursor/rules/README.md | 5 ++++ AGENTS.md | 48 ++++++++++++++++++++++++++++++ skills/README.md | 15 ++++++++++ skills/code-review/SKILL.md | 34 +++++++++++++++++++++ skills/contentstack-utils/SKILL.md | 42 ++++++++++++++++++++++++++ skills/dev-workflow/SKILL.md | 44 +++++++++++++++++++++++++++ skills/php-style/SKILL.md | 37 +++++++++++++++++++++++ skills/testing/SKILL.md | 40 +++++++++++++++++++++++++ 8 files changed, 265 insertions(+) create mode 100644 .cursor/rules/README.md create mode 100644 AGENTS.md create mode 100644 skills/README.md create mode 100644 skills/code-review/SKILL.md create mode 100644 skills/contentstack-utils/SKILL.md create mode 100644 skills/dev-workflow/SKILL.md create mode 100644 skills/php-style/SKILL.md create mode 100644 skills/testing/SKILL.md diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 0000000..b145041 --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,5 @@ +# Cursor (optional) + +**Cursor** users: start at **[`AGENTS.md`](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`**. + +This folder only points contributors to **`AGENTS.md`** so editor-specific config does not duplicate the canonical docs. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d528bca --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,48 @@ +# Contentstack Utils PHP – Agent guide + +**Universal entry point** for contributors and AI agents. Detailed conventions live in **`skills/*/SKILL.md`**. + +## What this repo is + +| Field | Detail | +| --- | --- | +| **Name:** | [contentstack/utils](https://packagist.org/packages/contentstack/utils) · [GitHub](https://github.com/contentstack/contentstack-utils-php) | +| **Purpose:** | PHP library for rendering Contentstack Rich Text (RTE) content and GraphQL-shaped JSON to HTML, including embedded entries and custom render options. | +| **Out of scope (if any):** | Not an HTTP client or full Contentstack Delivery SDK; it focuses on parsing/rendering utilities used alongside other Contentstack PHP packages. | + +## Tech stack (at a glance) + +| Area | Details | +| --- | --- | +| Language | PHP `>=7.2` (Composer); CI runs on PHP 8.3. `declare(strict_types=1);` in source files. | +| Build | [Composer](https://getcomposer.org/) — `composer.json`, `composer.lock`. No compile step; autoload PSR-4 `Contentstack\Utils\` → `src/`. | +| Tests | PHPUnit 9.x via `composer test` / `phpunit`; suite in `tests/`, config `phpunit.xml`. | +| Lint / coverage | PHP_CodeSniffer (PSR-2 ruleset) — `composer check-style` / `composer fix-style`; config `phpcs.xml.dist`. Coverage/logging paths under `build/` when generated. | +| Other | Dev dependency `marc-mabe/php-enum` for enums. | + +## Commands (quick reference) + +| Command type | Command | +| --- | --- | +| Install deps | `composer install` | +| Test | `composer test` | +| Lint | `composer check-style` | +| Format (fix) | `composer fix-style` | + +**CI:** [`.github/workflows/ci.yml`](.github/workflows/ci.yml) — validates `composer.json` / lockfile, installs dependencies, runs `composer run-script test`. Other workflows: `sca-scan.yml`, `policy-scan.yml`, `issues-jira.yml`, `check-branch.yml`. + +## Where the documentation lives: skills + +| Skill | Path | What it covers | +| --- | --- | --- | +| Dev workflow | [`skills/dev-workflow/SKILL.md`](skills/dev-workflow/SKILL.md) | Branches, CI, Composer scripts, PR expectations | +| Contentstack Utils API | [`skills/contentstack-utils/SKILL.md`](skills/contentstack-utils/SKILL.md) | Public API, namespaces, extension points (`Option`, `RenderableInterface`) | +| PHP style & layout | [`skills/php-style/SKILL.md`](skills/php-style/SKILL.md) | PSR-2, PHPCS, file layout under `src/` | +| Testing | [`skills/testing/SKILL.md`](skills/testing/SKILL.md) | PHPUnit layout, mocks, coverage output | +| Code review | [`skills/code-review/SKILL.md`](skills/code-review/SKILL.md) | PR checklist aligned with this repo | + +An index with “when to use” hints is in [`skills/README.md`](skills/README.md). + +## Using Cursor (optional) + +If you use **Cursor**, [`.cursor/rules/README.md`](.cursor/rules/README.md) only points to **`AGENTS.md`**—same docs as everyone else. diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..f54ffac --- /dev/null +++ b/skills/README.md @@ -0,0 +1,15 @@ +# Skills – Contentstack Utils PHP + +Source of truth for detailed guidance. Read [`AGENTS.md`](../AGENTS.md) first, then open the skill that matches your task. + +## When to use which skill + +| Skill folder | Use when | +| --- | --- | +| [`dev-workflow`](dev-workflow/SKILL.md) | Running installs/tests, understanding CI, branch rules for PRs to `master` | +| [`contentstack-utils`](contentstack-utils/SKILL.md) | Changing public APIs, `Utils` / `GQL`, parsers, models, or embed rendering | +| [`php-style`](php-style/SKILL.md) | Code style, PHPCS/PSR-2, namespaces, or `src/` layout | +| [`testing`](testing/SKILL.md) | Adding or changing PHPUnit tests, mocks, or coverage | +| [`code-review`](code-review/SKILL.md) | Preparing or reviewing a PR for this repository | + +Each folder contains `SKILL.md` with YAML frontmatter (`name`, `description`). diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 0000000..811ad3a --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,34 @@ +--- +name: code-review +description: Use when reviewing or preparing a PR — tests, style, SemVer, docs, and branch rules for this repository. +--- + +# Code review – Contentstack Utils PHP + +## When to use + +- Authoring a pull request into this repo +- Reviewing someone else’s PR for completeness and repo policy + +## Instructions + +### Checklist + +- **Tests:** New or changed behavior has PHPUnit coverage; `composer test` passes. +- **Style:** `composer check-style` passes (PSR-2 via PHPCS). +- **Docs:** User-visible behavior changes reflected in [`README.md`](../../README.md) or other maintainer-facing docs as appropriate. +- **API / SemVer:** Public signatures and documented behavior follow semantic versioning expectations per [`CONTRIBUTING.md`](../../CONTRIBUTING.md). +- **Branch policy:** PRs targeting **`master`** must come from the **`next`** branch per [`.github/workflows/check-branch.yml`](../../.github/workflows/check-branch.yml); confirm with the team if process changes. +- **Commits:** Prefer coherent history; squash noisy WIP commits when requested. + +### Severity (optional labels) + +- **Blocker:** Breaks tests, CI, or documented security/policy requirements. +- **Major:** Missing tests for non-trivial logic, public API breakage without version strategy, or policy violations (e.g. wrong base branch). +- **Minor:** Style nits, naming, or internal refactors with no contract change. + +## References + +- [`CONTRIBUTING.md`](../../CONTRIBUTING.md) +- [`PULL_REQUEST_TEMPLATE.md`](../../PULL_REQUEST_TEMPLATE.md) +- [`dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) diff --git a/skills/contentstack-utils/SKILL.md b/skills/contentstack-utils/SKILL.md new file mode 100644 index 0000000..234e472 --- /dev/null +++ b/skills/contentstack-utils/SKILL.md @@ -0,0 +1,42 @@ +--- +name: contentstack-utils +description: Use when changing Utils, GQL, BaseParser, models, enums, or embed/render behavior — the library’s public surface and integration boundaries. +--- + +# Contentstack Utils API – Contentstack Utils PHP + +## When to use + +- Adding or changing HTML/RTE rendering or GraphQL JSON → HTML conversion +- Extending or implementing render callbacks (`Option`, `RenderableInterface`) +- Working with metadata, embedded items, or enum-backed node/mark types + +## Instructions + +### Package identity + +- Composer package: `contentstack/utils` ([Packagist](https://packagist.org/packages/contentstack/utils)); PSR-4 root namespace `Contentstack\Utils\` maps to `src/`. + +### Main entry points (illustrative) + +- **`Contentstack\Utils\Utils`** ([`src/Utils.php`](../../src/Utils.php)) — static helpers such as `renderContent` / `jsonToHtml` for RTE strings and JSON payloads; extends `BaseParser`. +- **`Contentstack\Utils\GQL`** ([`src/GQL.php`](../../src/GQL.php)) — `jsonToHtml` and related parsing for GraphQL-shaped content; extends `BaseParser`. +- **`Contentstack\Utils\BaseParser`** ([`src/BaseParser.php`](../../src/BaseParser.php)) — shared parsing and embedded-object resolution logic. + +### Extension / integration + +- **`Contentstack\Utils\Model\Option`** — configure rendering; subclasses override `renderMark`, `renderNode`, `renderOptions`, etc. +- **`Contentstack\Utils\Resource\RenderableInterface`** — contract for types that participate in rendering. +- **`Contentstack\Utils\Model\Metadata`** — embed metadata (e.g. style type, attributes). +- **Enums** under `Contentstack\Utils\Enum\` (`NodeType`, `MarkType`, `StyleType`, `EmbedItemType`) use `marc-mabe/php-enum`. + +### Boundaries + +- This package does not ship HTTP calls; consumers fetch data with the Contentstack PHP SDK or other clients and pass strings/objects into `Utils` / `GQL`. +- Prefer backward-compatible changes to public method signatures; follow SemVer. + +## References + +- [`testing/SKILL.md`](../testing/SKILL.md) +- [`php-style/SKILL.md`](../php-style/SKILL.md) +- [Product README — usage](../../README.md) diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md new file mode 100644 index 0000000..e772790 --- /dev/null +++ b/skills/dev-workflow/SKILL.md @@ -0,0 +1,44 @@ +--- +name: dev-workflow +description: Use when running Composer, CI, or PRs to master/next — installs, tests, and branch policy for this repo. +--- + +# Dev workflow – Contentstack Utils PHP + +## When to use + +- Installing dependencies or running the test suite locally +- Understanding what GitHub Actions run on push/PR +- Opening or reviewing a PR and matching branch expectations + +## Instructions + +### Local setup + +- From the repo root: `composer install` (use `composer install --ignore-platform-reqs` only if you must match CI’s relaxed install; see `.github/workflows/ci.yml`). +- Run tests: `composer test` (runs PHPUnit as defined in `composer.json`). + +### Lint + +- Check: `composer check-style` (PHPCS on `src` and `tests`). +- Autofix where supported: `composer fix-style` (PHPCBF). + +### CI + +- [`ci.yml`](../../.github/workflows/ci.yml): `composer validate`, cache + `composer install`, then `composer run-script test`. +- Lint is not currently enforced in that workflow; still run `check-style` before pushing. + +### Branch / PR policy + +- [`check-branch.yml`](../../.github/workflows/check-branch.yml): PRs **into `master`** must use branch **`next`** as the head branch (automation comments and fails otherwise). +- Prefer feature branches (not your fork’s default branch name as the only source) per [`CONTRIBUTING.md`](../../CONTRIBUTING.md). + +### Releases / versioning + +- Project follows SemVer per [`CONTRIBUTING.md`](../../CONTRIBUTING.md); public API changes belong in changelog/release notes as the maintainers require. + +## References + +- [`AGENTS.md`](../../AGENTS.md) +- [`testing/SKILL.md`](../testing/SKILL.md) +- [`php-style/SKILL.md`](../php-style/SKILL.md) diff --git a/skills/php-style/SKILL.md b/skills/php-style/SKILL.md new file mode 100644 index 0000000..cf4cf18 --- /dev/null +++ b/skills/php-style/SKILL.md @@ -0,0 +1,37 @@ +--- +name: php-style +description: Use when applying PSR-2, running PHPCS, or matching src/tests layout and strict_types in this repo. +--- + +# PHP style & layout – Contentstack Utils PHP + +## When to use + +- Fixing or avoiding PHPCS violations +- Adding new classes under `src/` or tests under `tests/` +- Aligning with existing `declare(strict_types=1);` usage + +## Instructions + +### Coding standard + +- **PHPCS** ruleset: [`phpcs.xml.dist`](../../phpcs.xml.dist) extends **PSR-2** (``). +- Check: `composer check-style`; fix: `composer fix-style` (both target `src` and `tests` per `composer.json` scripts). + +### File layout + +- **Source:** `src/` — namespaces mirror directories (e.g. `Contentstack\Utils\Model\Option` → `src/Model/Option.php`). +- **Tests:** `tests/` — namespace `Contentstack\Tests\Utils\` per `composer.json` `autoload-dev`. + +### PHP version + +- `composer.json` requires `php: >=7.2`; avoid language features that require newer versions unless the project explicitly raises the minimum. + +### Strict typing + +- New PHP files in `src/` should use `declare(strict_types=1);` consistently with existing classes. + +## References + +- [`dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) +- [PSR-2 coding style guide](https://www.php-fig.org/psr/psr-2/) diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 0000000..d041a38 --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,40 @@ +--- +name: testing +description: Use when writing PHPUnit tests, mocks under tests/Mock, or coverage/output under build/ for this package. +--- + +# Testing – Contentstack Utils PHP + +## When to use + +- Adding or updating unit tests for `Utils`, `GQL`, models, or helpers +- Extending mocks/fixtures under `tests/Mock` or `tests/Helpers` +- Interpreting PHPUnit config, coverage, or CI test runs + +## Instructions + +### Runner and config + +- **Command:** `composer test` → PHPUnit (`phpunit/phpunit` ^9.3). +- **Config:** [`phpunit.xml`](../../phpunit.xml) — bootstrap `vendor/autoload.php`, suite directory `tests/`, whitelist coverage on `src/`. + +### Layout + +- Test classes live directly under `tests/` (e.g. `UtilsTest.php`, `GQLTest.php`, `MetadataTest.php`) plus **`tests/Mock/`** (`JsonMock.php`, `EmbedObjectMock.php`, etc.) and **`tests/Helpers/`** (`Utility.php`). + +### Coverage and reports + +- `phpunit.xml` logs JUnit, coverage (HTML, text, Clover), and testdox output under **`build/`** (e.g. `build/coverage/`, `build/logs/`). Add `build/` to `.gitignore` if generating locally; do not commit generated artifacts unless the project asks for them. + +### Expectations for contributions + +- [`CONTRIBUTING.md`](../../CONTRIBUTING.md) requires tests for changes; new behavior should include PHPUnit coverage in the same PR where feasible. + +### Credentials + +- Tests use mocks and fixtures; do not add real API keys or stack secrets to the repo. + +## References + +- [`dev-workflow/SKILL.md`](../dev-workflow/SKILL.md) +- [`contentstack-utils/SKILL.md`](../contentstack-utils/SKILL.md) From da0e4759ab1c1eb3669d52780bad7a044abf6773 Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Wed, 8 Apr 2026 15:04:21 +0530 Subject: [PATCH 19/20] Update branch restriction messages in check-branch.yml to require pull requests from the development branch instead of the next branch. --- .github/workflows/check-branch.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-branch.yml b/.github/workflows/check-branch.yml index 1e2d24a..421c253 100644 --- a/.github/workflows/check-branch.yml +++ b/.github/workflows/check-branch.yml @@ -8,13 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Comment PR - if: github.base_ref == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && 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 next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch. + 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 == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && 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 next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch." + 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 From 9cdd7617594dcc580612d5bbed549e9916ae29a3 Mon Sep 17 00:00:00 2001 From: harshitha-cstk Date: Wed, 8 Apr 2026 15:05:32 +0530 Subject: [PATCH 20/20] Update copyright year in LICENSE.md to 2026 --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 1e02d05..d7e40d6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2016-2024 Contentstack +Copyright (c) 2016-2026 Contentstack > Permission is hereby granted, free of charge, to any person obtaining a copy > of this software and associated documentation files (the "Software"), to deal