Skip to content

Commit 4ea18b2

Browse files
committedMay 14, 2021
added retry feature, fixes #66
1 parent e1c1c3b commit 4ea18b2

File tree

7 files changed

+111
-60
lines changed

7 files changed

+111
-60
lines changed
 

‎README.md

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ This workflow has additional options that you can use to customize it for your u
5959
| `committer_email` | `blog-post-bot@example.com` | Allows you to customize the committer email | No |
6060
| `output_only` | `false` | Sets the generated array as `results` [output variable](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs) so that it can be consumed in other actions and parsed via utilities like [jq](https://stedolan.github.io/jq/). This will also prevent committing to readme. See [#51](https://github.com/gautamkrishnar/blog-post-workflow/issues/51#issuecomment-758570235) for more details about the output format and how to use it. | No |
6161
| `enable_keepalive` | `true` | Workflow will automatically do a dummy commit to keep the repository active if there is no commit activity for the last 50 days. GitHub will stop running all cron based triggers if the repository is not active for more than 60 days. This flag allows you to disable this feature. See [#53](https://git.io/Jtm4V) for more details. | No |
62+
| `retry_count` | `0` | Maximum number of times to retry the fetch operation if it fails, See [#66](https://github.com/gautamkrishnar/blog-post-workflow/issues/66) for more details. | No |
63+
| `retry_wait_time` | `1` | Time to wait before each retry operation in seconds. | No |
6264

6365
### Advanced usage examples
6466
#### StackOverflow example

‎action.yml

+8
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ inputs:
8585
description: "Enables the feature that keeps the repo active by automatically committing to it even though there is no change"
8686
default: "true"
8787
required: false
88+
retry_count:
89+
description: "Maximum number of times to retry the fetch operation if it fails"
90+
default: "0"
91+
required: false
92+
retry_wait_time:
93+
description: "Time to wait before each retry operation in seconds"
94+
default: "1"
95+
required: false
8896
outputs:
8997
results:
9098
description: "JSON stringified array of posts"

‎blog-post-workflow.js

+78-60
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const core = require('@actions/core');
44
const fs = require('fs');
55
const dateFormat = require('dateformat');
66
const rand = require('random-seed');
7+
const promiseRetry = require('promise-retry');
78
const {
89
updateAndParseCompoundParams,
910
commitReadme,
@@ -49,6 +50,13 @@ const CUSTOM_TAGS = {};
4950
// Keepalive flag
5051
const ENABLE_KEEPALIVE = core.getInput('enable_keepalive') === 'true';
5152

53+
// Retry configuration
54+
const retryConfig = {
55+
retries: Number.parseInt(core.getInput('retry_count')),
56+
factor: 1,
57+
minTimeout: Number.parseInt(core.getInput('retry_wait_time')) * 1000
58+
};
59+
5260
core.setSecret(GITHUB_TOKEN);
5361

5462
core.getInput('custom_tags')
@@ -90,71 +98,80 @@ let parser = new Parser({
9098
feedList.forEach((siteUrl) => {
9199
runnerNameArray.push(siteUrl);
92100
promiseArray.push(new Promise((resolve, reject) => {
93-
parser.parseURL(siteUrl).then((data) => {
94-
if (!data.items) {
95-
reject('Cannot read response->item');
96-
} else {
97-
const responsePosts = data.items;
98-
const posts = responsePosts
99-
.filter(ignoreMediumComments)
100-
.filter(ignoreStackOverflowComments)
101-
.filter(ignoreStackExchangeComments)
102-
.map((item) => {
103-
// Validating keys to avoid errors
104-
if (ENABLE_SORT && !item.pubDate) {
105-
reject('Cannot read response->item->pubDate');
106-
}
107-
if (!item.title) {
108-
reject('Cannot read response->item->title');
109-
}
110-
if (!item.link) {
111-
reject('Cannot read response->item->link');
112-
}
113-
// Custom tags
114-
let customTags = {};
115-
Object.keys(CUSTOM_TAGS).forEach((tag) => {
116-
if (item[tag]) {
117-
Object.assign(customTags, {[tag]: item[tag]});
101+
promiseRetry((retry, tryNumber) => {
102+
// Retry block
103+
if (tryNumber > 1) {
104+
core.info(`Previous try for ${siteUrl} failed, retrying: ${tryNumber - 1}`);
105+
}
106+
return parser.parseURL(siteUrl)
107+
.catch(retry);
108+
}, retryConfig)
109+
.then((data) => {
110+
if (!data.items) {
111+
reject('Cannot read response->item');
112+
} else {
113+
const responsePosts = data.items;
114+
const posts = responsePosts
115+
.filter(ignoreMediumComments)
116+
.filter(ignoreStackOverflowComments)
117+
.filter(ignoreStackExchangeComments)
118+
.map((item) => {
119+
// Validating keys to avoid errors
120+
if (ENABLE_SORT && !item.pubDate) {
121+
reject('Cannot read response->item->pubDate');
118122
}
119-
});
120-
let post = {
121-
title: item.title.trim(),
122-
url: item.link.trim(),
123-
description: item.content ? item.content : '',
124-
...customTags
125-
};
126-
127-
if (ENABLE_SORT) {
128-
post.date = new Date(item.pubDate.trim());
129-
}
130-
131-
// Advanced content manipulation using javascript code
132-
if (ITEM_EXEC) {
133-
try {
134-
eval(ITEM_EXEC);
135-
} catch (e) {
136-
core.error('Failure in executing `item_exec` parameter');
137-
core.error(e);
138-
process.exit(1);
123+
if (!item.title) {
124+
reject('Cannot read response->item->title');
125+
}
126+
if (!item.link) {
127+
reject('Cannot read response->item->link');
128+
}
129+
// Custom tags
130+
let customTags = {};
131+
Object.keys(CUSTOM_TAGS).forEach((tag) => {
132+
if (item[tag]) {
133+
Object.assign(customTags, {[tag]: item[tag]});
134+
}
135+
});
136+
let post = {
137+
title: item.title.trim(),
138+
url: item.link.trim(),
139+
description: item.content ? item.content : '',
140+
...customTags
141+
};
142+
143+
if (ENABLE_SORT) {
144+
post.date = new Date(item.pubDate.trim());
139145
}
140-
}
141146

142-
if (TITLE_MAX_LENGTH && post && post.title) {
143-
// Trimming the title
144-
post.title = truncateString(post.title, TITLE_MAX_LENGTH);
145-
}
147+
// Advanced content manipulation using javascript code
148+
if (ITEM_EXEC) {
149+
try {
150+
eval(ITEM_EXEC);
151+
} catch (e) {
152+
core.error('Failure in executing `item_exec` parameter');
153+
core.error(e);
154+
process.exit(1);
155+
}
156+
}
146157

147-
if (DESCRIPTION_MAX_LENGTH && post && post.description) {
148-
const trimmedDescription = post.description.trim();
149-
// Trimming the description
150-
post.description = truncateString(trimmedDescription, DESCRIPTION_MAX_LENGTH);
151-
}
158+
if (TITLE_MAX_LENGTH && post && post.title) {
159+
// Trimming the title
160+
post.title = truncateString(post.title, TITLE_MAX_LENGTH);
161+
}
152162

153-
return post;
154-
});
155-
resolve(posts);
156-
}
157-
}).catch(reject);
163+
if (DESCRIPTION_MAX_LENGTH && post && post.description) {
164+
const trimmedDescription = post.description.trim();
165+
// Trimming the description
166+
post.description = truncateString(trimmedDescription, DESCRIPTION_MAX_LENGTH);
167+
}
168+
return post;
169+
});
170+
resolve(posts);
171+
}
172+
}, (err) => {
173+
reject(err);
174+
});
158175
}));
159176
});
160177

@@ -254,6 +271,7 @@ Promise.allSettled(promiseArray).then((results) => {
254271
core.setOutput('results', postsArray);
255272
}
256273
}
274+
process.exit(jobFailFlag ? 1 : 0);
257275
} else {
258276
// Calculating last commit date, please see https://git.io/Jtm4V
259277
const {outputData} = await exec('git', ['--no-pager', 'log', '-1', '--format=%ct'],

‎local-run.js

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ fs.writeFile(path.join(__dirname, 'test', 'Readme.md'), template, () => {
2929
process.env.INPUT_OUTPUT_ONLY = 'false';
3030
process.env.INPUT_ENABLE_KEEPALIVE = 'true';
3131
process.env.INPUT_TAG_POST_PRE_NEWLINE = 'false';
32+
process.env.INPUT_RETRY_COUNT = '0';
33+
process.env.INPUT_RETRY_WAIT_TIME = '1';
3234
const testFile = process.env.DIST ? './dist/blog-post-workflow' :'./blog-post-workflow';
3335
console.log('Testing: ', testFile);
3436
require(testFile);

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@actions/core": "^1.2.6",
3535
"dateformat": "^3.0.3",
3636
"process": "latest",
37+
"promise-retry": "^2.0.1",
3738
"random-seed": "^0.3.0",
3839
"rss-parser": "^3.9.0"
3940
},

‎test.js

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const DEFAULT_TEST_ENV = {
2121
INPUT_OUTPUT_ONLY: 'false',
2222
INPUT_ENABLE_KEEPALIVE: 'true',
2323
INPUT_TAG_POST_PRE_NEWLINE:'false',
24+
INPUT_RETRY_COUNT:'0',
25+
INPUT_RETRY_WAIT_TIME: '1',
2426
TEST_MODE: 'true'
2527
};
2628

‎yarn.lock

+18
Original file line numberDiff line numberDiff line change
@@ -2330,6 +2330,11 @@ envinfo@^7.3.1:
23302330
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.3.tgz#4b2d8622e3e7366afb8091b23ed95569ea0208cc"
23312331
integrity sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==
23322332

2333+
err-code@^2.0.2:
2334+
version "2.0.3"
2335+
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
2336+
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
2337+
23332338
error-ex@^1.3.1:
23342339
version "1.3.2"
23352340
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@@ -4726,6 +4731,14 @@ process@^0.11.10, process@latest:
47264731
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
47274732
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
47284733

4734+
promise-retry@^2.0.1:
4735+
version "2.0.1"
4736+
resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"
4737+
integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==
4738+
dependencies:
4739+
err-code "^2.0.2"
4740+
retry "^0.12.0"
4741+
47294742
promise.allsettled@1.0.2:
47304743
version "1.0.2"
47314744
resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.2.tgz#d66f78fbb600e83e863d893e98b3d4376a9c47c9"
@@ -5056,6 +5069,11 @@ ret@~0.1.10:
50565069
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
50575070
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
50585071

5072+
retry@^0.12.0:
5073+
version "0.12.0"
5074+
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
5075+
integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
5076+
50595077
rgb-regex@^1.0.1:
50605078
version "1.0.1"
50615079
resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1"

0 commit comments

Comments
 (0)
Please sign in to comment.