Build error when setting environment variable - ember-cli

When running ember build --environment staging I get a build error. In config/environment.js I have a condition looking for staging so I can change the baseUrl to our staging services. But when I try and build with the environment set I get the following error:
You must pass a file to 'EmberApp::import'. For directories specify them to the constructor under the 'trees' option.
Is this a problem with ember-cli or do I need to declare my environment in my Brocfile somehow?

Since Ember currently has issues with custom environments, try using shell variables for modifying behaviour inside single Ember production environment.
If you call ember like DEPLOY_ENV=staging ember build --environment=production then you will be able to access DEPLOY_ENV shall variable inside all JS files via process.env.DEPLOY_ENV and modify their behaviour accordingly.
I personally like decoupling deploy environment from application environment, cause it allows to have a staging server which is just like production.

Related

ASP Net Core multiple environment publishing

Coming from the .NET MVC world, I am confused on how .NET Core deals with multi-environment deployments. (Dev, Test, Production)
The tech used here are Bamboo (Build Server) + Octopus Deploy (CD).
.NET Core appears to be using appsettings instead, and web.config is only used for IIS Hosting.
Upon reading some guides, which suggests to add an Environment Variable "ASPNETCORE_ENVIRONMENT" to the project to define the environment currently in.
This is the command I used to build in Bamboo.
dotnet publish -c Test ${bamboo.build.working.directory}\HelloWorld.sln
Questions...
1. I have appsettings.json, appsettings.Test.json, appsettings.Production.json.
It looks like the app knows which appsettings file to read from, based on the
ASPNETCORE_ENVIRONMENT value.
How can I tell Octopus to use the correct file based on the environment I am deploying to?
Having a variable and multiple config files packaged up make things overly complicated, especially if you're using Octopus Deploy.
The only reason for having multiple .environment.json files is because these are probably held in source control and they have their values already set - so environment variables are probably all coming from the source code, rather than the release manager. Otherwise, they'd be identical files and Octopus would still be transforming them (which makes them redundant)
My advice would be to move to a single file, and move the variables into Octopus Deploy. Remove the ASPNETCORE_ENVIRONMENT and you only need one file appSettings.json, which can be transformed during deployment to whatever environment.
ASP.NET Core Web Applications - Octopus Deploy Documentation
Hope this helps

How do you configure jshint or eslint differently per environment in ember-cli?

I want to support the usage of 'debugger' statements locally and on the development deployment but not when it gets to staging or production.
I'm using Ember-cli with environments and am not understanding how to define the jshint or eslint directives differently.
By design we can configure both linting libraries differently via their configuration files for app code & test code via .eslintrc or .jshintrc files which reside at the root folder and the tests folder. So even though we can have different rules for these categories of code, we can't differentiate them per environment.
The reason it might not make sense to do so is because the assets that get generated after the build process that gets deployed doesn't necessarily need to conform to these rules since transpilers like babel (may) optimize generated code for us.
While I don't understand the need to keep debugger statements after a debugging session in the codebase, you can use broccoli-strip-debug to remove them automatically in production builds and disable the debugger flag in the linting configuration altogether which gets you the setup you're looking for.

web.config changes via TFS 2015 Release Management

In the past I've using web.config transforms when manually deploying code to set environment specific setting values and attributes. I am transitioning from environment specific manual builds to a single TFS 2015 Build deployed to multiple environments via Release Management. Environment specfic application settings values configured in the web.config are tokenized. This method essentially inserts tokens into setting values during the build process. When deployed the tokens are replaced with matching Release definition configuration values.
This method is insufficient setting attributes of non-settings however. Examples of these transforms include:
<httpCookies requireSSL="true" xdt:Transform="Insert" />
<compilation xdt:Transform="RemoveAttributes(debug)" />
<httpRuntime xdt:Transform="RemoveAttributes(executionTimeout,maxRequestLength,useFullyQualifiedRedirectUrl,minFreeThreads,minLocalRequestFreeThreads,appRequestQueueLimit,enableVersionHeader)"/>
<httpRuntime enableVersionHeader="false" maxRequestLength="12288" xdt:Transform="SetAttributes"/>
<customErrors mode="On" xdt:Transform="SetAttributes"/>
What is the best way to update these attributes during release?
Both Web Deploy's parameters.xml method and transforms can be used with Release Management. Transforms would be triggered from Build and the process of replacing tokens created by a publish would be triggered by Release Management.
To trigger transforms during the build, you can do this one of two ways:
Add the following MSBuild parameters to force the transformation to happen during the build
/p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false
Create a publish profile using the MSDeploy Package option and then trigger the packaging in Build using the following MSBuild parameters:
/p:DeployOnBuild=true /p:PublishProfile=[nameOfProfile]
Either of the above methods will cause normal Web.config XDT's to run. If you need other XML files to be transformed, you'll need to first install SlowCheetah.
Token Replace and Parameters
Now that you have a build artifact with XDT's run, you can use token replacement and the WinRM tasks from Release Management. These will take the Web Deploy package from the Build and execute the SetParameters command before deploying it. The trick is to take the SetParameters.xml file and run a token replace on it first, swapping out Release environment variables first.
User Sumo gave a proper answer, but I want to record some comments related to what instead of how.
IMHO there are different categories of settings to consider, let's exemplify. The database connection string changes at each environment, while requiring SSL should be turned on for all testing and production environments.
In this perspective, you should have settings applied as early as possible, traditionally at build time and called Debug/Release builds; and last-minute settings, environment dependent, up to runtime settings, like Feature toggles.
So in my view you can use a single tool or multiple tools, but it is important that you properly categorize your settings accordingly.

