Skip to content

Commit aab2483

Browse files
Merge remote-tracking branch 'origin/development' into fix/environment-tests-and-security-cleanup
# Conflicts: # src/test/java/com/contentstack/cms/TestClient.java # src/test/java/com/contentstack/cms/api/oauth/OAuthInterceptorTest.java # src/test/java/com/contentstack/cms/stack/APISanityTestSuite.java # src/test/java/com/contentstack/cms/stack/AssetAPITest.java
2 parents abff1de + 5f6b898 commit aab2483

46 files changed

Lines changed: 3699 additions & 207 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.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 *[AGENTS.md](../../AGENTS.md)*. All conventions live in **skills/*/SKILL.md**.
4+
5+
This folder only points contributors to *AGENTS.md* so editor-specific config does not duplicate the canonical docs.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Opens a PR from master → development after changes land on master (back-merge).
2+
#
3+
# Org/repo Settings → Actions → General → Workflow permissions: read and write
4+
# (so GITHUB_TOKEN can create pull requests). Or use a PAT in secret GH_TOKEN.
5+
6+
name: Back-merge master to development
7+
8+
on:
9+
push:
10+
branches: [master]
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
pull-requests: write
16+
17+
jobs:
18+
open-back-merge-pr:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 0
25+
26+
- name: Open back-merge PR if needed
27+
env:
28+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
run: |
30+
set -euo pipefail
31+
git fetch origin development master
32+
33+
MASTER_SHA=$(git rev-parse origin/master)
34+
DEV_SHA=$(git rev-parse origin/development)
35+
36+
if [ "$MASTER_SHA" = "$DEV_SHA" ]; then
37+
echo "master and development are at the same commit; nothing to back-merge."
38+
exit 0
39+
fi
40+
41+
EXISTING=$(gh pr list --repo "${{ github.repository }}" \
42+
--base development \
43+
--head master \
44+
--state open \
45+
--json number \
46+
--jq 'length')
47+
48+
if [ "$EXISTING" -gt 0 ]; then
49+
echo "An open PR from master to development already exists; skipping."
50+
exit 0
51+
fi
52+
53+
gh pr create --repo "${{ github.repository }}" \
54+
--base development \
55+
--head master \
56+
--title "chore: back-merge master into development" \
57+
--body "Automated back-merge after changes landed on \`master\`. Review and merge to keep \`development\` in sync."
58+
59+
echo "Created back-merge PR master → development."

.github/workflows/check-branch.yml

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Release-affecting changes under src/main/ or pom.xml require pom.xml + changelog.md bumps
2+
# aligned with the latest tag. Skips when only tests, .github, skills, or docs change.
3+
4+
name: Check Version Bump
5+
6+
on:
7+
pull_request:
8+
9+
jobs:
10+
version-bump:
11+
name: Version & changelog 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
20+
id: detect
21+
run: |
22+
FILES=$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}")
23+
echo "Changed files:"
24+
echo "$FILES"
25+
26+
CODE_CHANGED=false
27+
while IFS= read -r f; do
28+
[ -z "$f" ] && continue
29+
if [[ "$f" == src/main/* ]] || [[ "$f" == "pom.xml" ]]; then
30+
CODE_CHANGED=true
31+
break
32+
fi
33+
done <<< "$FILES"
34+
35+
POM_CHANGED=false
36+
CHANGELOG_CHANGED=false
37+
echo "$FILES" | grep -qx 'pom.xml' && POM_CHANGED=true
38+
echo "$FILES" | grep -qx 'changelog.md' && CHANGELOG_CHANGED=true
39+
40+
VERSION_FILES_OK=false
41+
if [ "$POM_CHANGED" = true ] && [ "$CHANGELOG_CHANGED" = true ]; then
42+
VERSION_FILES_OK=true
43+
fi
44+
45+
echo "code_changed=$CODE_CHANGED" >> "$GITHUB_OUTPUT"
46+
echo "version_files_ok=$VERSION_FILES_OK" >> "$GITHUB_OUTPUT"
47+
48+
- name: Skip when no release-affecting code changed
49+
if: steps.detect.outputs.code_changed != 'true'
50+
run: |
51+
echo "No src/main or pom-only release path triggered (e.g. tests/docs/.github only). Skipping version-bump check."
52+
exit 0
53+
54+
- name: Fail when version bump files were not both updated
55+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok != 'true'
56+
run: |
57+
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."
58+
exit 1
59+
60+
- name: Validate version vs latest tag and changelog header
61+
if: steps.detect.outputs.code_changed == 'true' && steps.detect.outputs.version_files_ok == 'true'
62+
run: |
63+
set -euo pipefail
64+
POM_VERSION=$(python3 <<'PY'
65+
import xml.etree.ElementTree as ET
66+
root = ET.parse("pom.xml").getroot()
67+
ns = {"m": "http://maven.apache.org/POM/4.0.0"}
68+
el = root.find("m:version", ns)
69+
if el is None or not (el.text or "").strip():
70+
raise SystemExit("Could not read project version from pom.xml")
71+
print(el.text.strip())
72+
PY
73+
)
74+
75+
git fetch --tags --force 2>/dev/null || true
76+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true)
77+
if [ -z "$LATEST_TAG" ]; then
78+
echo "No existing tags found. Skipping semver vs tag check (first release)."
79+
CHANGELOG_HEAD=$(sed -nE 's/^## v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' changelog.md | head -1)
80+
if [ -z "$CHANGELOG_HEAD" ]; then
81+
echo "::error::Could not find a ## vX.Y.Z entry at the top of changelog.md."
82+
exit 1
83+
fi
84+
if [ "$CHANGELOG_HEAD" != "$POM_VERSION" ]; then
85+
echo "::error::changelog.md top version ($CHANGELOG_HEAD) does not match pom.xml version ($POM_VERSION)."
86+
exit 1
87+
fi
88+
exit 0
89+
fi
90+
91+
LATEST_VERSION="${LATEST_TAG#v}"
92+
LATEST_VERSION="${LATEST_VERSION%%-*}"
93+
if [ "$(printf '%s\n' "$LATEST_VERSION" "$POM_VERSION" | sort -V | tail -1)" != "$POM_VERSION" ]; then
94+
echo "::error::pom.xml version ($POM_VERSION) must be greater than latest tag ($LATEST_TAG)."
95+
exit 1
96+
fi
97+
if [ "$POM_VERSION" = "$LATEST_VERSION" ]; then
98+
echo "::error::pom.xml version ($POM_VERSION) must be strictly greater than latest tag version ($LATEST_VERSION)."
99+
exit 1
100+
fi
101+
102+
CHANGELOG_HEAD=$(sed -nE 's/^## v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' changelog.md | head -1)
103+
if [ -z "$CHANGELOG_HEAD" ]; then
104+
echo "::error::Could not find a ## vX.Y.Z entry at the top of changelog.md."
105+
exit 1
106+
fi
107+
if [ "$CHANGELOG_HEAD" != "$POM_VERSION" ]; then
108+
echo "::error::changelog.md top version ($CHANGELOG_HEAD) does not match pom.xml version ($POM_VERSION)."
109+
exit 1
110+
fi
111+
echo "Version bump check passed: pom.xml and changelog.md at $POM_VERSION (latest tag: $LATEST_TAG)."

.github/workflows/issues-jira.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.

.github/workflows/maven-publish.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
name: Publish package to the Maven Central Repository
22

3+
# Publishes when a GitHub Release is created (same pattern as before tag-based experiments).
34
on:
45
release:
56
types:
67
- created
8+
79
jobs:
810
publish-maven:
911
runs-on: ubuntu-latest

.github/workflows/sca-scan.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ jobs:
1313
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
1414
with:
1515
args: --fail-on=all
16+
json: true
17+
continue-on-error: true
18+
- uses: contentstack/sca-policy@main

AGENTS.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Contentstack Management Java SDK – Agent guide
2+
3+
*Universal entry point* for contributors and AI agents. Detailed conventions live in **skills/*/SKILL.md**.
4+
5+
## What this repo is
6+
7+
| Field | Detail |
8+
| --- | --- |
9+
| *Name:* | [contentstack-management-java](https://github.com/contentstack/contentstack-management-java) |
10+
| *Purpose:* | Java client library for the Contentstack Content Management API (CMA): create, update, delete, and fetch account content and configuration from JVM applications. |
11+
| *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. |
12+
13+
## Tech stack (at a glance)
14+
15+
| Area | Details |
16+
| --- | --- |
17+
| Language | Java 8 (source/target in `pom.xml`); README suggests Java 8+ for consumers. |
18+
| Build | Apache Maven; `pom.xml` at repo root. |
19+
| Tests | JUnit 5 / Vintage, Mockito, OkHttp MockWebServer; tests under `src/test/java/com/contentstack/cms/`. |
20+
| 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`. |
21+
| Other | HTTP: Retrofit 3, OkHttp 5, Gson; RxJava 3; Lombok for generated code. |
22+
23+
## Commands (quick reference)
24+
25+
| Command type | Command |
26+
| --- | --- |
27+
| Build | `mvn clean compile` |
28+
| Test | `mvn clean test -DskipTests=false` |
29+
| Lint | `mvn compile` (compiler warnings; see Tech stack) |
30+
| Coverage | `mvn clean test -DskipTests=false jacoco:report` (open `target/site/jacoco/index.html`) |
31+
32+
**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.
33+
34+
**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.
35+
36+
## Where the documentation lives: skills
37+
38+
| Skill | Path | What it covers |
39+
| --- | --- | --- |
40+
| Dev workflow | [skills/dev-workflow/SKILL.md](skills/dev-workflow/SKILL.md) | Branches, Maven lifecycle, CI expectations, PR flow. |
41+
| 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. |
42+
| Java (repo conventions) | [skills/java/SKILL.md](skills/java/SKILL.md) | Package layout, language conventions, Lombok usage. |
43+
| Testing | [skills/testing/SKILL.md](skills/testing/SKILL.md) | Test layout, naming, skipping policy, credentials. |
44+
| Code review | [skills/code-review/SKILL.md](skills/code-review/SKILL.md) | PR checklist and severity guidance. |
45+
| HTTP client stack | [skills/http-client-stack/SKILL.md](skills/http-client-stack/SKILL.md) | Retrofit, OkHttp, retries, logging—what this repo actually wires. |
46+
47+
An index with “when to use” hints is in [skills/README.md](skills/README.md).
48+
49+
## Using Cursor (optional)
50+
51+
If you use *Cursor*, [.cursor/rules/README.md](.cursor/rules/README.md) only points to *AGENTS.md*—same docs as everyone else.

changelog.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,43 @@
11
# Changelog
22

3+
## v1.12.2
4+
5+
### Jul 06, 2026
6+
7+
- Snyk fix
8+
9+
## v1.12.1
10+
11+
### Jun 29, 2026
12+
13+
- Snyk fix
14+
15+
## v1.12.0
16+
17+
### Jun 15, 2026
18+
19+
- Feature: Dynamic endpoint resolution via `Endpoint.getContentstackEndpoint()` and `Builder.setRegion()` backed by the Contentstack Regions Registry.
20+
21+
## v1.11.2
22+
23+
### Jun 01, 2026
24+
25+
- 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.
26+
- 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.
27+
28+
## v1.11.1
29+
30+
### Apr 06, 2026
31+
32+
- Fix: `setTimeout` now applies to OkHttp connect, read, and write timeouts (previously only connect). Optional `setConnectTimeout`, `setReadTimeout`, and `setWriteTimeout` override individual phases.
33+
- Build: Maven Surefire updated with `surefire-junit-platform` so JUnit 5 tests run when enabled.
34+
35+
## v1.11.0
36+
37+
### Feb 09, 2026
38+
39+
- Enhancement: Retry Mechanism
40+
341
## v1.10.2
442

543
### Jan 27, 2026

0 commit comments

Comments
 (0)