@suffolklitlab/alkiln 4.1.1 → 4.2.1-custom-setup-timeout.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test_tests.yml +3 -3
- package/CHANGELOG.md +10 -1
- package/action.yml +7 -1
- package/lib/docassemble/docassemble_api_interface.js +49 -18
- package/lib/scope.js +1 -1
- package/lib/steps.js +1 -1
- package/lib/utils/session_vars.js +10 -0
- package/package.json +11 -11
|
@@ -78,12 +78,12 @@ jobs:
|
|
|
78
78
|
with:
|
|
79
79
|
name: report
|
|
80
80
|
path: ./**/*_report_*
|
|
81
|
-
- name:
|
|
81
|
+
- name: upload debug_log artifact
|
|
82
82
|
uses: actions/upload-artifact@v2
|
|
83
83
|
if: ${{ always() }}
|
|
84
84
|
with:
|
|
85
|
-
name:
|
|
86
|
-
path: ./
|
|
85
|
+
name: debug_log file
|
|
86
|
+
path: ./debug_log.txt
|
|
87
87
|
- name: Cleanup
|
|
88
88
|
if: ${{ always() }}
|
|
89
89
|
run: npm run takedown
|
package/CHANGELOG.md
CHANGED
|
@@ -38,7 +38,16 @@ Format:
|
|
|
38
38
|
### Security
|
|
39
39
|
-
|
|
40
40
|
-->
|
|
41
|
-
|
|
41
|
+
## [Unreleased]
|
|
42
|
+
### Added
|
|
43
|
+
- GitHub environment variable MAX_SECONDS_FOR_SETUP to set a custom maximum time for setup and takedown for packages that take a long time to load.
|
|
44
|
+
|
|
45
|
+
## [4.2.0] - 2022-04-05
|
|
46
|
+
### Changed
|
|
47
|
+
- Pin versions of dependencies in action.yml and package.json
|
|
48
|
+
- Change log.txt file to debug_log.txt and upload as github artifact.
|
|
49
|
+
- Update cheerio version to remove vulnerabilities.
|
|
50
|
+
|
|
42
51
|
## [4.1.1] - 2022-04-01
|
|
43
52
|
### Added
|
|
44
53
|
- Step to set vars to secret variables. That is, using environment variables while hiding the names of those variables in the report, errors, and console logs.
|
package/action.yml
CHANGED
|
@@ -28,6 +28,10 @@ inputs:
|
|
|
28
28
|
description: 'Version of ALKiln to get from npm.'
|
|
29
29
|
required: false
|
|
30
30
|
default: '^4.0.0'
|
|
31
|
+
MAX_SECONDS_FOR_SETUP:
|
|
32
|
+
description: 'Amount of time to give the Project to upload your package's GitHub code.'
|
|
33
|
+
required: false
|
|
34
|
+
default: '120'
|
|
31
35
|
|
|
32
36
|
runs:
|
|
33
37
|
using: "composite"
|
|
@@ -54,9 +58,11 @@ runs:
|
|
|
54
58
|
echo "PLAYGROUND_ID=${{ inputs.PLAYGROUND_ID }}" >> $GITHUB_ENV
|
|
55
59
|
echo "DOCASSEMBLE_DEVELOPER_API_KEY=${{ inputs.DOCASSEMBLE_DEVELOPER_API_KEY }}" >> $GITHUB_ENV
|
|
56
60
|
echo "ALKILN_VERSION=${{ inputs.ALKILN_VERSION }}" >> $GITHUB_ENV
|
|
61
|
+
echo "MAX_SECONDS_FOR_SETUP=${{ inputs.MAX_SECONDS_FOR_SETUP }}" >> $GITHUB_ENV
|
|
57
62
|
shell: bash
|
|
58
63
|
- name: "ALKiln: confirm info"
|
|
59
64
|
run: echo -e "\nRepo is $REPO_URL\nBranch ref is $BRANCH_PATH\nManually added languages are $EXTRA_LANGUAGES\nAll other data is secret\n"
|
|
65
|
+
run: echo -e "\nALKiln version is $ALKILN_VERSION\nRepo is $REPO_URL\nBranch ref is $BRANCH_PATH\nMAX_SECONDS_FOR_SETUP is $MAX_SECONDS_FOR_SETUP\nManually added languages are $EXTRA_LANGUAGES\n"
|
|
60
66
|
shell: bash
|
|
61
67
|
|
|
62
68
|
# This doesn't use an already established package-lock.json and that
|
|
@@ -76,7 +82,7 @@ runs:
|
|
|
76
82
|
},
|
|
77
83
|
"dependencies": {
|
|
78
84
|
"colors": "1.4.0",
|
|
79
|
-
"@cucumber/cucumber": "
|
|
85
|
+
"@cucumber/cucumber": "7.3.2",
|
|
80
86
|
"@suffolklitlab/alkiln": "$ALKILN_VERSION"
|
|
81
87
|
}
|
|
82
88
|
}
|
|
@@ -59,6 +59,10 @@ let da_i = {};
|
|
|
59
59
|
module.exports = da_i;
|
|
60
60
|
|
|
61
61
|
|
|
62
|
+
// Constants
|
|
63
|
+
const DEFAULT_MAX_REQUEST_MS = session_vars.get_setup_timeout_ms();
|
|
64
|
+
|
|
65
|
+
|
|
62
66
|
let is_timeout_error = function( error ) {
|
|
63
67
|
/** Return whether the error is an axios timeout error.
|
|
64
68
|
* See:
|
|
@@ -84,7 +88,7 @@ da_i.throw_an_error_if_server_is_not_responding = async function ( options ) {
|
|
|
84
88
|
*/
|
|
85
89
|
|
|
86
90
|
// Defaults
|
|
87
|
-
let { timeout } = options || { timeout:
|
|
91
|
+
let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
88
92
|
log.info({ pre: `Waiting for the docassemble server to respond. Will wait for ${ timeout/1000 } seconds at most.` });
|
|
89
93
|
|
|
90
94
|
try {
|
|
@@ -123,7 +127,7 @@ da_i.get_dev_id = async function ( dev_id_options ) {
|
|
|
123
127
|
* See https://docassemble.org/docs/api.html#user. */
|
|
124
128
|
|
|
125
129
|
// Default timeouts
|
|
126
|
-
let { timeout } = dev_id_options || { timeout:
|
|
130
|
+
let { timeout } = dev_id_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
127
131
|
let response = await _da_REST.get_dev_id( timeout );
|
|
128
132
|
return response.data.id;
|
|
129
133
|
}; // Ends da_i.get_dev_id();
|
|
@@ -137,7 +141,7 @@ da_i.validate_api_key = async function ( api_key_options ) {
|
|
|
137
141
|
log.info({ pre: `Checking the testing account's API key.` });
|
|
138
142
|
|
|
139
143
|
// Default timeouts
|
|
140
|
-
api_key_options = api_key_options || { timeout:
|
|
144
|
+
api_key_options = api_key_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
141
145
|
|
|
142
146
|
try {
|
|
143
147
|
|
|
@@ -174,8 +178,13 @@ da_i.loop_to_create_project = async function( creation_options ) {
|
|
|
174
178
|
/** Create a docassemble Project on the docassemble server's account.
|
|
175
179
|
* Loop through potential project names until we find one that
|
|
176
180
|
* isn't already taken and then use that name to create the Project. */
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
|
|
182
|
+
// Defaults
|
|
183
|
+
creation_options = creation_options || {};
|
|
184
|
+
let default_opts = { timeout: DEFAULT_MAX_REQUEST_MS, max_tries: 15, wait_seconds: 5 };
|
|
185
|
+
let timeout = creation_options.timeout || default_opts.timeout;
|
|
186
|
+
let max_tries = creation_options.max_tries || default_opts.max_tries;
|
|
187
|
+
let wait_seconds = creation_options.wait_seconds || default_opts.wait_seconds;
|
|
179
188
|
|
|
180
189
|
let project_name = null;
|
|
181
190
|
let name_incrementor = 0;
|
|
@@ -229,6 +238,7 @@ da_i.loop_to_create_project = async function( creation_options ) {
|
|
|
229
238
|
} else {
|
|
230
239
|
|
|
231
240
|
// If it's a timeout error, server is busy. Try again after waiting.
|
|
241
|
+
// Why are we using `max_tries` for timeout error as well?
|
|
232
242
|
if ( is_timeout_error( error ) && name_incrementor < max_tries ) {
|
|
233
243
|
log.info({ pre: `The docassemble server was busy when we tried to `
|
|
234
244
|
+ `create the Project. Attempt ${ name_incrementor } of `
|
|
@@ -256,7 +266,7 @@ da_i.pull = async function ( pull_options ) {
|
|
|
256
266
|
log.info({ pre: `Trying to pull code from the "${ session_vars.get_branch_name() }" branch.` });
|
|
257
267
|
|
|
258
268
|
// Default timeouts
|
|
259
|
-
let { timeout } = pull_options || { timeout:
|
|
269
|
+
let { timeout } = pull_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
260
270
|
|
|
261
271
|
try {
|
|
262
272
|
|
|
@@ -290,7 +300,7 @@ da_i.has_task_finished = async function ( task_id, options ) {
|
|
|
290
300
|
* See https://docassemble.org/docs/api.html#restart_status. */
|
|
291
301
|
|
|
292
302
|
// Defaults
|
|
293
|
-
let { timeout } = options || { timeout:
|
|
303
|
+
let { timeout } = options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
294
304
|
|
|
295
305
|
try {
|
|
296
306
|
|
|
@@ -340,8 +350,20 @@ da_i.wait_for_server_to_restart = async ( task_id, options ) => {
|
|
|
340
350
|
+ `"${ task_id }". A task_id is usually created for a package `
|
|
341
351
|
+ `with a module. It can take a few minutes to finish uploading.` });
|
|
342
352
|
|
|
343
|
-
//
|
|
344
|
-
|
|
353
|
+
// Base default
|
|
354
|
+
options = options || {};
|
|
355
|
+
// Default timeout
|
|
356
|
+
let default_timeout = DEFAULT_MAX_REQUEST_MS;
|
|
357
|
+
let timeout = options.timeout || default_timeout;
|
|
358
|
+
// Other defaults
|
|
359
|
+
let default_wait_between_loops = 4 * 1000;
|
|
360
|
+
let default_wait_for_response = 1 * 1000;
|
|
361
|
+
let default_max_loops = timeout/( default_wait_between_loops + default_wait_for_response );
|
|
362
|
+
// Actual values
|
|
363
|
+
let wait_between_loops = options.wait_between_loops || default_wait_between_loops;
|
|
364
|
+
let wait_for_response = options.wait_for_response || default_wait_for_response;
|
|
365
|
+
let max_loops = options.max_loops || default_max_loops;
|
|
366
|
+
let total_wait = wait_between_loops + wait_for_response;
|
|
345
367
|
|
|
346
368
|
// Flags for stopping the `while` loop
|
|
347
369
|
let num_tries = 0;
|
|
@@ -350,22 +372,29 @@ da_i.wait_for_server_to_restart = async ( task_id, options ) => {
|
|
|
350
372
|
// Why loop instead of one long timeout? Because it might not just hang.
|
|
351
373
|
// We might get a return value that's just `waiting`, meaning the
|
|
352
374
|
// task is not done.
|
|
353
|
-
// - [ ] How many tries/time do we give this? Do we allow customization of those values?
|
|
354
375
|
while ( !done_restarting && num_tries <= max_loops ) {
|
|
355
376
|
num_tries++;
|
|
356
|
-
|
|
357
|
-
done_restarting = await da_i.has_task_finished( task_id );
|
|
377
|
+
// Wait only a short time for the task to finish, not the full default timeout
|
|
378
|
+
done_restarting = await da_i.has_task_finished( task_id, { timeout: wait_for_response } );
|
|
358
379
|
if ( !done_restarting ) {
|
|
359
380
|
if ( num_tries < max_loops ) {
|
|
360
|
-
|
|
361
|
-
|
|
381
|
+
// Show a slightly different message after a number of tries to reassure
|
|
382
|
+
// users we're still paying attention
|
|
383
|
+
let msg_start = `Not yet complete`;
|
|
384
|
+
if ( num_tries > 3 ) { msg_start = `Still not complete`; }
|
|
385
|
+
|
|
386
|
+
// When the server is busy, the task timeout causes this loop to actually
|
|
387
|
+
// take 5 seconds to complete, but this only waits for 4. I'm not sure how
|
|
388
|
+
// to make that clear
|
|
389
|
+
log.info({ pre: `${ msg_start }. Check ${ num_tries } of ${ max_loops }. `
|
|
390
|
+
+ `Will check again in ${( wait_between_loops + wait_for_response )/1000 } seconds.`
|
|
362
391
|
});
|
|
363
|
-
await time.waitForTimeout(
|
|
392
|
+
await time.waitForTimeout( wait_between_loops );
|
|
364
393
|
|
|
365
394
|
} else {
|
|
366
395
|
// This is our last round, let's wrap it up
|
|
367
396
|
let server_msg = `ALKiln setup: It seems like the docassemble server `
|
|
368
|
-
+ `didn't finish uploading the code after ${
|
|
397
|
+
+ `didn't finish uploading the code after ${ timeout/1000 } `
|
|
369
398
|
+ `seconds. Some things you can try: check your server is up, try `
|
|
370
399
|
+ `re-running the test, and try pulling the package manually `
|
|
371
400
|
+ `into the playground.`;
|
|
@@ -385,7 +414,7 @@ da_i.delete_project = async function ( delete_options ) {
|
|
|
385
414
|
/** Delete a project on the user's da server. */
|
|
386
415
|
|
|
387
416
|
// Defaults
|
|
388
|
-
let { timeout } = delete_options || { timeout:
|
|
417
|
+
let { timeout } = delete_options || { timeout: DEFAULT_MAX_REQUEST_MS };
|
|
389
418
|
|
|
390
419
|
let project_name = session_vars.get_project_name()
|
|
391
420
|
log.info({ pre: `Trying to delete Project ${ project_name }` });
|
|
@@ -396,7 +425,9 @@ da_i.delete_project = async function ( delete_options ) {
|
|
|
396
425
|
log.info({ pre: `Deleted Project "${ project_name }"` });
|
|
397
426
|
|
|
398
427
|
} catch ( error ) {
|
|
399
|
-
//
|
|
428
|
+
// TODO: Add more useful error messages, like project doesn't exist. The devs
|
|
429
|
+
// shouldn't be deleting projects by hand, but it's still very possible they would
|
|
430
|
+
// Status 400
|
|
400
431
|
log.error({ pre: `Ran into an error when deleting Project "${ project_name }"` });
|
|
401
432
|
log.debug({ pre: `See https://docassemble.org/docs/api.html#playground_delete_project.` });
|
|
402
433
|
throw error;
|
package/lib/scope.js
CHANGED
|
@@ -60,7 +60,7 @@ module.exports = {
|
|
|
60
60
|
let scenario = await scope.makeSureReportPartsExist( scope );
|
|
61
61
|
scenario.lines.push({ type, value });
|
|
62
62
|
|
|
63
|
-
fs.appendFileSync('
|
|
63
|
+
fs.appendFileSync('debug_log.txt', `Report:\ntype: ${ type }, value: ${ value }`);
|
|
64
64
|
return scenario;
|
|
65
65
|
|
|
66
66
|
}, // Ends scope.addToReport()
|
package/lib/steps.js
CHANGED
|
@@ -20,10 +20,20 @@ const session_vars = {};
|
|
|
20
20
|
|
|
21
21
|
module.exports = session_vars;
|
|
22
22
|
|
|
23
|
+
// Default to null
|
|
23
24
|
session_vars.get_debug = function () { return process.env.DEBUG || null; };
|
|
24
25
|
session_vars.get_dev_api_key = function () { return process.env.DOCASSEMBLE_DEVELOPER_API_KEY || null; };
|
|
25
26
|
session_vars.get_repo_url = function () { return process.env.REPO_URL || null; };
|
|
26
27
|
|
|
28
|
+
// More complex logic
|
|
29
|
+
session_vars.get_setup_timeout_ms = function () {
|
|
30
|
+
let timeout = 120 * 1000;
|
|
31
|
+
if ( process.env.MAX_SECONDS_FOR_SETUP ) {
|
|
32
|
+
timeout = parseFloat( process.env.MAX_SECONDS_FOR_SETUP ) * 1000;
|
|
33
|
+
}
|
|
34
|
+
return timeout;
|
|
35
|
+
};
|
|
36
|
+
|
|
27
37
|
session_vars.get_da_server_url = function () {
|
|
28
38
|
try {
|
|
29
39
|
let url = process.env.SERVER_URL || process.env.BASE_URL;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suffolklitlab/alkiln",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.2.1-custom-setup-timeout.2",
|
|
4
4
|
"description": "Integrated automated end-to-end testing with docassemble, puppeteer, and cucumber.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://suffolklitlab.org/docassemble-AssemblyLine-documentation/docs/automated_integrated_testing/",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@cucumber/cucumber": "
|
|
38
|
-
"axios": "
|
|
39
|
-
"chai": "
|
|
40
|
-
"cheerio": "
|
|
41
|
-
"dotenv": "
|
|
42
|
-
"mocha": "
|
|
43
|
-
"puppeteer": "
|
|
44
|
-
"qs": "
|
|
45
|
-
"sanitize-filename": "
|
|
46
|
-
"uuid": "
|
|
37
|
+
"@cucumber/cucumber": "7.3.2",
|
|
38
|
+
"axios": "0.24.0",
|
|
39
|
+
"chai": "4.2.0",
|
|
40
|
+
"cheerio": "1.0.0-rc.10",
|
|
41
|
+
"dotenv": "8.2.0",
|
|
42
|
+
"mocha": "9.2.0",
|
|
43
|
+
"puppeteer": "13.1.3",
|
|
44
|
+
"qs": "6.10.2",
|
|
45
|
+
"sanitize-filename": "1.6.3",
|
|
46
|
+
"uuid": "8.3.2"
|
|
47
47
|
},
|
|
48
48
|
"bin": {
|
|
49
49
|
"alkiln-setup": "./lib/docassemble/setup.js",
|