-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deploy cmd #42
base: main
Are you sure you want to change the base?
Deploy cmd #42
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice PR @ugGit. Please have a look at my feedback.
src/createCli.js
Outdated
type: 'string', | ||
describe: 'Path to the Graasp app that shall be deployed', | ||
}), | ||
handler: promisify(deploy), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to promisify
? The function is already a promise. Just double-checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juancarlosfarah I'm actually not sure. This is inspired by the implementation of the new
command. But I tested now and the promisify()
could be omitted in both cases. Please let me know if I'm missing a point here, otherwise I'll remove it in the next PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe originally the function was not a promise, thus promisify
was needed. Looks like it's not needed anymore.
src/deploy.js
Outdated
console.error(`path passed '${path}'`); | ||
console.log(process.cwd()); | ||
try { | ||
await spawn('./src/test.sh'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be ./test.sh
after compiling inside the lib
folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juancarlosfarah the test.sh file is not copied into the lib folder. I suppose babel is only considering .js
file during compilation.
But even if I move the file manually, the command is executed at the location of the terminal and the path interpreted as relative path. Hence, the file would only be found when the command is executed in the lib
folder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/deploy.js
Outdated
@@ -1,15 +1,85 @@ | |||
import { spawn } from './utils'; | |||
import AWS from 'aws-sdk'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stick to either aws
or Aws
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to aws
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, I don't see the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just pushed the latest changes. Please check again
src/deploy.js
Outdated
import s3 from 's3-node-client'; | ||
import dotenv from 'dotenv'; | ||
|
||
const path = require('path'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use require
and not import
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
path
is not used anymore in the latest changes.
src/deploy.js
Outdated
} | ||
// const { path } = opts; | ||
|
||
const usageMessage = console.log( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this anymore.
src/deploy.sh
Outdated
@@ -0,0 +1,125 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed it.
src/utils.js
Outdated
@@ -1,5 +1,7 @@ | |||
import execa from 'execa'; | |||
|
|||
// TODO: this is not optimal naming since it may cause confusion with 'spawn()' from 'child_process' module; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor if needed to something like spawnProcess
in a future commit.
src/deploy.js
Outdated
const path = require('path'); | ||
|
||
// default build directory | ||
const BUILD = 'build/'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two options:
- Make default
-p
be./build
and-p
be described aspath/to/build/folder that will be deployed
. - Leave
-p
as is and allow for overriding this with a-b
.
I think that 1 might be cleaner, but I'm up for discussing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Currently I changed it to -b
. This keeps the syntax from the original deploy
script which might be appreciated by users of the script. Furthermore, i factored the default value out into the config.js
file.
As the changes are easy to make, let me know if you prefer the -p
variant.
src/deploy.js
Outdated
); | ||
|
||
console.log(`Exectued with path: ${opts.path}`); | ||
console.log(usageMessage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this.
src/deploy.js
Outdated
'usage: $0 [-e <path/to/file>] [-v <version string>] [-b <path/to/build>]', | ||
); | ||
|
||
console.log(`Exectued with path: ${opts.path}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in executed
. Also, we use all small caps in logs. I would suggest:
deploying app in {...} directory
or something similar.
src/deploy.js
Outdated
REACT_APP_HOST, | ||
REACT_APP_VERSION, | ||
REACT_APP_BASE, | ||
NODE_ENV, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need NODE_ENV
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure yet. It's removed now.
src/deploy.js
Outdated
} = process.env; | ||
/* eslint-enable no-unused-vars */ | ||
|
||
AWS.config.getCredentials(function (err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you using this? Maybe promisify in order not to have to shove everything inside the callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This reloads the credentials from the .env.xxx
set before. Hence, the below dev note in the sdk doc does not apply.
Note: If you configure the SDK with static or environment credentials, the credential data should already be present in credentials attribute. This method is primarily necessary to load credentials from asynchronous sources, or sources that can refresh credentials periodically.
However, I'm still looking for a proper way to refactor this parts and maybe promisify
will help me to do so. The challenge thereby is to check for the error and stop the further promise chain execution properly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By rethinking the look we already assure that the configuration can be loaded since we're manually checking that the env variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
) exist. I will implement a first draft that we might discuss during the next meeting.
@juancarlosfarah Just checked the PR! thanks for copying me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @ugGit, thanks for the changes. We're almost there! Some minor comments below. Also, I didn't see some of the changes you mentioned, like the aws
change. Please have a look.
src/deploy.js
Outdated
@@ -1,15 +1,85 @@ | |||
import { spawn } from './utils'; | |||
import AWS from 'aws-sdk'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, I don't see the change.
src/deploy.js
Outdated
// Both compilation hints because of backslashes used in RegExp but unecessary by conception in JS Strings | ||
// prettier-ignore | ||
// eslint-disable-next-line no-useless-escape | ||
const pattern = new RegExp('v\\d+(\.\\d+){0,2}$'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this patter is the same as the one in the bash file. Consider this one:
// matches v<major>.<minor>.<patch>[-<meta>] version format
^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\-[0-9A-Za-z]*)?$
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I haven't checked if it's JS compliant. Might be good to add some basic tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, please consider this comment.
.eslintrc
Outdated
@@ -12,6 +12,7 @@ | |||
"allow": ["_id"] | |||
} | |||
], | |||
"import/no-named-as-default": 0 | |||
"no-console": "off", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to turn this off, as it is a warning. I like to keep this on b/c it reminds me that we should use a logger
, but for now it's fine. There are very nice loggers for CLIs, but you can leave it off for now if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Answered here #42 (comment)
src/config.js
Outdated
// deploy settings | ||
export const DEFAULT_BUILD_DIR = 'build/'; | ||
export const DEFAULT_APP_VERSION = 'latest'; | ||
export const DEFAULT_ENV = '.env.dev'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is dev
default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, please consider this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juancarlosfarah Good question. As this was not the case in the previous deploy.sh
script, I will remove this default option. Should I make the flag required as a consequence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just saw that this can't be enforced. So, I suggest to simply let the validation error to pop up.
src/deploy.js
Outdated
}); | ||
|
||
console.log( | ||
`published app to https://${REACT_APP_HOST}/${APP_PATH}/index.html`, | ||
`info: published app to https://${REACT_APP_HOST}/${APP_PATH}/index.html`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for info
.
src/deploy.js
Outdated
}; | ||
const cloudfront = new AWS.CloudFront(); | ||
cloudfront.createInvalidation(invalidationParams, (err, data) => { | ||
if (err) console.log(err, err.stack); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always use {}
for if
statements, especially with else
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, put comments above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, please consider this comment.
src/deploy.js
Outdated
); | ||
|
||
// configure the deployment | ||
AWS.config.getCredentials((err) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to promisify
and await
here, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juancarlosfarah Absolutely correct. But currently not enough time to include it in this PR. Consequently, the commands risk not to be executed in the correct chronological order.
console.log('done uploading'); | ||
uploader.on('end', () => { | ||
progressBar.stop(); | ||
// TODO: insert here code that should be executed once the upload is done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be done. You can always create helper functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juancarlosfarah Yes, you are right. But I would require more time to do this. Might consider implementing this when finalizing the deploy
command.
src/deploy.js
Outdated
console.log(usageMessage); | ||
// Validate command options | ||
if (!validateTag(tag) || !validateEnv(env) || !validateBuild(build)) { | ||
console.error('Abort...'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aborting deployment...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ugGit for the changes. I think a bunch of my comments from the previous commits got overridden b/w when I made them and when you made the changes. I have tagged you in some. Please have a look at them. Also, no need to prefix logs with error:
or info:
. That was for Bash's echo
function. Here you can use console.info
or console.error
, or eventually use a fancier logging tool.
src/utils.js
Outdated
const [file, ...args] = cmd.split(/\s+/); | ||
return execa(file, args, opts); | ||
}; | ||
|
||
export const isDefined = (variable) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also a _.isUndefined
function that you could use from lodash
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't aware that this function existed. I have replaced it.
src/config.js
Outdated
// deploy settings | ||
export const DEFAULT_BUILD_DIR = 'build/'; | ||
export const DEFAULT_APP_VERSION = 'latest'; | ||
export const DEFAULT_ENV = '.env.dev'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, please consider this comment.
src/deploy.js
Outdated
|
||
// validate command options | ||
if (!validateTag(tag) || !validateEnv(env) || !validateBuild(build)) { | ||
console.error('Abort...'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In previous comment I suggest you change this message to aborting deployment
.
src/deploy.js
Outdated
}; | ||
const cloudfront = new AWS.CloudFront(); | ||
cloudfront.createInvalidation(invalidationParams, (err, data) => { | ||
if (err) console.log(err, err.stack); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, please consider this comment.
src/deploy.js
Outdated
|
||
console.log( | ||
`info: publishing app ${REACT_APP_GRAASP_APP_ID} version ${REACT_APP_VERSION}`, | ||
); | ||
|
||
// configure the deployment | ||
AWS.config.getCredentials((err) => { | ||
aws.config.getCredentials((err) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if you guarantee that the correct variables are present, don't you need to wait for the setup to be done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed the execution relies currently on a fast execution of this async method. A next PR must handle this problematic and properly chain the execution.
@ugGit, did you manage to look into the requested changes? |
@juancarlosfarah Yes. Apart of the handling for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ugGit, I did some more research, and the node S3 client that you have used is pretty outdated:
https://github.com/shreyawhiz/node-s3-client#readme
We should be using everything from AWS where possible and use the promises in order to avoid getting stuck in complex callback situations.
Let me know if you want to discuss this.
src/deploy.js
Outdated
!isDefined(REACT_APP_GRAASP_DEVELOPER_ID) || | ||
!isDefined(REACT_APP_GRAASP_APP_ID) | ||
) { | ||
console.error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, you forgot to remove the error:
bit.
src/deploy.js
Outdated
@@ -112,7 +113,7 @@ const deploy = async (opts) => { | |||
} = process.env; | |||
|
|||
console.log( | |||
`info: publishing app ${REACT_APP_GRAASP_APP_ID} version ${REACT_APP_VERSION}`, | |||
`publishing app ${REACT_APP_GRAASP_APP_ID} version ${REACT_APP_VERSION}`, | |||
); | |||
|
|||
// configure the deployment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ugGit, I think that you can use this promise version of getting the credentials.
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#getPromise-property
@@ -162,7 +163,7 @@ const deploy = async (opts) => { | |||
); | |||
|
|||
// ensure the correct distribution variables are defined | |||
if (!isDefined(DISTRIBUTION)) { | |||
if (_.isUndefined(DISTRIBUTION)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
everything after line 159 should be inside the on('end', () => {
call in order to work. Preferably you can use the promises version of the native s3
client from AWS.
Promisify
Which works fine if the command is executed in the project roots directory. E.g.