At this point, when a commit happens to the Master branch, a build pipeline will generate an artifact based on "ng build --prod", so this artifact uses the production configuration for the project. After that, the artifact will be deployed to the test and production environments.
For the test environment, I want the code to use "environment.dev.ts" and for production "environment.prod.ts". How can I achieve that?
There are many ways. I am doing it using "Tokens" My production environment looks like this
export const environment = {
production: true,
host: 'https://#{{FLYMARK_MAIN_DOMAIN}}#',
stripeKey: '#{{STRIPE_KEY}}'
};
So when I build my version is not usable because instead of variables i have tokens.
Then when I do release I do have step to replace tokens. this need to run before you deploy scripts (just modify to your needs)
steps:
- task: qetza.replacetokens.replacetokens-task.replacetokens@2
displayName: 'Replace tokens in **/Scripts/widgets/**/*.js'
inputs:
targetFiles: '**/Scripts/widgets/**/*.js'
actionOnMissing: fail
tokenPrefix: '#{{'
tokenSuffix: '}}#'
This task will find my release variables like FLYMARK_MAIN_DOMAIN, STRIPE_KEY and replace in my js files.
Main benefit is that you build once and can deploy to anywhere just need to replace tokens
PS. Lets say you have dev, staging, prod. Now To dev you deploy after build which is triggered by new push to master, to staging you release when its approved (azure pipeline support that)
So now lets say you have in dev version 100, you decided to push it into staging and your team start testing. After 3 days your development team pushed to master lots of new stuff so on dev you have version 123, but in staging you still have version 100. After team tested in staging you will push same version to production because you are confident, if you will use separate builds for environment when you are ready to deploy to production you have lots of new stuff in master and maybe you are not confident to push it to production. Again each case is different and there is many ways to do it, I just like this way of doing because it suits my projects.
My organization does not allow installing third-party extensions on DevOps. Therefore the top-voted answer was a no go. So I took a different approach. In the build pipelines, I created two build artifacts: one for QA, one for PROD. Different environment files were used in those build steps (Ex: ng build --c qa
). Both were using production:true
.
Then I published both of them to be consumed from the release pipelines. In the QA stage, I deployed the QA build to test servers.
Once testing has passed and signed off to be promoted to PROD, I could simply use the Azure DevOps approval workflow. When it is promoted to PROD stage, I used the PROD build for deployment.
I know, I'm not using the same build which got QA verified when deploying to PROD. But at least those builds were created on the same agent, almost at the same time so I guess that is an acceptable compromise.
Even if you use the tokenizer as the other answer suggests, you still end up with somewhat tampered artifact IMO. But then again that is something you have to live with, given that Angular needs to bake its config in. So when it comes to deployments, you will always be promoting a conceptually 'impure' artifact across your environments, one way or the other.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With