Skip to content

DX | 19-05-2025 | Release #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
db1b5d9
Merge pull request #180 from contentstack/staging
reeshika-h Mar 25, 2025
cc69601
Merge pull request #181 from contentstack/master
reeshika-h Apr 1, 2025
bb9315e
Merge pull request #182 from contentstack/staging
harshithad0703 Apr 1, 2025
236a058
Refactor assertions in tests to use assertNotNull for improved valida…
reeshika-h Apr 23, 2025
4ff32c9
Uncomment skipTests configuration in maven-surefire-plugin for test e…
reeshika-h Apr 23, 2025
cb5ce37
Merge branch 'master' into fix/dx-2373-skips-single-item
harshithad0703 Apr 24, 2025
8beaa58
Fix item processing in SyncStack to handle JSONObject correctly and p…
harshithad0703 Apr 24, 2025
9d39ac5
Add test for handling single JSONObject under "items" in SyncStack
harshithad0703 Apr 24, 2025
c62265f
Merge pull request #185 from contentstack/fix/dx-2373-skips-single-item
harshithad0703 Apr 24, 2025
eed871f
Add Slack reporting functionality and update dependencies
reeshika-h Apr 30, 2025
10f0bd2
Enhance tests by adding assertions for entry parameters and headers; …
reeshika-h May 5, 2025
6567ff4
Add SLF4J dependency and update JavaDoc links; comment out disabled t…
reeshika-h May 5, 2025
1435a5d
Update assertions in tests to reflect expected header and entry counts
reeshika-h May 5, 2025
9448814
Remove header size assertions from entry and query tests
reeshika-h May 6, 2025
82e75af
Merge pull request #184 from contentstack/fix/DX-2420-pipeline-friendly
reeshika-h May 6, 2025
527f953
Update version to 2.1.1 and updated changelog
reeshika-h May 15, 2025
7eb50ed
Merge pull request #187 from contentstack/version-bump
reeshika-h May 15, 2025
0299754
Merge pull request #186 from contentstack/development
reeshika-h May 15, 2025
11199c8
Merge pull request #189 from contentstack/master
harshithad0703 May 15, 2025
02a355d
Update branch restrictions in PR workflow and add Talisman configuration
harshithad0703 May 16, 2025
5d12b4a
Merge pull request #190 from contentstack/fix/talismanrc-update
reeshika-h May 16, 2025
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
8 changes: 4 additions & 4 deletions .github/workflows/check-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 != '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.
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 staging 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 != '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."
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 staging branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch."
exit 1
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ local.properties
.settings/
.loadpath
.recommenders
# Ignore test configuration
test-config.properties

# External tool builders
.externalToolBuilders/
Expand Down
4 changes: 4 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
threshold: medium
fileignoreconfig:
- filename: .github/workflows/secrets-scan.yml
checksum: d79ec3f3288964f7d117b9ad319a54c0ebc152e35f69be8fde95522034fdfb2a
version: "1.0"
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CHANGELOG

## v2.1.1

### Date: 1-Apr-2025

- Github Issue fix
- Sanity test Integration

## v2.1.0

### Date: 1-Apr-2025
Expand Down
40 changes: 26 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.contentstack.sdk</groupId>
<artifactId>java</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
<packaging>jar</packaging>
<name>contentstack-java</name>
<description>Java SDK for Contentstack Content Delivery API</description>
Expand All @@ -22,7 +22,7 @@
<dotenv-source.version>3.0.0</dotenv-source.version>
<rxjava-source.version>3.1.10</rxjava-source.version>
<retrofit-source.version>2.11.0</retrofit-source.version>
<loggin.version>5.0.0-alpha.11</loggin.version>
<loggin.version>4.12.0</loggin.version>
<jococo-plugin.version>0.8.5</jococo-plugin.version>
<lombok-source.version>1.18.36</lombok-source.version>
<junit-jupiter.version>5.11.4</junit-jupiter.version>
Expand All @@ -34,7 +34,7 @@
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
<json-version>20250107</json-version>
<jacoco-maven-plugin-version>0.8.7</jacoco-maven-plugin-version>
<jacoco-maven-plugin-version>0.8.11</jacoco-maven-plugin-version>
<maven-release-plugin-version>2.5.3</maven-release-plugin-version>
<contentstack-utils-version>1.2.15</contentstack-utils-version>
</properties>
Expand Down Expand Up @@ -122,14 +122,6 @@
<scope>compile</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/io.github.cdimascio/java-dotenv -->
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>java-dotenv</artifactId>
<version>5.2.2</version>
</dependency>


