Skip to content

Commit 06fd3a5

Browse files
committed
Add new GitHub API fields to scenario files
This uses a script to add the new `stargazers_count` and `updated_at` to the scenario files. This is done by using the GitHub API to get the information for each repo and then updating the scenario file. The `updated_at` values are not completely representative since they are the `updated_at` at time of running the script, rather than at the time the variant analysis was run. However, this should not really matter in practice. An alternative for scanned repositories might be getting the creation time of the `database_commit_sha` commit.
1 parent be62bd3 commit 06fd3a5

File tree

74 files changed

+35922
-11918
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+35922
-11918
lines changed

extensions/ql-vscode/package-lock.json

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/ql-vscode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@
13121312
"@babel/core": "^7.18.13",
13131313
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
13141314
"@faker-js/faker": "^7.5.0",
1315+
"@octokit/plugin-throttling": "^4.3.2",
13151316
"@storybook/addon-actions": "^6.5.10",
13161317
"@storybook/addon-essentials": "^6.5.10",
13171318
"@storybook/addon-interactions": "^6.5.10",
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* This scripts helps after adding a new field in the GitHub API. You will
3+
* need to modify this script to add the new field to the scenarios. This
4+
* is just a template and should not be used as-is since it has already been
5+
* applied.
6+
*
7+
* Depending on the actual implementation of the script, you might run into
8+
* rate limits. If that happens, you can set a `GITHUB_TOKEN` environment
9+
* variable. For example, use: ``export GITHUB_TOKEN=`gh auth token```.
10+
*
11+
* Usage: npx ts-node scripts/add-fields-to-scenarios.ts
12+
*/
13+
14+
import * as fs from 'fs-extra';
15+
import * as path from 'path';
16+
17+
import { Octokit, type RestEndpointMethodTypes } from '@octokit/rest';
18+
import { throttling } from '@octokit/plugin-throttling';
19+
20+
import { getFiles } from './util/files';
21+
import type { GitHubApiRequest } from '../src/mocks/gh-api-request';
22+
import { isGetVariantAnalysisRequest } from '../src/mocks/gh-api-request';
23+
import { VariantAnalysis } from '../src/remote-queries/gh-api/variant-analysis';
24+
import { RepositoryWithMetadata } from '../src/remote-queries/gh-api/repository';
25+
26+
const extensionDirectory = path.resolve(__dirname, '..');
27+
const scenariosDirectory = path.resolve(extensionDirectory, 'src/mocks/scenarios');
28+
29+
// Make sure we don't run into rate limits by automatically waiting until we can
30+
// make another request.
31+
const MyOctokit = Octokit.plugin(throttling);
32+
33+
const auth = process.env.GITHUB_TOKEN;
34+
35+
const octokit = new MyOctokit({
36+
auth,
37+
throttle: {
38+
onRateLimit: (retryAfter: number, options: any, octokit: Octokit): boolean => {
39+
octokit.log.warn(
40+
`Request quota exhausted for request ${options.method} ${options.url}. Retrying after ${retryAfter} seconds!`
41+
);
42+
43+
return true;
44+
},
45+
onSecondaryRateLimit: (_retryAfter: number, options: any, octokit: Octokit): void => {
46+
octokit.log.warn(
47+
`SecondaryRateLimit detected for request ${options.method} ${options.url}`
48+
);
49+
},
50+
}
51+
});
52+
const repositories = new Map<number, RestEndpointMethodTypes['repos']['get']['response']['data']>();
53+
54+
async function addFieldsToRepository(repository: RepositoryWithMetadata) {
55+
if (!repositories.has(repository.id)) {
56+
const [owner, repo] = repository.full_name.split('/');
57+
58+
const apiRepository = await octokit.repos.get({
59+
owner,
60+
repo,
61+
});
62+
63+
repositories.set(repository.id, apiRepository.data);
64+
}
65+
66+
const apiRepository = repositories.get(repository.id)!;
67+
68+
repository.stargazers_count = apiRepository.stargazers_count;
69+
repository.updated_at = apiRepository.updated_at;
70+
}
71+
72+
async function addFieldsToScenarios() {
73+
if (!(await fs.pathExists(scenariosDirectory))) {
74+
console.error('Scenarios directory does not exist: ' + scenariosDirectory);
75+
return;
76+
}
77+
78+
for await (const file of getFiles(scenariosDirectory)) {
79+
if (!file.endsWith('.json')) {
80+
continue;
81+
}
82+
83+
const data: GitHubApiRequest = await fs.readJson(file);
84+
85+
if (!isGetVariantAnalysisRequest(data)) {
86+
continue;
87+
}
88+
89+
if (!data.response.body || !('controller_repo' in data.response.body)) {
90+
continue;
91+
}
92+
93+
console.log(`Adding fields to '${path.relative(scenariosDirectory, file)}'`);
94+
95+
const variantAnalysis = data.response.body as VariantAnalysis;
96+
97+
if (variantAnalysis.scanned_repositories) {
98+
for (const item of variantAnalysis.scanned_repositories) {
99+
await addFieldsToRepository(item.repository);
100+
}
101+
}
102+
103+
if (variantAnalysis.skipped_repositories?.access_mismatch_repos) {
104+
for (const item of variantAnalysis.skipped_repositories.access_mismatch_repos.repositories) {
105+
await addFieldsToRepository(item);
106+
}
107+
}
108+
109+
if (variantAnalysis.skipped_repositories?.no_codeql_db_repos) {
110+
for (const item of variantAnalysis.skipped_repositories.no_codeql_db_repos.repositories) {
111+
await addFieldsToRepository(item);
112+
}
113+
}
114+
115+
if (variantAnalysis.skipped_repositories?.over_limit_repos) {
116+
for (const item of variantAnalysis.skipped_repositories.over_limit_repos.repositories) {
117+
await addFieldsToRepository(item);
118+
}
119+
}
120+
121+
await fs.writeJson(file, data, { spaces: 2 });
122+
}
123+
}
124+
125+
addFieldsToScenarios().catch(e => {
126+
console.error(e);
127+
process.exit(2);
128+
});

