How does a Cordova app build know what CodePush environment is applicate? - code-push

I have a CodePush app that has three deployments: testing, staging and production.
I have different app builds that align with these:
A build that does out to testers (testing)
A build that goes out to a group of preview users (staging)
A production build (production).
How does CodePush know what deployment it should be sending to a build?
And how do I set up my app to make sure the right build (e.g. staging version of app) is getting the right deployment (e.g. staging deployment in CodePush)?

The CodePush server knows which deployment you want to query for updates against based on the deployment key which is configured in the config.xml file or is passed to the call to sync (with the later taking precedence). If you want to generate three separate builds for QA/staging/production, then you simply need to make sure you update the deployment key that is set in your config.xml file before running cordova build to generate the APK or IPA file.
Unfortunately, Cordova doesn't really have a standard way of defining multiple environments, which would allow you to add your per-environment keys to the config.xml and have the right one be selected when doing an environment-specific build.
Depending on how your app is structured, you could also skip the config.xml file completely, and just pass the deployment key directly to the call to sync(). Then, you just need to make sure your app defines all the neccesary keys in a config somehow and loads the correct one for each build. You can take a look at this starter project for an idea of how this could be generally done.

I have configured CodePush for my dev, test and prod environments. But my application is a react-native one. I think the same will works for Cordova as well.
The important point is CodePush identify particular app by it's CodePushDeploymentKey. First you should create 3 channels on AppCenter for dev, test and prod. Then setup CodePush on those 3 environments and Get relevant CodePushDeploymentKeys.
Then you have to add those 3 keys for 3 different targets on your app. For iOS you can create 3 different targets on Xcode with 3 different plist files and add those different CodePush keys in relevant plist files.
For android you can create 3 different Product Flavors for dev, test and prod and then add DeploymentKeys on each flavor.
In this article I have explained everything step by step with all the screenshots and links.

Related

How can I test a build while developing a feature without updating to the testflight or any other testers

I am developing an app. I need to test my build before handling to other testers. How can I automate that and how can I build this.
Note: Now I am using testflight to upload (fastlane) my build to the testers. But If I upload this the other testers giving feedbacks. Here I need to test it thoroughly in real device and then I need to submit under testflight.
Can anyone have any idea how can I test it internally before giving the build to testers?
Also, If I archive the file via Xcode to generate ipa file does it make any certificate issues while generating the ipa and installing in real device.
I would suggest to build an ipa file for Ad-hoc deployment since you want to test it internally and if you are in a hurry.
If you have more time. You can update your iOS fastlane Fastfile to increment the build number using "increment_build_number" to prevent override:
desc "Push a new release build to TestFlight"
lane :beta do
increment_build_number(xcodeproj: "sampleAppFLwk.xcodeproj")
match(type: "appstore")
cocoapods
build_app(workspace: "sampleAppFLwk.xcworkspace", scheme: "sampleAppFLwk")
upload_to_testflight(
skip_waiting_for_build_processing: true
)
clean_build_artifacts
end
Solution 1: XCode
You can make a release build from within XCode and run it on local device. Make sure your scheme is configured for release. Go to Product > Scheme > Edit Scheme > Run > Info, set Build Configuration to Release, and uncheck Debug executable. Note that you need the correct certificates to make a release build like this.
I don't know how you could automate this however, so solution 2 might be better and definitely more scalable.
Solution 2: TestFlight Groups
TestFlight lets you have multiple test groups. This means a freshly submitted build doesn't necessarily have to be visible to all testers. Read more about creating groups and adding groups to a build here
Hope this helps :)

Is there a difference between the staging and production env in code push?

