How can I run a env variables on bitbucket pipeline? - reactjs

I've learned about pipelines with bitbucket and I want to make a new one to upload my react application (bootstrapped with create-react-app) and uploaded to an Amazon S3 bucket.
I made a bitbucket-pipelines.yml file like this one
image: node:10.15.3
pipelines:
default:
- step:
name: Installing dependencies
caches:
- node
script: # Modify the commands below to build your repository.
- rm -rf package-lock.json
- rm -f node_modules
- yarn add
- step:
name: Build
script:
- yarn build
When Bitbucket runs it, it shows me the next error message
env-cmd -f .env.production.local react-scripts build
Error: Unable to locate env file at location (.env.production.local)
This is it because in my package.json I use env-cmd to read my environment variables for the building script.
"scripts": {
"start": "env-cmd -f .env.development.local react-scripts start",
"build": "env-cmd -f .env.production.local react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
But I don't know how to read that environment variables (localized inside of my .env files) in my bitbucket-pipelines.yml file
How can I get that?

Better late than never...
.env, .env.production.local, or whatever file name you want. Interchangable.
first encode you .env file:
base64 -w 0 .env > envout.txt
Then add the contents of envout.txt to a repository variable in bitbucket $ENV_ENCODED or similar
Add decode command to your pipeline:
echo $ENV_ENCODED | base64 -d > .env
Extra info:
this needs to be done as one step, so include it just before your build
if the command is not found, use build image with base64
Other option is to include .env in docker image that you host on a secure service like AWS ECR and pull the image from there, and it will have your .env file
If someone is able to download build agent as artifact, they will be able to view the contents of your .env. This is more of a deterrent than the most secure option.
adding - cat .env as a step would validate the process, but maybe use fake .env
I would also recommend doing your installation and build in the same step. I've ran into issues where generated files (especially .env) are different between steps.
image: node:10.15.3
pipelines:
default:
- step:
name: Installing dependencies and Build
caches:
- node
script: # Modify the commands below to build your repository.
- rm -rf package-lock.json
- rm -f node_modules
- yarn add
- echo $ENV_ENCODED | base64 -d > .env
- yarn build

Related

Why is my npm build for test picking up production properties?

I want to wire up two production-style builds in my React 16.13 project. One for the test environment and another for the production. I have configured the below scripts ...
"scripts": {
"start": "react-scripts start",
"build": "NODE_ENV=development react-scripts build",
"build:test": "NODE_ENV=test react-scripts build",
"build:prod": "NODE_ENV=production react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
I have these two .env files defined ...
localhost:client davea$ cat .env.test
REACT_APP_PROXY=http://lab.mydomain.com
davea$ cat .env.production
REACT_APP_PROXY=http://prod.mydomain.com
I run my build for test as follows ...
localhost:client davea$ npm run build:test
> client#0.1.0 build:test /Users/davea/Documents/workspace/chicommons/maps/client
> NODE_ENV=test react-scripts build
Creating an optimized production build...
Compiled with warnings.
./src/containers/FormContainer.jsx
Line 112:31: Unnecessary escape character: \[ no-useless-escape
./src/components/Flash/index.js
Line 26:45: Expected dot to be on same line as property dot-location
./src/components/CoopTypes.jsx
Line 52:9: Do not mutate state directly. Use setState() react/no-direct-mutation-state
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
File sizes after gzip:
92.83 KB build/static/js/2.05641348.chunk.js
22.47 KB build/static/css/2.af3c1da9.chunk.css
4.07 KB build/static/js/main.367658f7.chunk.js
1.26 KB build/static/css/main.dcf9a285.chunk.css
774 B build/static/js/runtime-main.8c40394c.js
The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
Find out more about deployment here:
bit.ly/CRA-deploy
However, after when I scan "build/static/js/main.367658f7.chunk.js" (the built file) it only has references to my production property, "prod.mydomain.com" and not the test property, "lab.mydomain.com". What else do I need to do to get my test properties incorporated into my build?
Update
How can we still use .env files?
We could use something like env-cmd. It will help us execute commands use the env file that we provide. We can have it installed locally or globally.
So, the following remain as is.
localhost:client davea$ cat .env.test
REACT_APP_PROXY=http://lab.mydomain.com
davea$ cat .env.production
REACT_APP_PROXY=http://prod.mydomain.com
Now, the build commands can be (assuming global env-cmd)
"build:test": "env-cmd -f .env.test react-scripts build",
"build:prod": "env-cmd -f .env.production react-scripts build",
For local env-cmd, you could do something like ./node-modules/.bin/env-cmd -f .env.test as mentioned in their README file.
Original answer
From react-docs, (As DCTID also stated in the comment)
You cannot override NODE_ENV manually.
But, since we want two different values of the variable, we can use a custom variable instead of NODE_ENV? As per docs, it has to be prefixed with REACT_APP_. Let's say we decide to use REACT_APP_ENVIRONMENT.
We could set the same on build commands, for example:
"build:test": "REACT_APP_ENVIRONMENT=test react-scripts build",
"build:prod": "REACT_APP_ENVIRONMENT=production react-scripts build",
and, use it in the following manner:
// File: config.js
export const REACT_APP_PROXY = process.env.REACT_APP_ENVIRONMENT === 'production' ?
'prod.mydomain.com' : 'lab.mydomain.com';
Hope that helps! I use it this way in my apps, so if you have any more questions, I'd be happy to help.

serve static assets in storybook monorepo

I have a lerna + yarn workspaces monorepo which uses storybook.
Each package/component has its own /assets folder containing static images as following:
/packages
/component1
/assets
... static images
index.tsx
/component2
/assets
... static images
index.tsx
in the official documentation it says to include -s option but it suits only for a single general assets folder, not per package:
start-storybook -p 6006 -s assets
how can I serve those static assets in storybook for each component?
You can specify multiple static directories if you split them via a , as documented here.
Plus you can also specify a path to serve it at if you split the source location and the path location with a :, undocumented, but you can have a look at this split call in the source code here.
Putting this together in this instance, you could run
"scripts" {
"storybook": "start-storybook -s ./packages/component1/assets:assets,./packages/component2/assets:assets"
}
well.. it seems that it is not supported out-of-the-box so this is my solution to the problem, hope it will help other people.
the basic idea is to copy all the static assets of all the packages into the storybook output directory:
package.json
"scripts": {
// build the storybook and run copy assets script
"build-storybook": "build-storybook -c .storybook -o .out && yarn copy-storybook-assets",
// clean output directory, copy the assets to the output directory and run the storybook
"dev": "yarn clean-storybook-output && yarn copy-storybook-assets && start-storybook -p 6006 -s .out",
// clean the output directory
"clean-storybook-output": "rimraf .out",
// run on all the packages and copy all the static assets to the output directory
"copy-storybook-assets": "copyfiles -f \"packages/**/assets/*\" -u 1 .out"
},

How to deploy react project to ftp using Bitbucket Pipelines?

I am trying to set up bitbucket-pipelines.yml file to do the build and then deploy react project. There is my code below.
image: node:10.15.1
pipelines:
default: # Pipelines that are triggered manually via the Bitbucket GUI
- step:
name: Build
script:
- yarn
- yarn build
- step:
name: Deploy
script:
- apt-get update
- apt-get install ncftp
- ncftpput -v -u "$FTP_USERNAME" -p "$FTP_PASSWORD" -R $FTP_HOST $FTP_SITE_ROOT_DEV build/*
- echo Finished uploading /build files to $FTP_HOST$FTP_SITE_ROOT
I am getting the result:
+ ncftpput -v -u "$FTP_USERNAME" -p "$FTP_PASSWORD" -R $FTP_HOST $FTP_SITE_ROOT_DEV build/*
could not stat build/*: No such file or directory.
ncftpput build/*: no valid files were specified.
It says that there is no build file or directory. but yarn build is actually build folder creates: react-scripts build
From Atlassian documentation
Key concepts
A pipeline is made up of a set of steps.
Each step in your pipeline runs a separate Docker container. If you
want, you can use different types of container for each step, by
selecting different images
So, when you try to send it in Deploy Step it's not there because you built it in another container.
To pass files between steps you have to use Artifacts
image: node:10.15.1
pipelines:
default: # Pipelines that are triggered manually via the Bitbucket GUI
- step:
name: Build
script:
- yarn
- yarn build
artifacts: # defining build/ as an artifact
- build/**
- step:
name: Deploy
script:
- apt-get update
- apt-get install ncftp
- ncftpput -v -u "$FTP_USERNAME" -p "$FTP_PASSWORD" -R $FTP_HOST $FTP_SITE_ROOT_DEV build/*
- echo Finished uploading /build files to $FTP_HOST$FTP_SITE_ROOT

setting PORT and HOST manually for facebook/create-react-app production build

i used facebook/create-react-app to create a react application and successfully got production build running on http://localhost:5000.
my question is is there any way to change the 5000 PORT in this production build ?
according to the Advanced Configurations, there is no way to change HOST and PORT in production, only available for the development
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#advanced-configuration.
this is my package.json
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"deploy": "serve -s build"
}
this is my .env
##
HOST=127.0.0.1
PORT=8008
## PUBLIC_URL=http://myexamplesite.lk/
##
REACT_APP_ROOT_BASE_URL=https://myexamplesite.lk/api/
REACT_APP_ROOT_BASE_URL_META=http://myexamplesite.lk/
From react docs:
"the port can be adjusted using the -p or --port flags."
serve -p 7000 -s build
create-react-app listed all .env files which can used when run npm run build
To change PORT in local production build you can create a file name .env.production.local and set the PORT you want:
##
HOST=127.0.0.1
PORT=5000
## PUBLIC_URL=http://myexamplesite.lk/
##
REACT_APP_ROOT_BASE_URL=https://myexamplesite.lk/api/
REACT_APP_ROOT_BASE_URL_META=http://myexamplesite.lk/

Use custom build output folder when using create-react-app

Facebook provides a create-react-app command to build react apps. When we run npm run build, we see output in /build folder.
npm run build
Builds the app for production to the build folder. It correctly
bundles React in production mode and optimizes the build for the best
performance.
The build is minified and the filenames include the hashes. Your app
is ready to be deployed!
How can we use custom folder instead of /build for the output? Thanks.
With react-scripts >= 4.0.2, this is officially supported:
By default, Create React App will output compiled assets to a /build directory adjacent to /src. You may use this variable to specify a new path for Create React App to output assets. BUILD_PATH should be specified as a path relative to the root of your project.
// package.json
"scripts": {
"build": "BUILD_PATH='./dist' react-scripts build",
// ...
},
or adding a .env file to the root of your project:
# .env
BUILD_PATH='./dist'
Caution: the path specified in BUILD_PATH will be wiped out without mercy. Double check that your environment variable is specified correctly, especially when using continuous integration.
Edit your package.json:
"build": "react-scripts build && mv build webapp"
Create-react-app Version 2+ answer
For recent (> v2) versions of create-react-app (and possible older as well), add the following line to your package.json, then rebuild.
"homepage": "./"
You should now see the build/index.html will have relative links ./static/... instead of links to the server root: /static/....
Edit: Support for a configurable BUILD_PATH just landed into v4.0.2. See t_dom93's answer.
You can't change the build output folder name with the current configuration options.
Moreover, you shouldn't. This is a part of the philosophy behind create-react-app: they say Convention over Configuration.
If you really need to rename your folder, I see two options:
Right after the build process finishes, write a command that copies the build folder content to another folder you want. For example you can try the copyfiles npm package, or anything similar.
You could try to eject create-react-app and tweak the configuration.
If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
However, it is important to note that this is a one-way operation. Once you eject, you can’t go back! You loose all future updates.
Therefore, I'd recommend you to not use a custom folder naming, if possible. Try to stick with the default naming. If not an option, try #1. If it still doesn't work for your specific use-case and you're really out of options - explore #2. Good luck!
Support for BUILD_PATH just landed into v4.0.2.
Add BUILD_PATH variable to .env file and run build script command:
// .env file
BUILD_PATH=foo
That should place all build files into foo folder.
Félix's answer is correct and upvoted, backed-up by Dan Abramov himself.
But for those who would like to change the structure of the output itself (within the build folder), one can run post-build commands with the help of postbuild, which automatically runs after the build script defined in the package.json file.
The example below changes it from static/ to user/static/, moving files and updating file references on relevant files (full gist here):
package.json
{
"name": "your-project",
"version": "0.0.1",
[...]
"scripts": {
"build": "react-scripts build",
"postbuild": "./postbuild.sh",
[...]
},
}
postbuild.sh
#!/bin/bash
# The purpose of this script is to do things with files generated by
# 'create-react-app' after 'build' is run.
# 1. Move files to a new directory called 'user'
# The resulting structure is 'build/user/static/<etc>'
# 2. Update reference on generated files from
# static/<etc>
# to
# user/static/<etc>
#
# More details on: https://github.com/facebook/create-react-app/issues/3824
# Browse into './build/' directory
cd build
# Create './user/' directory
echo '1/4 Create "user" directory'
mkdir user
# Find all files, excluding (through 'grep'):
# - '.',
# - the newly created directory './user/'
# - all content for the directory'./static/'
# Move all matches to the directory './user/'
echo '2/4 Move relevant files'
find . | grep -Ev '^.$|^.\/user$|^.\/static\/.+' | xargs -I{} mv -v {} user
# Browse into './user/' directory
cd user
# Find all files within the folder (not subfolders)
# Replace string 'static/' with 'user/static/' on all files that match the 'find'
# ('sed' requires one to create backup files on OSX, so we do that)
echo '3/4 Replace file references'
find . -type f -maxdepth 1 | LC_ALL=C xargs -I{} sed -i.backup -e 's,static/,user/static/,g' {}
# Delete '*.backup' files created in the last process
echo '4/4 Clean up'
find . -name '*.backup' -type f -delete
# Done
I had the scenario like want to rename the folder and change the build output location, and used below code in the package.json with the latest version
"build": "react-scripts build && mv build ../my_bundles"
Here is my solution:
create .env in root, then add this line to it.
BUILD_PATH=$npm_package_name-$npm_package_version
the build path will be "name_of_app"-"version"
these values could be set in package.json
{
"name": "my-app",
"version": "0.1.2",
...
}
Based on the answers by Ben Carp and Wallace Sidhrée:
This is what I use to copy my entire build folder to my wamp public folder.
package.json
{
"name": "[your project name]",
"homepage": "http://localhost/[your project name]/",
"version": "0.0.1",
[...]
"scripts": {
"build": "react-scripts build",
"postbuild": "#powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./post_build.ps1",
[...]
},
}
post_build.ps1
Copy-Item "./build/*" -Destination "C:/wamp64/www/[your project name]" -Recurse -force
The homepage line is only needed if you are deploying to a subfolder on your server (See This answer from another question).
Move command for windows did not work for me. Because it does not copy the "static" folder and subfolders. So I was able to solve this problem using 'ROBOCOPY'.
"build": "react-scripts build && ROBOCOPY build ../my-relative-path/react-app /E",
Quick compatibility build script (also works on Windows):
"build": "react-scripts build && rm -rf docs && mv build docs"
For anyone still looking for an answer that works on both Linux and Windows:
Add this to the scripts section in package.json
"build": "react-scripts build && mv build ../docs || move build ../docs",
with ../docs is the relative folder you want to move the build folder to
Using cross-env is the solution.
Install cross-env:
npm install cross-env
You should update to:
"scripts": {
"build": "cross-env BUILD_PATH='../yourCustomBuildFolder' react-scripts build",
}
Windows Powershell Script
//package.json
"scripts": {
"postbuildNamingScript": "#powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./powerShellPostBuildScript.ps1",
// powerShellPostBuildScript.ps1
move build/static/js build/new-folder-name
(Get-Content build/index.html).replace('static/js', 'new-folder-name') | Set-Content
build/index.html
"Finished Running BuildScript"
Running npm run postbuildNamingScript in powershell will move the JS files to build/new-folder-name and point to the new location from index.html.
Open Command Prompt inside your Application's source.
Run the Command
npm run eject
Open your scripts/build.js file and add this at the beginning of the file after 'use strict' line
'use strict';
....
process.env.PUBLIC_URL = './'
// Provide the current path
.....
Open your config/paths.js and modify the buildApp property in the exports object to your destination folder. (Here, I provide 'react-app-scss' as the destination folder)
module.exports = {
.....
appBuild: resolveApp('build/react-app-scss'),
.....
}
Run
npm run build
Note: Running Platform dependent scripts are not advisable
You have two possibilities:
Change in your package.json the script item into "build": "react-scripts build && mv build webapp" where webapp is your destination folder;
Create .env file in your root directory and insert in it the new definition of build destination folder (ex. BUILD_PATH='./data')
You can update the configuration with a little hack, under your root directory:
npm run eject
config/webpack.config.prod.js - line 61 - change path to: __dirname + './../--your directory of choice--'
config/paths.js - line 68 - update to resolveApp('./--your directory of choice--')
replace --your directory of choice-- with the folder directory you want it to build on
note the path I provided can be a bit dirty, but this is all you need to do to modify the configuration.
webpack =>
renamed as build to dist
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},

Resources