diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
new file mode 100644
index 0000000..d1324a1
--- /dev/null
+++ b/.github/workflows/ci-cd.yml
@@ -0,0 +1,149 @@
+name: CI
+
+on:
+ pull_request:
+ branches: [ main, develop ]
+ push:
+ branches: [ main, develop ]
+
+jobs:
+ code-checks:
+ name: Type Check, Lint & Unit Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+ cache: 'yarn'
+
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+
+ - name: Type check
+ run: yarn tsc --noEmit
+
+ - name: Lint
+ run: yarn lint
+
+ - name: Run unit tests
+ run: yarn test
+
+ - name: Upload test results
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-results
+ path: |
+ coverage/
+ junit.xml
+
+ e2e-android:
+ name: E2E Tests (Android)
+ needs: code-checks
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+ cache: 'yarn'
+
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+
+ - name: Setup Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ bundler-cache: true
+
+ - name: Setup Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Install Fastlane
+ run: |
+ cd android
+ bundle install
+
+ - name: Build Android app
+ run: |
+ cd android
+ bundle exec fastlane android build_dev
+
+ - name: Install Maestro
+ run: |
+ curl -Ls "https://get.maestro.mobile.dev" | bash
+ echo "$HOME/.maestro/bin" >> $GITHUB_PATH
+
+ - name: Run Maestro tests
+ uses: nick-fields/retry@v2
+ with:
+ timeout_minutes: 10
+ max_attempts: 2
+ command: yarn test-e2e-android
+
+ - name: Upload Maestro logs
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: maestro-android-logs
+ path: ~/.maestro/logs
+
+ e2e-ios:
+ name: E2E Tests (iOS)
+ needs: code-checks
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+ cache: 'yarn'
+
+ - name: Install dependencies
+ run: yarn install --frozen-lockfile
+
+ - name: Setup Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.0'
+ bundler-cache: true
+
+ - name: Install Fastlane
+ run: |
+ cd ios
+ bundle install
+
+ - name: Build iOS app
+ run: |
+ cd ios
+ bundle exec fastlane ios build_dev
+
+ - name: Install Maestro
+ run: |
+ curl -Ls "https://get.maestro.mobile.dev" | bash
+ echo "$HOME/.maestro/bin" >> $GITHUB_PATH
+
+ - name: Run Maestro tests
+ uses: nick-fields/retry@v2
+ with:
+ timeout_minutes: 10
+ max_attempts: 2
+ command: yarn test-e2e-ios
+
+ - name: Upload Maestro logs
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: maestro-ios-logs
+ path: ~/.maestro/logs
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index 8d72c37..1595bff 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,3 +7,4 @@ ruby ">= 2.6.10"
# bound in the template on Cocoapods with next React Native release.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
+gem "fastlane"
diff --git a/Gemfile.lock b/Gemfile.lock
index fd340c8..6a30220 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -5,18 +5,35 @@ GEM
base64
nkf
rexml
- activesupport (6.1.7.8)
+ activesupport (7.0.8.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- zeitwerk (~> 2.3)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
+ artifactory (3.0.17)
atomos (0.1.3)
+ aws-eventstream (1.3.0)
+ aws-partitions (1.984.0)
+ aws-sdk-core (3.209.1)
+ aws-eventstream (~> 1, >= 1.3.0)
+ aws-partitions (~> 1, >= 1.651.0)
+ aws-sigv4 (~> 1.9)
+ jmespath (~> 1, >= 1.6.1)
+ aws-sdk-kms (1.94.0)
+ aws-sdk-core (~> 3, >= 3.207.0)
+ aws-sigv4 (~> 1.5)
+ aws-sdk-s3 (1.167.0)
+ aws-sdk-core (~> 3, >= 3.207.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.5)
+ aws-sigv4 (1.10.0)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
cocoapods (1.14.3)
@@ -56,42 +73,202 @@ GEM
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
+ colored (1.2)
colored2 (3.1.2)
- concurrent-ruby (1.3.3)
+ commander (4.6.0)
+ highline (~> 2.0.0)
+ concurrent-ruby (1.3.4)
+ declarative (0.0.20)
+ digest-crc (0.6.5)
+ rake (>= 12.0.0, < 14.0.0)
+ domain_name (0.6.20240107)
+ dotenv (2.8.1)
+ emoji_regex (3.2.3)
escape (0.0.4)
ethon (0.16.0)
ffi (>= 1.15.0)
+ excon (0.112.0)
+ faraday (1.10.4)
+ faraday-em_http (~> 1.0)
+ faraday-em_synchrony (~> 1.0)
+ faraday-excon (~> 1.1)
+ faraday-httpclient (~> 1.0)
+ faraday-multipart (~> 1.0)
+ faraday-net_http (~> 1.0)
+ faraday-net_http_persistent (~> 1.0)
+ faraday-patron (~> 1.0)
+ faraday-rack (~> 1.0)
+ faraday-retry (~> 1.0)
+ ruby2_keywords (>= 0.0.4)
+ faraday-cookie_jar (0.0.7)
+ faraday (>= 0.8.0)
+ http-cookie (~> 1.0.0)
+ faraday-em_http (1.0.0)
+ faraday-em_synchrony (1.0.0)
+ faraday-excon (1.1.0)
+ faraday-httpclient (1.0.1)
+ faraday-multipart (1.0.4)
+ multipart-post (~> 2)
+ faraday-net_http (1.0.2)
+ faraday-net_http_persistent (1.2.0)
+ faraday-patron (1.0.0)
+ faraday-rack (1.0.0)
+ faraday-retry (1.0.3)
+ faraday_middleware (1.2.1)
+ faraday (~> 1.0)
+ fastimage (2.3.1)
+ fastlane (2.223.1)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.8, < 3.0.0)
+ artifactory (~> 3.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored (~> 1.2)
+ commander (~> 4.6)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 1.0)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-apis-androidpublisher_v3 (~> 0.3)
+ google-apis-playcustomapp_v1 (~> 0.1)
+ google-cloud-env (>= 1.6.0, < 2.0.0)
+ google-cloud-storage (~> 1.31)
+ highline (~> 2.0)
+ http-cookie (~> 1.0.5)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (>= 2.0.0, < 3.0.0)
+ naturally (~> 2.2)
+ optparse (>= 0.1.1, < 1.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ rubyzip (>= 2.0.0, < 3.0.0)
+ security (= 0.1.5)
+ simctl (~> 1.6.3)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (~> 3)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
ffi (1.17.0)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
+ google-apis-androidpublisher_v3 (0.54.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.3)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.16.2, < 2.a)
+ httpclient (>= 2.8.1, < 3.a)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.a)
+ rexml
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.31.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-cloud-core (1.7.1)
+ google-cloud-env (>= 1.0, < 3.a)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.6.0)
+ faraday (>= 0.17.3, < 3.0)
+ google-cloud-errors (1.4.0)
+ google-cloud-storage (1.47.0)
+ addressable (~> 2.8)
+ digest-crc (~> 0.4)
+ google-apis-iamcredentials_v1 (~> 0.1)
+ google-apis-storage_v1 (~> 0.31.0)
+ google-cloud-core (~> 1.6)
+ googleauth (>= 0.16.2, < 2.a)
+ mini_mime (~> 1.0)
+ googleauth (1.8.1)
+ faraday (>= 0.17.3, < 3.a)
+ jwt (>= 1.4, < 3.0)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (>= 0.16, < 2.a)
+ highline (2.0.3)
+ http-cookie (1.0.7)
+ domain_name (~> 0.5)
httpclient (2.8.3)
- i18n (1.14.5)
+ i18n (1.14.6)
concurrent-ruby (~> 1.0)
+ jmespath (1.6.2)
json (2.7.2)
- minitest (5.24.1)
+ jwt (2.9.3)
+ base64
+ mini_magick (4.13.2)
+ mini_mime (1.1.5)
+ minitest (5.25.1)
molinillo (0.8.0)
+ multi_json (1.15.0)
+ multipart-post (2.4.1)
nanaimo (0.3.0)
nap (1.1.0)
+ naturally (2.2.1)
netrc (0.11.0)
nkf (0.2.0)
+ optparse (0.5.0)
+ os (1.1.4)
+ plist (3.7.1)
public_suffix (4.0.7)
- rexml (3.2.9)
- strscan
+ rake (13.2.1)
+ representable (3.2.0)
+ declarative (< 0.1.0)
+ trailblazer-option (>= 0.1.1, < 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rexml (3.3.8)
+ rouge (2.0.7)
ruby-macho (2.5.1)
- strscan (3.1.0)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ security (0.1.5)
+ signet (0.19.0)
+ addressable (~> 2.8)
+ faraday (>= 0.17.5, < 3.a)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.10)
+ CFPropertyList
+ naturally
+ terminal-notifier (2.0.0)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ trailblazer-option (0.1.2)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.2)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
typhoeus (1.4.1)
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- xcodeproj (1.24.0)
+ uber (0.1.0)
+ unicode-display_width (2.6.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.25.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
- rexml (~> 3.2.4)
- zeitwerk (2.6.17)
+ rexml (>= 3.3.6, < 4.0)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.1)
+ xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
@@ -99,9 +276,10 @@ PLATFORMS
DEPENDENCIES
activesupport (>= 6.1.7.5, < 7.1.0)
cocoapods (>= 1.13, < 1.15)
+ fastlane
RUBY VERSION
- ruby 2.6.10p210
+ ruby 3.3.4p94
BUNDLED WITH
- 1.17.2
+ 2.5.11
diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile
new file mode 100644
index 0000000..40f49ad
--- /dev/null
+++ b/android/fastlane/Fastfile
@@ -0,0 +1,12 @@
+
+default_platform(:android)
+
+platform :android do
+ desc "Build development APK"
+ lane :build_dev do
+ gradle(
+ task: "clean assembleDebug",
+ project_dir: "./"
+ )
+ end
+end
\ No newline at end of file
diff --git a/android/fastlane/README.md b/android/fastlane/README.md
new file mode 100644
index 0000000..927b202
--- /dev/null
+++ b/android/fastlane/README.md
@@ -0,0 +1,32 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+## Android
+
+### android build_dev
+
+```sh
+[bundle exec] fastlane android build_dev
+```
+
+Build development APK
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/ios/Fastlane/Fastfile b/ios/Fastlane/Fastfile
new file mode 100644
index 0000000..6e040a3
--- /dev/null
+++ b/ios/Fastlane/Fastfile
@@ -0,0 +1,15 @@
+default_platform(:ios)
+
+platform :ios do
+ desc "Build development IPA"
+ lane :build_dev do
+ build_ios_app(
+ workspace: "weatherApp.xcworkspace",
+ scheme: "weatherApp",
+ export_method: "development",
+ configuration: "Debug",
+ skip_package_ipa: false,
+ skip_codesigning: false
+ )
+ end
+end
\ No newline at end of file
diff --git a/ios/Fastlane/README.md b/ios/Fastlane/README.md
new file mode 100644
index 0000000..4f6b713
--- /dev/null
+++ b/ios/Fastlane/README.md
@@ -0,0 +1,32 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+## iOS
+
+### ios build_dev
+
+```sh
+[bundle exec] fastlane ios build_dev
+```
+
+Build development IPA
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/ios/weatherApp.app.dSYM.zip b/ios/weatherApp.app.dSYM.zip
new file mode 100644
index 0000000..19d8349
Binary files /dev/null and b/ios/weatherApp.app.dSYM.zip differ
diff --git a/ios/weatherApp.xcodeproj/project.pbxproj b/ios/weatherApp.xcodeproj/project.pbxproj
index 7556c3f..474764b 100644
--- a/ios/weatherApp.xcodeproj/project.pbxproj
+++ b/ios/weatherApp.xcodeproj/project.pbxproj
@@ -500,7 +500,10 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = AJNMX63HJN;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = weatherApp/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = weatherApp;
@@ -514,8 +517,9 @@
"-ObjC",
"-lc++",
);
- PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
+ PRODUCT_BUNDLE_IDENTIFIER = com.weatherApp.callstack;
PRODUCT_NAME = weatherApp;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "weatherApp-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -529,7 +533,10 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = AJNMX63HJN;
INFOPLIST_FILE = weatherApp/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = weatherApp;
LD_RUNPATH_SEARCH_PATHS = (
@@ -542,8 +549,9 @@
"-ObjC",
"-lc++",
);
- PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
+ PRODUCT_BUNDLE_IDENTIFIER = com.weatherApp.callstack;
PRODUCT_NAME = weatherApp;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "weatherApp-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/ios/weatherApp/Info.plist b/ios/weatherApp/Info.plist
index b7b1c7e..16ed186 100644
--- a/ios/weatherApp/Info.plist
+++ b/ios/weatherApp/Info.plist
@@ -26,7 +26,6 @@
NSAppTransportSecurity
-
NSAllowsArbitraryLoads
NSAllowsLocalNetworking
diff --git a/jest-setup.ts b/jest-setup.ts
index aa5f7b8..64126e4 100644
--- a/jest-setup.ts
+++ b/jest-setup.ts
@@ -11,8 +11,8 @@ afterEach(() => server.resetHandlers());
// Clean up after the tests are finished.
afterAll(() => server.close());
-
jest.mock('react-native-permissions', () =>
- require('react-native-permissions/mock'),
+ require('react-native-permissions/mock'),
);
-
\ No newline at end of file
+
+jest.setTimeout(30000);
diff --git a/jest.config.js b/jest.config.js
index f041f2d..e52f030 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -7,6 +7,6 @@ module.exports = {
'\\.svg': '/__mocks__/svgMock.js',
},
transformIgnorePatterns: [
- "node_modules/(?!(react-native|@react-native|react-native-permissions)/)"
+ 'node_modules/(?!(react-native|@react-native|react-native-permissions)/)',
],
};
diff --git a/package.json b/package.json
index 8d07a8c..2c60a5f 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
+ "lint:fix": "eslint . --fix",
"start": "react-native start",
"test": "jest",
"test-e2e-ios": "maestro test e2e/main-flow-ios.yaml",