I accidentally push the binary with staging key. Is there any real difference between the two stages(in terms of cli / library setting) aside from the obvious naming differences ?
Will I have problem trying to push updates using the staging env?
Code push Staging deployments are for debug builds (app-debug.apk)s while Production is as you guess, production releases (app-release.apk)s.
Refer to this text on their README here, Saying:
And that's it! Now when you run or build your app, your debug builds will automatically be configured to sync with your Staging deployment, and your release builds will be configured to sync with your Production deployment.
In your case I think you won't have any problems pushing updates with staging env as it a feature but they will be limited to app-debug.apks and not app-release.apk ones.
I would guess you wrote something like
code-push release-react <appName> <platform>
Then it said something like this
Upload progress:[==================================================]
100% 0.0s Successfully released an update containing the
"/tmp/CodePush" directory to the "Staging" deployment of the
"APP_NAME" app.
This is staging and should be used to test your app in the devices you installed the app-debug.apk bundle so you know how your update is going to work.
If you are okay with it, then you should promote it to the Production builds with
code-push promote APP_NAME_HERE Staging Production
Or Follow this answer here: How to update "Production" deployment using Code Push CLI?
to just release an update straight to production builds.
To answer your question:
Is there any real difference between the two stages(in terms of cli /
library setting) aside from the obvious naming differences
I can say - no, there is no difference and its up to you to decide how to build your workflow (although there are some practices in terms of how you can use it e.g. https://github.com/Microsoft/react-native-code-push#multi-deployment-testing).
The difference between two of this is more on semantically level and how you will use it depends upon you.
Moreover you can create arbitrary number of deployments if having a staging and production version of your app is enough to meet your needs.
You can use code-push deployment add <appName> <deploymentName> for this.
Also you can rename/delete deployments if it is needed.

IBM Ready Healthcare app migration from v6.3 to v8.0 issue

I am trying to migrate the IBM Ready Healthcare app (https://github.com/IBM-MIL/IBM-Ready-App-for-Healthcare) from v6.3 to v8.0.
I ran "mfpmigrate client ..." command from 'healthcare-mfpf' folder (folder structure shown below), and I got "No supported platforms were detected to migrate" error. Next, I ran the command "mfp add environment" in order to add the environment, that would add the platform. However, I get an error saying that there needs to be a hybrid app available to add environment. I had no luck on running the commands from apps folder as well (folder structure shown below).
Would anyone please kindly let me know the folder I should run the command from, or do I need to go through some extra steps before I can run the "mfpmigrage client ..." command.
Folder structure
Notice: please note that the Ready Apps are no longer maintained by IBM. Just take this under considerations
This project is a Hybrid app, meaning you need to first add it to MobileFirst Studio and then add a supported environment. The project does not come with environments by default.
Only once you do this step will the migration tool find a platform (= environment) to migrate from...
Looking at the file structure you've provided, it's wrong.
It shows:
Apps
- android
- iphone
It's supposed to be:
Apps
- some app
--- android
--- iphone
--- common
It could be that they call the app in the platform name, but that doesn't matter, it still needs to have the environment folder, so maybe to "Android" you need to add the "Android environment" (right-click > add environment...).
It could be because you thought this is Cordova app and used mfp add environment in the wrong filesystem location (also looks like you're trying to use a CLI instead of Studio?).
Looking at the GitHub repository, this whole structure is unconventional and it's not clear why they did it this way.
The links to the documentation there are also dead. This looks like a dead project.

Setting up xcode configuration/scheme for beta distribution

I'm trying to create a way to be able to distribute a beta version of my app via Testflight without overwriting the production version. I'd like to be able to know in the code whether it's a beta build or a production build (i.e. somehow define #if BETA_VERSION, similar to the global DEBUG variable), and I'd like to be able to differentiate it with a separate app icon on the springboard, as well as a different app name (i.e. MyApp Beta or similar).
I set up a beta configuration by duplicating my release configuration, and I already have a provisioning profile for AdHoc builds (I've been distributing via Testflight for the last six months or so). I know that to change the app name I need to change the bundle display name property in the project's plist file, but I'm not really sure how to make a separate "profile" to hold all of these changes.
I've tried reading through this article, but I couldn't get it to work and I inadvertently messed up all my provisioning profiles when going through the instructions.
I've been struggling with this for a few weeks now. The details of this process are pretty opaque, so any detailed instructions or pointers are particularly appreciated.
Thank you in advance!
PS it probably doesn't help that I'm really confused about the relationship between targets, schemes, and configurations in Xcode.
I use three configurations in my project: Release, Beta and Debug, where Beta is a duplicate of Release. In each of the three configurations, I'm including the following in my target's build settings:
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) CONFIGURATION_$(CONFIGURATION)
What this will do is define a separate preprocessor macro for each configuration. In your code, you can then do the following:
#if defined(CONFIGURATION_Beta)
// Something that should only happen in Beta builds
#endif
You can define additional build settings per-configuration in the “User-Defined” category (at the bottom of the build settings in Xcode), and then reference them in your Info.plist file. For example, you could define a custom BUNDLE_ID build setting that's different for Release, Beta and Debug builds, and then set the value of CFBundleIdentifier in your Info.plist file to ${BUNDLE_ID}, which would allow you to install Release, Beta and Debug builds side by side on your device.
Update:
If you want to see a good example of how to set all of this up, check out the project configuration in Cheddar for iOS.

How do i prevent Xcode from overwriting iTunes binary?

I have a really annoying problem. My app is published in the AppStore.
Everytime i run the app from Xcode, the iTunes binary just gets overwritten... and next time i need to test something with the production version of the app, i need to re-download it.
Is there any way to solve this?
Thanks in advance!
You need to change your bundle identifier. Here's how I set it up in my projects
Select your Project
Select your target
Navigate to the Info tab
Change the bundle identifier to a custom build setting e.g. I have it as ${BUNDLE_IDENTIFIER}
Now click on Project - (you may wish to keep at target level your choice)
Navigate to the Build Settings tab
Scroll all the way to the bottom to see User-Defined
Click Add Build Setting
(1) Select Add User-Defined Setting
(2) Add Key as the name you chose earlier
Set a different bundle identifier for each scheme
Bonus
You can use the same trick for icons so you can easily tell apart your builds on one device
Changing the bundle identifier, as Paul.s suggested, works — but it means your Release and Debug builds will diverge. Technically they will be different apps that use different containers. There can be good reasons to do this, but it has it's risks too: it's a bit more complicated, and you usually have to work a little harder to make sure you test that the development version properly handles data from the production version. You'll want to make sure any ad hoc builds you send to testers use the production bundle identifier.
Another way to approach the problem is to streamline installing the old version. If you Archive your production builds, then you can install them without downloading them again through the App Store. Just open-up a previously exported IPA and sync.