Codemagic - Set Dynamic Environment Variables for the Build arguments - flutter

I am looking a way to manage dynamic environment variables in my build arguments.
I am able to make it work if I define values for TARGET_FILE and FLAVOR in the environment variable section in CodeMagic.
But my goal is to have the values specified in my git repository. So I will be able to change it and have a dynamic build.
I was thinking I would be able to set the env var in the pre-build section.
Following is a sample of my pre-build.sh file
# in my case it’s `dev`, `qa` and `prod`
export FLAVOR='qa'
# major and minor part of app version e.g. 1.0
export VERSION_NUMBER='1.0.0'
# this is the entry point of the app e.g. main_dev.dart
export TARGET_FILE="lib/main_$FLAVOR.dart"
My build is still failing because the TARGET_FILE for example is not specified
Target file "--flavor" not found.
Build failed :|
Failed to build for Android
I was wondering if anyone has ever encountered this scenario

As for configuring build from GitHub you can use codemagic.yaml file that allows you to define the configuration for CodeMagic build, including env variables (here is a docs).
Additional notes, just a proposition))
I actually don't know what is going on in your Flavors and env entry points, but quite possible you can actually get rid of both.
For instance, you can use .env file and flutter_config package to pass env specific variables to the native layer, including plist's and Gradle. Also, you can load this .env file into Dart code and use variables from it. On top of this, you can use this package to generate .env file with the terminal command (if you don't want to create any sh scripts))). Alongside with .env file, it can generate Dart class specifically for Dart code. It also can generate files based on global env variables.
In that way all environment specific configuration will be defined once, you won't expose your prod credentials anywhere except build tool and you won't need to copy/paste multiple entry points.
Update 08/05/2020:
Starting from Flutter 1.17 you can use --dart-defines argument instead of environment_config and flutter_config package to define compile-time variables. You can read more about this argument here

Related

where does the variables defined using "--dart-define" go and can we reverse engineer them?

I am building a flluter application.
I don't want to compromise my secret_key by putting it in the code, so I tried making a .env file and created an apk. Then I unzipped the apk and found my config file there. So now I am not doing that.
The next thing I tried is using --dart-define variable declarations to put my secret_key while building the app and I am accessing it using
const secret = String.fromEnvironment("secret_key");
Coming to the question, where do these variables go inside the dart code and is there a way to get them by reverse engineering.
Basically is it safe to put my secret key this way?
From what I found, you can find the --dart-define variables in the binary file generated for each ABI, so yes, you can reverse-engineer it.
How to try:
Call the variable from your code with String.fromEnvironment("ANIMAL").
Run flutter build apk --dart-define=ANIMAL=Dog to build for Android
Open the generated .APK file with a file archiver (7-Zip, for example) and navigate to /lib/(ABI)/
Open /lib/(ABI)/libapp.so file with a text editor or hex viewer and search for the value Dog and you will find it
Observations:
If you don't use the variable in your code, it won't be added to the binary
Using --obfuscate with flutter build won't help, because it doesn't obfuscate environment variables

How do I run a project in eclipse with different jboss-ejb-client.properties

I have EJBs deployed on several different servers, for different environments. I have many projects that use these EJBs. I usually just run my projects against the DEV server EJBs, but sometimes I need to run against the TEST or PROD environment EJBs. This necessitates having to comment out all of the DEV nodes in my jboss-client-ejb.properties file and uncomment all of the TEST nodes. But then if I forget to change them back, I may mess up some data if I run it later. What I would like to do is create a different runtime configuration for each environment, and have each runtime config use a different version of the jboss-client-ejb.properties. Is there a way to do this? If so how? I have looked at all of properties of a run configuration, and don't see anything helpful.
In eclipse preferences search for string variable substitution. Here create variables that point to multiple config files for each of your environments. Then create multiple run configurations and for each one (like dev or prod) add a program argument that points to your string variable defined in your preferences like this -DmyconfigFile={$MyDevPropertiesFilePath}, or you could hard code the config path and have multiple runtime configurations that use different config files. Key point here is create multiple runtime launch configurations for each environment and add the properties for each environment that point to the config file respective to each environment. This way you can easily select the launch menu and decide to run "dev" "prod" or whatever you name your multiple configurations. Trying to do this with one runtime configuration will cause pain as you say, because it is easy to forget to revert or change the config file you want to to use. Hope that helps. Also if you create a new workspace you can export your runtime configurations using the export wizard which is also helpful for passing on to other developers or putting in source control.
P.S Looking more at your question you wan to pass in the config file path as a program argument, you are correct there are no specific options for setting this file path. Using program arguments with multiple launch configurations.

how do i change values in .properties file and run a build using this in jenkins

