diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
new file mode 100644
index 0000000..633ecee
--- /dev/null
+++ b/.github/workflows/ci-cd.yml
@@ -0,0 +1,73 @@
+name: CI/CD Pipeline
+
+on:
+ push:
+ branches:
+ - '**' # Runs for all branches
+ workflow_dispatch:
+
+jobs:
+ build:
+ name: Build & Test
+ runs-on: ubuntu-latest
+ if: github.ref != 'refs/heads/master' # Runs on all branches except master
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup Java 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: 'maven'
+
+ - name: Make Maven wrapper executable
+ run: chmod +x mvnw
+
+ - name: Build and Run Tests
+ run: ./mvnw --no-transfer-progress clean verify
+
+ - if: ${{ github.ref == 'refs/heads/master' }}
+ name: Publish to GitHub Packages Apache Maven
+ run: ./mvnw deploy -s $GITHUB_WORKSPACE/settings.xml
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+
+ deploy:
+ name: Build, Test & Deploy
+ runs-on: ubuntu-latest
+ if: github.ref == 'refs/heads/master' # Runs only on master
+ permissions:
+ contents: read
+ packages: write # Needed to publish to GitHub Packages
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup Java
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
+ settings-path: ${{ github.workspace }} # location for the settings.xml file
+ cache: 'maven'
+
+ - name: Build and Deploy to GitHub Packages
+ run: ./mvnw --no-transfer-progress clean deploy -s $GITHUB_WORKSPACE/settings.xml
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ env.VERSION }}
+ generate_release_notes: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
diff --git a/.run/All Unit Tests.run.xml b/.run/All Unit Tests.run.xml
new file mode 100644
index 0000000..ab3d792
--- /dev/null
+++ b/.run/All Unit Tests.run.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 32ad84d..0296be5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,51 +2,99 @@
4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.4.3
-
-
+
com.amalvadkar
am-commons-utils
0.0.1-SNAPSHOT
+ jar
am-commons-utils
- Common Utilities
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Common Utility Library
+
+
21
+ 5.10.2
+ 3.25.3
+
+
+ 3.11.0
+ 3.2.5
+ 3.3.0
+ 3.0.0-M1
+
+
+
+ github
+ GitHub Packages
+ https://maven.pkg.github.com/abhishekmalvadkar/${project.artifactId}
+
+
+
+
+
- org.springframework.boot
- spring-boot-starter
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit-jupiter.version}
+ test
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit-jupiter.version}
+ test
+
- org.springframework.boot
- spring-boot-starter-test
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
test
+
+ ${project.artifactId}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ false
+
+
+
+
- org.springframework.boot
- spring-boot-maven-plugin
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${maven-deploy-plugin.version}
diff --git a/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java b/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java
deleted file mode 100644
index 3509f1c..0000000
--- a/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.amalvadkar.commons.utils;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class AmCommonsUtilsApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(AmCommonsUtilsApplication.class, args);
- }
-
-}
diff --git a/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java b/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java
new file mode 100644
index 0000000..1f3d27d
--- /dev/null
+++ b/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java
@@ -0,0 +1,11 @@
+package com.amalvadkar.commons.utils.constants;
+
+public class StringConstants {
+
+ public static final String EMPTY_STRING = "";
+
+ private StringConstants() {
+ throw new UnsupportedOperationException("Constants class");
+ }
+
+}
diff --git a/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java b/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java
new file mode 100644
index 0000000..25bd7f9
--- /dev/null
+++ b/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java
@@ -0,0 +1,10 @@
+package com.amalvadkar.commons.utils.exceptions;
+
+/**
+ * Custom exception for invalid string operations.
+ */
+public class InvalidStringException extends RuntimeException {
+ public InvalidStringException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java b/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java
new file mode 100644
index 0000000..5e041d4
--- /dev/null
+++ b/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java
@@ -0,0 +1,71 @@
+package com.amalvadkar.commons.utils.string;
+
+import com.amalvadkar.commons.utils.constants.StringConstants;
+import com.amalvadkar.commons.utils.exceptions.InvalidStringException;
+
+/**
+ * Utility class for common string operations.
+ */
+public final class StringUtils {
+
+ private StringUtils() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ /**
+ * Capitalizes the first letter of the input string.
+ *
+ * @param input The string to capitalize.
+ * @return Capitalized string or an empty string if input is null/empty.
+ * @throws InvalidStringException if the input is null or empty.
+ */
+ public static String capitalize(String input) {
+ if (isEmpty(input)) {
+ throw new InvalidStringException("Input string cannot be null or empty.");
+ }
+ return input.substring(0, 1).toUpperCase() + input.substring(1);
+ }
+
+ /**
+ * Checks if a string is null or empty.
+ *
+ * @param input The string to check.
+ * @return True if the string is null or empty, otherwise false.
+ */
+ public static boolean isEmpty(String input) {
+ return input == null || input.trim().isEmpty();
+ }
+
+ /**
+ * Reverses a given string.
+ *
+ * @param input The string to reverse.
+ * @return The reversed string.
+ */
+ public static String reverse(String input) {
+ if (isEmpty(input)) {
+ return StringConstants.EMPTY_STRING;
+ }
+ return new StringBuilder(input).reverse().toString();
+ }
+
+ /**
+ * Trims spaces from both ends of the string.
+ *
+ * @param input The string to trim.
+ * @return The trimmed string.
+ */
+ public static String trim(String input) {
+ return isEmpty(input) ? StringConstants.EMPTY_STRING : input.trim();
+ }
+
+ /**
+ * Checks if a string contains only letters.
+ *
+ * @param input The string to check.
+ * @return True if the string contains only letters, otherwise false.
+ */
+ public static boolean containsOnlyLetters(String input) {
+ return !isEmpty(input) && input.matches("[a-zA-Z]+");
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644
index e255222..0000000
--- a/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-spring.application.name=am-commons-utils
diff --git a/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java b/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java
deleted file mode 100644
index 4aa48e4..0000000
--- a/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.amalvadkar.commons.utils;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class AmCommonsUtilsApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
-}
diff --git a/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java b/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java
new file mode 100644
index 0000000..7d0e53b
--- /dev/null
+++ b/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java
@@ -0,0 +1,59 @@
+package com.amalvadkar.commons.utils.string;
+
+import com.amalvadkar.commons.utils.exceptions.InvalidStringException;
+import common.AbstractUnitTest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class StringUtilsTest extends AbstractUnitTest {
+
+ @Test
+ void capitalize_should_capitalize_first_letter() {
+ assertThat(StringUtils.capitalize("hello")).isEqualTo("Hello");
+ }
+
+ @Test
+ void capitalize_should_throw_exception_when_input_is_null() {
+ assertThatThrownBy(() -> StringUtils.capitalize(null))
+ .isInstanceOf(InvalidStringException.class)
+ .hasMessage("Input string cannot be null or empty.");
+ }
+
+ @Test
+ void is_empty_should_return_true_when_string_is_empty() {
+ assertThat(StringUtils.isEmpty("")).isTrue();
+ }
+
+ @Test
+ void is_empty_should_return_false_when_string_is_not_empty() {
+ assertThat(StringUtils.isEmpty("test")).isFalse();
+ }
+
+ @Test
+ void reverse_should_return_reversed_string() {
+ assertThat(StringUtils.reverse("hello")).isEqualTo("olleh");
+ }
+
+ @Test
+ void reverse_should_return_empty_when_input_is_empty() {
+ assertThat(StringUtils.reverse("")).isEqualTo("");
+ }
+
+ @Test
+ void trim_should_remove_leading_and_trailing_spaces() {
+ assertThat(StringUtils.trim(" hello ")).isEqualTo("hello");
+ }
+
+ @Test
+ void contains_only_letters_should_return_true_when_only_letters() {
+ assertThat(StringUtils.containsOnlyLetters("Hello")).isTrue();
+ }
+
+ @Test
+ void contains_only_letters_should_return_false_when_contains_numbers() {
+ assertThat(StringUtils.containsOnlyLetters("Hello123")).isFalse();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/common/AbstractUnitTest.java b/src/test/java/common/AbstractUnitTest.java
new file mode 100644
index 0000000..e134db1
--- /dev/null
+++ b/src/test/java/common/AbstractUnitTest.java
@@ -0,0 +1,7 @@
+package common;
+
+import org.junit.jupiter.api.Tag;
+
+@Tag("unit")
+public class AbstractUnitTest {
+}