Change environment variable value of react app using azure devops - Deployment on aws (s3) - amazon-s3

I have a react application in which they are getting backend api address by using Environment variable. Below in the example:
this._baseUrl = process.env.API_GATEWAY;
In local development environment, development team create .env. file and set environment variable value in that file, to call backend api and every things work fine, like below.
API_GATEWAY=http://localhost:3000
When i create CI/CD pipeline for same project then every things works fine and application is also successfully deployed on AWS (s3 bucket) but i am not able to change the value of environment variable while building the project using npm, like below:
- script: |
npm run build
displayName: 'npm build'
env:
API_GATEWAY: $(envAppApi)
API_GATEWAY used above is the name of environment variable used in code and $(envAppApi) is variable defined in variable group.
But when application is deployed on AWS then environment variable value not changed and it shows below error.
mutation.js:106 ReferenceError: process is not defined
at new e (http-api.ts:17:42)
at Function.value (http-api.ts:24:12)
at Object.mutationFn (Auth.ts:13:26)
at Object.fn (mutation.js:132:31)
at c (retryer.js:95:31)
at new u (retryer.js:156:3)
at t.executeMutation (mutation.js:126:20)
at mutation.js:86:20
(http-api.ts:17:42) => This is the same line where API_GATEWAY environment variable is set and already showed above.
Problem statement:
Is there is any way that we can update the value of environment variable while creating CI/CD pipeline? so the application run successfully. Thanks.
Note: I don't want to use .env. file in my pipeline for updating environment values in react application.

Is there is any way that we can update the value of environment variable while creating CI/CD pipeline?
Yes. I suggest that you can use RegEx Match & Replace task from RegEx Match & Replace.
This task will use regular expressions to match fields in the file.
Here is an example:
steps:
- task: RegExMatchReplace#2
displayName: 'RegEx Match & Replace'
inputs:
PathToFile: test.js
RegEx: 'this._baseUrl = ([a-zA-Z]+(\.[a-zA-Z]+)+)_[a-zA-Z]+;'
ValueToReplace: ' this._baseUrl = $(envAppApi)'
Then the value will update.
You can use this site to convert the regular expressions : Regex Generator

Related

Azure Devops Browserstack integration - BrowserStackResults task - Unexpected "Build not found by name" error

Trying to set up Azure Devops pipeline for test automation run (Java + Maven + Selenium) tests are running on Browserstack
To view Browser Stack Results I added two tasks BrowserStackConfig and BrowserStackResults to pipiline YAML file
(according to instructions from BrowserStack)
But I am getting unexpected error on BrowserStackResults step : 'Build not found by name ..'
Now I am trying to get results for "old" automation run on BS (Set BROWSERSTACK_BUILD_NAME to existing BS results = 20220114_666666)
Setup:
Using Azure Devops with installed Browserstack extension
Steps:
Prepared YML file
Add pipeline for YML
Run pipeline
Result:
BS Configuration step works
Unexpected error on BrowserStackResults step "##[error] Build not found by name: "20220114_666666" error
The following only fixes BrowserStackConfig task:
variables:
- name: BROWSERSTACK_BUILD_NAME
value: "test-001"
But not for BrowserStackResults task. Is there another environment variable that controls the later? Or a list of variables used by browserstack?
According to the Browserstack
Note: Ensure to set the build capability in your test script using the environment variable BROWSERSTACK_BUILD_NAME. The extension will fail to embed test reports in your pipeline if this capability is missing.
Set variables for BrowserStack Azure DevOps Extension
The BrowserStack Azure DevOps extension, by default, sets the following environment variables:
BROWSERSTACK_USERNAME
BROWSERSTACK_ACCESS_KEY
BROWSERSTACK_LOCAL
BROWSERSTACK_LOCAL_IDENTIFIER
BROWSERSTACK_BUILD_NAME
When you create a service connection, the BROWSERSTACK_USERNAME and the BROWSERSTACK_ACCESS_KEY are automatically added as variables during the configuration step.
The extension also adds the BROWSERSTACK_BUILD_NAME variable that autogenerates a build name for your test runs.
Edit your test script to call environment variables
Edit your test script to add the environment variables for setting capabilities using the following code snippets:
String buildName = System.getenv("BROWSERSTACK_BUILD_NAME");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("build", buildName); // CI/CD job name using BROWSERSTACK_BUILD_NAME env variable
Seems you need to check your code if BROWSERSTACK_BUILD_NAME environment variable value is passed to buildName and added to capabilities. Otherwise, the report won't be generated

In what order is the serverless file evaluated?