How to parameterize Bamboo builds?

Please note, although my specific example here involves Java/Grails, it really applies to any type of task available in Bamboo.
I have a task that is a part of a Bamboo build where I run a Java/Grails app like so:
grails run-app -Dgrails.env=<ENV>
Where "<ENV>" can be one of several values (dev, prod, staging, etc.). It would be nice to "parameterize" the plan so that, sometimes, it runs like so:
grails run-app -Dgrails.env=dev
And other times, it runs like so:
grails run-app -Dgrails.env=staging
etc. Is this possible, if so, how? And does the REST API allow me to specify parameter info so I can kick off different-parameterized builds using cURL or wget?
This seems to be a work around but I believe it can help resolve your issue. Atlassian has a free plugin call Bamboo Inject Variables Plugin. Basically, with this plugin, you can create an "Inject Bamboo Variables from file" task to read a variable from a file.
So the idea here is to have your script set the variable to a specific file then kick off the build; the build itself will read that variable from the file and use it in the grails task.
UPDATE
After a search, I found that you can use REST API to change plan variables (NOT global). This would make your task simpler: just define a plan variable (in Plan Configuration -> tab Variables) then change it every time you need to. The information on how to change is available at Bamboo Knowledge Base

Passing RAILS_ENV into Torquebox without using a Deployment Descriptor

I am wondering if there is a way to pass a value for RAILS_ENV directly into the Torquebox server without going through a deployment descriptor; similar to how I can pass properties into Java with the -D option.
I have been wrestling with various deployment issues with Torquebox over the past couple weeks. I think a large part of the problem has to do with packaging the gems into the Knob file, which is the most practical way for managing them on a Window environment. I have tried archive deployment and expanded deployment; with and without external deployment descriptor.
With an external deployment descriptor, I found the packaged Gem dependencies were not properly deployed and I received errors about missing dependencies.
When expanded, I had to fudge around a lot with the dependencies and what got included in the Knob, but eventually I got it to deploy. However, certain files in the expanded Knob were marked as failed (possible duplicate dependencies?), but they did not affect the overall deployment. The problem was when the server restarted, deployment would fail the second time mentioning it could not redeploy one of the previously failed files.
The only one I have found to work consistently for me is archive without external deployment descriptor. However, I still need a way to tell the application in which environment it is running. I have different Torquebox instances for each environment and they only run the one application, so it would be fairly reasonable to configure this at the server level.
Any assistance in this matter would be greatly appreciated. Thank you very much!
The solution I finally came to was to pass in RAILS_ENV as a Java property to the Torquebox server and then to set ENV['RAILS_ENV'] to this value in the Rails boot.rb initializer.
Step 1: Set Java Property
First, you will need to set a Rails Environment java property for your Torquebox server. To keep with standard Java conventions, I called this rails.env.
Dependent on your platform and configuration, this change will need to be made in one of the following scripts:
Using JBoss Windows Service Wrapper: service.bat
Standalone environment: standalone.conf.bat (Windows) or standalone.conf (Unix)
Domain environment:: domain.conf.bat (Windows) or domain.conf (Unix)
Add the following line to the appropriate file above to set this Java property:
set JAVA_OPTS=%JAVA_OPTS% -Drails.env=staging
The -D option is used for setting Java system properties.
Step 2: Set ENV['RAILS_ENV'] based on Java Property
We want to set the RAILS_ENV as early as possible, since it is used by a lot of Rails initialization logic. Our first opportunity to inject application logic into the Rails Initialization Process is boot.rb.
See: http://guides.rubyonrails.org/initialization.html#config-boot-rb
The following line should be added to the top of boot.rb:
# boot.rb (top of the file)
ENV['RAILS_ENV'] = ENV_JAVA['rails.env'] if defined?(ENV_JAVA) && ENV_JAVA['rails.env']
This needs to be the first thing in the file, so Bundler can make intelligent decisions about the environment.
As you can see above, a seldom mentioned feature of JRuby is that it conveniently exposes all Java system properties via the ENV_JAVA global map (mirroring the ENV ruby map), so we can use it to access our Java system property.
We check that ENV_JAVA is defined (i.e. JRuby is being used), since we support multiple deployment environments.
I force the rails.env property to be used when present, as it appears that *RAILS_ENV* already has a default value at this point.