@opentermsarchive/engine 2.3.0 β†’ 2.3.1

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/reporter/github.js +103 -124
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentermsarchive/engine",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Tracks and makes visible changes to the terms of online services",
5
5
  "homepage": "https://opentermsarchive.org",
6
6
  "bugs": {
@@ -90,7 +90,7 @@
90
90
  "mongodb": "^4.9.0",
91
91
  "morgan": "^1.10.0",
92
92
  "node-fetch": "^3.1.0",
93
- "octokit": "^1.7.0",
93
+ "octokit": "2.0.2",
94
94
  "pdfjs-dist": "^2.9.359",
95
95
  "puppeteer": "^22.8.1",
96
96
  "puppeteer-extra": "^3.3.6",
@@ -16,7 +16,14 @@ export default class GitHub {
16
16
  constructor(repository) {
17
17
  const { version } = require('../../package.json');
18
18
 
19
- this.octokit = new Octokit({ auth: process.env.OTA_ENGINE_GITHUB_TOKEN, userAgent: `opentermsarchive/${version}` });
19
+ this.octokit = new Octokit({
20
+ auth: process.env.OTA_ENGINE_GITHUB_TOKEN,
21
+ userAgent: `opentermsarchive/${version}`,
22
+ throttle: {
23
+ onRateLimit: () => false, // Do not retry after hitting a rate limit error
24
+ onSecondaryRateLimit: () => false, // Do not retry after hitting a secondary rate limit error
25
+ },
26
+ });
20
27
 
21
28
  const [ owner, repo ] = repository.split('/');
22
29
 
@@ -25,173 +32,145 @@ export default class GitHub {
25
32
 
26
33
  async initialize() {
27
34
  this.MANAGED_LABELS = require('./labels.json');
28
-
29
- const existingLabels = await this.getRepositoryLabels();
30
- const existingLabelsNames = existingLabels.map(label => label.name);
31
- const missingLabels = this.MANAGED_LABELS.filter(label => !existingLabelsNames.includes(label.name));
32
-
33
- if (missingLabels.length) {
34
- logger.info(`πŸ€– Following required labels are not present on the repository: ${missingLabels.map(label => `"${label.name}"`).join(', ')}. Creating them…`);
35
-
36
- for (const label of missingLabels) {
37
- await this.createLabel({ /* eslint-disable-line no-await-in-loop */
38
- name: label.name,
39
- color: label.color,
40
- description: `${label.description} ${MANAGED_BY_OTA_MARKER}`,
41
- });
35
+ try {
36
+ const existingLabels = await this.getRepositoryLabels();
37
+ const existingLabelsNames = existingLabels.map(label => label.name);
38
+ const missingLabels = this.MANAGED_LABELS.filter(label => !existingLabelsNames.includes(label.name));
39
+
40
+ if (missingLabels.length) {
41
+ logger.info(`Following required labels are not present on the repository: ${missingLabels.map(label => `"${label.name}"`).join(', ')}. Creating them…`);
42
+
43
+ for (const label of missingLabels) {
44
+ await this.createLabel({ /* eslint-disable-line no-await-in-loop */
45
+ name: label.name,
46
+ color: label.color,
47
+ description: `${label.description} ${MANAGED_BY_OTA_MARKER}`,
48
+ });
49
+ }
42
50
  }
51
+ } catch (error) {
52
+ logger.error(`Failed to handle repository labels: ${error.message}`);
43
53
  }
44
54
  }
45
55
 
46
56
  async getRepositoryLabels() {
47
- try {
48
- const { data: labels } = await this.octokit.request('GET /repos/{owner}/{repo}/labels', { ...this.commonParams });
57
+ const { data: labels } = await this.octokit.request('GET /repos/{owner}/{repo}/labels', { ...this.commonParams });
49
58
 
50
- return labels;
51
- } catch (error) {
52
- logger.error(`πŸ€– Could not get labels: ${error}`);
53
- }
59
+ return labels;
54
60
  }
55
61
 
56
62
  async createLabel({ name, color, description }) {
57
- try {
58
- await this.octokit.request('POST /repos/{owner}/{repo}/labels', {
59
- ...this.commonParams,
60
- name,
61
- color,
62
- description,
63
- });
64
-
65
- logger.info(`πŸ€– Created repository label "${name}"`);
66
- } catch (error) {
67
- logger.error(`πŸ€– Could not create label "${name}": ${error}`);
68
- }
63
+ await this.octokit.request('POST /repos/{owner}/{repo}/labels', {
64
+ ...this.commonParams,
65
+ name,
66
+ color,
67
+ description,
68
+ });
69
69
  }
70
70
 
71
71
  async createIssue({ title, description: body, labels }) {
72
- try {
73
- const { data: issue } = await this.octokit.request('POST /repos/{owner}/{repo}/issues', {
74
- ...this.commonParams,
75
- title,
76
- body,
77
- labels,
78
- });
79
-
80
- logger.info(`πŸ€– Created GitHub issue #${issue.number} "${title}": ${issue.html_url}`);
81
-
82
- return issue;
83
- } catch (error) {
84
- logger.error(`πŸ€– Could not create GitHub issue "${title}": ${error}`);
85
- }
72
+ const { data: issue } = await this.octokit.request('POST /repos/{owner}/{repo}/issues', {
73
+ ...this.commonParams,
74
+ title,
75
+ body,
76
+ labels,
77
+ });
78
+
79
+ return issue;
86
80
  }
87
81
 
88
82
  async setIssueLabels({ issue, labels }) {
89
- try {
90
- await this.octokit.request('PUT /repos/{owner}/{repo}/issues/{issue_number}/labels', {
91
- ...this.commonParams,
92
- issue_number: issue.number,
93
- labels,
94
- });
95
-
96
- logger.info(`πŸ€– Updated labels to GitHub issue #${issue.number}`);
97
- } catch (error) {
98
- logger.error(`πŸ€– Could not update GitHub issue #${issue.number} "${issue.title}": ${error}`);
99
- }
83
+ await this.octokit.request('PUT /repos/{owner}/{repo}/issues/{issue_number}/labels', {
84
+ ...this.commonParams,
85
+ issue_number: issue.number,
86
+ labels,
87
+ });
100
88
  }
101
89
 
102
90
  async openIssue(issue) {
103
- try {
104
- await this.octokit.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
105
- ...this.commonParams,
106
- issue_number: issue.number,
107
- state: GitHub.ISSUE_STATE_OPEN,
108
- });
109
-
110
- logger.info(`πŸ€– Opened GitHub issue #${issue.number}`);
111
- } catch (error) {
112
- logger.error(`πŸ€– Could not update GitHub issue #${issue.number} "${issue.title}": ${error}`);
113
- }
91
+ await this.octokit.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
92
+ ...this.commonParams,
93
+ issue_number: issue.number,
94
+ state: GitHub.ISSUE_STATE_OPEN,
95
+ });
114
96
  }
115
97
 
116
98
  async closeIssue(issue) {
117
- try {
118
- await this.octokit.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
119
- ...this.commonParams,
120
- issue_number: issue.number,
121
- state: GitHub.ISSUE_STATE_CLOSED,
122
- });
123
-
124
- logger.info(`πŸ€– Closed GitHub issue #${issue.number}`);
125
- } catch (error) {
126
- logger.error(`πŸ€– Could not update GitHub issue #${issue.number} "${issue.title}": ${error}`);
127
- }
99
+ await this.octokit.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
100
+ ...this.commonParams,
101
+ issue_number: issue.number,
102
+ state: GitHub.ISSUE_STATE_CLOSED,
103
+ });
128
104
  }
