diff --git a/.github/bump_versions_in_release_branch.sh b/.github/bump_versions_in_release_branch.sh index 00970d3..f7e7d8f 100755 --- a/.github/bump_versions_in_release_branch.sh +++ b/.github/bump_versions_in_release_branch.sh @@ -1,45 +1,91 @@ #!/bin/bash +set -e -# Check if the parameter is provided +# === Validate input === if [ $# -eq 0 ]; then echo "Please provide the release version number as a parameter." exit 1 fi -# Check if the version number matches the semver format if ! [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then echo "The release version number does not match the semver format (X.Y.Z or X.Y.Z-rc)." exit 1 fi -# Check the current Git branch +version=$1 current_branch=$(git symbolic-ref --short HEAD) -echo "Currently on branch: $current_branch" +echo "→ Currently on branch: $current_branch" if [[ ! $current_branch =~ ^(release|support)/[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then - echo "The current Git branch ($current_branch) is not in the format 'release/X.Y.Z', 'release/X.Y.Z-rc', 'support/X.Y.Z' or 'support/X.Y.Z-rc'." - exit 1 + echo "❌ The current Git branch ($current_branch) is not in the correct format." + exit 1 fi -version=$1 +# === Update gradle.properties === +properties_file="gradle.properties" +if [ ! -f "$properties_file" ]; then + echo "❌ $properties_file not found." + exit 1 +fi -# Show the current directory and its files -echo "Current directory: $(pwd)" -echo "Files in the current directory:" -ls -l +current_version=$(grep -E '^SDK_VERSION_NAME=' "$properties_file" | cut -d'=' -f2) +echo "→ Current SDK_VERSION_NAME: ${current_version:-}" +echo "→ Updating SDK_VERSION_NAME to $version" -# Add changelog to the index and create a commit -properties_file="gradle.properties" -current_version=$(grep -E '^KMP_SDK_VERSION_NAME=' gradle.properties | cut -d'=' -f2) -sed -i "s/^KMP_SDK_VERSION_NAME=.*/KMP_SDK_VERSION_NAME=$version/" $properties_file +if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "s/^SDK_VERSION_NAME=.*/SDK_VERSION_NAME=$version/" "$properties_file" +else + sed -i "s/^SDK_VERSION_NAME=.*/SDK_VERSION_NAME=$version/" "$properties_file" +fi + +grep "^SDK_VERSION_NAME=" "$properties_file" +git add "$properties_file" + +# === Update MindboxCommon.podspec (only s.version) === +podspec_file="MindboxCommon.podspec" +if [ -f "$podspec_file" ]; then + echo "→ Updating $podspec_file version to $version" -echo "Bump Common SDK version from $current_version to $version." + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' -E "s|^[[:space:]]*s\.version[[:space:]]*=.*| s.version = '$version'|" "$podspec_file" + else + sed -i -E "s|^[[:space:]]*s\.version[[:space:]]*=.*| s.version = '$version'|" "$podspec_file" + fi -git add $properties_file -git commit -m "Bump Common SDK version to $version" + grep "s.version" "$podspec_file" + git add "$podspec_file" +else + echo "⚠️ $podspec_file not found, skipping podspec update." +fi + +# === Commit changes === +echo "" +git commit -m "Bump Common SDK version to $version" || echo "No changes to commit" + +# === Validation === +echo "→ Validating version bump..." +new_version=$(grep -E '^SDK_VERSION_NAME=' "$properties_file" | cut -d'=' -f2) + +if [ "$new_version" != "$version" ]; then + echo "❌ Validation failed: expected SDK_VERSION_NAME=$version but found $new_version" + exit 1 +fi -echo "Pushing changes to branch: $current_branch" -if ! git push origin $current_branch; then - echo "Failed to push changes to the origin $current_branch" +if [ -f "$podspec_file" ]; then + podspec_version=$(grep -E "^[[:space:]]*s\.version" "$podspec_file" | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+(-rc)?") + if [ "$podspec_version" != "$version" ]; then + echo "❌ Validation failed: expected s.version=$version but found $podspec_version" exit 1 + fi fi + +echo "✅ Validation passed: version successfully updated to $version" + +# === Push changes === +echo "→ Pushing changes to branch: $current_branch" +if ! git push origin "$current_branch"; then + echo "❌ Failed to push changes to origin/$current_branch" + exit 1 +fi + +echo "✅ bump_versions_in_release_branch.sh completed successfully." diff --git a/.github/git-release-ci.sh b/.github/git-release-ci.sh index c9e47b3..264ebc9 100755 --- a/.github/git-release-ci.sh +++ b/.github/git-release-ci.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -version=$(grep '^KMP_SDK_VERSION_NAME=' gradle.properties | cut -d '=' -f2) +version=$(awk -F= '/^[[:space:]]*SDK_VERSION_NAME[[:space:]]*=/ { val=$2; sub(/#.*/,"",val); gsub(/[[:space:]]/,"",val); print val; exit }' gradle.properties) is_beta=false if [[ $version == *"rc"* ]]; then diff --git a/.github/workflows/lint_unitTests_build.yml b/.github/workflows/lint_unitTests_build.yml index 52e362c..32ea0ef 100644 --- a/.github/workflows/lint_unitTests_build.yml +++ b/.github/workflows/lint_unitTests_build.yml @@ -13,7 +13,7 @@ on: jobs: checks: - runs-on: macos-latest + runs-on: macos-26 steps: - uses: actions/checkout@v3 with: diff --git a/.github/workflows/manual-prepare_release_branch.yml b/.github/workflows/manual-prepare_release_branch.yml index f32dedd..1483bdd 100644 --- a/.github/workflows/manual-prepare_release_branch.yml +++ b/.github/workflows/manual-prepare_release_branch.yml @@ -1,4 +1,4 @@ -name: "Manual Release Prep: Branch & Version Bump" +name: "1. Release branch manual preparation" on: workflow_dispatch: @@ -23,7 +23,7 @@ jobs: - name: Check version matches semver or semver-rc run: | VER="${{ github.event.inputs.release_version }}" - echo "→ release_version = $VER" + echo "✅ release_version = $VER" if ! [[ "$VER" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc)?$ ]]; then echo "❌ release_version must be X.Y.Z or X.Y.Z-rc" exit 1 @@ -92,34 +92,10 @@ jobs: run: | git push origin "${{ steps.bump.outputs.release_branch }}" - check_sdk_version: - name: Check SDK Version - runs-on: ubuntu-latest - needs: bump_and_branch - steps: - - name: Checkout the release branch - uses: actions/checkout@v4 - with: - ref: ${{ needs.bump_and_branch.outputs.release_branch }} - fetch-depth: 0 - - - name: Pull latest changes - run: git pull - - - name: Validate sdkVersion - run: | - EXPECT="${{ github.event.inputs.release_version }}" - SDK_VERSION=$(grep -E '^KMP_SDK_VERSION_NAME=' gradle.properties | cut -d'=' -f2) - echo "→ Found in code: $SDK_VERSION, expected: $EXPECT" - if [ "$SDK_VERSION" != "$EXPECT" ]; then - echo "❌ SDK version does not match!" - exit 1 - fi - create_pull_request: name: Create Pull Request runs-on: ubuntu-latest - needs: [bump_and_branch, check_sdk_version] + needs: [bump_and_branch] steps: - name: Create PR via GitHub CLI env: @@ -134,4 +110,4 @@ jobs: --base "$DST" \ --head "$SRC" \ --title "Release ${{ github.event.inputs.release_version }}" \ - --body "Updates the release version to ${{ github.event.inputs.release_version }}. Automated PR: merge $SRC into $DST" \ No newline at end of file + --body "Updates the release version to ${{ github.event.inputs.release_version }}. Automated PR: merge $SRC into $DST" diff --git a/.github/workflows/prepare_release_branch.yml b/.github/workflows/prepare_release_branch.yml deleted file mode 100644 index 9cf3e79..0000000 --- a/.github/workflows/prepare_release_branch.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Prepare release branch - -on: - push: - branches: - - 'release/*.*.*' - - 'support/*.*.*' - -jobs: - extract_version: - if: github.event.created - name: Extract Version - runs-on: ubuntu-latest - outputs: - version: ${{ steps.extract.outputs.version }} - steps: - - name: Extract version from branch name - id: extract - run: | - BRANCH_NAME="${{ github.ref_name }}" - echo "BRANCH_NAME: $BRANCH_NAME" - VERSION="${BRANCH_NAME#release/}" - VERSION="${VERSION#support/}" - echo "VERSION: $VERSION" - echo "version=${VERSION}" >> $GITHUB_OUTPUT - - bump_version: - name: Bump Version - runs-on: ubuntu-latest - needs: extract_version - outputs: - version2: ${{ steps.bump.outputs.version2 }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Configure Git identity for GitHub Action Bot - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - - name: Bump version - run: ./.github/bump_versions_in_release_branch.sh "${{ needs.extract_version.outputs.version }}" - - - name: Ouput version - id: bump - run: | - echo "version2=${{ needs.extract_version.outputs.version }}" >> $GITHUB_OUTPUT - - check_sdk_version: - name: Check SDK Version - runs-on: ubuntu-latest - needs: bump_version - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Pull latest changes - run: git pull - - - name: Check if KMP_SDK_VERSION_NAME matches VERSION - run: | - SDK_VERSION=$(grep '^KMP_SDK_VERSION_NAME=' gradle.properties | cut -d '=' -f2) - EXPECTED_VERSION=${{ needs.bump_version.outputs.version2 }} - - if [ "$SDK_VERSION" != "$EXPECTED_VERSION" ]; then - echo "SDK_VERSION_NAME ($ACTUAL_VERSION) does not match the expected version ($EXPECTED_VERSION)." - exit 1 - fi - shell: bash - - create_pull_request: - name: Create Pull Request - runs-on: ubuntu-latest - needs: check_sdk_version - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Create Pull Request - run: | - gh pr create \ - --base master \ - --head ${{ github.ref_name }} \ - --title "${{ github.ref_name }}" \ - --body "Updates the release version to ${{ github.ref_name }}" - PR_URL=$(gh pr view --json url --jq '.url') - echo "PR_URL=$PR_URL" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }} - diff --git a/.github/workflows/publish-from-master-or-support.yml b/.github/workflows/publish-from-master-or-support.yml index 74a4cb4..a8625cd 100644 --- a/.github/workflows/publish-from-master-or-support.yml +++ b/.github/workflows/publish-from-master-or-support.yml @@ -1,4 +1,4 @@ -name: Common SDK publish from master or support branch +name: 2. Auto Github Release on: pull_request: diff --git a/.github/workflows/publish-manual.yml b/.github/workflows/publish-manual.yml index 4051d1d..05f7f46 100644 --- a/.github/workflows/publish-manual.yml +++ b/.github/workflows/publish-manual.yml @@ -1,4 +1,4 @@ -name: Common SDK publish RC manual +name: 2. Manual Github Release on: @@ -10,8 +10,8 @@ jobs: steps: - name: Check if branch matches pattern run: | - if ! echo "${{ github.ref_name }}" | grep -q "release/.*-rc"; then - echo "Branch name must match pattern 'release/*-rc' (e.g. release/2.13.2-rc)" + if ! echo "${{ github.ref_name }}" | grep -q "release/"; then + echo "Branch name must match pattern 'release' (e.g. release/2.13.2)" exit 1 fi diff --git a/.github/workflows/publish-reusable.yml b/.github/workflows/publish-reusable.yml index 59f050c..2680ea3 100644 --- a/.github/workflows/publish-reusable.yml +++ b/.github/workflows/publish-reusable.yml @@ -1,4 +1,4 @@ -name: SDK publish +name: 2. Github Release Reusable on: workflow_call: @@ -9,12 +9,13 @@ on: jobs: checks: - runs-on: macos-latest + runs-on: macos-26 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: ref: ${{ inputs.branch }} fetch-depth: 2 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: @@ -42,7 +43,7 @@ jobs: needs: [checks] runs-on: ubuntu-latest outputs: - tag: ${{ steps.extract_version.outputs.SDK_VERSION }} + tag: ${{ steps.extract_version.outputs.sdk_version }} steps: - uses: actions/checkout@v4 with: @@ -50,89 +51,30 @@ jobs: - name: Extract SDK version id: extract_version run: | - SDK_VERSION=$(grep '^KMP_SDK_VERSION_NAME=' gradle.properties | cut -d '=' -f2) - echo "SDK_VERSION=$SDK_VERSION" >> $GITHUB_ENV - echo "SDK_VERSION=$SDK_VERSION" >> $GITHUB_OUTPUT - echo "Extracted Common SDK version: $SDK_VERSION" - # Tag will be created later after updating Package.swift - - publish: - needs: [set-tag] - runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: '17' - cache: 'gradle' - - name: Prepare to publish - run: | - echo '${{secrets.GPGKEYCONTENTS}}' | base64 -d > /tmp/publish_key.gpg - gpg --quiet --batch --yes --decrypt --passphrase="${{secrets.SECRETPASSPHRASE}}" \ - --output /tmp/secret.gpg /tmp/publish_key.gpg - echo "signing.password=${{secrets.SIGNINGPASSWORD}}" >> gradle.properties - echo "signing.keyId=${{secrets.SIGNINGKEYID}}" >> gradle.properties - echo "signing.secretKeyRingFile=/tmp/secret.gpg" >> gradle.properties - echo "mavenCentralUsername=${{secrets.CENTER_PORTAL_USERNAME}}" >> gradle.properties - echo "mavenCentralPassword=${{secrets.CENTER_PORTAL_PASSWORD}}" >> gradle.properties - env: - signingpassword: ${{secrets.SIGNINGPASSWORD}} - signingkeyId: ${{secrets.SIGNINGKEYID}} - SECRETPASSPHRASE: ${{secrets.SECRETPASSPHRASE}} - GPGKEYCONTENTS: ${{secrets.GPGKEYCONTENTS}} - SONATYPE_CONNECT_TIMEOUT_SECONDS: 60 - SONATYPE_CLOSE_TIMEOUT_SECONDS: 900 - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - - name: Publish to Central Portal - # Change github variable CENTER_PORTAL_AUTO_RELEASE to set up auto release Maven Central + SDK_VERSION=$(grep '^SDK_VERSION_NAME=' gradle.properties | cut -d '=' -f2) + echo "Extracted SDK version: ${SDK_VERSION}" + echo "sdk_version=${SDK_VERSION}" >> $GITHUB_OUTPUT + echo "SDK_VERSION=${SDK_VERSION}" >> $GITHUB_ENV + - name: Create tag run: | - if [ "${{ vars.CENTER_PORTAL_AUTO_RELEASE }}" = "true" ]; then - ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache - else - ./gradlew publishToMavenCentral --no-configuration-cache - fi - + git tag "${{ env.SDK_VERSION }}" + git push origin "${{ env.SDK_VERSION }}" + release-github: - needs: [publish, set-tag] - runs-on: macos-latest + needs: [set-tag] + runs-on: macos-26 + outputs: + tag: ${{ needs.set-tag.outputs.tag }} steps: - uses: actions/checkout@v4 with: ref: ${{ inputs.branch }} - name: Build XCFramework run: ./make-ios-framework.sh - - name: Update Package.swift with URL and checksum - run: | - VERSION=${{ needs.set-tag.outputs.tag }} - ZIP_PATH="mindbox-common/build/XCFrameworks/release/MindboxCommon.xcframework.zip" - CHECKSUM=$(swift package compute-checksum "$ZIP_PATH") - echo "Computed checksum: $CHECKSUM" - sed -i '' -E "s#(url: \"").*(MindboxCommon.xcframework.zip)(\",)#\\1https://github.com/mindbox-cloud/kmp-common-sdk/releases/download/${VERSION}/MindboxCommon.xcframework.zip\\3#g" Package.swift - sed -i '' -E "s#(checksum:\")[^"]*(\")#\\1${CHECKSUM}\\2#g" Package.swift - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add Package.swift - git commit -m "chore(spm): update Package.swift for ${VERSION}" - git push origin HEAD:${{ inputs.branch }} - - name: Create and push tag - run: | - VERSION=${{ needs.set-tag.outputs.tag }} - git tag ${VERSION} - git push origin ${VERSION} - name: Github Release generation run: ./.github/git-release-ci.sh env: GH_TOKEN: ${{ github.token }} - - name: Mark release as draft if configured - if: ${{ vars.SPM_DRAFT_RELEASE == 'true' }} - run: | - gh release edit ${{ needs.set-tag.outputs.tag }} --draft - env: - GH_TOKEN: ${{ github.token }} - name: Verify framework existence run: ls -R mindbox-common/build/XCFrameworks/release - name: Upload XCFramework to release @@ -143,20 +85,34 @@ jobs: env: GH_TOKEN: ${{ github.token }} - message-to-loop-if-success: + trigger-kmp-common-spm: needs: [release-github] runs-on: ubuntu-latest steps: - - name: Send message to LOOP - env: - LOOP_NOTIFICATION_WEBHOOK_URL: ${{ secrets.LOOP_NOTIFICATION_WEBHOOK_URL }} - VERSION: ${{ github.ref_name }} + - name: Trigger workflow in repo B + run: | + echo "Triggering workflow in repo KMP-COMMON-SDK-SPM..." + echo "TAG=${{ needs.release-github.outputs.tag }}" + curl -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \ + https://api.github.com/repos/mindbox-cloud/kmp-common-sdk-spm/dispatches \ + -d "{\"event_type\": \"download_xcframework\", \"client_payload\": {\"version\": \"${{ needs.release-github.outputs.tag }}\"}}" + + merge: + needs: [trigger-kmp-common-spm] + if: startsWith(github.head_ref, 'release/') && github.base_ref == 'master' + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.PAT_FOR_TRIGGERING_BRANCH_PROTECTION }} + steps: + - name: Checkout develop branch + uses: actions/checkout@v5 + with: + ref: develop + - name: Create Pull Request + run: gh pr create --base develop --head master --title "Merge 'master' into 'develop' after release" --body "Automated Pull Request to merge 'master' into 'develop' after release" + - name: Merge Pull Request run: | - MESSAGE=$(cat < "CC BY-NC-ND 4.0", :text => "See LICENSE.md in the repository: https://github.com/mindbox-cloud/kmp-common-sdk" } + s.author = { "Mindbox" => "ios-sdk@mindbox.ru" } + + s.source = { :git => 'https://github.com/mindbox-cloud/kmp-common-sdk.git', :tag => s.version.to_s } + + s.prepare_command = <<-CMD + chmod +x gradlew + ./gradlew assembleMindboxCommonReleaseXCFramework + CMD + + s.platform = :ios, '12.0' + s.vendored_frameworks = 'mindbox-common/build/XCFrameworks/release/MindboxCommon.xcframework' + end \ No newline at end of file diff --git a/Package.swift b/Package.swift index 4338be5..7c491a9 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( targets: [ .binaryTarget( name: "MindboxCommon", - url: "https://github.com/mindbox-cloud/kmp-common-sdk/releases/download/1.0.3-rc/MindboxCommon.xcframework.zip", - checksum:"422dad4454addc735ea7469286dea5a828ee114c392b008af69188952ea004f4"), + path: "mindbox-common/build/XCFrameworks/release/MindboxCommon.xcframework" + ) ] ) \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 44726a3..a84ea30 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,5 +10,4 @@ kotlin.code.style=official android.useAndroidX=true android.nonTransitiveRClass=true -#SDK -KMP_SDK_VERSION_NAME=1.0.4 +SDK_VERSION_NAME=2.14.4 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e6e2144..0ac13bb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,12 @@ [versions] -agp = "8.2.0" -kotlin = "1.9.22" +agp = "8.9.1" +kotlin = "2.2.21" +kotlinxCoroutinesTest = "1.9.0" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" } [plugins] androidLibrary = { id = "com.android.library", version.ref = "agp" } diff --git a/mindbox-common/build.gradle.kts b/mindbox-common/build.gradle.kts index 583379c..74c30f9 100644 --- a/mindbox-common/build.gradle.kts +++ b/mindbox-common/build.gradle.kts @@ -1,19 +1,20 @@ + import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask import org.jlleitschuh.gradle.ktlint.tasks.KtLintFormatTask plugins { - id("org.jetbrains.kotlin.multiplatform") version "1.9.22" + id("org.jetbrains.kotlin.multiplatform") id("com.android.library") id("maven-publish") - id("com.vanniktech.maven.publish") version "0.33.0" - id("org.jlleitschuh.gradle.ktlint") version "12.1.1" + id("com.vanniktech.maven.publish") + id("org.jlleitschuh.gradle.ktlint") } group = "cloud.mindbox" -version = providers.gradleProperty("KMP_SDK_VERSION_NAME").get() -println("KMP_SDK_VERSION_NAME: $version") +version = providers.gradleProperty("SDK_VERSION_NAME").get() +println("mindbox-common version: $version") kotlin { androidTarget { @@ -44,9 +45,11 @@ kotlin { sourceSets { commonMain.dependencies { + implementation(libs.kotlin.stdlib) } commonTest.dependencies { implementation(kotlin("test")) + implementation(libs.kotlinx.coroutines.test) } } } @@ -90,7 +93,7 @@ ktlint { } mavenPublishing { - publishToMavenCentral() + publishToMavenCentral("CENTRAL_PORTAL") if (System.getenv("CI") == "true") { signAllPublications() diff --git a/mindbox-common/src/androidMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt b/mindbox-common/src/androidMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt new file mode 100644 index 0000000..48632fb --- /dev/null +++ b/mindbox-common/src/androidMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt @@ -0,0 +1,5 @@ +package cloud.mindbox.mobile_sdk.utils + +internal actual fun getSystemNanoTime(): Long { + return System.nanoTime() +} diff --git a/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtils.kt b/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtils.kt new file mode 100644 index 0000000..9bada3d --- /dev/null +++ b/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtils.kt @@ -0,0 +1,43 @@ +package cloud.mindbox.mobile_sdk.utils + +import kotlin.time.Duration +import kotlin.time.Duration.Companion.nanoseconds + +public object MindboxUtils { + public object Stopwatch { + + public const val INIT_SDK: String = "INIT_SDK" + public const val GET_PUSH_TOKENS: String = "GET_PUSH_TOKENS" + public const val INIT_PUSH_SERVICES: String = "INIT_PUSH_SERVICES" + + private val entries: MutableMap by lazy { mutableMapOf() } + + /*** + * Start tracking duration with tag + */ + public fun start(tag: String) { + entries[tag] = getSystemNanoTime() + } + + /*** + * Stop tracking duration from call of [start] with the same tag + * + * @return Duration in nanoseconds or null if tag not found + */ + public fun stop(tag: String): Duration? = + track(tag)?.also { + entries.remove(tag) + } + + /*** + * Track duration from call of [start] with the same tag + * + * @return Duration in nanoseconds or null if tag not found + */ + public fun track(tag: String): Duration? = + entries[tag]?.let { start -> + val now = getSystemNanoTime() + (now - start).nanoseconds + } + } +} diff --git a/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt b/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt new file mode 100644 index 0000000..7f6e648 --- /dev/null +++ b/mindbox-common/src/commonMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt @@ -0,0 +1,3 @@ +package cloud.mindbox.mobile_sdk.utils + +internal expect fun getSystemNanoTime(): Long diff --git a/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtilsTest.kt b/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtilsTest.kt new file mode 100644 index 0000000..a69ab29 --- /dev/null +++ b/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/MindboxUtilsTest.kt @@ -0,0 +1,45 @@ +package cloud.mindbox.mobile_sdk.utils + +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import kotlin.test.* +import kotlin.time.Duration + +class MindboxUtilsTest { + + @Test + fun `stopwatch start stop in 1 seconds`() = runBlocking { + MindboxUtils.Stopwatch.start("test") + delay(1000) + val duration: Duration? = MindboxUtils.Stopwatch.stop("test") + assertEquals(duration?.inWholeSeconds, 1) + } + + @Test + fun `stopwatch stop not started tag`() { + MindboxUtils.Stopwatch.start("test2") + val duration: Duration? = MindboxUtils.Stopwatch.stop("test") + assertNull(duration) + } + + @Test + fun `stopwatch track 1 seconds twice`() = runBlocking { + MindboxUtils.Stopwatch.start("test3") + delay(1000) + val duration1: Duration? = MindboxUtils.Stopwatch.track("test3") + assertEquals(1, duration1?.inWholeSeconds) + delay(1000) + val duration2: Duration? = MindboxUtils.Stopwatch.track("test3") + assertEquals(2, duration2?.inWholeSeconds) + } + + @Test + fun `stopwatch stop twice`() { + MindboxUtils.Stopwatch.start("test4") + val duration1: Duration? = MindboxUtils.Stopwatch.stop("test4") + assertNotNull(duration1) + + val duration2: Duration? = MindboxUtils.Stopwatch.stop("test4") + assertNull(duration2) + } +} diff --git a/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/TimeTest.kt b/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/TimeTest.kt new file mode 100644 index 0000000..3cb9236 --- /dev/null +++ b/mindbox-common/src/commonTest/kotlin/cloud/mindbox/mobile_sdk/utils/TimeTest.kt @@ -0,0 +1,13 @@ +package cloud.mindbox.mobile_sdk.utils + +import kotlin.test.* + +class TimeTest { + + @Test + fun `get system nano time returns a positive value`() { + val nanoTime = getSystemNanoTime() + assertTrue(nanoTime > 0) + } + +} diff --git a/mindbox-common/src/iosMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt b/mindbox-common/src/iosMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt new file mode 100644 index 0000000..e41347f --- /dev/null +++ b/mindbox-common/src/iosMain/kotlin/cloud/mindbox/mobile_sdk/utils/Time.kt @@ -0,0 +1,8 @@ +package cloud.mindbox.mobile_sdk.utils + +import platform.posix.CLOCK_MONOTONIC +import platform.posix.clock_gettime_nsec_np + +internal actual fun getSystemNanoTime(): Long { + return clock_gettime_nsec_np(CLOCK_MONOTONIC.toUInt()).toLong() +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 0b7d17a..35c000b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,11 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { + plugins { + id("org.jetbrains.kotlin.multiplatform") version "2.2.21" + id("com.android.library") version "8.9.1" + id("com.vanniktech.maven.publish") version "0.33.0" + id("org.jlleitschuh.gradle.ktlint") version "12.1.1" + } repositories { google() gradlePluginPortal()