9
votes

I have a vue.js application that is creating and building using vue-cli 3. I have some environment variables in .env.test and .env.prod files.

To build the app I'm using a azure devops build pipeline where I run the command: npm run build:test or npm run build:prod

That generates different artifacts that are input for Stage in azure devops release pipeline.

The problem I'm facing is I don't want to have separate builds for every environment. I want to build one and deploy to different environments is that possible?

How do I handle those variables to build once package for all environments? Is it a good practice? Or should I have different pipelines for different environments as I have right now?

2
You shouldn't need multiple pipelines to achieve your goal. Are you asking how to configure the build such that it will output a test and prod artifact folder?Steve L.
Did you ever figure this out? I have the same issue.alec
Hey alec, no I've never figured out. I just quit from using azure release pipelines and move forward with just build pipelines where I have some AWS tasks that make the deployment.chamix
@chamix let me know if my answer below does help you, otherwise, I could extend answer providing more detailsSerhii Kyslyi

2 Answers

9
votes

From perspective of CI

There should be only single build pipeline that will build artifact regardless of the environment where it will run.

.env.prod might be used to deploy artifacts to any environments (Development, Production, etc.)

You have to provide configuration with tokens, which will be replaced on Deployment/Release stage:

env_key1=#{token_key1}#
env_key2=#{token_key2}#
env_key3=#{token_key3}#

Therefore, just build project and publish artifact using single configuration file for all environments.

From perspective of CD

I would recommend to use single release pipeline with multiple stages (Development, Production, etc). enter image description here

Provide separate variables groups based on stages. It allows to keep variables separate, logically grouped and use Azure Key Vault as source of secrets. Variable names must be equal to environment tokens (without prefix and suffix).

enter image description here

Add any Task you wish into Stage, which will find and replace tokens.

Currently, I use Replace Tokens extension from marketplace. Depend on stage, different group of variables will be substituted. Replace Tokens task does all of the job automatically, e.i. scans js files and replaces tokens. Default token prefix and suffix are: #{ }#, but task allow to provide custom you wish. enter image description here

0
votes

So we had a similar problem. We are about to update our solution to work with a variable group, but if you want a way to do it without one you can always do something like this:

- script: |
    npm install
    npm run test:unit
    if [ $? -ne 0 ]; then
        exit 1
    fi
    npm run build-prod
  condition: and(succeeded(), not(in(variables['Build.Reason'], 'PullRequest', 'Manual')))
  displayName: 'npm install, test and build for prod'

- script: |
    npm install
    npm run test:unit
    if [ $? -ne 0 ]; then
        exit 1
    fi
    npm run build
  condition: and(succeeded(), in(variables['Build.Reason'], 'PullRequest', 'Manual'))
  displayName: 'npm install, test and build for test'

So quick breakdown on the scripts. If the build was part of a PullRequet or manual we wanted a staging build which used the default build script. Otherwise we assumed the build was meant for production (You will want some branch policies to enforce this). Then the release pipe-line checked for the a build tag which we set with the following:

- task: PowerShell@2
  condition: and(succeeded(), not(in(variables['Build.Reason'], 'PullRequest', 'Manual')))
  inputs:
    targetType: 'inline'
    script: 'Write-Host "##vso[build.addbuildtag]release"'

- task: PowerShell@2
  condition: and(succeeded(), in(variables['Build.Reason'], 'PullRequest', 'Manual'))
  inputs:
    targetType: 'inline'
    script: 'Write-Host "##vso[build.addbuildtag]test"'

Now, like I said we are moving away from this, but it did work pretty well and it allowed us to have one build that would deploy with the correct settings without needing to do anything too fancy.

If you use something like this the last step is filter the builds when they get to the release pipeline based on the build tag and branch.