<dependency>
<groupId>io.reactivex.rxjava3</groupId>
<artifactId>rxjava</artifactId>
Expand Down Expand Up @@ -189,6 +181,27 @@
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<dependency>
<groupId>com.slack.api</groupId>
<artifactId>bolt</artifactId>
<version>1.44.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -237,8 +250,7 @@
<use>false</use>
<source>1.8</source>
<links>
<link>https://docs.oracle.com/javase/7/docs/api/</link>
<link>https://docs.oracle.com/javase/7/docs/api/</link>
<link>https://docs.oracle.com/en/java/javase/23/docs/api/index.html</link>
</links>
<doclint>none</doclint>
</configuration>
Expand All @@ -251,7 +263,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests>
<!-- <skipTests>true</skipTests> -->
</configuration>
</plugin>

Expand Down
14 changes: 14 additions & 0 deletions send-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -e # Exit immediately if any command fails

echo "🧪 Running tests..."
mvn clean test

echo "📄 Generating Surefire HTML report..."
mvn surefire-report:report-only

echo "📤 Sending test report to Slack..."
mvn compile exec:java -Dexec.mainClass="com.contentstack.sdk.SanityReport"

echo "✅ Done."
2 changes: 1 addition & 1 deletion src/main/java/com/contentstack/sdk/CSHttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ private String getParams(HashMap<String, Object> params) {
urlParams += urlParams.equals("?") ? key + "=" + value : "&" + key + "=" + value;
}
} catch (Exception e1) {
e1.printStackTrace();
logger.log(Level.SEVERE, e1.getLocalizedMessage(), e1);
}
}
return urlParams;
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/com/contentstack/sdk/Entry.java
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ private void setIncludeJSON(JSONObject mainJson, ResultCallBack callBack) {

private void throwException(@Nullable String errorMsg, Exception e, EntryResultCallBack callBack) {
Error error = new Error();
if (errorMsg != null) {
if (!errorMsg.isEmpty()) {
error.setErrorMessage(errorMsg);
} else {
error.setErrorMessage(e.toString());
Expand Down Expand Up @@ -1124,11 +1124,9 @@ public Entry includeMetadata() {
}

/**
* @method variants
* @memberof Entry
* @description The variant header will be added to client
* @returns {Entry}
* @example
* The variant header will be added to client
* @return {Entry}
*
* import contentstack from '@contentstack/delivery-sdk'
*
* Stack stack = contentstack.Stack("apiKey", "deliveryToken",
Expand Down
149 changes: 149 additions & 0 deletions src/main/java/com/contentstack/sdk/SanityReport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package com.contentstack.sdk;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.slack.api.bolt.App;
import com.slack.api.methods.SlackApiException;
import com.slack.api.methods.response.chat.ChatPostMessageResponse;
import com.slack.api.methods.response.files.FilesUploadV2Response;

public class SanityReport {

private static final String PROPERTIES_FILE = "src/test/resources/test-config.properties";

public void generateTestSummaryAndSendToSlack(File reportFile) throws IOException, SlackApiException {
Properties properties = loadProperties(PROPERTIES_FILE);

String slackToken = properties.getProperty("SLACK_BOT_TOKEN");
String slackChannelID = properties.getProperty("SLACK_CHANNEL_ID");
String signingSecret = properties.getProperty("SLACK_SIGNING_SECRET");
String slackChannel = properties.getProperty("SLACK_CHANNEL");

if (slackToken == null || slackChannelID == null) {
System.err.println("Missing Slack credentials in properties.");
return;
}

if (!reportFile.exists()) {
System.err.println("Surefire report file not found at: " + reportFile.getAbsolutePath());
return;
}

String message = generateTestSummary(reportFile);
App app = configureSlackApp(slackToken, signingSecret);

sendMessageToSlack(app, slackChannel, message);
uploadReportToSlack(app, slackChannelID, reportFile);
}

private Properties loadProperties(String filePath) {
Properties properties = new Properties();
try (FileInputStream inputStream = new FileInputStream(filePath)) {
properties.load(inputStream);
} catch (IOException e) {
System.err.println("Failed to load properties: " + e.getMessage());
}
return properties;
}

private App configureSlackApp(String token, String secret) {
App app = new App();
app.config().setSigningSecret(secret);
app.config().setSingleTeamBotToken(token);
return app;
}

private void sendMessageToSlack(App app, String channel, String message) throws IOException, SlackApiException {
ChatPostMessageResponse response = app.client().chatPostMessage(r -> r
.channel(channel)
.text(message)
);
if (response.isOk()) {
System.out.println("Message sent successfully!");
} else {
System.err.println("Failed to send message: " + response.getError());
}
}

private void uploadReportToSlack(App app, String channelID, File file) throws IOException, SlackApiException {
FilesUploadV2Response response = app.client().filesUploadV2(fuvr -> fuvr
.channel(channelID)
.initialComment("Here is the report generated")
.filename(file.getName())
.file(file)
);
if (response.isOk()) {
System.out.println("Report uploaded successfully!");
} else {
System.err.println("Failed to upload report: " + response.getError());
}

}

private String generateTestSummary(File surefireReportFile) throws IOException {
Document doc = Jsoup.parse(surefireReportFile, "UTF-8");
Elements summaryRows = doc.select("table.table tr.b");
Element summaryRow = summaryRows.first();

int totalTests = 0, errors = 0, failures = 0, skipped = 0, passedTests, totalSuites, failedSuites = 0;
String duration = "0m 0s";

if (summaryRow != null) {
Elements cells = summaryRow.select("td");
if (cells.size() >= 6) {
totalTests = Integer.parseInt(cells.get(0).text());
errors = Integer.parseInt(cells.get(1).text());
failures = Integer.parseInt(cells.get(2).text());
skipped = Integer.parseInt(cells.get(3).text());

String timeText = cells.get(5).text();
if (timeText.contains("s")) {
double seconds = Double.parseDouble(timeText.replace(" s", ""));
duration = (int) seconds / 60 + "m " + (int) seconds % 60 + "s";
}
}
}

Elements testSuiteRows = doc.select("table:contains(Class) tr");
totalSuites = testSuiteRows.size() - 1;

for (Element row : testSuiteRows) {
Elements errorCells = row.select("td:nth-child(4)");
Elements failureCells = row.select("td:nth-child(5)");
if (!errorCells.isEmpty() && !failureCells.isEmpty()) {
try {
if (Integer.parseInt(errorCells.text()) > 0 || Integer.parseInt(failureCells.text()) > 0) {
failedSuites++;
}
} catch (NumberFormatException ignored) {
}
}
}

passedTests = totalTests - failures - errors - skipped;

return "*Java CDA Test Report*\n"
+ "• Total Suites: " + totalSuites + "\n"
+ "• Total Tests: " + totalTests + "\n"
+ "• Passed Tests: " + passedTests + "\n"
+ "• Failed Suites: " + failedSuites + "\n"
+ "• Failed Tests: " + failures + "\n"
+ "• Skipped Tests: " + skipped + "\n"
+ "• Duration: " + duration;
}

public static void main(String[] args) {
File reportFile = new File("target/reports/surefire.html");
try {
new SanityReport().generateTestSummaryAndSendToSlack(reportFile);
} catch (IOException | SlackApiException e) {
System.err.println("Error: " + e.getMessage());
}
}

}
2 changes: 1 addition & 1 deletion src/main/java/com/contentstack/sdk/Stack.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void includeLivePreview() {
if (config.enableLivePreview) {
String urlLivePreview = config.livePreviewHost;
if(config.region != null && !config.region.name().isEmpty()){
if(config.region.name() == "US" ){
if(config.region.name().equals("US") ){
config.livePreviewHost = urlLivePreview;
}else{
String regionPrefix = config.region.name().toLowerCase();
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/contentstack/sdk/SyncStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,13 @@ protected synchronized void setJSON(@NotNull JSONObject jsonobject) {
}
}
} else {
logger.warning("'items' is not a valid list. Skipping processing."); // ✅ Prevent crashes
syncItems = new ArrayList<>();
if (itemsObj instanceof JSONObject) {
syncItems = new ArrayList<>();
syncItems.add(sanitizeJson((JSONObject) itemsObj));
} else {
logger.warning("'items' is not a valid list. Skipping processing.");
syncItems = new ArrayList<>();
}
}
} else {
syncItems = new ArrayList<>();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/contentstack/sdk/Taxonomy.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* Taxonomy, currently in the Early Access Phase simplifies
* the process of organizing content in your system, making
* it effortless to find and retrieve information.
* @implSpec To implement the taxonomy use below code
* To implement the taxonomy use below code
* <pre>
* {@code
* Stack stack = Contentstack.stack("API_KEY", "DELIVERY_TOKEN", "ENVIRONMENT");
Expand Down
Loading
Loading