I have tried to find out in what order the statements of the serverless file are evaluated (maybe it is more common to say that 'variables are resolved').
I haven't been able to find any information about this and to some extent it makes working with serverless feel like a guessing game for me.
As an example, the latest surprise I got was when I tried to run:
$ sls deploy
serverless.yaml
useDotenv: true
provider:
stage: ${env:stage}
region: ${env:region}
.env
region=us-west-1
stage=dev
I got an error message stating that env is not available at the time when stage is resolved. This was surprising to me since I have been able to use env to resolve other variables in the provider section, and there is nothing in the syntax to indicate that stage is resolved earlier.
In what order is the serverless file evaluated?
In effect you've created a circular dependency. Stage is special because it is needed to identify which .env file to load. ${env:stage} is being resolved from ${stage}.env, but Serverless needs to know what ${stage} is in order to find ${stage}.env etc.
This is why it's evaluated first.
Stage (and region, actually) are both optional CLI parameters. In your serverless.yml file what you're setting is a default, with the CLI parameter overriding it where different.
Example:
provider:
stage: staging
region: ca-central-1
Running serverless deploy --stage prod --region us-west-2 will result in prod and us-west-2 being used for stage and region (respectively) for that deployment.
I'd suggest removing any variable interpolation for stage and instead setting a default, and overriding via CLI when needed.
Then dotenv will know which environment file to use, and complete the rest of the template.

How to pass the Azure DevOps variables into Postman tests?

I have a Postman collection exported as json and integrated into Azure DevOps pipelines. It currently uses a URL variable from the Postman environment exported as json.
I need to set the URL variable in Azure DevOps and use it in my Postman tests.
I have set the variable in the Command Line task for running tests (see the screenshot).
Question 1. I'm not sure if this is the correct place to set this variable.
Question 2. How do I pass the Azure variable into the Postman tests?
In addition to running postman test with a script, I also recommend that you use this out-of-the-box task:Newman the cli Companion for Postman from extension: Newman the cli Companion for Postman.
You can directly set the global variable in this task.
Yaml sample:
steps:
- task: NewmanPostman#4
displayName: 'Newman - Postman'
inputs:
collectionFileSource: 'test1.postman_collection.json'
environment: 'test.postman_environment.json'
globalVars: 'aa=azuretest23'
ignoreRedirect: false
bail: false
sslInsecure: false
htmlExtraDarkTheme: false
htmlExtraLogs: false
htmlExtraTestPaging: false
You can hard code global variables directly, or you can use pipeline variables(e.g. aa=$(var))
Using this task may make it easier for you to set environment variables and global variables.
Update:
Here is my example:
In Release Pipeline:
You could test the same settings in Postman and check if it could work.
In Postman:
testurl is global variable. version is environment variable.
Environment Variables is a correct place if you inside of you scripts use syntax like $env:url (for powershell for instance) and from what I found this is not possible. Please check here
But you can pass variable like it is shown here or here
newman run -g environment.json --global-var "foo=$(YOURVARIABLE)"
So you should go to variables tab and there define this variable and use as above ot paste url instead of $(YOURVARIABLE)

How to set gitlab-ci variables dynamically?

How to set gitlab-ci varibales through script not just in "varibales" section in .gitlab-ci.yaml?So that I can set variables in one job and use in different job
There is currently no way in GitLab to pass environment variable between stages or jobs.
But there is a request for that: https://gitlab.com/gitlab-org/gitlab/-/issues/22638
Current workaround is to use artifacts - basically pass files.
We had a similar use case - get Java app version from pom.xml and pass it to various jobs later in the pipeline.
How we did it in .gitlab-ci.yml:
stages:
- prepare
- package
variables:
VARIABLES_FILE: ./variables.txt # "." is required for image that have sh not bash
get-version:
stage: build
script:
- APP_VERSION=...
- echo "export APP_VERSION=$APP_VERSION" > $VARIABLES_FILE
artifacts:
paths:
- $VARIABLES_FILE
package:
stage: package
script:
- source $VARIABLES_FILE
- echo "Use env var APP_VERSION here as you like ..."
If you run a script you can set an environment variable
export MY_VAR=the-value
once the environment variable is set it should persist in the current environment.
Now for why you do not want to do that.
A tool like Gitlab CI is meant to achieve repeatability in your
artifacts. Consistency is the matter here. What happens if a second job
has to pick up a variable from the first? Then you have multiple paths!
# CI is a sequence
first -> second -> third -> fourth -> ...
# not a graph
first -> second A -> third ...
\> second B />
How did you get to third? Now if you had to debug third which path do you test? If the build in third is broken who is responsible second A or second B?
If you need a variable use it now, not later in another job/script. Whenever you
want to write a longer sequence of commands make it a script and execute the script!
You can use either Artifact or Cache to achieve this, see the official documentation for more information around Artifact and Cache:
https://docs.gitlab.com/ee/ci/caching/#how-cache-is-different-from-artifacts

Passing environment variables from command line

Is it possible to pass environment variable with sls deploy , sls doesn't seem to have switch like -e and the only possible way looks like having a seperate yaml file to manage variables and pass it on using "environment:" element in the serverless.yml file as mentioned in this article.
You can use any arbitrary name for your environment variable and pass it to serverless.yml with:
serverless deploy --myEnvVar <value>
You reference this inside serverless.yml with:
environment:
myLocalVar: ${opt:myEnvVar}
You can use serverless parameters
Parameters can be passed directly via CLI --param flag, following the pattern --param="<key>=<value>":
serverless deploy --param="domain=myapp.com" --param="key=value"
Parameters can then be used via the ${param:XXX} variables:
provider:
environment:
APP_DOMAIN: ${param:domain}
KEY: ${param:key}
https://www.serverless.com/framework/docs/guides/parameters