diff --git a/.github/actions/common-reporting/action.yml b/.github/actions/common-reporting/action.yml new file mode 100644 index 0000000..62a3ef6 --- /dev/null +++ b/.github/actions/common-reporting/action.yml @@ -0,0 +1,40 @@ +name: Reporting +description: Publish test report and upload metrics artifacts + +inputs: + report-name: + description: Typically name of workflow that called action + matrix-identifier: + description: Typically {os}-{runner}-{arch} + required: true + report-path: + description: Glob for test result XML files + required: false + default: "**/build/test-results/**/TEST*.xml,**/build/outputs/androidTest-results/managedDevice/**/TEST*.xml" + metrics-path: + description: Glob for metrics JSON files + required: false + default: "metrics/*.json" + +runs: + using: "composite" + steps: + - name: Test Report + uses: dorny/test-reporter@v2 + if: ${{ !cancelled() }} + env: + NODE_OPTIONS: --max-old-space-size=8192 + with: + name: ${{ inputs.report-name }}-${{ inputs.matrix-identifier }} + path: ${{ inputs.report-path }} + list-suites: failed + list-tests: failed + reporter: java-junit + use-actions-summary: true + + - name: Upload metrics + uses: actions/upload-artifact@v6 + with: + name: metrics-${{ inputs.matrix-identifier }} + path: ${{ inputs.metrics-path }} + if-no-files-found: ignore diff --git a/.github/actions/common-setup/action.yml b/.github/actions/common-setup/action.yml new file mode 100644 index 0000000..a59a7b9 --- /dev/null +++ b/.github/actions/common-setup/action.yml @@ -0,0 +1,51 @@ +name: Common CI Setup +description: Checkout + Java + optional Xcode + optional KVM + +inputs: + override-cache: + description: 'Override Cache?' + required: false + default: "false" + enable-kvm: + description: Enable KVM for Android emulator tests + required: false + default: "false" # composite inputs are strings + setup-xcode: + description: "Setup XCode version" + required: false + default: false + +runs: + using: "composite" + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Setup Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "17" + + - name: Setup Xcode + if: ${{ runner.os == 'macOS' && inputs.setup-xcode == 'true' }} + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "16.4.0" + + - name: Enable KVM + if: ${{ inputs.enable-kvm == 'true' }} + shell: bash + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Setup Gradle # Gradle-native cache handling + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: ${{ inputs.override-cache != 'true' }} + cache-cleanup: 'never' + dependency-graph: ${{ inputs.override-cache == 'true' && 'generate-and-submit' || 'disabled' }} # Dependency graph for Dependabot diff --git a/.github/workflows/build-everything.yml b/.github/workflows/build-everything.yml new file mode 100644 index 0000000..5da49ed --- /dev/null +++ b/.github/workflows/build-everything.yml @@ -0,0 +1,57 @@ +name: Build - Everything + +on: + workflow_call: + inputs: + matrix-file-name: + description: 'Json File containing arbitrary strategy-matrix; MUST be inside repository ./github folder' + required: true + type: string + kotlin-version: + description: 'Override Kotlin version?' + required: false + default: '' + type: string + testballoon-version: + description: 'Override TestBalloon version (full version string)?' + required: false + default: '' + type: string + build-matrix-runner: + description: 'Name of target runner to parse build matrix; defaults to ubuntu-latest' + required: false + type: string + default: 'ubuntu-latest' + +jobs: + prepare-matrix: + name: Prepare build matrix + uses: a-sit-plus/internal-workflows/.github/workflows/prepare-matrix.yml@feature/modularTests + with: + file-name: ${{ inputs.matrix-file-name }} + runner: ${{ inputs.build-matrix-runner }} + + build-jar: + name: Build JAR - ${{ matrix.module }} + needs: prepare-matrix + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }} + uses: a-sit-plus/internal-workflows/.github/workflows/build-jar-matrix-entry.yml@feature/modularTests + with: + module: ${{ matrix.module }} + kotlin-version: ${{ inputs.kotlinVersion }} + testballoon-version: ${{ inputs.testballoonVersion }} + + build-xc: + name: Build XCFramework - ${{ matrix.module }} + needs: prepare-matrix + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }} + uses: a-sit-plus/internal-workflows/.github/workflows/build-xc-matrix-entry.yml@feature/modularTests + with: + module: ${{ matrix.module }} + artifact-name: ${{ matrix.artifactName }} + kotlin-version: ${{ inputs.kotlinVersion }} + testballoon-version: ${{ inputs.testballoonVersion }} diff --git a/.github/workflows/build-jar-matrix-entry.yml b/.github/workflows/build-jar-matrix-entry.yml new file mode 100644 index 0000000..75ebf2f --- /dev/null +++ b/.github/workflows/build-jar-matrix-entry.yml @@ -0,0 +1,43 @@ +name: Build - JAR Matrix Entry + +on: + workflow_call: + inputs: + module: + description: "Module path/name (used for artifact name and jar path)" + required: true + type: string + kotlin-version: + description: "Override Kotlin version?" + required: false + default: "" + type: string + testballoon-version: + description: "Override TestBalloon version (full version string)?" + required: false + default: "" + type: string + +jobs: + build: + name: "Build JAR (ubuntu-latest) - ${{ inputs.module }}" + runs-on: ubuntu-latest + timeout-minutes: 120 + + env: + KOTLIN_VERSION_ENV: ${{ inputs.kotlin-version }} + TESTBALLOON_VERSION_OVERRIDE: ${{ inputs.testballoon-version }} + + steps: + - name: Common setup + uses: a-sit-plus/internal-workflows/.github/actions/common-setup@feature/modularTests + + - name: Build jar + run: ./gradlew assemble + + - name: Upload jar ${{ inputs.module }} + uses: actions/upload-artifact@v6 + with: + name: ${{ inputs.module }} + path: ${{ inputs.module }}/build/libs/*.jar + if-no-files-found: error diff --git a/.github/workflows/build-xc-matrix-entry.yml b/.github/workflows/build-xc-matrix-entry.yml new file mode 100644 index 0000000..22f78c8 --- /dev/null +++ b/.github/workflows/build-xc-matrix-entry.yml @@ -0,0 +1,55 @@ +name: Build - XCFramework Matrix Entry + +on: + workflow_call: + inputs: + module: + required: true + type: string + artifact-name: + required: true + type: string + kotlin-version: + description: "Override Kotlin version?" + required: false + default: "" + type: string + testballoon-version: + description: "Override TestBalloon version (full version string)?" + required: false + default: "" + type: string + +jobs: + build: + name: "Build XCFramework (macos-latest) - ${{ inputs.module }}" + runs-on: macos-latest + timeout-minutes: 120 + + env: + KOTLIN_VERSION_ENV: ${{ inputs.kotlin-version }} + TESTBALLOON_VERSION_OVERRIDE: ${{ inputs.testballoon-version }} + + steps: + - name: Common setup + uses: a-sit-plus/internal-workflows/.github/actions/common-setup@feature/modularTests + + - name: Build klibs + run: ./gradlew iosArm64MainKlibrary iosX64MainKlibrary + + - name: Build XCFramework + run: ./gradlew assemble${{ inputs.artifact-name }}XCFramework + + - name: Upload debug XCFramework + uses: actions/upload-artifact@v6 + with: + name: ${{ inputs.artifact-name }}-debug.xcframework + path: ${{ inputs.name }}/build/XCFrameworks/debug/ + if-no-files-found: error + + - name: Upload release XCFramework + uses: actions/upload-artifact@v6 + with: + name: ${{ inputs.artifact-name }}-release.xcframework + path: ${{ inputs.name }}/build/XCFrameworks/release/ + if-no-files-found: error diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 41c9923..43b9642 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v6 - name: Parse Extracted Authors env: diff --git a/.github/workflows/guard-main.yml b/.github/workflows/guard-main.yml index fce24d1..df211ed 100644 --- a/.github/workflows/guard-main.yml +++ b/.github/workflows/guard-main.yml @@ -7,7 +7,7 @@ jobs: if: github.head_ref != '${{ vars.DEV_BRANCH }}' runs-on: 'ubuntu-latest' steps: - - uses: 'actions/github-script@v6' + - uses: 'actions/github-script@v7' with: script: | try { diff --git a/.github/workflows/prepare-matrix.yml b/.github/workflows/prepare-matrix.yml new file mode 100644 index 0000000..1535ca1 --- /dev/null +++ b/.github/workflows/prepare-matrix.yml @@ -0,0 +1,34 @@ +name: Matrix - Prepare + +on: + workflow_call: + inputs: + file-name: + description: 'Json File containing arbitrary strategy-matrix' + required: true + type: string + runner: + description: 'Name of target runner; defaults to ubuntu-latest' + required: false + type: string + default: 'ubuntu-latest' + outputs: + matrix: + description: 'JSON matrix to be used by caller' + value: ${{ jobs.prepare.outputs.matrix }} + +jobs: + prepare: + name: Generate matrix JSON + runs-on: ${{ inputs.runner }} + outputs: + matrix: ${{ steps.load.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Load matrix.json + id: load + run: | + MATRIX_JSON=$(jq -c . ${{ inputs.file-name}}) + echo "matrix=$MATRIX_JSON" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-everything.yml new file mode 100644 index 0000000..d8fa8da --- /dev/null +++ b/.github/workflows/test-everything.yml @@ -0,0 +1,59 @@ +name: Test - Everything + +on: + workflow_call: + inputs: + override-cache: + description: 'Override Cache?' + required: true + default: false + type: boolean + kotlin-version: + description: 'Override Kotlin version?' + required: false + default: '' + type: string + testballoon-version: + description: 'Override TestBalloon version (full version string)?' + required: false + default: '' + type: string + matrix-file-name: + description: 'Json File containing arbitrary strategy-matrix' + required: true + type: string + test-matrix-runner: + description: 'Name of target runner to parse test matrix; defaults to ubuntu-latest' + required: false + type: string + default: 'ubuntu-latest' + setup-xcode: + description: "Setup XCode version" + type: boolean + required: false + default: false + +jobs: + prepare-matrix: + name: Prepare test matrix + uses: a-sit-plus/internal-workflows/.github/workflows/prepare-matrix.yml@feature/modularTests + with: + file-name: ${{ inputs.matrix-file-name }} + runner: ${{ inputs.test-matrix-runner }} + + run-tests: + name: Run tests - ${{ matrix.name }} on ${{ matrix.os }} + needs: prepare-matrix + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }} + uses: a-sit-plus/internal-workflows/.github/workflows/test-matrix-entry.yml@feature/modularTests + with: + override-cache: ${{ inputs.override-cache }} + os: ${{ matrix.os }} + name: ${{ matrix.name }} + testCommand: ${{ matrix.testCommand }} + enable-kvm: ${{ matrix.enableKvm || false }} + kotlin-version: ${{ inputs.kotlin-version }} + testballoon-version: ${{ inputs.testballoon-version }} + setup-xcode: ${{ inputs.setup-xcode }} diff --git a/.github/workflows/test-manually.yml b/.github/workflows/test-manually.yml new file mode 100644 index 0000000..2d482a7 --- /dev/null +++ b/.github/workflows/test-manually.yml @@ -0,0 +1,72 @@ +name: Test Manually (Matrix Entry) + +on: + workflow_call: + inputs: + matrix-path: + description: "Path to json which contains the test strategy matrix" + required: true + default: ".github/config/test-strategy-matrix.json" + type: string + runner-name: + description: "Runner as defined in matrix (e.g., iosRunner, appleOtherRunner, jvmRunner)" + required: true + default: "jvmRunner" + type: string + override-cache: + required: false + default: false + type: boolean + kotlin-version: + description: "Override Kotlin version?" + required: false + default: "" + type: string + testballoon-version: + description: "Override TestBalloon version (full version string)?" + required: false + default: "" + type: string + +jobs: + select-entry: + runs-on: ubuntu-latest + outputs: + os: ${{ steps.pick.outputs.os }} + testCommand: ${{ steps.pick.outputs.testCommand }} + enableKvm: ${{ steps.pick.outputs.enableKvm }} + steps: + - uses: actions/checkout@v6 + - id: pick + uses: actions/github-script@v7 + env: + ENTRY_NAME: ${{ inputs.runner-name }} + with: + script: | + const fs = require('fs'); + const entryName = process.env.ENTRY_NAME; + if (!entryName) { + core.setFailed('Missing runner-name input'); + return; + } + const matrix = JSON.parse(fs.readFileSync('${{ inputs.matrix-path }}', 'utf8')); + const entry = (matrix.include || []).find(e => e.name === entryName); + if (!entry) { + core.setFailed(`No matrix entry named "${entryName}"`); + return; + } + core.setOutput('os', entry.os || ''); + core.setOutput('testCommand', entry.testCommand || ''); + core.setOutput('enableKvm', entry.enableKvm ? 'true' : 'false'); + + test: + needs: select-entry + uses: a-sit-plus/internal-workflows/.github/workflows/test-matrix-entry.yml@feature/modularTests + with: + override-cache: ${{ inputs.override-cache }} + os: ${{ needs.select-entry.outputs.os }} + name: ${{ inputs.runner-name }} + testCommand: ${{ needs.select-entry.outputs.testCommand }} + enable-kvm: ${{ needs.select-entry.outputs.enableKvm == 'true' }} + kotlin-version: ${{ inputs.kotlin-version }} + testballoon-version: ${{ inputs.testballoon-version }} diff --git a/.github/workflows/test-matrix-entry.yml b/.github/workflows/test-matrix-entry.yml new file mode 100644 index 0000000..ed1650a --- /dev/null +++ b/.github/workflows/test-matrix-entry.yml @@ -0,0 +1,85 @@ +name: Test - Matrix Entry + +on: + workflow_call: + inputs: + override-cache: + description: 'Override Cache?' + required: true + type: boolean + os: + description: 'GitHub Actions runner label to execute this test job on + (e.g. ubuntu-latest, macos-latest, windows-latest).' + required: true + type: string + name: + description: 'Logical name of the matrix entry, used for display and reporting + (for example: jvm, native, android, ios)' + required: true + type: string + testCommand: + description: 'Gradle command-line arguments specifying which tests to run' + required: true + type: string + enable-kvm: + description: 'Enable KVM for Android emulator tests' + required: false + default: false + type: boolean + setup-xcode: + description: 'set xcode version' + required: false + default: false + type: boolean + kotlin-version: + description: 'Override Kotlin version?' + required: false + default: '' + type: string + testballoon-version: + description: 'Override TestBalloon version (full version string)?' + required: false + default: '' + type: string + report-path: + description: Glob for test result XML files + type: string + required: false + default: "**/build/test-results/**/TEST*.xml,**/build/outputs/androidTest-results/managedDevice/**/TEST*.xml" + metrics-path: + description: Glob for metrics JSON files + required: false + type: string + default: "metrics/*.json" + +jobs: + test: + name: Test - ${{ inputs.name }} on ${{ inputs.os }} + runs-on: ${{ inputs.os }} + timeout-minutes: 300 + + env: + KOTLIN_VERSION_ENV: ${{ inputs.kotlin-version }} + TESTBALLOON_VERSION_OVERRIDE: ${{ inputs.testballoon-version }} + + steps: + - name: Common setup + uses: a-sit-plus/internal-workflows/.github/actions/common-setup@feature/modularTests + with: + override-cache: ${{ inputs.override-cache }} + enable-kvm: ${{ inputs.enable-kvm }} + setup-xcode: ${{ inputs.setup-xcode }} + + - name: Run tests + shell: 'bash' + run: | + export GRADLE_OPTS="-Dkotlin.build.report.json.directory=$PWD/metrics" + ${{ inputs.testCommand }} + + - name: Reporting + uses: a-sit-plus/internal-workflows/.github/actions/common-reporting@feature/modularTests + with: + report-name: ${{ github.workflow }} + matrix-identifier: ${{ runner.os }}-${{ inputs.name }}-${{ runner.arch }} + report-path: ${{ inputs.report-path }} + metrics-path: ${{ inputs.metrics-path }}