8

I have a task to deploy aspnet core React application to 2 different environments: development and production environments. Each of this environments should be configured separately.

I use Azure devops for CI/CD

AspNet project contains following commands for building application

    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

I use adal for authorization that is why I have to pass some secret variables that are different for Dev and Prod

const adalConfig = {
    tenant: process.env.REACT_APP_TENANT,
    clientId: process.env.REACT_APP_CLIENT_ID,
    redirectUri: process.env.REACT_APP_REDIRECT_URI,

In Azure devops I set params with command:

echo ##vso[task.setvariable variable=REACT_APP_TENANT;isOutput=true]c00000-00ce-000-0f00-0000000004000

in the azure devops I have next standard commands for aspnet core build app

  • .Net core installer
  • Resore
  • run command (to set env variables)
  • Build
  • publish

Issues:

  1. Environment variable is not set.
  2. I even don't know how to build another artefact for production, but not for development.

Maybe you already had task to deploy core react app to 2 different environments? Or please give advice if I need to change deployment strategy at all.

The only solutions what I found is to use .env file but I have to commit this file to git - to deploy it from master. And I still don't know how to use different files for dev and prod.

halfer
  • 19,824
  • 17
  • 99
  • 186
NILF
  • 367
  • 2
  • 7
  • 1
    You have to actually set the environment variable(s) as part of the pipeline in some way. How is dependent on how you're deploying, which you haven't provided any information for. For example, in an App Service, you'd add it to the settings. – Chris Pratt Oct 28 '19 at 13:51
  • 1
    Agree with Chris, how are you deploying? What's the difference between these two deployment ways? Just the different config or other? You's better update with these details. Only with deployment detailed message, then SO users could help you find the best strategy. – Mengdi Liang Oct 29 '19 at 05:37
  • You do need to run either the development mode or production mode in vue.js because the build is very different. The problem for me as well, is that there is no way to set up at build time that environment variable. You can use .env.production which you can commit, but you shouldn't be using the main one. The problem is mainly that in the config.vue.js, if you refer to your webpack config, you need to specify the mode as well and well....how can you make sure this work in all environment ? I'd say the only way this is possible is through a token replacement plugin. Azure as several open source – NewBie1234 Feb 10 '20 at 13:00

1 Answers1

1

TLDR;

  1. You have isOutput=true in your task.setvariable command. This only sets a variable in Pipelines engine, to be available to other steps, but doesn't actually map to an env variable. Remove isOutput and you shall see REACT_APP_TENANT env variable.
  2. But only in the following steps - the env variable is not immediately accessible in the same pipeline step.
  3. You can define variables at pipeline level if you know their values upfront - that should simplify things. task.setvariable is more useful for dynamic variables.
  4. If you need different process (or a different set of variables) for different environments, I recommend using multistage YAML pipelines or classic Releases. They both allow for setting up different stages, each with their set of variables.

Long story

We need to distinguish two separate processes:

  1. Deployment pipeline that's executed on CI agent
  2. Web application that may be hosted in many different ways - Azure Web Apps, self hosting, docker/k8s, etc.

Doing echo ##vso[task.setvariable ...] sets the variable in the pipeline (1.).

The place where reading variables takes place (like tenant: process.env.REACT_APP_TENANT) isn't that obvious. If it's nodejs server-side code, it'll be executed in 2. If it's a part of some build script, it'll be read in 1.

React is tricky, because:

  • It react behaves differently in development and release mode. In Release mode, during the build phase, the whole client-side code is compiled down to a static JS file. So the env variables you set in your pipeline should work.
  • It cannot simply access any env variable (to protect you from exposing your server env variables on client browser by accident). If using create-react-app (which is what ASP.NET React App does by default), you have to prefix env variables with REACT_APP_ to use them. If using Webpack directly, you'll need some plugin for this.
qbik
  • 5,502
  • 2
  • 27
  • 33