Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .cursor/rules/README.md
Original file line number Diff line number Diff line change
@@ -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.
59 changes: 59 additions & 0 deletions .github/workflows/back-merge-pr.yml
Original file line number Diff line number Diff line change
@@ -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."
20 changes: 0 additions & 20 deletions .github/workflows/check-branch.yml

This file was deleted.

111 changes: 111 additions & 0 deletions .github/workflows/check-version-bump.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Release-affecting changes under src/main/ or pom.xml require pom.xml + changelog.md bumps
# aligned with the latest tag. Skips when only tests, .github, skills, or docs change.

name: Check Version Bump

on:
pull_request:

jobs:
version-bump:
name: Version & changelog bump
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Detect changed files
id: detect
run: |
FILES=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}")
echo "Changed files:"
echo "$FILES"

CODE_CHANGED=false
while IFS= read -r f; do
[ -z "$f" ] && continue
if [[ "$f" == src/main/* ]] || [[ "$f" == "pom.xml" ]]; then
CODE_CHANGED=true
break
fi
done <<< "$FILES"

POM_CHANGED=false
CHANGELOG_CHANGED=false
echo "$FILES" | grep -qx 'pom.xml' && POM_CHANGED=true
echo "$FILES" | grep -qx 'changelog.md' && CHANGELOG_CHANGED=true

VERSION_FILES_OK=false
if [ "$POM_CHANGED" = true ] && [ "$CHANGELOG_CHANGED" = true ]; then
VERSION_FILES_OK=true
fi

echo "code_changed=$CODE_CHANGED" >> "$GITHUB_OUTPUT"
echo "version_files_ok=$VERSION_FILES_OK" >> "$GITHUB_OUTPUT"

- name: Skip when no release-affecting code changed
if: steps.detect.outputs.code_changed != 'true'
run: |
echo "No src/main or pom-only release path triggered (e.g. tests/docs/.github only). Skipping version-bump check."
exit 0

- name: Fail when version bump files were not both updated
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok != 'true'
run: |
echo "::error::This PR changes release-affecting code but pom.xml and/or changelog.md were not both updated. Bump <version> in pom.xml and add a ## vX.Y.Z section in changelog.md."
exit 1

- name: Validate version vs latest tag and changelog header
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok == 'true'
run: |
set -euo pipefail
POM_VERSION=$(python3 <<'PY'
import xml.etree.ElementTree as ET
root = ET.parse("pom.xml").getroot()
ns = {"m": "http://maven.apache.org/POM/4.0.0"}
el = root.find("m:version", ns)
if el is None or not (el.text or "").strip():
raise SystemExit("Could not read project version from pom.xml")
print(el.text.strip())
PY
)

git fetch --tags --force 2>/dev/null || true
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
if [ -z "$LATEST_TAG" ]; then
echo "No existing tags found. Skipping semver vs tag check (first release)."
CHANGELOG_HEAD=$(sed -nE 's/^## v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' changelog.md | head -1)
if [ -z "$CHANGELOG_HEAD" ]; then
echo "::error::Could not find a ## vX.Y.Z entry at the top of changelog.md."
exit 1
fi
if [ "$CHANGELOG_HEAD" != "$POM_VERSION" ]; then
echo "::error::changelog.md top version ($CHANGELOG_HEAD) does not match pom.xml version ($POM_VERSION)."
exit 1
fi
exit 0
fi

LATEST_VERSION="${LATEST_TAG#v}"
LATEST_VERSION="${LATEST_VERSION%%-*}"
if [ "$(printf '%s\n' "$LATEST_VERSION" "$POM_VERSION" | sort -V | tail -1)" != "$POM_VERSION" ]; then
echo "::error::pom.xml version ($POM_VERSION) must be greater than latest tag ($LATEST_TAG)."
exit 1
fi
if [ "$POM_VERSION" = "$LATEST_VERSION" ]; then
echo "::error::pom.xml version ($POM_VERSION) must be strictly greater than latest tag version ($LATEST_VERSION)."
exit 1
fi

CHANGELOG_HEAD=$(sed -nE 's/^## v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' changelog.md | head -1)
if [ -z "$CHANGELOG_HEAD" ]; then
echo "::error::Could not find a ## vX.Y.Z entry at the top of changelog.md."
exit 1
fi
if [ "$CHANGELOG_HEAD" != "$POM_VERSION" ]; then
echo "::error::changelog.md top version ($CHANGELOG_HEAD) does not match pom.xml version ($POM_VERSION)."
exit 1
fi
echo "Version bump check passed: pom.xml and changelog.md at $POM_VERSION (latest tag: $LATEST_TAG)."
2 changes: 2 additions & 0 deletions .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
name: Publish package to the Maven Central Repository

# Publishes when a GitHub Release is created (same pattern as before tag-based experiments).
on:
release:
types:
- created

jobs:
publish-maven:
runs-on: ubuntu-latest
Expand Down
51 changes: 51 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Contentstack Management Java SDK – 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-management-java](https://github.com/contentstack/contentstack-management-java) |
| *Purpose:* | Java client library for the Contentstack Content Management API (CMA): create, update, delete, and fetch account content and configuration from JVM applications. |
| *Out of scope (if any):* | Content Delivery API (CDA) and delivery-only use cases belong in the Delivery SDK, not this package. This SDK is read/write against CMA; do not treat it as the primary way to serve content to end users. |

## Tech stack (at a glance)

| Area | Details |
| --- | --- |
| Language | Java 8 (source/target in `pom.xml`); README suggests Java 8+ for consumers. |
| Build | Apache Maven; `pom.xml` at repo root. |
| Tests | JUnit 5 / Vintage, Mockito, OkHttp MockWebServer; tests under `src/test/java/com/contentstack/cms/`. |
| Lint / coverage | Compiler: `-Xlint:all` (see `maven-compiler-plugin`). Coverage: JaCoCo (`jacoco-maven-plugin`); HTML report under `target/site/jacoco` after tests + `jacoco:report`. No separate Checkstyle/SpotBugs in this `pom.xml`. |
| Other | HTTP: Retrofit 3, OkHttp 5, Gson; RxJava 3; Lombok for generated code. |

## Commands (quick reference)

| Command type | Command |
| --- | --- |
| Build | `mvn clean compile` |
| Test | `mvn clean test -DskipTests=false` |
| Lint | `mvn compile` (compiler warnings; see Tech stack) |
| Coverage | `mvn clean test -DskipTests=false jacoco:report` (open `target/site/jacoco/index.html`) |

**Note:** `maven-surefire-plugin` sets `skipTests` to `true` by default in this repo, so you must pass `-DskipTests=false` (or override in your IDE) to run unit tests locally.

**CI:** [.github/workflows/coverage.yml](.github/workflows/coverage.yml) runs `mvn clean package` and JaCoCo steps on push. Other workflows under [.github/workflows/](.github/workflows/) handle publish, scans, and branch checks.

## Where the documentation lives: skills

| Skill | Path | What it covers |
| --- | --- | --- |
| Dev workflow | [skills/dev-workflow/SKILL.md](skills/dev-workflow/SKILL.md) | Branches, Maven lifecycle, CI expectations, PR flow. |
| Contentstack Java CMA SDK | [skills/contentstack-java-cma-sdk/SKILL.md](skills/contentstack-java-cma-sdk/SKILL.md) | Public API, `Contentstack` entry point, auth, versioning boundaries. |
| Java (repo conventions) | [skills/java/SKILL.md](skills/java/SKILL.md) | Package layout, language conventions, Lombok usage. |
| Testing | [skills/testing/SKILL.md](skills/testing/SKILL.md) | Test layout, naming, skipping policy, credentials. |
| Code review | [skills/code-review/SKILL.md](skills/code-review/SKILL.md) | PR checklist and severity guidance. |
| HTTP client stack | [skills/http-client-stack/SKILL.md](skills/http-client-stack/SKILL.md) | Retrofit, OkHttp, retries, logging—what this repo actually wires. |

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.
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## v1.11.2

### Jun 01, 2026

- Fix: `SocketTimeoutException` now correctly triggers the retry mechanism in `AuthInterceptor` and `OAuthInterceptor`. Previously, network-level timeouts bypassed retry logic entirely, causing `.setRetry(true)` to have no effect on timeout errors.
- Enhancement: Added `setProtocols(List<Protocol>)` to the Builder, allowing callers to restrict the HTTP protocol (e.g. force HTTP/1.1 via `Collections.singletonList(Protocol.HTTP_1_1)`) for environments where proxies or intermediaries have issues with HTTP/2.

## v1.11.1

### Apr 06, 2026
Expand Down
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<artifactId>cms</artifactId>
<packaging>jar</packaging>
<name>contentstack-management-java</name>
<version>1.11.1</version>
<version>1.11.2</version>
<description>Contentstack Java Management SDK for Content Management API, Contentstack is a headless CMS with an
API-first approach
</description>
Expand Down Expand Up @@ -93,7 +93,7 @@
<converter-gson-version>3.0.0</converter-gson-version>
<okhttp.version>5.3.2</okhttp.version>
<jococo-plugin.version>0.8.13</jococo-plugin.version>
<lombok-source.version>1.18.42</lombok-source.version>
<lombok-source.version>1.18.44</lombok-source.version>
<junit-jupiter.version>5.11.4</junit-jupiter.version>
<junit-jupiter-engine.version>5.10.1</junit-jupiter-engine.version>
<gson.version>2.13.2</gson.version>
Expand Down Expand Up @@ -148,7 +148,7 @@
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>26.0.2</version>
<version>26.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -214,12 +214,12 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.21.2</version>
<version>1.22.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>2.2.21</version>
<version>2.3.20</version>
</dependency>
<dependency>
<groupId>com.warrenstrange</groupId>
Expand Down Expand Up @@ -254,7 +254,7 @@
</includes>
<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
<!-- Skip during default lifecycle (e.g. publish); run tests locally with: mvn test -DskipTests=false -->
<skipTests>true</skipTests>
<!-- <skipTests>true</skipTests> -->
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
Expand Down
16 changes: 16 additions & 0 deletions skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Skills – Contentstack Management Java SDK

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) | Branching (`development` → `master`, back-merge, GitHub Release publish), Maven/CI, publish touchpoints. |
| [contentstack-java-cma-sdk](contentstack-java-cma-sdk/SKILL.md) | Changing public API, `Contentstack` / `Stack` flows, auth tokens, or SDK surface exposed to integrators. |
| [java](java/SKILL.md) | Package structure under `com.contentstack.cms`, Java 8 compatibility, Lombok, imports, and code style in this repo. |
| [testing](testing/SKILL.md) | Adding or fixing tests, Surefire `skipTests` behavior, MockWebServer or live API tests, env/credentials. |
| [code-review](code-review/SKILL.md) | Preparing or reviewing a PR: scope, tests, API compatibility, and security around tokens. |
| [http-client-stack](http-client-stack/SKILL.md) | Retrofit services, OkHttp client/interceptors, retries, proxies, or HTTP logging. |

Each folder contains `SKILL.md` with YAML frontmatter (`name`, `description`).
42 changes: 42 additions & 0 deletions skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: code-review
description: Use when reviewing or preparing a PR—API safety, tests, auth handling, and compatibility checklist.
---

# Code review – Contentstack Management Java SDK

## When to use

- You are reviewing a pull request or self-reviewing before request.
- You need a quick severity rubric (blocker / major / minor) aligned with this SDK.

## Instructions

### Blocker

- Real credentials, tokens, or stack keys committed in source or fixtures.
- Breaking public API changes without version strategy or without team agreement.
- New network behavior that bypasses existing interceptors, retry policy, or auth without explicit design.

### Major

- Missing or insufficient tests for new CMA behavior or error paths.
- Behavior change for `Contentstack` / `Stack` builders or defaults without README or Javadoc updates where integrators would notice.
- Regressions for Java 8 compatibility or new compiler warnings left unaddressed.

### Minor

- Style inconsistencies fixable in follow-up, or internal refactors with no API impact.
- Javadoc typos or non-user-facing comment cleanup.

### PR checklist (short)

- [ ] `mvn clean test -DskipTests=false` passes locally.
- [ ] Public changes documented (Javadoc / README / changelog per team process).
- [ ] No secrets in repo; test config uses env or mocks.
- [ ] HTTP changes reviewed against [http-client-stack/SKILL.md](../http-client-stack/SKILL.md).

## References

- [dev-workflow/SKILL.md](../dev-workflow/SKILL.md)
- [contentstack-java-cma-sdk/SKILL.md](../contentstack-java-cma-sdk/SKILL.md)
Loading
Loading