Skip to content

Commit b2750ae

Browse files
authored
feature/ci-retry-on-fail (#302)
* Impl retry on fail action
1 parent 6efbd11 commit b2750ae

File tree

6 files changed

+129
-47
lines changed

6 files changed

+129
-47
lines changed

.github/workflows/main.yml

Lines changed: 115 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
jobs:
66
compose-ui-tests:
77
runs-on: ubuntu-latest
8-
timeout-minutes: 25
8+
timeout-minutes: 60
99

1010
steps:
1111
- uses: actions/checkout@v4
@@ -23,114 +23,204 @@ jobs:
2323
sudo udevadm control --reload-rules
2424
sudo udevadm trigger --name-match=kvm
2525
26-
- name: Run instrumented tests
26+
- name: Set up Emulator, Build and Run Tests
2727
uses: ReactiveCircus/android-emulator-runner@v2.33.0
2828
with:
2929
api-level: 29
30-
script: ./gradlew connectedCheck
30+
script: |
31+
adb devices
32+
./gradlew assembleDebug
33+
./gradlew connectedCheck -PtestBuildType=debug --info
34+
35+
- name: Retry Tests if Failed
36+
uses: nick-fields/retry@v2
37+
if: failure()
38+
with:
39+
timeout_minutes: 15
40+
max_attempts: 2
41+
command: |
42+
adb devices
43+
./gradlew connectedCheck -PtestBuildType=debug --info
44+
45+
- name: Upload Compose UI Test Results
46+
if: always()
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: compose-ui-test-results
50+
path: '**/build/reports/androidTests/'
3151

3252
unit-tests-and-detekt:
3353
runs-on: ubuntu-latest
34-
timeout-minutes: 10
54+
timeout-minutes: 45
3555

3656
steps:
3757
- uses: actions/checkout@v4
3858

39-
- name: Set Java 17
59+
- name: Set up JDK 17
4060
uses: actions/setup-java@v4
4161
with:
42-
distribution: 'temurin'
4362
java-version: 17
63+
distribution: 'adopt'
64+
cache: 'gradle'
4465

4566
- name: Run Detekt
46-
uses: eskatos/gradle-command-action@v3
67+
uses: nick-fields/retry@v2
4768
with:
48-
arguments: detekt
69+
timeout_minutes: 15
70+
max_attempts: 2
71+
command: ./gradlew detekt
4972

5073
- name: Run Unit Tests
51-
run: ./gradlew test --stacktrace
74+
uses: nick-fields/retry@v2
75+
with:
76+
timeout_minutes: 15
77+
max_attempts: 2
78+
command: ./gradlew test --stacktrace
79+
80+
- name: Upload Unit Test Results
81+
if: always()
82+
uses: actions/upload-artifact@v4
83+
with:
84+
name: unit-test-results
85+
path: '**/build/reports/tests/'
86+
87+
- name: Upload Detekt Results
88+
if: always()
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: detekt-results
92+
path: '**/build/reports/detekt/'
5293

5394
iOS-build:
5495
runs-on: macos-latest
55-
timeout-minutes: 20
96+
timeout-minutes: 60
5697

5798
steps:
5899
- uses: actions/checkout@v4
59100

60-
- uses: actions/setup-java@v4
101+
- name: Set up Java
102+
uses: actions/setup-java@v4
61103
with:
62104
distribution: 'zulu'
63105
java-version: 17
64106

65107
- name: Build macOS shared code
66-
run: ./gradlew :shared:compileKotlinIosSimulatorArm64
108+
uses: nick-fields/retry@v2
109+
with:
110+
timeout_minutes: 20
111+
max_attempts: 2
112+
command: ./gradlew :shared:compileKotlinIosSimulatorArm64
67113

68114
- name: iOS set up
69115
uses: ./.github/actions/ios-action
70116

71117
- name: Build iOS app
72-
run: xcodebuild build -workspace iosApp/iosApp.xcworkspace -configuration Debug -scheme iosApp -sdk iphoneos -destination name='iPhone 14' -verbose
118+
uses: nick-fields/retry@v2
119+
with:
120+
timeout_minutes: 25
121+
max_attempts: 2
122+
command: xcodebuild build -workspace iosApp/iosApp.xcworkspace -configuration Debug -scheme iosApp -sdk iphoneos -destination name='iPhone 14' -verbose
73123

74124
maestro-ui-tests-and-upload-apk:
75125
runs-on: ubuntu-latest
76-
timeout-minutes: 20
126+
timeout-minutes: 45
77127

78128
outputs:
79129
app: androidApp/build/outputs/apk/debug
80130
steps:
81131
- uses: actions/checkout@v4
132+
82133
- name: Set up JDK 17
83134
uses: actions/setup-java@v4
84135
with:
85136
java-version: 17
86137
distribution: 'adopt'
87138
cache: 'gradle'
88-
- run: ./gradlew :androidApp:assembleDebug
89-
- uses: mobile-dev-inc/action-maestro-cloud@v1.9.2
139+
140+
- name: Assemble Debug APK
141+
uses: nick-fields/retry@v2
142+
with:
143+
timeout_minutes: 20
144+
max_attempts: 2
145+
command: ./gradlew :androidApp:assembleDebug
146+
147+
- name: Run Maestro Tests
148+
uses: mobile-dev-inc/action-maestro-cloud@v1.9.2
90149
with:
91150
api-key: ${{ secrets.MAESTRO_CLOUD_API_KEY }}
92151
app-file: androidApp/build/outputs/apk/debug/androidApp-debug.apk
152+
93153
- name: Upload APK
94154
uses: actions/upload-artifact@v4
95155
with:
96156
name: apk
97157
path: androidApp/build/outputs/apk/debug/androidApp-debug.apk
98158

159+
- name: Upload Maestro Test Results
160+
if: always()
161+
uses: actions/upload-artifact@v4
162+
with:
163+
name: maestro-test-results
164+
path: |
165+
${{ github.workspace }}/report*.xml
166+
~/.maestro/tests/**/*
167+
99168
desktop-build:
100169
runs-on: ubuntu-latest
101-
timeout-minutes: 20
170+
timeout-minutes: 45
102171

103172
steps:
104173
- uses: actions/checkout@v4
105-
- uses: actions/setup-java@v4
174+
175+
- name: Set up Java
176+
uses: actions/setup-java@v4
106177
with:
107178
distribution: 'zulu'
108179
java-version: 17
180+
109181
- name: Build desktop app
110-
run: ./gradlew :desktop:packageDistributionForCurrentOS
182+
uses: nick-fields/retry@v2
183+
with:
184+
timeout_minutes: 20
185+
max_attempts: 2
186+
command: ./gradlew :desktop:packageDistributionForCurrentOS
111187

112188
web-build:
113189
runs-on: ubuntu-latest
114-
timeout-minutes: 20
190+
timeout-minutes: 45
115191

116192
steps:
117193
- uses: actions/checkout@v4
118-
- uses: actions/setup-java@v4
194+
195+
- name: Set up Java
196+
uses: actions/setup-java@v4
119197
with:
120198
distribution: 'zulu'
121199
java-version: 17
200+
122201
- name: Build web app
123-
run: ./gradlew :webApp:jsBrowserDevelopmentExecutableDistribution
202+
uses: nick-fields/retry@v2
203+
with:
204+
timeout_minutes: 20
205+
max_attempts: 2
206+
command: ./gradlew :webApp:jsBrowserDevelopmentExecutableDistribution
124207

125208
wasm-build:
126209
runs-on: ubuntu-latest
127-
timeout-minutes: 20
210+
timeout-minutes: 45
128211

129212
steps:
130213
- uses: actions/checkout@v4
131-
- uses: actions/setup-java@v4
214+
215+
- name: Set up Java
216+
uses: actions/setup-java@v4
132217
with:
133218
distribution: 'zulu'
134219
java-version: 17
220+
135221
- name: Build wasm app
136-
run: ./gradlew :wasmApp:wasmBrowserDevelopmentExecutableDistribution
222+
uses: nick-fields/retry@v2
223+
with:
224+
timeout_minutes: 20
225+
max_attempts: 2
226+
command: ./gradlew :wasmApp:wasmBrowserDevelopmentExecutableDistribution
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.mbakgun.mj.di
22

3-
import org.koin.androidx.viewmodel.dsl.viewModel
3+
import org.koin.core.module.dsl.viewModelOf
44
import org.koin.dsl.module
55
import ui.MjImagesViewModel
66

77
val viewModelModule = module {
8-
viewModel { MjImagesViewModel(get(), get()) }
8+
viewModelOf(::MjImagesViewModel)
99
}

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
33

44
#Kotlin
55
kotlin.code.style=official
6+
kotlin.native.ignoreDisabledTargets=true
67

78
#MPP
89
kotlin.mpp.stability.nowarn=true

shared/src/androidInstrumentedTest/kotlin/ui/ScreenTestUtil.kt

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,20 @@ import data.source.remote.model.MjImageResponse
66
import data.source.remote.model.MjImagesResponse
77
import di.initKoin
88
import org.koin.android.ext.koin.androidContext
9-
import org.koin.androidx.viewmodel.dsl.viewModel
9+
import org.koin.core.context.loadKoinModules
10+
import org.koin.core.module.dsl.viewModelOf
1011
import org.koin.dsl.module
1112
import java.io.IOException
1213

1314
// setAppContext for ImageLoader &-init koin - mock response - return viewModel
1415
fun initAppAndMockViewModel(
1516
context: Context,
1617
dataSource: MjImagesDataSource.Remote? = null
17-
): MjImagesViewModel {
18-
return initKoin {
19-
androidContext(androidContext = context)
20-
if (dataSource != null) {
21-
modules(
22-
module { factory { dataSource } },
23-
module { viewModel { MjImagesViewModel(get(), get()) } }
24-
)
25-
} else {
26-
modules(
27-
module { viewModel { MjImagesViewModel(get(), get()) } }
28-
)
29-
}
30-
}.koin.get()
31-
}
18+
): MjImagesViewModel = initKoin {
19+
androidContext(androidContext = context)
20+
if (dataSource != null) modules(module { factory { dataSource } })
21+
loadKoinModules(module { viewModelOf(::MjImagesViewModel) })
22+
}.koin.get()
3223

3324
class SuccessMjImagesDataSource : MjImagesDataSource.Remote {
3425

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.mbakgun.mj.di
22

3-
import org.koin.androidx.viewmodel.dsl.viewModel
3+
import org.koin.core.module.dsl.viewModelOf
44
import org.koin.dsl.module
55
import ui.MjImagesViewModel
66

77
val viewModelModule = module {
8-
viewModel { MjImagesViewModel(get(), get()) }
8+
viewModelOf(::MjImagesViewModel)
99
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.mbakgun.mj.di
22

3-
import org.koin.androidx.viewmodel.dsl.viewModel
3+
import org.koin.core.module.dsl.viewModelOf
44
import org.koin.dsl.module
55
import ui.MjImagesViewModel
66

77
val viewModelModule = module {
8-
viewModel { MjImagesViewModel(get(), get()) }
8+
viewModelOf(::MjImagesViewModel)
99
}

0 commit comments

Comments
 (0)