-
Notifications
You must be signed in to change notification settings - Fork 0
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
action to: update app_settings, set medic-credentials #1
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.
It's shaping up well @kitsao. Great progress.
I've left some feedback inline. Do include some static analysis checking e.g eslint
const settingsFile = 'app_settings.json'; | ||
const flowsFile = 'flows.js'; | ||
|
||
run(githubWorkspacePath, core, fs); |
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.
run is an async function and as such should be await
ed.
For this scenario, you could use an IIFE
(async() => {
const githubWorkspacePath = process.env['GITHUB_WORKSPACE'];
const settingsFile = 'app_settings.json';
const flowsFile = 'flows.js';
run(githubWorkspacePath, core, fs);
)();
"test": "mocha test/*.spec.js --timeout 10000 --slow 500" | ||
}, | ||
"author": "Medic Inc.", | ||
"license": "ISC", |
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.
Medic code is released under AGPL (AGPL-3.0-only)
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.
Most repos use ISC
. Updated to AGPL-3.0-only
.
"build": "ncc build index.js --license licenses.txt", | ||
"test": "mocha test/*.spec.js --timeout 10000 --slow 500" | ||
}, | ||
"author": "Medic Inc.", |
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.
Unsure if we use this in our package.json files
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.
Removed.
"axios": "^0.21.4", | ||
"chai": "^4.3.6", | ||
"fs": "^0.0.1-security", | ||
"mocha": "^9.2.1", |
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.
mocha and chai should be dev dependencies
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.
Moved.
@@ -0,0 +1,26 @@ | |||
|
|||
const { Factory } = require('rosie'); | |||
const { faker } = require('@faker-js/faker'); |
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.
Nit: I don't think rosie
should be a hard dependency since we just need to cook up a couple of field values
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.
Moved to devDependencies.
describe(`rapidpro action test suite`, () => { | ||
const mockedAxiosResponse = { | ||
data: {}, | ||
status: 200, |
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.
How would the code behave with a non-2xx response?
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.
Added an extra test.
|
||
it(`should fail if no argument is passed to get required secrets`, async () => { | ||
expect( function () { | ||
utils.getInputs(); |
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.
What happens if we pass sone random parameters?
e.g {}
, null
, undefined
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.
Expected to fail, throw Error
.
try { | ||
await utils.getReplacedContent(settings); | ||
} catch (err) { | ||
expect(err).to.include(new 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.
I would expect to use to include
with containers e.g arrays etc.
Consider using the expect(...).to.throw(Error Class) pattern
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 works for sync functions only, because async functions return a promise. Try catch easily handles asyc functions to catch and throw errors.
Potential usecase for this as well: medic/cht-conf#348 |
fs.writeFileSync(`${codeRepository}/${secrets.app_settings_file}`, settings); | ||
fs.writeFileSync(`${codeRepository}/${secrets.flows_file}`, getFormattedFlows(secrets.rp_flows)); | ||
core.info('Successful'); | ||
return true; |
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 use this return value?
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 really. Removed.
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 is coming together nicely @kitsao
I've left some feedback inline
rp_flows: ${{ secrets.RAPIDPRO_STAGING_FLOWS }} | ||
write_patient_state_flow: ${{ secrets.RAPIDPRO_STAGING_WRITE_PATIENT_STATE_FLOW }} | ||
app_settings_file: app_settings.json | ||
flows_file: flows.js |
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.
Is this still relevant? I don't see it in actions.yml
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. Added.
|
||
(async () => { | ||
const githubWorkspacePath = process.env['GITHUB_WORKSPACE']; | ||
run(githubWorkspacePath, core, fs); |
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.
run is an async method. We should await
here
"chai": "^4.3.6", | ||
"eslint": "^8.12.0", | ||
"eslint-plugin-json": "^2.1.2", | ||
"fs": "^0.0.1-security", |
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.
fs is a core module. Unsure why we are getting it from npm
"devDependencies": { | ||
"@faker-js/faker": "^6.0.0-beta.0", | ||
"@medic/eslint-config": "^1.1.0", | ||
"axios": "^0.21.4", |
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 is a core dependency
"rosie": "^2.1.0", | ||
"sinon": "^13.0.1", | ||
"template-file": "^6.0.1", | ||
"util": "^0.12.4" |
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 is a core dependency
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 is a core dependency.
Any library that is used in the core code (i.e not tests) is a core dependency and should be moved to "dependencies"
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 these manually moved to dependencies
? Running npm i --save
doesn't add them directly.
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.
At this stage, yes.
In principle, dev dependencies are used when developing the tool/code/package and are never referenced when running the code in production
npm
however provides two flags that determine where they get saved: --save
and --save-dev
"description": "dynamic-rapidpro-workspace Shared GitHub Action", | ||
"main": "index.js", | ||
"scripts": { | ||
"eslint": "npx eslint {,**}/*.js {,**}/*.json", |
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.
We probably should have the expressions quoted to prevent any interpretation from the underlying shell
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.
Gotcha
required: true | ||
|
||
outputs: | ||
app-settings: |
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.
Where the these values stored and used?
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.
Outputs should be values used as the program runs. In this case, these are unnecessary. Removed.
const settings = await getReplacedContent(JSON.parse(appSettings), secrets); | ||
|
||
await axios.put(url.href, `"${secrets.rp_api_token}"`); | ||
fs.writeFileSync(`${codeRepository}/${secrets.app_settings_file}`, settings); |
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.
can we validate that these paths exist and fail cleanly if not?
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.
A clean fail handled by default.
description: The CHT app-settings file. | ||
required: true | ||
|
||
flows_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.
From here, it seems we don't really need the flow file to exist since the contents are loaded from secrets.
Thoughts?
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 is simply a file name that would be referenced in other files such as tasks.js
.
|
||
await axios.put(url.href, `"${secrets.rp_api_token}"`); | ||
fs.writeFileSync(`${codeRepository}/${secrets.app_settings_file}`, settings); | ||
fs.writeFileSync(`${codeRepository}/${secrets.flows_file}`, getFormattedFlows(secrets.rp_flows)); |
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 we validating the contents of secrets.flows_file? What happens if you put in a malformed value?
Could we add tests around the same?
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.
That would be similar to validating the extension to be .js
. Maybe updating the file name required in other files such as tasks.js
is necessary. Looking into that.
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 got rid of both flows file and app settings file, and handled them in-code.
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.
Awesome. Let's put it in use in a project, deploy some code
app_settings.json
medic-credentials
in CouchDB