From 339079665219799744ccf0e7b4f0a82ab0355cce Mon Sep 17 00:00:00 2001 From: Olivier Corradi <1655848+corradio@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:36:22 +0100 Subject: [PATCH] Mobile app CI build and deploy (#2890) * Deploy electricityMap static assets to GCS * update dockerfile paths * Revert * Fix dockerfile * Add config * update container path * Mobile app CI build and deploy * Show app version on mobile info tab * lint * restore build.sh * update * Add staging * Add promote stage * Final * Req changes --- mobileapp/BUILD.yaml | 55 +++++++++++++++++++++++ mobileapp/build.sh | 8 ++-- mobileapp/config.xml | 5 ++- mobileapp/package-lock.json | 22 +++++---- mobileapp/package.json | 8 ++-- mobileapp/sentry.properties | 4 ++ web/BUILD.yaml | 2 +- web/src/layout/leftpanel/mobileinfotab.js | 28 +++++++++++- 8 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 mobileapp/BUILD.yaml create mode 100644 mobileapp/sentry.properties diff --git a/mobileapp/BUILD.yaml b/mobileapp/BUILD.yaml new file mode 100644 index 0000000000..779969933f --- /dev/null +++ b/mobileapp/BUILD.yaml @@ -0,0 +1,55 @@ +steps: + prepare: + image: node:10.19.0-alpine + inputs: + - package.json + - package-lock.json + commands: + - apk add --no-cache git imagemagick + # Install gsutil + - apk add --no-cache curl bash python3 + - curl https://sdk.cloud.google.com | bash > /dev/null + - npm ci + - npm install -g cordova@9.0.0 code-push-cli@2.1.9 + + build: + inputs: + - ../web/public + - ../web/{locales,src,views/pages/index.ejs} + - ../web/locales-config.json + - www/index.html + - ./icon*.png + - generate-index.js + - config.xml + - res/screen/ios + - sentry.properties + commands: + - cp -r ../web/public/ www/electricitymap + - cp -r ../web/locales/ . + - cp ../web/locales-config.json ./locales-config.json + - cp -r ../web/src . + # Generate bundle + - node generate-index.js + # Generate icons + - node_modules/.bin/app-icon generate -i icon_ios.png --platforms=ios + - node_modules/.bin/app-icon generate -i icon_android_legacy.png --platforms=android --adaptive-icons + # Set Sentry auth-token + - echo "auth-token=${BRICK_SENTRY_AUTH_TOKEN:-unknown}" >> sentry.properties + + deploy: + commands: + # Prepare + - /root/google-cloud-sdk/bin/gsutil cp gs://electricitymap-secrets/mobileapp/google-services.json . + - /root/google-cloud-sdk/bin/gsutil cp gs://electricitymap-secrets/mobileapp/GoogleService-Info.plist . + - cordova prepare + # Release to staging + - code-push login --accessKey ${BRICK_CODE_PUSH_ACCESS_KEY:-unknown} + - code-push release-cordova electricitymap-android android --noDuplicateReleaseError --description ${BRICK_DRONE_COMMIT_SHA:-latest} + - code-push release-cordova electricitymap-ios ios --noDuplicateReleaseError --description ${BRICK_DRONE_COMMIT_SHA:-latest} + # Promote + - code-push promote electricitymap-android Staging Production + - code-push promote electricitymap-ios Staging Production + secrets: + gcloud: + src: ~/.config/gcloud + target: /root/.config/gcloud diff --git a/mobileapp/build.sh b/mobileapp/build.sh index 4f2b6f804e..d5282909d2 100755 --- a/mobileapp/build.sh +++ b/mobileapp/build.sh @@ -5,12 +5,12 @@ set -eu -o pipefail CONTAINER_ID=$(docker create eu.gcr.io/tmrow-152415/electricitymap_web:latest) rm -rf www/electricitymap locales src || true -docker cp $CONTAINER_ID:/home/web/public/ www/electricitymap +docker cp $CONTAINER_ID:/home/src/electricitymap/contrib/web/public/ www/electricitymap rm -rf locales || true -docker cp $CONTAINER_ID:/home/web/locales/ . -docker cp $CONTAINER_ID:/home/web/locales-config.json ./locales-config.json -docker cp $CONTAINER_ID:/home/web/src . +docker cp $CONTAINER_ID:/home/src/electricitymap/contrib/web/locales/ . +docker cp $CONTAINER_ID:/home/src/electricitymap/contrib/web/locales-config.json ./locales-config.json +docker cp $CONTAINER_ID:/home/src/electricitymap/contrib/web/src . docker rm $CONTAINER_ID diff --git a/mobileapp/config.xml b/mobileapp/config.xml index 14e110bb6b..4a2366b8a2 100644 --- a/mobileapp/config.xml +++ b/mobileapp/config.xml @@ -20,6 +20,8 @@ + + @@ -32,6 +34,8 @@ + + @@ -51,7 +55,6 @@ - diff --git a/mobileapp/package-lock.json b/mobileapp/package-lock.json index 8d708d9e93..7b81169e3f 100644 --- a/mobileapp/package-lock.json +++ b/mobileapp/package-lock.json @@ -630,9 +630,9 @@ "integrity": "sha512-GQBrZtnJQmRn7J6biJrG1GD9dm3mEmH/+RoG640qkavS9CMehTJTjDJO52nlnYzKyX4AILEIzx9r9gw/Cbts3Q==" }, "cordova-universal-links-plugin": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cordova-universal-links-plugin/-/cordova-universal-links-plugin-1.2.1.tgz", - "integrity": "sha1-M70nhc3UdIc6Q7jDGVuTTlAA5Js=", + "version": "git+https://github.com/walteram/cordova-universal-links-plugin.git#c648d3025643731c244f615ff5bbf2e375dea544", + "from": "git+https://github.com/walteram/cordova-universal-links-plugin.git", + "dev": true, "requires": { "mkpath": ">=1.0.0", "node-version-compare": ">=1.0.1", @@ -1428,7 +1428,8 @@ "mkpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", - "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=" + "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", + "dev": true }, "ms": { "version": "2.0.0", @@ -1461,9 +1462,10 @@ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-version-compare": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/node-version-compare/-/node-version-compare-1.0.2.tgz", - "integrity": "sha512-OVcHSPS3nROlBQXcALptOR0j2lOabC9wE2S+y+Fvr7nSDqoO/LCNzRdVGVovipeHUXs5jAqq7GelWE1X4J1sEw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/node-version-compare/-/node-version-compare-1.0.3.tgz", + "integrity": "sha512-unO5GpBAh5YqeGULMLpmDT94oanSDMwtZB8KHTKCH/qrGv8bHN0mlDj9xQDAicCYXv2OLnzdi67lidCrcVotVw==", + "dev": true }, "nopt": { "version": "3.0.6", @@ -1821,6 +1823,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" }, @@ -1829,6 +1832,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1874,7 +1878,8 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true }, "scandirectory": { "version": "2.5.0", @@ -2315,6 +2320,7 @@ "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, "requires": { "sax": ">=0.6.0", "xmlbuilder": "~9.0.1" diff --git a/mobileapp/package.json b/mobileapp/package.json index f1ca8c0ebe..9703e8c4aa 100644 --- a/mobileapp/package.json +++ b/mobileapp/package.json @@ -19,7 +19,6 @@ "cordova-plugin-zip": "^3.1.0", "cordova-support-android-plugin": "^1.0.2", "cordova-support-google-services": "^1.3.2", - "cordova-universal-links-plugin": "^1.2.1", "ejs": "^2.7.4", "i18n": "^0.8.3", "sentry-cordova": "^0.16.2" @@ -40,11 +39,11 @@ "cordova-plugin-file": {}, "cordova-plugin-file-transfer": {}, "cordova-plugin-zip": {}, - "cordova-universal-links-plugin": {}, "cordova-plugin-code-push": {}, "sentry-cordova": {}, "cordova-support-google-services": {}, - "cordova-plugin-firebase-analytics": {} + "cordova-plugin-firebase-analytics": {}, + "cordova-universal-links-plugin": {} }, "platforms": [ "android", @@ -52,6 +51,7 @@ ] }, "devDependencies": { - "app-icon": "^0.13.1" + "app-icon": "^0.13.1", + "cordova-universal-links-plugin": "git+https://github.com/walteram/cordova-universal-links-plugin.git" } } \ No newline at end of file diff --git a/mobileapp/sentry.properties b/mobileapp/sentry.properties new file mode 100644 index 0000000000..0214b7d472 --- /dev/null +++ b/mobileapp/sentry.properties @@ -0,0 +1,4 @@ +defaults.url=https://sentry.io/ +defaults.org=tomorrow +defaults.project=electricitymap-app +cli.executable=node_modules/@sentry/cli/bin/sentry-cli diff --git a/web/BUILD.yaml b/web/BUILD.yaml index ec7c25af5f..4a6b616b46 100644 --- a/web/BUILD.yaml +++ b/web/BUILD.yaml @@ -11,7 +11,7 @@ steps: build: environment: - ELECTRICITYMAP_PUBLIC_TOKEN: ${BRICK_ELECTRICITYMAP_PUBLIC_TOKEN} + ELECTRICITYMAP_PUBLIC_TOKEN: ${BRICK_ELECTRICITYMAP_PUBLIC_TOKEN:-unknown} inputs: # geometries - generate-geometries.js diff --git a/web/src/layout/leftpanel/mobileinfotab.js b/web/src/layout/leftpanel/mobileinfotab.js index a4e785a093..551e3f4a0d 100644 --- a/web/src/layout/leftpanel/mobileinfotab.js +++ b/web/src/layout/leftpanel/mobileinfotab.js @@ -3,7 +3,7 @@ /* eslint-disable react/jsx-no-target-blank */ // TODO: re-enable rules -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { Redirect, useLocation } from 'react-router-dom'; import { __ } from '../../helpers/translation'; @@ -20,6 +20,29 @@ const MobileInfoTab = () => { return ; } + const [mobileAppVersion, setMobileAppVersion] = useState(null); + // Check app version once + useEffect(() => { + if (!mobileAppVersion && window.isCordova) { + codePush.getCurrentPackage((localPackage) => { + if (!localPackage) { + console.log('CodePush: No updates have been installed yet'); + setMobileAppVersion(null); + return; + } + + const { + appVersion, // The native version of the application this package update is intended for. + description, // same as given during deployment + // isFirstRun, // flag indicating if the current application run is the first one after the package was applied. + label, // The internal label automatically given to the update by the CodePush server, such as v5. This value uniquely identifies the update within it's deployment + } = localPackage; + + setMobileAppVersion(`${appVersion} ${label} (${description})`); + }, err => console.error(err)); + } + }, []); + return (
@@ -47,6 +70,9 @@ const MobileInfoTab = () => {
+ { mobileAppVersion ? ( +

{`App version: ${mobileAppVersion}`}

+ ) : null}

{__('panel-initial-text.thisproject')} {' '}