129
105
 
130
106
  async getIssue({ title, ...searchParams }) {
131
- try {
132
- const issues = await this.octokit.paginate('GET /repos/{owner}/{repo}/issues', {
133
- ...this.commonParams,
134
- per_page: 100,
135
- ...searchParams,
136
- }, response => response.data);
107
+ const issues = await this.octokit.paginate('GET /repos/{owner}/{repo}/issues', {
108
+ ...this.commonParams,
109
+ per_page: 100,
110
+ ...searchParams,
111
+ }, response => response.data);
137
112
 
138
- const [issue] = issues.filter(item => item.title === title); // since only one is expected, use the first one
113
+ const [issue] = issues.filter(item => item.title === title); // since only one is expected, use the first one
139
114
 
140
- return issue;
141
- } catch (error) {
142
- logger.error(`πŸ€– Could not find GitHub issue "${title}": ${error}`);
143
- }
115
+ return issue;
144
116
  }
145
117
 
146
118
  async addCommentToIssue({ issue, comment: body }) {
147
- try {
148
- const { data: comment } = await this.octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
149
- ...this.commonParams,
150
- issue_number: issue.number,
151
- body,
152
- });
119
+ const { data: comment } = await this.octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
120
+ ...this.commonParams,
121
+ issue_number: issue.number,
122
+ body,
123
+ });
153
124
 
