1
1
import { QuickPickItem , Uri , window } from 'vscode' ;
2
+ import * as path from 'path' ;
2
3
import * as yaml from 'js-yaml' ;
3
4
import * as fs from 'fs-extra' ;
5
+ import * as tmp from 'tmp-promise' ;
4
6
import { findLanguage , showAndLogErrorMessage , showAndLogInformationMessage , showInformationMessageWithAction } from './helpers' ;
5
7
import { Credentials } from './authentication' ;
6
8
import * as cli from './cli' ;
@@ -68,6 +70,22 @@ export async function getRepositories(): Promise<string[] | undefined> {
68
70
}
69
71
}
70
72
73
+ async function generateQueryPack ( cliServer : cli . CodeQLCliServer , queryFile : string ) : Promise < string > {
74
+
75
+ const packRoot = path . dirname ( queryFile ) ;
76
+
77
+ const bundlePath = await tmp . tmpName ( {
78
+ postfix : '.tgz' ,
79
+ prefix : 'qlpack-' ,
80
+ } ) ;
81
+
82
+ await cliServer . packBundle ( packRoot , bundlePath ) ;
83
+ const base64Pack = ( await fs . readFile ( bundlePath ) ) . toString ( 'base64' ) ;
84
+
85
+ await fs . unlink ( bundlePath ) ;
86
+ return base64Pack ;
87
+ }
88
+
71
89
export async function runRemoteQuery ( cliServer : cli . CodeQLCliServer , credentials : Credentials , uri ?: Uri ) {
72
90
if ( ! uri ?. fsPath . endsWith ( '.ql' ) ) {
73
91
return ;
@@ -81,6 +99,7 @@ export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials
81
99
let language : string | undefined ;
82
100
let repositories : string [ ] | undefined ;
83
101
102
+ await cliServer . packInstall ( path . dirname ( queryFile ) ) ;
84
103
// If the user has an explicit `.repositories` file, use that.
85
104
// Otherwise, prompt user to select repositories from the `codeQL.remoteQueries.repositoryLists` setting.
86
105
if ( await fs . pathExists ( repositoriesFile ) ) {
@@ -130,10 +149,11 @@ export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials
130
149
void logger . log ( `Using controller repository: ${ controllerRepo } ` ) ;
131
150
const [ owner , repo ] = controllerRepo . split ( '/' ) ;
132
151
133
- await runRemoteQueriesApiRequest ( credentials , ref , language , repositories , query , owner , repo ) ;
152
+ const queryPackBase64 = await generateQueryPack ( cliServer , queryFile ) ;
153
+ await runRemoteQueriesApiRequest ( credentials , ref , language , repositories , query , owner , repo , queryPackBase64 ) ;
134
154
}
135
155
136
- async function runRemoteQueriesApiRequest ( credentials : Credentials , ref : string , language : string , repositories : string [ ] , query : string , owner : string , repo : string ) {
156
+ async function runRemoteQueriesApiRequest ( credentials : Credentials , ref : string , language : string , repositories : string [ ] , query : string , owner : string , repo : string , queryPackBase64 : string ) : Promise < void > {
137
157
const octokit = await credentials . getOctokit ( ) ;
138
158
139
159
try {
@@ -143,22 +163,23 @@ async function runRemoteQueriesApiRequest(credentials: Credentials, ref: string,
143
163
owner,
144
164
repo,
145
165
data : {
146
- ref : ref ,
147
- language : language ,
148
- repositories : repositories ,
149
- query : query ,
166
+ ref,
167
+ language,
168
+ repositories,
169
+ query,
170
+ queryPack : queryPackBase64 ,
150
171
}
151
172
}
152
173
) ;
153
174
void showAndLogInformationMessage ( `Successfully scheduled runs. [Click here to see the progress](https://github.com/${ owner } /${ repo } /actions).` ) ;
154
175
155
176
} catch ( error ) {
156
- await attemptRerun ( error , credentials , ref , language , repositories , query , owner , repo ) ;
177
+ await attemptRerun ( error , credentials , ref , language , repositories , query , owner , repo , queryPackBase64 ) ;
157
178
}
158
179
}
159
180
160
181
/** Attempts to rerun the query on only the valid repositories */
161
- export async function attemptRerun ( error : any , credentials : Credentials , ref : string , language : string , repositories : string [ ] , query : string , owner : string , repo : string ) {
182
+ export async function attemptRerun ( error : any , credentials : Credentials , ref : string , language : string , repositories : string [ ] , query : string , owner : string , repo : string , queryPackBase64 : string ) {
162
183
if ( typeof error . message === 'string' && error . message . includes ( 'Some repositories were invalid' ) ) {
163
184
const invalidRepos = error ?. response ?. data ?. invalid_repos || [ ] ;
164
185
const reposWithoutDbUploads = error ?. response ?. data ?. repos_without_db_uploads || [ ] ;
@@ -181,7 +202,7 @@ export async function attemptRerun(error: any, credentials: Credentials, ref: st
181
202
if ( rerunQuery ) {
182
203
const validRepositories = repositories . filter ( r => ! invalidRepos . includes ( r ) && ! reposWithoutDbUploads . includes ( r ) ) ;
183
204
void logger . log ( `Rerunning query on set of valid repositories: ${ JSON . stringify ( validRepositories ) } ` ) ;
184
- await runRemoteQueriesApiRequest ( credentials , ref , language , validRepositories , query , owner , repo ) ;
205
+ await runRemoteQueriesApiRequest ( credentials , ref , language , validRepositories , query , owner , repo , queryPackBase64 ) ;
185
206
}
186
207
187
208
} else {
0 commit comments