i have a basic job that runs a .bat file to do an export of an application from a file server somewhere. it uses a .properties file in standard format to get the login details, server location and application name/version etc
i've made it work from command line and hard coding the values in the .properties file and running it. the export works and saves in the directory i specify.
i moved over to jenkins and it also works using the hardcoded .properties file.
what i want to do now is set the values in the .properties file inside jenkins so it can be updated without having to manually open the .properties file and then run the same .bat file
if someone could provide an example of setting just one value in a .properties file through jenkins, i feel i can do the rest.
You can try to use the EnvInject Plugin for Jenkins which allows to inject environment variables into build process, and modify your .bat file to use them instead of reading values from the properties file.
Here are some of the plugin's usecases/features:
To remove inherited environment variables (PATH, ANT_HOME, ...) at node level (master/slave), available by default for a job run.
To inject variables in the first step of the job (before the SCM checkout)
To inject variables based on user parameter values
To execute an initialization script before a SCM checkout.
To execute an initialization script after a SCM checkout
To inject variables as a build step obtained from a file filled in by a previous build step
To know environment variables used for a build
To inject build cause as environment variable for a build
To inject environment variables from the evaluation of a Groovy script (powered by Script Security Plugin)
To export environment variables as a metadata in your binary repository

Packaging with NAnt, how to handle different environments

I'm using NAnt to build an ASP.NET MVC project.
The NAnt script then creates a zip package, containing a deploy script and all the necessary files.
The deploy script backs up the current running website, sets up the newer version of the website and updates the DB.
This works fine for a single environment.
However, we're asked more and more to set up a Staging/Acceptance environment next to the production. These environments, of course, differ in file structure, DB server, config settings etc.
How can I best handle this in the deploy scripts? I don't want to create separate variables for each environment, distinguishable by name only.
Providing defaults and providing the variables in separate files seems more logical.
Does anyone have practical experiences with this?
Store the things that you think are likely to change between environments in config files.
Visual Studio can do the heavy lifting here if you like; you can create settings and specify default values from the Settings tab of a Visual Studio project's properties.
This will create the config file for you and provide strongly-typed access through Properties.Settings.Default.
As for handling multiple environments through your build, I've seen some people recommend maintaining multiple copies of the config files - one for each environment for example - and others recommend using nant to modify the config files during the build or deployment phase. You can use a property passed to nant on the command line (for example) to select which environment you are building (or deploying, depending on how you're doing it).
I don't recommend either of these approaches because:
They both require changes to your build to support new environments.
If you change a setting in a deployed environment and forget to update the build then the next deployment will reset the change (somewhat defeating the point of config settings).
If someone creates a new environment (lets say they want to explore issues arising from upgrading to a new version of SQL Server for example) and doesn't fancy creating all new config files in the build system, they might decide to just use an existing environment's settings. Let's say they choose to deploy using the live settings and forget to change something afterwards. Your new 'test' environment could now be pointing to live kit.
I create a copy of each config file (called web.config.example, for example) and comment out the settings within them (unless they have meaningful defaults). I check these in and have those deployed instead of the real web.config (that is, web.config is NOT deployed automatically. web.config.example is deployed as web.config.example.
The admin of the new environment will have to copy and rename the file to web.config and provide meaningful values). I also put all the calls to the settings behind my own wrapper class - if a mandatory setting is missing I throw an exception.
The build and my environments no longer depend on each other - one build can be deployed to any environment.
If a setting is missing (a new environment or a new setting in an existing environment) then you get a nice clear exception raised to tell the admin what to do.
Existing settings are not altered after an upgrade because only the .example files were updated. It's an admin task to compare the current settings with the latest example and revise if necessary.
To configure the deployment, you could put all the environmental settings (install paths, etc) into nant properties and move them into a separate file (settings.build for example) then use the nant include task to include that file at the top of your deployment file (deploy.build for example). You can then deploy a new version of deploy.build without overwriting your config changes as they are in settings.build. If a new property is introduced into deploy.build nant will fail with a nice message to tell you that you haven't set that property.

Copy file to the App Resources directory if debug configuration is selected

I need to copy a few files into the App's Resources directory during debug builds. I am thinking about using build rules but don't know how to determine if the build is a debug build. I do have a compiler option of "DEBUG" set.
You can use a Run Script build phase to do the copying. All build settings applied when building the target are available via environment variables in your script.
You can determine what configuration is being built via the CONFIGURATION environment variable; you can look at other environment variables like BUILT_PRODUCTS_DIR to determine where to put your resource. If you specify your Run Script build phase's output correctly, it will only be run when the output needs to be brought up to date, not every time you build.
More information on Run Script build phases is available here: Xcode Build System Guide: Build Phases: Run Script Build Phase
The same kind of thing can be done with script build rules, which is useful if you have multiple resources you want to apply this to: You can create a script build rule that matches your extension (e.g. *.myresource) and use the build settings and input files that are passed to your script via environment variables to do the actual copying. If you specify your build rule's output correctly, it will only be run when its input is newer than its output, not every time you build.
More information on script build rules is available here: Xcode Build System Guide: Build Phases: Build Rules