From 76df3c286dc7721f7293c0db400ea6dabf4e45a1 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 24 Nov 2020 16:45:50 -0800 Subject: [PATCH 1/5] Android Notification - First Cut This commit has the basics of notifications on Android working again, updated to the latest Android SDK way of doing things (with channel IDs and grouping). Android users will get notified when the app is open for new Peer Messages across all profiles. In the future, this should be extended to add notifications for new peer invites, actual have actionable actions (accept/block) and maybe even work when the app isn't open... --- ANDROID_DEBUGGING.md | 9 ++- .../openprivacy/cwtch/ui/CwtchActivity.java | 80 +++++++------------ go/handlers/peerHandler.go | 1 - go/ui/android/CwtchActivity.go | 20 +---- go/ui/gcd.go | 4 + go/ui/manager.go | 9 +++ main.go | 11 +-- qml/main.qml | 10 +++ 8 files changed, 65 insertions(+), 79 deletions(-) diff --git a/ANDROID_DEBUGGING.md b/ANDROID_DEBUGGING.md index 9378bffc..bf59e2c3 100644 --- a/ANDROID_DEBUGGING.md +++ b/ANDROID_DEBUGGING.md @@ -79,4 +79,11 @@ Theoretically speaking it should be possible to use `ANDROID_EXTRA_PLUGINS` to i SVG images on Android. However, we have been unable to make it work. If you would like to try, the following issues might be helpful: -* https://bugreports.qt.io/browse/QTBUG-60022 \ No newline at end of file +* https://bugreports.qt.io/browse/QTBUG-60022 + +## Notifications + +- Android 8 (API Level 26) forces you to call setChannelId() +- Android 9 "Do Not Disturb" mode also hides all notifications +- Setting up notification channels only seems possible *once* per install. any changes you need to make +require that the app is reinstalled, or the actual channel deleted and changed. \ No newline at end of file diff --git a/android/src/ca/openprivacy/cwtch/ui/CwtchActivity.java b/android/src/ca/openprivacy/cwtch/ui/CwtchActivity.java index 736c10ca..b99dce53 100644 --- a/android/src/ca/openprivacy/cwtch/ui/CwtchActivity.java +++ b/android/src/ca/openprivacy/cwtch/ui/CwtchActivity.java @@ -23,20 +23,13 @@ import static android.app.Notification.CATEGORY_SERVICE; public class CwtchActivity extends org.qtproject.qt5.android.bindings.QtActivity { private static NotificationManager m_notificationManager; - private static Notification.Builder m_builder; private static Notification.Builder m_builderOngoing; private static CwtchActivity m_instance; - private static int PRIORITY_MIN = -2; // From NotificationCompat - private static int PRIORITY_DEFAULT = 0; // From NotificationCompat - private static String NOTIFICATION_CHANNEL_ID = "cwtch_notification_channel"; + private static int CONTENT_NOTIFICATION_ID = 2; + private static String CONTENT_NOTIFICATION_ID_NAME = "Notifications from Peers"; - private static int ONGOING_NOTIFICATION_ID = 0; - private static String ONGOING_NOTIFICATION_ID_NAME = "ongoing"; - - private static int CONTENT_NOTIFICATION_ID = 1; - private static String CONTENT_NOTIFICATION_ID_NAME = "content"; public CwtchActivity() { @@ -57,66 +50,47 @@ public class CwtchActivity extends org.qtproject.qt5.android.bindings.QtActivity } } - public static void notify(String s) + public static void notify(String s, String o) { if (m_notificationManager == null) { m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE); createNotificationChannel(); } - if (m_builder == null) { - m_builder = new Notification.Builder(m_instance); - m_builder.setSmallIcon(R.drawable.ic_launcher); - m_builder.setContentTitle("Cwtch"); - m_builder.setPriority(PRIORITY_DEFAULT); + // Apparently thr android documentation is just wrong and we need to provide a setGroupSummary + // notification regardless of targetted support version... + Notification groupSummary = + new Notification.Builder(m_instance) + .setContentTitle("Cwtch") + .setContentText("New Message from Peer: " + o) + .setGroupSummary(true) + .setWhen(System.currentTimeMillis()) + .setSmallIcon(R.drawable.ic_launcher) + .setGroup(NOTIFICATION_CHANNEL_ID) + .setChannelId(NOTIFICATION_CHANNEL_ID) + .build(); + m_notificationManager.notify(1, groupSummary); - } + Notification.Builder m_builder = new Notification.Builder(m_instance) + .setSmallIcon(R.drawable.ic_launcher) + .setChannelId(NOTIFICATION_CHANNEL_ID) + .setGroup(NOTIFICATION_CHANNEL_ID) + .setWhen(System.currentTimeMillis()) + .setAutoCancel(true) + .setContentTitle("New Message from Peer: " + o) + .setContentText("[redacted: Open Cwtch App to see the Message]"); + m_notificationManager.notify(CONTENT_NOTIFICATION_ID++, m_builder.build()); - m_builder.setContentText(s); - m_notificationManager.notify(CONTENT_NOTIFICATION_ID, m_builder.build()); - } - public static void ongoingNotify(String s) - { - if (m_notificationManager == null) { - m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE); - createNotificationChannel(); - } - if (m_builderOngoing == null) { - m_builderOngoing = new Notification.Builder(m_instance); - m_builderOngoing.setSmallIcon(R.drawable.ic_launcher); - m_builderOngoing.setContentTitle("Cwtch"); - m_builderOngoing.setPriority(PRIORITY_MIN); - - m_builderOngoing.setWhen(0); // Don't show the time - m_builderOngoing.setOngoing(true); - if (SDK_INT >= 21) { - m_builderOngoing.setCategory(CATEGORY_SERVICE); - //m_builder.setVisibility(VISIBILITY_SECRET); - } - - } - - m_builderOngoing.setContentText(s); - m_notificationManager.notify(ONGOING_NOTIFICATION_ID, m_builderOngoing.build()); } private static void createNotificationChannel() { // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is new and not in the support library if (SDK_INT >= 26) { - String description = "Cwtch Ongoing Notification Channel"; - int importance = NotificationManager.IMPORTANCE_LOW; - NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, ONGOING_NOTIFICATION_ID_NAME, importance); - channel.setDescription(description); - // Register the channel with the system; you can't change the importance - // or other notification behaviors after this - m_notificationManager.createNotificationChannel(channel); - - description = "Cwtch Content Notification Channel"; - importance = NotificationManager.IMPORTANCE_DEFAULT; - channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CONTENT_NOTIFICATION_ID_NAME, importance); + String description = "Cwtch Notification Channel"; + NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, CONTENT_NOTIFICATION_ID_NAME, NotificationManager.IMPORTANCE_HIGH); channel.setDescription(description); // Register the channel with the system; you can't change the importance // or other notification behaviors after this diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go index 83ce5fa3..e6aba32c 100644 --- a/go/handlers/peerHandler.go +++ b/go/handlers/peerHandler.go @@ -58,7 +58,6 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) { case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived]) uiManager.StoreAndNotify(peer, e.Data[event.RemotePeer], e.Data[event.Data], ts, onion) - case event.PeerAcknowledgement: uiManager.Acknowledge(e.Data[event.RemotePeer], e.Data[event.EventID]) diff --git a/go/ui/android/CwtchActivity.go b/go/ui/android/CwtchActivity.go index 0bfaa2c6..e8750b4b 100644 --- a/go/ui/android/CwtchActivity.go +++ b/go/ui/android/CwtchActivity.go @@ -11,6 +11,7 @@ type CwtchActivity struct { _ func() `constructor:"init"` + _ string `property:"channel"` _ string `property:"notification"` _ func(string) `slot:"updateAndroidNotification"` @@ -20,7 +21,6 @@ type CwtchActivity struct { func (c *CwtchActivity) init() { log.Debugln("CwtchActivity.init()") - c.createOngoingNotification() c.ConnectNotificationChanged(c.updateAndroidNotification) } @@ -29,8 +29,8 @@ func (c *CwtchActivity) updateAndroidNotification(n string) { var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught( "ca/openprivacy/cwtch/ui/CwtchActivity", "notify", - "(Ljava/lang/String;)V", - n, + "(Ljava/lang/String;Ljava/lang/String;)V", + n, c.Channel(), ) if err != nil { @@ -38,20 +38,6 @@ func (c *CwtchActivity) updateAndroidNotification(n string) { } } -func (c *CwtchActivity) createOngoingNotification() { - - var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught( - "ca/openprivacy/cwtch/ui/CwtchActivity", - "ongoingNotify", - "(Ljava/lang/String;)V", - "Cwtch is running", - ) - - if err != nil { - log.Errorf("Error calling Java CwtchActivity.ongoingNotify(): %v\n", err.Error()) - } -} - func (c *CwtchActivity) rootHomeButtonHandle() { log.Infoln("CwtchActivity.rootHomeButtonHandle()!") var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught( diff --git a/go/ui/gcd.go b/go/ui/gcd.go index 3dbf9d2a..39458ab9 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -8,6 +8,7 @@ import ( "cwtch.im/cwtch/protocol/connections" "cwtch.im/ui/go/constants" "cwtch.im/ui/go/features/groups" + "cwtch.im/ui/go/ui/android" "github.com/therecipe/qt/qml" "strconv" "sync" @@ -22,6 +23,7 @@ import ( type GrandCentralDispatcher struct { core.QObject + AndroidCwtchActivity *android.CwtchActivity QMLEngine *qml.QQmlApplicationEngine Translator, OpaqueTranslator *core.QTranslator @@ -58,6 +60,7 @@ type GrandCentralDispatcher struct { _ func() `signal:"ResetProfileList"` _ func(failed bool) `signal:"ChangePasswordResponse"` _ func(onion string, online bool) `signal:"UpdateProfileNetworkStatus"` + _ func(onion string) `signal:"Notify"` // server management _ func(handle, displayname, image string, status int, autostart bool, bundle string, messages int, key_types []string, keys []string) `signal:"AddServer"` @@ -147,6 +150,7 @@ func (this *GrandCentralDispatcher) init() { this.SetTheme(this.GlobalSettings.Theme) this.SetExperimentsEnabled(this.GlobalSettings.ExperimentsEnabled) this.SetExperiments(this.GlobalSettings.Experiments) + this.AndroidCwtchActivity = android.NewCwtchActivity(nil) } // GetUiManager gets (and creates if required) a ui Manager for the supplied profile id diff --git a/go/ui/manager.go b/go/ui/manager.go index 279d1520..0828df4e 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -301,6 +301,11 @@ func (this *manager) MessageJustAdded() { } func (this *manager) StoreAndNotify(pere peer.CwtchPeer, onion string, messageTxt string, sent time.Time, profileOnion string) { + + // Send a New Message from Peer Notification + this.gcd.AndroidCwtchActivity.SetChannel(onion) + this.gcd.AndroidCwtchActivity.NotificationChanged("New Message from Peer") + this.gcd.DoIfProfileElse(this.profile, func() { this.gcd.DoIfConversationElse(onion, func() { this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) @@ -314,6 +319,7 @@ func (this *manager) StoreAndNotify(pere peer.CwtchPeer, onion string, messageTx }, func() { the.CwtchApp.GetPeer(profileOnion).StoreMessage(onion, messageTxt, sent) }) + this.gcd.Notify(onion) } // AddMessage adds a message to the message pane for the supplied conversation if it is active @@ -331,6 +337,9 @@ func (this *manager) AddMessage(handle string, from string, message string, from }) this.gcd.IncContactUnreadCount(handle) }) + if !fromMe { + this.gcd.Notify(handle) + } } func (this *manager) ReloadProfiles() { diff --git a/main.go b/main.go index ff02d7db..13cef305 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,6 @@ import ( os2 "cwtch.im/ui/go/os" "cwtch.im/ui/go/the" "cwtch.im/ui/go/ui" - "cwtch.im/ui/go/ui/android" "encoding/base64" "flag" "git.openprivacy.ca/openprivacy/connectivity/tor" @@ -161,6 +160,7 @@ func mainUi(flagLocal bool, flagClientUI bool) { log.Errorf("Could not access global ui config: %v\n", err) os.Exit(-1) } + gcd := ui.NewGrandCentralDispatcher(nil) gcd.SetOs(runtime.GOOS) dir := core.QCoreApplication_ApplicationDirPath() @@ -186,8 +186,6 @@ func mainUi(flagLocal bool, flagClientUI bool) { gcd.SetBuildDate("now") } - - // this is to load local qml files quickly when developing var qmlSource *core.QUrl if flagLocal { @@ -223,13 +221,13 @@ func mainUi(flagLocal bool, flagClientUI bool) { return nam }) engine.SetNetworkAccessManagerFactory(factory) - engine.RootContext().SetContextProperty("gcd", gcd) gcd.TimelineInterface = ui.NewMessageModel(nil) engine.RootContext().SetContextProperty("mm", gcd.TimelineInterface) - var androidCwtchActivity = android.NewCwtchActivity(nil) - engine.RootContext().SetContextProperty("androidCwtchActivity", androidCwtchActivity) + + engine.RootContext().SetContextProperty("androidCwtchActivity", gcd.AndroidCwtchActivity) + engine.Load(qmlSource) @@ -263,7 +261,6 @@ func loadACN() { } } - // generate a random socks and control port (not real random...these are port numbers...) mrand.Seed(int64(time.Now().Nanosecond())) port := mrand.Intn(1000) + 9600 diff --git a/qml/main.qml b/qml/main.qml index d50a40c4..b2c17069 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -419,6 +419,14 @@ ApplicationWindow { parentStack.updateToolbar() statusbar.resetHeight() } + + onNotify: function(onion) { + // If we are processing QML it means the app is open, and as such we don't want to + // Send a notification - in the future we should probably use an API like this to Cancel notifications + // Until then I am leaving this here for documentation. + // androidCwtchActivity.channel = onion + // androidCwtchActivity.notification = "Message from " + onion; + } } Component.onCompleted: Mutant.standard.imagePath = gcd.assetPath; @@ -433,4 +441,6 @@ ApplicationWindow { } } } + + } From 4f4df63e5101f1fcd0f61c77546d3a6b10f06485 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 23 Nov 2020 15:52:48 -0800 Subject: [PATCH 2/5] updated splash screen and app icon for android --- ANDROID_DEBUGGING.md | 6 +++--- android/AndroidManifest.xml | 19 +++++++++++++++---- android/res/drawable/cwtch_title.png | Bin 0 -> 5134 bytes android/res/drawable/knot.png | Bin 0 -> 3811 bytes android/res/drawable/splash.xml | 9 ++++++--- android/res/drawable/splash_350.png | Bin 0 -> 13640 bytes android/res/values/apptheme.xml | 2 +- android/res/values/strings.xml | 5 +++++ 8 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 android/res/drawable/cwtch_title.png create mode 100644 android/res/drawable/knot.png create mode 100644 android/res/drawable/splash_350.png create mode 100644 android/res/values/strings.xml diff --git a/ANDROID_DEBUGGING.md b/ANDROID_DEBUGGING.md index bf59e2c3..2d8e2c4f 100644 --- a/ANDROID_DEBUGGING.md +++ b/ANDROID_DEBUGGING.md @@ -19,12 +19,12 @@ for every major version change of therecipe dependencies. You will also need the Android 28 SDK (Pie), the NDK, SDK build tools and platform tools, gradle and **JDK 8** - JAVA_HOME=/path/to/jre8 + JAVA_JDK=/path/to/jre8 ANDROID_NDK_DIR=/path/to/ndk Once all that setup is done you should be able to run: - qtdeploy build android + ANDROID_MODULES_INCLUDE="Core,Gui,Svg,QuickWidgets,Xml" qtdeploy build android 2-4 minutes later an android apk will pop out in `./deploy/android/build-debug.apk`. @@ -86,4 +86,4 @@ issues might be helpful: - Android 8 (API Level 26) forces you to call setChannelId() - Android 9 "Do Not Disturb" mode also hides all notifications - Setting up notification channels only seems possible *once* per install. any changes you need to make -require that the app is reinstalled, or the actual channel deleted and changed. \ No newline at end of file +require that the app is reinstalled, or the actual channel deleted and changed. diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 3504fa2d..955c390d 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,9 +1,20 @@ - - + + + + android:label="cwtch" + android:theme="@style/AppTheme" + android:screenOrientation="unspecified" + android:launchMode="singleTop" + android:windowSoftInputMode="adjustResize"> @@ -110,7 +121,7 @@ - --> + --> diff --git a/android/res/drawable/cwtch_title.png b/android/res/drawable/cwtch_title.png new file mode 100644 index 0000000000000000000000000000000000000000..a96474154c3f770f6cf8e6b387f34da14b067e4e GIT binary patch literal 5134 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 Zp8iL8gmr_={?-3L(>s<%)wf*}{ty42_D=u+ literal 0 HcmV?d00001 diff --git a/android/res/drawable/knot.png b/android/res/drawable/knot.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f3d41698daf779ff2e2cd91d3271eb35b56f1c GIT binary patch literal 3811 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 ZzXA8Q(P0KkpOXLp002ovPDHLkV1fyLSb+cl literal 0 HcmV?d00001 diff --git a/android/res/drawable/splash.xml b/android/res/drawable/splash.xml index 0599ae76..ee441ed3 100644 --- a/android/res/drawable/splash.xml +++ b/android/res/drawable/splash.xml @@ -2,11 +2,14 @@ - + + + - + + diff --git a/android/res/drawable/splash_350.png b/android/res/drawable/splash_350.png new file mode 100644 index 0000000000000000000000000000000000000000..8c5b0d6150cd2c54a1ec76eeb19629f78226d0d4 GIT binary patch literal 13640 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 - diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml new file mode 100644 index 00000000..9bc1252a --- /dev/null +++ b/android/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Loading tor... + + From 44e0f9ebab4b75edf966792d05472d7573c69083 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 25 Nov 2020 10:00:19 -0800 Subject: [PATCH 3/5] drone android: stop qtsetup generate android and add ANDROID_MODULES_INCLUDE --- .drone.yml | 2 +- .drone.yml.orig | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 .drone.yml.orig diff --git a/.drone.yml b/.drone.yml index cd4227d3..f58e02bf 100644 --- a/.drone.yml +++ b/.drone.yml @@ -58,7 +58,7 @@ pipeline: - go mod vendor - qtsetup generate android - mv assets android/ - - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android + - ANDROID_MODULES_INCLUDE="Core,Gui,Svg,QuickWidgets,Xml" qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android - mv android/assets assets - cd deploy - export FILENAME=cwtch-android-$BUILDDATE.apk diff --git a/.drone.yml.orig b/.drone.yml.orig new file mode 100644 index 00000000..9a72ab71 --- /dev/null +++ b/.drone.yml.orig @@ -0,0 +1,126 @@ +workspace: + base: /media/sf_GOPATH1/src/cwtch.im + path: ui + +pipeline: + build-linux: + mem_limit: 3G + image: therecipe/qt:linux_static + when: + repo: cwtch.im/ui + branch: master + event: [ push, pull_request ] + environment: + - QT_DIR=/opt/Qt + - QT_DOCKER='true' + - QT_API=5.13.0 + commands: + - export GOPATH=$GOPATH:/media/sf_GOPATH1/ + - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin + - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git openssh-client + - go get -d + - $QT_DIR/$QT_API/gcc_64/bin/lrelease ui.pro + - git fetch --tags + - export VERSION=`git describe --tags` + - export BUILDDATE=`date +%G-%m-%d-%H-%M` + - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build linux + - cp README.md deploy/linux + - export FILENAME=cwtch-linux-$BUILDDATE.tar.gz + - cd deploy + - mv linux cwtch + - tar -czf $FILENAME cwtch + - sha256sum $FILENAME > $FILENAME.sha256 + - rm -r cwtch + build-android: + mem_limit: 3G + image: therecipe/qt:android + when: + repo: cwtch.im/ui + branch: master + event: push + environment: + - QT_DIR=/opt/Qt + - QT_DOCKER='true' + - QT_API=5.13.0 + - ANDROID_NDK_DIR=/home/user/android-ndk-r18b + - ANDROID_SDK_DIR=/home/user/android-sdk-linux + commands: + - export GOPATH=$GOPATH:/media/sf_GOPATH1/ + - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin + - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git + - find -iname 'moc*' | xargs rm + - find -iname 'rcc*' | xargs rm + - go get -d + - export VERSION=`git describe --tags` + - export BUILDDATE=`date +%G-%m-%d-%H-%M` + - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android + - cd deploy + - export FILENAME=cwtch-android-$BUILDDATE.apk + - cp android/build-debug.apk $FILENAME + - sha256sum $FILENAME > $FILENAME.sha256 + build-windows: + mem_limit: 3G + image: therecipe/qt:windows_64_static + when: + repo: cwtch.im/ui + branch: master + event: push + environment: + - QT_DIR=/opt/Qt + - QT_DOCKER='true' + - QT_API=5.13.0 + commands: + - export GOPATH=$GOPATH:/media/sf_GOPATH1/ + - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin + - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git zip + - find -iname 'moc*' | xargs rm + - find -iname 'rcc*' | xargs rm + - go get -d + - export VERSION=`git describe --tags` + - export BUILDDATE=`date +%G-%m-%d-%H-%M` + - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build windows + - cp README.md deploy/windows + - cp -r windows/* deploy/windows + - cd deploy + - mv windows cwtch + - export FILENAME=cwtch-windows-$BUILDDATE.zip + - zip -r $FILENAME cwtch + - sha256sum $FILENAME > $FILENAME.sha256 + - rm -r cwtch + deploy-buildfiles: + image: pivotaldata/concourse-ssh + secrets: [buildfiles_key] + when: + repo: cwtch.im/ui + branch: master + event: push + status: [ success ] + commands: + - apk add --no-cache git + - echo $BUILDFILES_KEY > ~/id_rsab64 + - base64 -d ~/id_rsab64 > ~/id_rsa + - chmod 400 ~/id_rsa + - export DIR=`date +%G.%m.%d-%H.%M`-`git describe --tags` + - cd deploy + - mkdir $DIR + - mv cwtch* $DIR/ + - scp -r -o StrictHostKeyChecking=no -i ~/id_rsa $DIR buildfiles@openprivacy.ca:/home/buildfiles/buildfiles/ + notify-email: + image: drillster/drone-email + host: build.openprivacy.ca + port: 25 + skip_verify: true + from: drone@openprivacy.ca + when: + repo: cwtch.im/ui + branch: master + status: [ failure ] + notify-gogs: + image: openpriv/drone-gogs + when: + repo: cwtch.im/ui + branch: master + event: pull_request + status: [ success, changed, failure ] + secrets: [gogs_account_token] + gogs_url: https://git.openprivacy.ca From 2f6395697ebf26e4cd6f12a7ab80635cec54f4d5 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 25 Nov 2020 10:05:41 -0800 Subject: [PATCH 4/5] drone android: stop qtsetup generate android and add ANDROID_MODULES_INCLUDE --- .drone.yml | 2 +- .drone.yml.orig | 126 ------------------------------------------------ 2 files changed, 1 insertion(+), 127 deletions(-) delete mode 100644 .drone.yml.orig diff --git a/.drone.yml b/.drone.yml index f58e02bf..689d3496 100644 --- a/.drone.yml +++ b/.drone.yml @@ -56,7 +56,7 @@ pipeline: - export VERSION=`git describe --tags` - export BUILDDATE=`date +%G-%m-%d-%H-%M` - go mod vendor - - qtsetup generate android + # - qtsetup generate android - mv assets android/ - ANDROID_MODULES_INCLUDE="Core,Gui,Svg,QuickWidgets,Xml" qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android - mv android/assets assets diff --git a/.drone.yml.orig b/.drone.yml.orig deleted file mode 100644 index 9a72ab71..00000000 --- a/.drone.yml.orig +++ /dev/null @@ -1,126 +0,0 @@ -workspace: - base: /media/sf_GOPATH1/src/cwtch.im - path: ui - -pipeline: - build-linux: - mem_limit: 3G - image: therecipe/qt:linux_static - when: - repo: cwtch.im/ui - branch: master - event: [ push, pull_request ] - environment: - - QT_DIR=/opt/Qt - - QT_DOCKER='true' - - QT_API=5.13.0 - commands: - - export GOPATH=$GOPATH:/media/sf_GOPATH1/ - - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin - - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git openssh-client - - go get -d - - $QT_DIR/$QT_API/gcc_64/bin/lrelease ui.pro - - git fetch --tags - - export VERSION=`git describe --tags` - - export BUILDDATE=`date +%G-%m-%d-%H-%M` - - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build linux - - cp README.md deploy/linux - - export FILENAME=cwtch-linux-$BUILDDATE.tar.gz - - cd deploy - - mv linux cwtch - - tar -czf $FILENAME cwtch - - sha256sum $FILENAME > $FILENAME.sha256 - - rm -r cwtch - build-android: - mem_limit: 3G - image: therecipe/qt:android - when: - repo: cwtch.im/ui - branch: master - event: push - environment: - - QT_DIR=/opt/Qt - - QT_DOCKER='true' - - QT_API=5.13.0 - - ANDROID_NDK_DIR=/home/user/android-ndk-r18b - - ANDROID_SDK_DIR=/home/user/android-sdk-linux - commands: - - export GOPATH=$GOPATH:/media/sf_GOPATH1/ - - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin - - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git - - find -iname 'moc*' | xargs rm - - find -iname 'rcc*' | xargs rm - - go get -d - - export VERSION=`git describe --tags` - - export BUILDDATE=`date +%G-%m-%d-%H-%M` - - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android - - cd deploy - - export FILENAME=cwtch-android-$BUILDDATE.apk - - cp android/build-debug.apk $FILENAME - - sha256sum $FILENAME > $FILENAME.sha256 - build-windows: - mem_limit: 3G - image: therecipe/qt:windows_64_static - when: - repo: cwtch.im/ui - branch: master - event: push - environment: - - QT_DIR=/opt/Qt - - QT_DOCKER='true' - - QT_API=5.13.0 - commands: - - export GOPATH=$GOPATH:/media/sf_GOPATH1/ - - export PATH=$PATH:/home/user/work/bin:/media/sf_GOPATH1/bin - - apt-get -qq update && apt-get --no-install-recommends -qq -y install ca-certificates curl git zip - - find -iname 'moc*' | xargs rm - - find -iname 'rcc*' | xargs rm - - go get -d - - export VERSION=`git describe --tags` - - export BUILDDATE=`date +%G-%m-%d-%H-%M` - - qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build windows - - cp README.md deploy/windows - - cp -r windows/* deploy/windows - - cd deploy - - mv windows cwtch - - export FILENAME=cwtch-windows-$BUILDDATE.zip - - zip -r $FILENAME cwtch - - sha256sum $FILENAME > $FILENAME.sha256 - - rm -r cwtch - deploy-buildfiles: - image: pivotaldata/concourse-ssh - secrets: [buildfiles_key] - when: - repo: cwtch.im/ui - branch: master - event: push - status: [ success ] - commands: - - apk add --no-cache git - - echo $BUILDFILES_KEY > ~/id_rsab64 - - base64 -d ~/id_rsab64 > ~/id_rsa - - chmod 400 ~/id_rsa - - export DIR=`date +%G.%m.%d-%H.%M`-`git describe --tags` - - cd deploy - - mkdir $DIR - - mv cwtch* $DIR/ - - scp -r -o StrictHostKeyChecking=no -i ~/id_rsa $DIR buildfiles@openprivacy.ca:/home/buildfiles/buildfiles/ - notify-email: - image: drillster/drone-email - host: build.openprivacy.ca - port: 25 - skip_verify: true - from: drone@openprivacy.ca - when: - repo: cwtch.im/ui - branch: master - status: [ failure ] - notify-gogs: - image: openpriv/drone-gogs - when: - repo: cwtch.im/ui - branch: master - event: pull_request - status: [ success, changed, failure ] - secrets: [gogs_account_token] - gogs_url: https://git.openprivacy.ca From 78400a17c605a32c438681ed529c6f01e2781986 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 25 Nov 2020 10:16:21 -0800 Subject: [PATCH 5/5] drone android: android and add ANDROID_MODULES_INCLUDE and docker to 2020.01 --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 689d3496..9c284f20 100644 --- a/.drone.yml +++ b/.drone.yml @@ -56,7 +56,7 @@ pipeline: - export VERSION=`git describe --tags` - export BUILDDATE=`date +%G-%m-%d-%H-%M` - go mod vendor - # - qtsetup generate android + - qtsetup generate android - mv assets android/ - ANDROID_MODULES_INCLUDE="Core,Gui,Svg,QuickWidgets,Xml" qtdeploy -ldflags "-X main.buildVer=$VERSION -X main.buildDate=$BUILDDATE" build android - mv android/assets assets