extensions/ql-vscode/scripts/lint-scenarios.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import * as path from 'path';
44
import Ajv from 'ajv';
55
import * as tsj from 'ts-json-schema-generator';
66

7+
import { getFiles } from './util/files';
8+
79
const extensionDirectory = path.resolve(__dirname, '..');
810
const rootDirectory = path.resolve(extensionDirectory, '../..');
911
const scenariosDirectory = path.resolve(extensionDirectory, 'src/mocks/scenarios');
@@ -60,19 +62,6 @@ async function lintScenarios() {
6062
}
6163
}
6264

63-
// https://stackoverflow.com/a/45130990
64-
async function* getFiles(dir: string): AsyncGenerator<string> {
65-
const dirents = await fs.readdir(dir, { withFileTypes: true });
66-
for (const dirent of dirents) {
67-
const res = path.resolve(dir, dirent.name);
68-
if (dirent.isDirectory()) {
69-
yield* getFiles(res);
70-
} else {
71-
yield res;
72-
}
73-
}
74-
}
75-
7665
lintScenarios().catch(e => {
7766
console.error(e);
7867
process.exit(2);

extensions/ql-vscode/scripts/tsconfig.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,9 @@
22
"$schema": "https://json.schemastore.org/tsconfig",
33
"extends": "../tsconfig.json",
44
"include": ["**/*.ts"],
5-
"exclude": []
5+
"exclude": [],
6+
"compilerOptions": {
7+
"rootDir": "..",
8+
"noEmit": true
9+
}
610
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as fs from 'fs-extra';
2+
import * as path from 'path';
3+
4+
// https://stackoverflow.com/a/45130990
5+
export async function* getFiles(dir: string): AsyncGenerator<string> {
6+
const dirents = await fs.readdir(dir, { withFileTypes: true });
7+
for (const dirent of dirents) {
8+
const res = path.resolve(dir, dirent.name);
9+
if (dirent.isDirectory()) {
10+
yield* getFiles(res);
11+
} else {
12+
yield res;
13+
}
14+
}
15+
}

extensions/ql-vscode/src/mocks/scenarios/problem-query-success/11-getVariantAnalysis.json

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@
105105
"id": 206444,
106106
"name": "hive",
107107
"full_name": "apache/hive",
108-
"private": false
108+
"private": false,
109+
"stargazers_count": 4523,
110+
"updated_at": "2022-11-02T10:04:02Z"
109111
},
110112
"analysis_status": "succeeded",
111113
"artifact_size_in_bytes": 81841,
@@ -116,7 +118,9 @@
116118
"id": 20753500,
117119
"name": "ng-nice",
118120
"full_name": "angular-cn/ng-nice",
119-
"private": false
121+
"private": false,
122+
"stargazers_count": 192,
123+
"updated_at": "2022-03-17T08:34:30Z"
120124
},
121125
"analysis_status": "in_progress"
122126
},
@@ -125,7 +129,9 @@
125129
"id": 23418517,
126130
"name": "hadoop",
127131
"full_name": "apache/hadoop",
128-
"private": false
132+
"private": false,
133+
"stargazers_count": 13030,
134+
"updated_at": "2022-11-02T08:23:58Z"
129135
},
130136
"analysis_status": "succeeded",
131137
"artifact_size_in_bytes": 66895,
@@ -136,7 +142,9 @@
136142
"id": 236095576,
137143
"name": "backstage",
138144
"full_name": "backstage/backstage",
139-
"private": false
145+
"private": false,
146+
"stargazers_count": 19033,
147+
"updated_at": "2022-11-02T10:25:24Z"
140148
},
141149
"analysis_status": "in_progress"
142150
},
@@ -145,7 +153,9 @@
145153
"id": 257485422,
146154
"name": "vite",
147155
"full_name": "vitejs/vite",
148-
"private": false
156+
"private": false,
157+
"stargazers_count": 49064,
158+
"updated_at": "2022-11-02T11:29:22Z"
149159
},
150160
"analysis_status": "succeeded",
151161
"artifact_size_in_bytes": 702,

