Created
June 29, 2020 19:54
-
-
Save stevenselcuk/4cbdd44ff45ce9fdb2ef9f51192c6a4b to your computer and use it in GitHub Desktop.
CI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const shell = require('shelljs'); | |
| require('shelljs/global'); | |
| const path = require('path'); | |
| const fs = require('fs'); | |
| const fsP = require('fs-path'); | |
| const helpers = require('../helpers'); | |
| const templates = require('../templates'); | |
| const api = require('../helpers/api'); | |
| const mainPath = `${path.dirname(__filename)}/../boilerplate`; | |
| const generator = async function (projectId, buildId) { | |
| const projectResponse = await helpers.api.getProject(projectId); | |
| const projectData = { | |
| ...projectResponse, | |
| screens: projectResponse.screens.filter(x => x.type !== "splash").map((screen) => ({ | |
| ...screen, | |
| name: screen.name.replace(/ /g, '').replace(/./, (x) => x.toUpperCase()), | |
| })), | |
| }; | |
| await helpers.file.write( | |
| mainPath + '/src/projectData.js', | |
| `export default ${JSON.stringify(projectData)}` | |
| ); | |
| const createScreens = projectData.screens.map(async (screen) => { | |
| await helpers.file.write( | |
| mainPath + '/src/screens/' + screen.name + '.js', | |
| templates.screen(screen, projectData) | |
| ); | |
| }); | |
| await Promise.all(createScreens); | |
| await helpers.file.write( | |
| mainPath + '/src/appNavigator.js', | |
| templates.appNavigator(projectData) | |
| ); | |
| // Create componentList.js file | |
| const componentsList = await helpers.api.getComponentsList(projectId); | |
| await helpers.file.write( | |
| mainPath + '/src/componentsList.js', | |
| templates.componentList(componentsList) | |
| ); | |
| // Rename project identifiers | |
| if (projectData.activePlatforms.includes('android')) { | |
| shell.exec( | |
| `cd ./boilerplate && react-native-rename "${projectData.name}" -b ${projectData.platformConfigs.android.applicationId}` | |
| ); | |
| } else { | |
| console.log('idddddd : ' + projectData.platformConfigs.apple.applicationId); | |
| shell.exec( | |
| `cd ./boilerplate && react-native-rename "${projectData.name}" -b ${projectData.platformConfigs.apple.applicationId}` | |
| ); | |
| } | |
| if (projectData.sentry.length > 0) { | |
| const iosDsn = projectData.sentry.find((x) => x.platform === 'ios').dsn; | |
| const androidDsn = projectData.sentry.find((x) => x.platform === 'android') | |
| .dsn; | |
| if (iosDsn) { | |
| sed('-i', 'SENTRY_IOS_ID', iosDsn, mainPath + '/App.js'); | |
| } | |
| if (androidDsn) { | |
| sed('-i', 'SENTRY_ANDROID_ID', androidDsn, mainPath + '/App.js'); | |
| } | |
| } | |
| if (projectData.platformConfigs.pushNotification.isActive) { | |
| sed( | |
| '-i', | |
| 'ONESIGNAL_APP_ID', | |
| projectData.platformConfigs.pushNotification.oneSignalId, | |
| mainPath + '/src/components/NotificationController.js' | |
| ); | |
| sed( | |
| '-i', | |
| 'ONESIGNAL-EXTENSION-BUNDLE-ID', | |
| projectData.platformConfigs.apple.applicationId + | |
| '.OneSignalNotificationServiceExtension', | |
| mainPath + `/ios/${projectData.name}.xcodeproj/project.pbxproj` | |
| ); | |
| console.log('onesignal app id updated'); | |
| } | |
| // Download AppIcon file | |
| if (projectData.appIcon !== undefined && projectData.appIcon !== '') { | |
| let iconPath = projectData.appIcon; | |
| if (projectData.appIcon.includes('http')) | |
| iconPath = process.env.AWS_S3_URL + projectData.appIcon; | |
| shell.exec(`npm run file-download "${iconPath}" "${mainPath}/AppIcon.png"`); | |
| } | |
| function hexToStoryBoardRgb(hex) { | |
| hex = hex.replace(/^.*#/, ''); | |
| var bigint = parseInt(hex, 16); | |
| var r = (bigint >> 16) / 255; | |
| var g = (bigint >> 8) / 255; | |
| var b = bigint & 255 / 255; | |
| return ( | |
| '<color key="backgroundColor" red="' + | |
| r + | |
| '" green="' + | |
| g + | |
| '" blue="' + | |
| b + | |
| '" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>' | |
| ); | |
| } | |
| // Download SplashIcon file | |
| shell.exec("chmod u+r+x scripts/prepare_splash_icon.sh"); | |
| shell.exec("chmod u+r+x scripts/splash_icon_generator.sh"); | |
| const splashScreen = projectResponse.screens.find(x => x.type === "splash").components[0].values; | |
| const splashData = { | |
| bgColor: splashScreen.find(x => x.name === "bgColor").value, | |
| image: splashScreen.find(x => x.name === "image").value || projectData.logo | |
| }; | |
| if (splashData.image !== undefined && splashData.image !== '') { | |
| let iconPath = splashData.image; | |
| if (splashData.image.includes('http')) | |
| iconPath = splashData.image.replace(process.env.AWS_S3_URL, ""); | |
| shell.exec( | |
| `npm run file-download "${iconPath}" "${mainPath}/SplashScreen.png"` | |
| ); | |
| } | |
| if (splashData.bgColor) { | |
| sed( | |
| '-i', | |
| '#DF5F27', | |
| splashData.bgColor, | |
| mainPath + '/android/app/src/main/res/values/colors.xml' | |
| ); | |
| sed( | |
| '-i', | |
| '<!--BG_COLOR-->', | |
| hexToStoryBoardRgb(splashData.bgColor), | |
| mainPath + `/ios/${projectData.name}/LaunchScreen.storyboard` | |
| // mainPath + `/ios/LaunchScreen.storyboard` | |
| ); | |
| console.log('Splash Screen BG Color has been updated'); | |
| } | |
| switch (process.env.TARGET_PLATFORM) { | |
| case 'android': | |
| shell.exec( | |
| `npm run file-download "${projectData.platformConfigs.android.credentialId.keyPath}" "${mainPath}/android/api.json"` | |
| ); | |
| shell.exec( | |
| `npm run set-platform-configs android ${projectData.platformConfigs.android.version.code} ${projectData.platformConfigs.android.version.name}` | |
| ); | |
| await helpers.file.write( | |
| mainPath + '/android/fastlane/Appfile', | |
| templates.androidAppFile(projectData) | |
| ); | |
| await helpers.file.write( | |
| mainPath + '/android/fastlane/Fastfile', | |
| templates.androidFastlane(projectData, buildId) | |
| ); | |
| break; | |
| case 'ios': | |
| shell.exec( | |
| `npm run set-platform-configs ios ${projectData.platformConfigs.apple.version.code} ${projectData.platformConfigs.apple.version.name}` | |
| ); | |
| const IOS_APP_NAME = shell.exec( | |
| `ls ./boilerplate/ios/ | grep xcodeproj | cut -d. -f1 | tr -d $'\n'` | |
| ); | |
| let metadata = {}; | |
| if ( | |
| targetEnv === 'production' && | |
| projectData.platformConfigs.apple.metadataActive | |
| ) { | |
| shell.exec('cd ./boilerplate/ios/fastlane && mkdir metadata'); | |
| metadata = (await helpers.api.getProjectMarketData(projectId)).apple; | |
| const metaPath = './boilerplate/ios/fastlane/metadata'; | |
| const ratConfig = metadata.ratingConfig; | |
| Object.keys(ratConfig).forEach(function (el) { | |
| ratConfig[el] = parseInt(ratConfig[el]); | |
| }); | |
| const replacementData = [ | |
| { path: '/copyright.txt', value: metadata.copyright }, | |
| { path: '/primary_category.txt', value: metadata.primary_category }, | |
| { | |
| path: '/review_information/first_name.txt', | |
| value: metadata.reviewInformation.first_name, | |
| }, | |
| { | |
| path: '/review_information/last_name.txt', | |
| value: metadata.reviewInformation.last_name, | |
| }, | |
| { | |
| path: '/review_information/phone_number.txt', | |
| value: metadata.reviewInformation.phone_number, | |
| }, | |
| { | |
| path: '/review_information/email_address.txt', | |
| value: metadata.reviewInformation.email_address, | |
| }, | |
| { | |
| path: '/review_information/demo_user.txt', | |
| value: metadata.reviewInformation.demo_user, | |
| }, | |
| { | |
| path: '/review_information/demo_password.txt', | |
| value: metadata.reviewInformation.demo_password, | |
| }, | |
| { | |
| path: '/review_information/notes.txt', | |
| value: metadata.reviewInformation.notes, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/first_name.txt', | |
| value: metadata.contactInformation.first_name, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/last_name.txt', | |
| value: metadata.contactInformation.last_name, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/address_line1.txt', | |
| value: metadata.contactInformation.address_line1, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/address_line2.txt', | |
| value: metadata.contactInformation.address_line2, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/address_line3.txt', | |
| value: metadata.contactInformation.address_line3, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/city_name.txt', | |
| value: metadata.contactInformation.city_name, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/state.txt', | |
| value: metadata.contactInformation.state, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/country.txt', | |
| value: metadata.contactInformation.country, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/postal_code.txt', | |
| value: metadata.contactInformation.postal_code, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/phone_number.txt', | |
| value: metadata.contactInformation.phone_number, | |
| }, | |
| { | |
| path: '/trade_representative_contact_information/email_address.txt', | |
| value: metadata.contactInformation.email_address, | |
| }, | |
| { | |
| path: | |
| '/trade_representative_contact_information/is_displayed_on_app_store.txt', | |
| value: metadata.contactInformation.is_displayed_on_app_store, | |
| }, | |
| { path: '/rating.json', value: JSON.stringify(ratConfig) }, | |
| ...Object.entries(metadata.name).map((x) => ({ | |
| path: '/' + x[0] + '/name.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.subtitle).map((x) => ({ | |
| path: '/' + x[0] + '/subtitle.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.privacy_url).map((x) => ({ | |
| path: '/' + x[0] + '/privacy_url.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.description).map((x) => ({ | |
| path: '/' + x[0] + '/description.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.keywords).map((x) => ({ | |
| path: '/' + x[0] + '/keywords.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.release_notes).map((x) => ({ | |
| path: '/' + x[0] + '/release_notes.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.support_url).map((x) => ({ | |
| path: '/' + x[0] + '/support_url.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.marketing_url).map((x) => ({ | |
| path: '/' + x[0] + '/marketing_url.txt', | |
| value: x[1], | |
| })), | |
| ...Object.entries(metadata.promotional_text).map((x) => ({ | |
| path: '/' + x[0] + '/promotional_text.txt', | |
| value: x[1], | |
| })), | |
| ]; | |
| replacementData.forEach((item) => { | |
| fsP.writeFileSync(metaPath + item.path, item.value.toString()); | |
| }); | |
| console.log('metadata files created'); | |
| } | |
| await helpers.file.write( | |
| mainPath + '/ios/fastlane/Appfile', | |
| templates.iosAppFile(projectData) | |
| ); | |
| await helpers.file.write( | |
| mainPath + '/ios/fastlane/Fastfile', | |
| templates.iosFastlane(projectData, IOS_APP_NAME, metadata, buildId) | |
| ); | |
| // IOS push notification setup | |
| console.log(JSON.stringify(projectData.platformConfigs.pushNotification)); | |
| if (projectData.platformConfigs.pushNotification.isActive) { | |
| console.log( | |
| 'notif-test', | |
| projectData.platformConfigs.pushNotification.ios.initializationStatus | |
| ); | |
| if ( | |
| !projectData.platformConfigs.pushNotification.ios.initializationStatus | |
| ) { | |
| console.log('Notification intialization started'); | |
| shell.exec( | |
| `cd ${mainPath}/ios && bundle exec fastlane ios initialize_notification_setup` | |
| ); | |
| await api.updateProjectInitializationStatus(projectId, true); | |
| console.log('notification_certificate_manager initialize'); | |
| } | |
| } | |
| shell.exec( | |
| `cd ${mainPath}/ios && bundle exec fastlane ios update_identifier` | |
| ); | |
| // const infoPlist = mainPath + `/ios/${IOS_APP_NAME}/Info.plist`; | |
| // fs.readFile(infoPlist, "utf8", function(err, data) { | |
| // if (err) return console.log(err); | |
| // if (!data.includes("ITSAppUsesNonExemptEncryption")) { | |
| // const replaceString = `</dict> | |
| // </plist>`; | |
| // const replacement = `<key>ITSAppUsesNonExemptEncryption</key><false/>${replaceString}`; | |
| // const result = data.replace(replaceString, replacement); | |
| // helpers.file.write(infoPlist, result); | |
| // } | |
| // }); | |
| break; | |
| default: | |
| } | |
| }; | |
| const args = process.argv.slice(2); | |
| const projectId = args[0]; | |
| const buildId = args[1]; | |
| const targetEnv = args[2]; | |
| generator(projectId, buildId, targetEnv); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment