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 5a6b9c8..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 == 'master' && github.head_ref != 'staging'
- 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.
- - name: Check branch
- if: github.base_ref == 'master' && github.head_ref != 'staging'
- 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."
- exit 1
diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml
new file mode 100644
index 0000000..73b871a
--- /dev/null
+++ b/.github/workflows/check-version-bump.yml
@@ -0,0 +1,87 @@
+# Runs only when production code under src/main/ changes. Version must be > latest v* tag
+# (not compared to the base branch, so rebases onto an already-bumped main still pass when tag requires a new release).
+
+name: Check Version Bump
+
+on:
+ pull_request:
+
+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="pom.xml"
+ 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_production_source_change() {
+ local f="$1"
+ [[ "$f" == src/main/* ]]
+ }
+
+ has_source_changes=false
+ for file in "${CHANGED_FILES[@]}"; do
+ if is_production_source_change "$file"; then
+ has_source_changes=true
+ break
+ fi
+ done
+
+ if [ "$has_source_changes" = false ]; then
+ echo "Skipping: no src/main/ production code changes."
+ 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; }
+
+ extract_version() {
+ python3 -c 'import sys,xml.etree.ElementTree as ET;r=ET.fromstring(sys.stdin.read());ns={"m":r.tag.split("}")[0].strip("{")} if r.tag.startswith("{") else None;n=(r.find("m:version",ns) if ns else r.find("version"));print((n.text or "").strip() if n is not None else "")'
+ }
+
+ head_version=$(extract_version < "$VERSION_FILE")
+ # Changelog uses "## Date" sections with versions on "#### vX.Y.Z" lines; support that and legacy "## vX.Y.Z".
+ CHANGELOG_HEAD=$(
+ sed -nE 's/^####[[:space:]]+v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' "$CHANGELOG_FILE" | head -1
+ )
+ if [ -z "$CHANGELOG_HEAD" ]; then
+ CHANGELOG_HEAD=$(sed -nE 's/^##[[:space:]]+v?([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' "$CHANGELOG_FILE" | head -1)
+ fi
+
+ [ -n "$CHANGELOG_HEAD" ] || { echo "::error::Could not find a version in $CHANGELOG_FILE (expected '#### vX.Y.Z' under a date section or legacy '## vX.Y.Z')."; exit 1; }
+ [ "$CHANGELOG_HEAD" = "$head_version" ] || { echo "::error::$CHANGELOG_FILE top release version ($CHANGELOG_HEAD) does not match project version ($head_version)."; exit 1; }
+
+ 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" "$latest_version")" = "true" ] || { echo "Version must be greater than latest tag version ($latest_version). Found $head_version."; exit 1; }
diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml
index e7e1b76..c2fec1e 100644
--- a/.github/workflows/maven-publish.yml
+++ b/.github/workflows/maven-publish.yml
@@ -4,12 +4,15 @@ on:
types: [created]
jobs:
publish-maven:
+ if: ${{ startsWith(github.event.release.tag_name, 'v') && !github.event.release.draft }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.release.tag_name }}
- name: Set up Maven Central Repository
uses: actions/setup-java@v3
with:
@@ -27,9 +30,12 @@ jobs:
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
publish-github:
+ if: ${{ startsWith(github.event.release.tag_name, 'v') && !github.event.release.draft }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.release.tag_name }}
- name: Set up Java for publishing to GitHub Packages
uses: actions/setup-java@v3
with:
@@ -37,7 +43,7 @@ jobs:
distribution: 'adopt'
server-id: github
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
- gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ gpg-passphrase: GPG_PASSPHRASE
- name: Set up Maven settings for Central and GitHub
run: |
mkdir -p $HOME/.m2
@@ -58,4 +64,4 @@ jobs:
- name: Publish to GitHub Packages
run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} deploy
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/AGENTS.md b/AGENTS.md
index 95bc73e..44e0d9e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -33,7 +33,7 @@
| Single test class | `mvn test -Dtest=UtilTests` |
| Javadoc | `mvn javadoc:javadoc` |
| Sample (after `mvn install` with skips if needed) | `mvn -f sample/pom.xml compile` |
-| **CI** | Java **17** publish: `.github/workflows/maven-publish.yml` · SCA: `.github/workflows/sca-scan.yml` · branch rules: `.github/workflows/check-branch.yml` |
+| **CI** | Java **17** publish: `.github/workflows/maven-publish.yml` (GitHub **Release** for tag `v*`, draft releases skipped) · SCA: `.github/workflows/sca-scan.yml` · back-merge automation: `.github/workflows/back-merge-pr.yml` |
## Where the documentation lives: skills
diff --git a/Changelog.md b/CHANGELOG.md
similarity index 85%
rename from Changelog.md
rename to CHANGELOG.md
index ae598d0..163bdc8 100644
--- a/Changelog.md
+++ b/CHANGELOG.md
@@ -1,12 +1,18 @@
-# Changelog
+# CHANGELOG
A brief description of what changes project contains
+## Apr 30, 2026
+
+#### v1.5.1
+
+- Fix: Upgraded `org.springframework:spring-web` to 7.0.7 to address Snyk-reported vulnerabilities in Spring Framework (including transitive `spring-core`)
+
## Apr 20, 2026
#### v1.5.0
-- Enhancement: Live Preview Editable tags
+- Enhancement: Live Preview Editable tags
## Mar 23, 2026
@@ -36,7 +42,7 @@ A brief description of what changes project contains
#### v1.2.11
-- Fix: ignore td/th in case of attrs has void:true
+- Fix: ignore td/th in case of attrs has void:true
## May 14, 2024
@@ -48,7 +54,7 @@ A brief description of what changes project contains
#### v1.2.9
-- Fixed vulnerability issue related to strAttrs and children.
+- Fixed vulnerability issue related to strAttrs and children.
## April 23, 2024
@@ -136,4 +142,3 @@ A brief description of what changes project contains
## Support
- For support, email fake@fake.com or join our Slack channel.
-
diff --git a/pom.xml b/pom.xml
index c643cf7..aead79d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0com.contentstack.sdkutils
- 1.5.0
+ 1.5.1jarContentstack-utilsJava Utils SDK for Contentstack Content Delivery API, Contentstack is a headless CMS
@@ -28,7 +28,7 @@
2.5.32.0.1.Final20251224
- 7.0.6
+ 7.0.71.15.0
@@ -212,8 +212,7 @@
17
- http://docs.oracle.com/javase/8/docs/api/
- http://docs.oracle.com/javase/8/docs/api/
+ https://docs.oracle.com/en/java/javase/17/docs/api/
none
diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md
index 8f3e938..806e4bd 100644
--- a/skills/code-review/SKILL.md
+++ b/skills/code-review/SKILL.md
@@ -16,7 +16,7 @@ description: PR checklist and optional Blocker/Major/Minor — use when reviewin
### API design and stability
- [ ] **Public API:** New or changed methods on `Utils`, `GQL`, `DefaultOption`, or `interfaces` are necessary, Javadoc’d, and safe for `com.contentstack.sdk:utils` consumers.
-- [ ] **Backward compatibility:** Breaking changes only with major version / **`Changelog.md`** plan.
+- [ ] **Backward compatibility:** Breaking changes only with major version / **`CHANGELOG.md`** plan.
- [ ] **Naming:** Consistent with existing Utils and RTE/embedded terminology.
### Error handling and robustness
diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md
index 3a988df..a44abd0 100644
--- a/skills/dev-workflow/SKILL.md
+++ b/skills/dev-workflow/SKILL.md
@@ -15,7 +15,7 @@ description: Branches, CI, build and test commands, PR expectations, optional TD
### Branches
-- Default integration for PRs is often **`staging`**; merging into **`master`** may be restricted (see `.github/workflows/check-branch.yml`).
+- Feature/fix PRs should target **`development`**. Release PRs are raised directly from **`development`** to **`master`**.
- Feature/fix branches often use ticket-style names (e.g. `fix/DX-5734`).
### Running tests and builds
@@ -28,7 +28,7 @@ description: Branches, CI, build and test commands, PR expectations, optional TD
### Pull requests
- Describe the change; link issues/tickets when applicable.
-- Keep public API backward-compatible unless releasing a breaking version; update **`Changelog.md`** for user-visible behavior.
+- Keep public API backward-compatible unless releasing a breaking version; update **`CHANGELOG.md`** for user-visible behavior.
- Use **`skills/code-review/SKILL.md`** as the review checklist.
### Optional: TDD