extensions/ql-vscode/src/mocks/scenarios/problem-query-success/16-getVariantAnalysis.json

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@
105105
"id": 206444,
106106
"name": "hive",
107107
"full_name": "apache/hive",
108-
"private": false
108+
"private": false,
109+
"stargazers_count": 4523,
110+
"updated_at": "2022-11-02T10:04:02Z"
109111
},
110112
"analysis_status": "succeeded",
111113
"artifact_size_in_bytes": 81841,
@@ -116,7 +118,9 @@
116118
"id": 20753500,
117119
"name": "ng-nice",
118120
"full_name": "angular-cn/ng-nice",
119-
"private": false
121+
"private": false,
122+
"stargazers_count": 192,
123+
"updated_at": "2022-03-17T08:34:30Z"
120124
},
121125
"analysis_status": "in_progress"
122126
},
@@ -125,7 +129,9 @@
125129
"id": 23418517,
126130
"name": "hadoop",
127131
"full_name": "apache/hadoop",
128-
"private": false
132+
"private": false,
133+
"stargazers_count": 13030,
134+
"updated_at": "2022-11-02T08:23:58Z"
129135
},
130136
"analysis_status": "succeeded",
131137
"artifact_size_in_bytes": 66895,
@@ -136,7 +142,9 @@
136142
"id": 236095576,
137143
"name": "backstage",
138144
"full_name": "backstage/backstage",
139-
"private": false
145+
"private": false,
146+
"stargazers_count": 19033,
147+
"updated_at": "2022-11-02T10:25:24Z"
140148
},
141149
"analysis_status": "in_progress"
142150
},
@@ -145,7 +153,9 @@
145153
"id": 257485422,
146154
"name": "vite",
147155
"full_name": "vitejs/vite",
148-
"private": false
156+
"private": false,
157+
"stargazers_count": 49064,
158+
"updated_at": "2022-11-02T11:29:22Z"
149159
},
150160
"analysis_status": "succeeded",
151161
"artifact_size_in_bytes": 702,

0 commit comments

Comments
 (0)