154
- logger.info(`πŸ€– Added comment to GitHub issue #${issue.number}: ${comment.html_url}`);
155
-
156
- return comment;
157
- } catch (error) {
158
- logger.error(`πŸ€– Could not add comment to GitHub issue #${issue.number} "${issue.title}": ${error}`);
159
- }
125
+ return comment;
160
126
  }
161
127
 
162
128
  async closeIssueWithCommentIfExists({ title, comment }) {
163
- const openedIssue = await this.getIssue({ title, state: GitHub.ISSUE_STATE_OPEN });
129
+ try {
130
+ const openedIssue = await this.getIssue({ title, state: GitHub.ISSUE_STATE_OPEN });
164
131
 
165
- if (!openedIssue) {
166
- return;
167
- }
132
+ if (!openedIssue) {
133
+ return;
134
+ }
168
135
 
169
- await this.addCommentToIssue({ issue: openedIssue, comment });
136
+ await this.addCommentToIssue({ issue: openedIssue, comment });
137
+ await this.closeIssue(openedIssue);
170
138
 
171
- return this.closeIssue(openedIssue);
139
+ return logger.info(`Closed issue #${openedIssue.number}: ${openedIssue.html_url}`);
140
+ } catch (error) {
141
+ logger.error(`Failed to update issue "${title}": ${error.message}`);
142
+ }
172
143
  }
173
144
 
174
145
  async createOrUpdateIssue({ title, description, label }) {
175
- const issue = await this.getIssue({ title, state: GitHub.ISSUE_STATE_ALL });
146
+ try {
147
+ const issue = await this.getIssue({ title, state: GitHub.ISSUE_STATE_ALL });
176
148
 
177
- if (!issue) {
178
- return this.createIssue({ title, description, labels: [label] });
179
- }
149
+ if (!issue) {
150
+ const createdIssue = await this.createIssue({ title, description, labels: [label] });
180
151
 
181
- if (issue.state == GitHub.ISSUE_STATE_CLOSED) {
182
- await this.openIssue(issue);
183
- }
152
+ return logger.info(`Created issue #${createdIssue.number} "${title}": ${createdIssue.html_url}`);
153
+ }
184
154
 
185
- const managedLabelsNames = this.MANAGED_LABELS.map(label => label.name);
186
- const [managedLabel] = issue.labels.filter(label => managedLabelsNames.includes(label.name)); // it is assumed that only one specific reason for failure is possible at a time, making managed labels mutually exclusive
155
+ if (issue.state == GitHub.ISSUE_STATE_CLOSED) {
156
+ await this.openIssue(issue);
157
+ logger.info(`Reopened issue #${issue.number}: ${issue.html_url}`);
158
+ }
187
159
 
188
- if (managedLabel?.name == label) { // if the label is already assigned to the issue, the error is redundant with the one already reported and no further action is necessary
189
- return;
190
- }
160
+ const managedLabelsNames = this.MANAGED_LABELS.map(label => label.name);
161
+ const [managedLabel] = issue.labels.filter(label => managedLabelsNames.includes(label.name)); // it is assumed that only one specific reason for failure is possible at a time, making managed labels mutually exclusive
162
+
163
+ if (managedLabel?.name == label) { // if the label is already assigned to the issue, the error is redundant with the one already reported and no further action is necessary
164
+ return;
165
+ }
191
166
 
192
- const labelsNotManagedToKeep = issue.labels.map(label => label.name).filter(label => !managedLabelsNames.includes(label));
167
+ const labelsNotManagedToKeep = issue.labels.map(label => label.name).filter(label => !managedLabelsNames.includes(label));
193
168
 
194
- await this.setIssueLabels({ issue, labels: [ label, ...labelsNotManagedToKeep ] });
195
- await this.addCommentToIssue({ issue, comment: description });
169
+ await this.setIssueLabels({ issue, labels: [ label, ...labelsNotManagedToKeep ] });
170
+ await this.addCommentToIssue({ issue, comment: description });
171
+ logger.info(`Updated issue #${issue.number}: ${issue.html_url}`);
172
+ } catch (error) {
173
+ logger.error(`Failed to update issue "${title}": ${error.message}`);
174
+ }
196
175
  }
197
176
  }