mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-08-15 12:21:16 +00:00
feat: integrate codemagic for testing ios/android (#6719)
* fix: pages overflow when selecting homepage * feat: integrate codemagic * Revert "fix: pages overflow when selecting homepage" This reverts commit 156882a9a7e039a38cd206306e19b94eb391f948. * chore: try to fix build * chore: remove flutter analyuze * chore: launch ios simulator * fix: flutter version * fix: integration tests on mobile * fix: mobile tests * test: fix page style test * chore: enable ios ci * chore: update codemagic token * chore: update app_id
This commit is contained in:
parent
3cd26cca35
commit
d268f8c715
36
.github/workflows/ios_ci.yaml
vendored
36
.github/workflows/ios_ci.yaml
vendored
@ -97,21 +97,25 @@ jobs:
|
||||
cargo make --profile development-ios-arm64-sim appflowy-core-dev-ios
|
||||
cargo make --profile development-ios-arm64-sim code_generation
|
||||
|
||||
# - uses: futureware-tech/simulator-action@v3
|
||||
# id: simulator-action
|
||||
# with:
|
||||
# model: "iPhone 15"
|
||||
# shutdown_after_job: false
|
||||
- uses: futureware-tech/simulator-action@v3
|
||||
id: simulator-action
|
||||
with:
|
||||
model: "iPhone 15"
|
||||
shutdown_after_job: false
|
||||
|
||||
# - name: Run AppFlowy on simulator
|
||||
# working-directory: frontend/appflowy_flutter
|
||||
# run: |
|
||||
# flutter run -d ${{ steps.simulator-action.outputs.udid }} &
|
||||
# pid=$!
|
||||
# sleep 500
|
||||
# kill $pid
|
||||
# continue-on-error: true
|
||||
- name: Run AppFlowy on simulator
|
||||
working-directory: frontend/appflowy_flutter
|
||||
run: |
|
||||
flutter run -d ${{ steps.simulator-action.outputs.udid }} &
|
||||
pid=$!
|
||||
sleep 500
|
||||
kill $pid
|
||||
continue-on-error: true
|
||||
|
||||
# - name: Run integration tests
|
||||
# working-directory: frontend/appflowy_flutter
|
||||
# run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
|
||||
- name: Run integration tests
|
||||
working-directory: frontend/appflowy_flutter
|
||||
# The integration tests are flaky and sometimes fail with "Connection timed out":
|
||||
# Don't block the CI. If the tests fail, the CI will still pass.
|
||||
# Instead, we're using Code Magic to re-run the tests to check if they pass.
|
||||
continue-on-error: true
|
||||
run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
|
||||
|
82
.github/workflows/mobile_ci.yml
vendored
Normal file
82
.github/workflows/mobile_ci.yml
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
name: Mobile-CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: "Branch to build"
|
||||
required: true
|
||||
default: "main"
|
||||
workflow_id:
|
||||
description: "Codemagic workflow ID"
|
||||
required: true
|
||||
default: "ios-workflow"
|
||||
type: choice
|
||||
options:
|
||||
- ios-workflow
|
||||
- android-workflow
|
||||
|
||||
env:
|
||||
CODEMAGIC_API_TOKEN: ${{ secrets.CODEMAGIC_API_TOKEN }}
|
||||
APP_ID: "6731d2f427e7c816080c3674"
|
||||
|
||||
jobs:
|
||||
trigger-mobile-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger Codemagic Build
|
||||
id: trigger_build
|
||||
run: |
|
||||
RESPONSE=$(curl -X POST \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "x-auth-token: $CODEMAGIC_API_TOKEN" \
|
||||
--data '{
|
||||
"appId": "${{ env.APP_ID }}",
|
||||
"workflowId": "${{ github.event.inputs.workflow_id }}",
|
||||
"branch": "${{ github.event.inputs.branch }}"
|
||||
}' \
|
||||
https://api.codemagic.io/builds)
|
||||
|
||||
BUILD_ID=$(echo $RESPONSE | jq -r '.buildId')
|
||||
echo "build_id=$BUILD_ID" >> $GITHUB_OUTPUT
|
||||
echo "build_id=$BUILD_ID"
|
||||
|
||||
- name: Wait for build and check status
|
||||
id: check_status
|
||||
run: |
|
||||
while true; do
|
||||
RESPONSE=$(curl -X GET \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "x-auth-token: $CODEMAGIC_API_TOKEN" \
|
||||
https://api.codemagic.io/builds/${{ steps.trigger_build.outputs.build_id }})
|
||||
|
||||
STATUS=$(echo $RESPONSE | jq -r '.build.status')
|
||||
|
||||
if [ "$STATUS" = "finished" ]; then
|
||||
SUCCESS=$(echo $RESPONSE | jq -r '.success')
|
||||
BUILD_URL=$(echo $RESPONSE | jq -r '.buildUrl')
|
||||
echo "status=$STATUS" >> $GITHUB_OUTPUT
|
||||
echo "success=$SUCCESS" >> $GITHUB_OUTPUT
|
||||
echo "build_url=$BUILD_URL" >> $GITHUB_OUTPUT
|
||||
break
|
||||
elif [ "$STATUS" = "failed" ]; then
|
||||
echo "status=failed" >> $GITHUB_OUTPUT
|
||||
break
|
||||
fi
|
||||
|
||||
sleep 60
|
||||
done
|
||||
|
||||
- name: Slack Notification
|
||||
uses: 8398a7/action-slack@v3
|
||||
if: always()
|
||||
with:
|
||||
status: ${{ steps.check_status.outputs.success == 'true' && 'success' || 'failure' }}
|
||||
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
|
||||
text: |
|
||||
Mobile CI Build Result
|
||||
Branch: ${{ github.event.inputs.branch }}
|
||||
Workflow: ${{ github.event.inputs.workflow_id }}
|
||||
Build URL: ${{ steps.check_status.outputs.build_url }}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.RELEASE_SLACK_WEBHOOK }}
|
47
codemagic.yaml
Normal file
47
codemagic.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
workflows:
|
||||
ios-workflow:
|
||||
name: iOS Workflow
|
||||
instance_type: mac_mini_m2
|
||||
max_build_duration: 30
|
||||
environment:
|
||||
flutter: 3.22.3
|
||||
xcode: latest
|
||||
cocoapods: default
|
||||
|
||||
scripts:
|
||||
- name: Build Flutter
|
||||
script: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustc --version
|
||||
cargo --version
|
||||
|
||||
cd frontend
|
||||
|
||||
rustup target install aarch64-apple-ios-sim
|
||||
cargo install --force cargo-make
|
||||
cargo install --force duckscript_cli
|
||||
cargo install --force cargo-lipo
|
||||
|
||||
cargo make appflowy-flutter-deps-tools
|
||||
cargo make --profile development-ios-arm64-sim appflowy-core-dev-ios
|
||||
cargo make --profile development-ios-arm64-sim code_generation
|
||||
|
||||
- name: iOS integration tests
|
||||
script: |
|
||||
cd frontend/appflowy_flutter
|
||||
flutter emulators --launch apple_ios_simulator
|
||||
flutter -d iPhone test integration_test/runner.dart
|
||||
|
||||
artifacts:
|
||||
- build/ios/ipa/*.ipa
|
||||
- /tmp/xcodebuild_logs/*.log
|
||||
- flutter_drive.log
|
||||
|
||||
publishing:
|
||||
email:
|
||||
recipients:
|
||||
- lucas.xu@appflowy.io
|
||||
notify:
|
||||
success: true
|
||||
failure: true
|
@ -36,7 +36,7 @@ import '../../shared/util.dart';
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('document page style', () {
|
||||
group('document page style:', () {
|
||||
double getCurrentEditorFontSize() {
|
||||
final editorPage = find
|
||||
.byType(AppFlowyEditorPage)
|
||||
@ -59,9 +59,7 @@ void main() {
|
||||
return editorPage.styleCustomizer
|
||||
.style()
|
||||
.textStyleConfiguration
|
||||
.text
|
||||
.height ??
|
||||
PageStyleLineHeightLayout.normal.lineHeight;
|
||||
.lineHeight;
|
||||
}
|
||||
|
||||
testWidgets('change font size in page style settings', (tester) async {
|
||||
@ -87,20 +85,24 @@ void main() {
|
||||
await tester.openPage(gettingStarted);
|
||||
// click the layout button
|
||||
await tester.tapButton(find.byType(MobileViewPageLayoutButton));
|
||||
var lineHeight = getCurrentEditorLineHeight();
|
||||
expect(
|
||||
getCurrentEditorLineHeight(),
|
||||
lineHeight,
|
||||
PageStyleLineHeightLayout.normal.lineHeight,
|
||||
);
|
||||
// change line height from normal to large
|
||||
await tester.tapSvgButton(FlowySvgs.m_layout_large_s);
|
||||
await tester.pumpAndSettle();
|
||||
lineHeight = getCurrentEditorLineHeight();
|
||||
expect(
|
||||
getCurrentEditorLineHeight(),
|
||||
lineHeight,
|
||||
PageStyleLineHeightLayout.large.lineHeight,
|
||||
);
|
||||
// change line height from large to small
|
||||
await tester.tapSvgButton(FlowySvgs.m_layout_small_s);
|
||||
lineHeight = getCurrentEditorLineHeight();
|
||||
expect(
|
||||
getCurrentEditorLineHeight(),
|
||||
lineHeight,
|
||||
PageStyleLineHeightLayout.small.lineHeight,
|
||||
);
|
||||
});
|
||||
|
@ -29,19 +29,18 @@ import '../../shared/util.dart';
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('create new page', () {
|
||||
group('create new page in home page:', () {
|
||||
testWidgets('create document', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.local,
|
||||
);
|
||||
await tester.launchInAnonymousMode();
|
||||
|
||||
// tap the create page button
|
||||
final createPageButton = find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is FlowySvg &&
|
||||
widget.svg.path == FlowySvgs.m_home_unselected_m.path,
|
||||
widget.svg.path == FlowySvgs.m_home_add_m.path,
|
||||
);
|
||||
await tester.tapButton(createPageButton);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(MobileDocumentScreen), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
@ -25,9 +25,9 @@ import '../../shared/util.dart';
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('anonymous sign in on mobile', () {
|
||||
group('anonymous sign in on mobile:', () {
|
||||
testWidgets('anon user and then sign in', (tester) async {
|
||||
await tester.initializeAppFlowy();
|
||||
await tester.launchInAnonymousMode();
|
||||
|
||||
// expect to see the home page
|
||||
expect(find.byType(MobileHomeScreen), findsOneWidget);
|
||||
|
@ -5,8 +5,13 @@ import 'mobile/document/page_style_test.dart' as page_style_test;
|
||||
import 'mobile/home_page/create_new_page_test.dart' as create_new_page_test;
|
||||
import 'mobile/sign_in/anonymous_sign_in_test.dart' as anonymous_sign_in_test;
|
||||
|
||||
Future<void> runIntegrationOnMobile() async {
|
||||
Future<void> main() async {
|
||||
Log.shared.disableLog = true;
|
||||
|
||||
await runIntegration1OnMobile();
|
||||
}
|
||||
|
||||
Future<void> runIntegration1OnMobile() async {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
anonymous_sign_in_test.main();
|
@ -8,7 +8,7 @@ import 'desktop_runner_5.dart';
|
||||
import 'desktop_runner_6.dart';
|
||||
import 'desktop_runner_7.dart';
|
||||
import 'desktop_runner_8.dart';
|
||||
import 'mobile_runner.dart';
|
||||
import 'mobile_runner_1.dart';
|
||||
|
||||
/// The main task runner for all integration tests in AppFlowy.
|
||||
///
|
||||
@ -28,7 +28,7 @@ Future<void> main() async {
|
||||
await runIntegration7OnDesktop();
|
||||
await runIntegration8OnDesktop();
|
||||
} else if (Platform.isIOS || Platform.isAndroid) {
|
||||
await runIntegrationOnMobile();
|
||||
await runIntegration1OnMobile();
|
||||
} else {
|
||||
throw Exception('Unsupported platform');
|
||||
}
|
||||
|
@ -65,7 +65,10 @@ class _MobileViewPageState extends State<MobileViewPage> {
|
||||
@override
|
||||
void dispose() {
|
||||
_appBarOpacity.dispose();
|
||||
_scrollNotificationObserver?.removeListener(_onScrollNotification);
|
||||
|
||||
// there's no need to remove the listener, because the observer will be disposed when the widget is unmounted.
|
||||
// inside the observer, the listener will be removed automatically.
|
||||
// _scrollNotificationObserver?.removeListener(_onScrollNotification);
|
||||
_scrollNotificationObserver = null;
|
||||
|
||||
super.dispose();
|
||||
|
@ -1543,10 +1543,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
||||
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "3.1.5"
|
||||
plugin_platform_interface:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -1941,10 +1941,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
string_validator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -2246,10 +2246,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.1"
|
||||
version: "14.2.5"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
Loading…
x
Reference in New Issue
Block a user