Compare commits
59 Commits
v1.13.1
...
mh-refacto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
390dfeb087 | ||
|
|
012e597d4a | ||
|
|
cd568db7b4 | ||
|
|
dc745dd8e1 | ||
|
|
29d6b127e2 | ||
|
|
1cbfba32a0 | ||
|
|
c2b2d10591 | ||
|
|
1fe4abf6e8 | ||
|
|
efaef8a2cb | ||
|
|
a8d61a605a | ||
|
|
e44024763d | ||
|
|
9a6aa52a40 | ||
|
|
c106903f01 | ||
|
|
d40cda150c | ||
|
|
d4df484acb | ||
|
|
3e1d924110 | ||
|
|
cc4666a614 | ||
|
|
51906bbcee | ||
|
|
fcfa6979e2 | ||
|
|
f0783ed274 | ||
|
|
fe45e00fb3 | ||
|
|
4a317d33a9 | ||
|
|
ffc7135c1f | ||
|
|
c805b48f18 | ||
|
|
e1b95c2f7c | ||
|
|
481d2f5404 | ||
|
|
15fa23acb4 | ||
|
|
a625d9aabe | ||
|
|
cd70b19bb3 | ||
|
|
7a58084df9 | ||
|
|
916d16126b | ||
|
|
a5eb915267 | ||
|
|
a5440ef482 | ||
|
|
fc86be7687 | ||
|
|
f0909a9d67 | ||
|
|
40b5b5ba7e | ||
|
|
fa85bcfad6 | ||
|
|
dd1b054f26 | ||
|
|
b96cd6c7e1 | ||
|
|
b466d2aa36 | ||
|
|
7f6c1ad7f7 | ||
|
|
10f4b47019 | ||
|
|
b31a769fdd | ||
|
|
c4e2f11372 | ||
|
|
9494d32144 | ||
|
|
12555d90c1 | ||
|
|
d46e03b4cc | ||
|
|
f0e2285122 | ||
|
|
f4d0d23170 | ||
|
|
513fb65560 | ||
|
|
7d353ced9b | ||
|
|
be3506d987 | ||
|
|
3fa6304050 | ||
|
|
bb40e5bcad | ||
|
|
e2a8ae318b | ||
|
|
79867e2f9d | ||
|
|
1bc13d70ce | ||
|
|
0bd359997d | ||
|
|
28a7d1cf34 |
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
@@ -5,8 +5,4 @@
|
||||
|
||||
Replace this with a description of the changes your pull request makes.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] [CHANGELOG.md](https://github.com/github/vscode-codeql/blob/main/extensions/ql-vscode/CHANGELOG.md) has been updated to incorporate all user visible changes made by this pull request.
|
||||
- [ ] Issues have been created for any UI or other user-facing changes made by this pull request.
|
||||
- [ ] _[Maintainers only]_ If this pull request makes user-facing changes that require documentation changes, open a corresponding docs pull request in the [github/codeql](https://github.com/github/codeql/tree/main/docs/codeql/codeql-for-visual-studio-code) repo and add the `ready-for-doc-review` label there.
|
||||
Remember to update the [changelog](https://github.com/github/vscode-codeql/blob/main/extensions/ql-vscode/CHANGELOG.md) if there have been user-facing changes!
|
||||
|
||||
13
.github/workflows/main.yml
vendored
13
.github/workflows/main.yml
vendored
@@ -144,6 +144,19 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
steps:
|
||||
# Enable 8.3 filename creation. This is not required to run the extension but it is required for the unit tests to pass.
|
||||
# This feature is currently enabled by default in Windows 11 for the C: drive and therefore we must maintain support for it.
|
||||
# This setting needs to be enabled before files are created, i.e. before we checkout the repository.
|
||||
- name: Enable 8.3 filenames
|
||||
shell: pwsh
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
$shortNameEnableProcess = Start-Process -FilePath fsutil.exe -ArgumentList ('8dot3name', 'set', '0') -Wait -PassThru
|
||||
$shortNameEnableExitCode = $shortNameEnableProcess.ExitCode
|
||||
if ($shortNameEnableExitCode -ne 0) {
|
||||
exit $shortNameEnableExitCode
|
||||
}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -111,4 +111,10 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
},
|
||||
"github.copilot.advanced": {
|
||||
|
||||
|
||||
},
|
||||
"codeQL.variantAnalysis.enableGhecDr": true,
|
||||
"github-enterprise.uri": "http://server:8080/"
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ Here are a few things you can do that will increase the likelihood of your pull
|
||||
- [Integration tests that do require the VS Code API are located here](extensions/ql-vscode/src/vscode-tests).
|
||||
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
|
||||
- Write a [good commit message](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
- Update the [changelog](https://github.com/github/vscode-codeql/blob/main/extensions/ql-vscode/CHANGELOG.md) if you are making user-facing changes.
|
||||
|
||||
## Setting up a local build
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ Run one of the above MRVAs, but cancel it from within VS Code:
|
||||
import semmle.python.frameworks.data.internal.ApiGraphModelsExtensions
|
||||
|
||||
from string path, string kind
|
||||
where sinkModel("vscode-codeql", path, kind)
|
||||
where sinkModel("vscode-codeql", path, kind, _)
|
||||
select path, kind
|
||||
```
|
||||
|
||||
@@ -210,17 +210,7 @@ Run one of the above MRVAs, but cancel it from within VS Code:
|
||||
4. Open the ".model.yml" file corresponding to the library that was changed.
|
||||
- Check that the file contains entries for the methods that were modeled.
|
||||
|
||||
#### Test Case 3: Model with AI
|
||||
|
||||
Note that this test requires the feature flag: `codeQL.model.llmGeneration`
|
||||
|
||||
A package that the AI normally gives models for is `javax.servlet-api` from the `jhy/jsoup` repository.
|
||||
|
||||
1. Click "Model with AI".
|
||||
- Check that rows change to "Thinking".
|
||||
- Check that results come back and rows get filled out.
|
||||
|
||||
#### Test Case 4: Model as dependency
|
||||
#### Test Case 3: Model as dependency
|
||||
|
||||
Note that this test requires the feature flag: `codeQL.model.flowGeneration`
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const baseConfig = {
|
||||
"@typescript-eslint/no-throw-literal": "error",
|
||||
"@typescript-eslint/consistent-type-imports": "error",
|
||||
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
|
||||
curly: ["error", "all"],
|
||||
// curly: ["error", "all"],
|
||||
"escompat/no-regexp-lookbehind": "off",
|
||||
"etc/no-implicit-any-catch": "error",
|
||||
"filenames/match-regex": "off",
|
||||
|
||||
@@ -1 +1 @@
|
||||
v18.18.2
|
||||
v20.9.0
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# CodeQL for Visual Studio Code: Changelog
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
## 1.13.1 - 29 May 2024
|
||||
|
||||
- Fix a bug when re-importing test databases that erroneously showed old source code. [#3616](https://github.com/github/vscode-codeql/pull/3616)
|
||||
|
||||
@@ -111,9 +111,9 @@ If you wish to navigate the query results from your keyboard, you can bind short
|
||||
We recommend reading the [full documentation for the extension](https://docs.github.com/code-security/codeql-for-vs-code/) on the GitHub documentation website. You may also find the following resources useful:
|
||||
|
||||
- [Create a database for a different codebase](https://codeql.github.com/docs/codeql-cli/creating-codeql-databases/).
|
||||
- [Try out variant analysis](https://help.semmle.com/QL/learn-ql/ql-training.html).
|
||||
- [Try out variant analysis](https://docs.github.com/code-security/codeql-for-vs-code/getting-started-with-codeql-for-vs-code/running-codeql-queries-at-scale-with-multi-repository-variant-analysis).
|
||||
- [Learn more about CodeQL](https://codeql.github.com/docs/).
|
||||
- [Read how security researchers use CodeQL to find CVEs](https://securitylab.github.com/research).
|
||||
- [Read how security researchers use CodeQL to find CVEs](https://github.blog/tag/github-security-lab/).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
983
extensions/ql-vscode/package-lock.json
generated
983
extensions/ql-vscode/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
"description": "CodeQL for Visual Studio Code",
|
||||
"author": "GitHub",
|
||||
"private": true,
|
||||
"version": "1.13.1",
|
||||
"version": "1.13.2",
|
||||
"publisher": "GitHub",
|
||||
"license": "MIT",
|
||||
"icon": "media/VS-marketplace-CodeQL-icon.png",
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.82.0",
|
||||
"node": "^18.18.2",
|
||||
"node": "^20.9.0",
|
||||
"npm": ">=7.20.6"
|
||||
},
|
||||
"categories": [
|
||||
@@ -339,13 +339,6 @@
|
||||
"title": "Variant analysis",
|
||||
"order": 5,
|
||||
"properties": {
|
||||
"codeQL.variantAnalysis.controllerRepo": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"pattern": "^$|^(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+/[a-zA-Z0-9-_]+$",
|
||||
"patternErrorMessage": "Please enter a valid GitHub repository",
|
||||
"markdownDescription": "[For internal use only] The name of the GitHub repository in which the GitHub Actions workflow is run when using the \"Run Variant Analysis\" command. The repository should be of the form `<owner>/<repo>`)."
|
||||
},
|
||||
"codeQL.variantAnalysis.defaultResultsFilter": {
|
||||
"type": "string",
|
||||
"default": "all",
|
||||
@@ -1931,11 +1924,6 @@
|
||||
{
|
||||
"view": "codeQLEvalLogViewer",
|
||||
"contents": "Run the 'Show Evaluator Log (UI)' command on a CodeQL query run in the Query History view."
|
||||
},
|
||||
{
|
||||
"view": "codeQLVariantAnalysisRepositories",
|
||||
"contents": "Set up a controller repository to start using variant analysis. [Learn more](https://codeql.github.com/docs/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva#controller-repository) about controller repositories. \n[Set up controller repository](command:codeQLVariantAnalysisRepositories.setupControllerRepository)",
|
||||
"when": "!config.codeQL.variantAnalysis.controllerRepo"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2004,7 +1992,7 @@
|
||||
"zip-a-folder": "^3.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/core": "^7.24.6",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.18.6",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@babel/preset-react": "^7.24.1",
|
||||
@@ -2012,22 +2000,22 @@
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@github/markdownlint-github": "^0.6.2",
|
||||
"@playwright/test": "^1.40.1",
|
||||
"@storybook/addon-a11y": "^8.1.3",
|
||||
"@storybook/addon-actions": "^8.1.3",
|
||||
"@storybook/addon-essentials": "^8.1.3",
|
||||
"@storybook/addon-interactions": "^8.1.3",
|
||||
"@storybook/addon-links": "^8.1.3",
|
||||
"@storybook/addon-a11y": "^8.1.10",
|
||||
"@storybook/addon-actions": "^8.1.10",
|
||||
"@storybook/addon-essentials": "^8.1.10",
|
||||
"@storybook/addon-interactions": "^8.1.10",
|
||||
"@storybook/addon-links": "^8.1.10",
|
||||
"@storybook/blocks": "^8.0.2",
|
||||
"@storybook/components": "^8.0.2",
|
||||
"@storybook/csf": "^0.1.7",
|
||||
"@storybook/csf": "^0.1.8",
|
||||
"@storybook/icons": "^1.2.9",
|
||||
"@storybook/manager-api": "^8.1.3",
|
||||
"@storybook/react": "^8.1.3",
|
||||
"@storybook/react-vite": "^8.1.3",
|
||||
"@storybook/theming": "^8.1.3",
|
||||
"@storybook/manager-api": "^8.1.10",
|
||||
"@storybook/react": "^8.1.10",
|
||||
"@storybook/react-vite": "^8.1.10",
|
||||
"@storybook/theming": "^8.1.10",
|
||||
"@testing-library/dom": "^10.1.0",
|
||||
"@testing-library/jest-dom": "^6.4.5",
|
||||
"@testing-library/react": "^15.0.7",
|
||||
"@testing-library/jest-dom": "^6.4.6",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/child-process-promise": "^2.2.1",
|
||||
"@types/d3": "^7.4.0",
|
||||
@@ -2039,7 +2027,7 @@
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/js-yaml": "^4.0.6",
|
||||
"@types/nanoid": "^3.0.0",
|
||||
"@types/node": "18.18.*",
|
||||
"@types/node": "20.9.*",
|
||||
"@types/node-fetch": "^2.5.2",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
@@ -2078,7 +2066,7 @@
|
||||
"gulp-esbuild": "^0.12.0",
|
||||
"gulp-replace": "^1.1.3",
|
||||
"gulp-typescript": "^5.0.1",
|
||||
"husky": "^9.0.11",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.0.3",
|
||||
"jest-environment-jsdom": "^29.0.3",
|
||||
"jest-runner-vscode": "^3.0.1",
|
||||
@@ -2088,13 +2076,13 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"patch-package": "^8.0.0",
|
||||
"prettier": "^3.2.5",
|
||||
"storybook": "^8.1.3",
|
||||
"storybook": "^8.1.10",
|
||||
"tar-stream": "^3.1.7",
|
||||
"through2": "^4.0.2",
|
||||
"ts-jest": "^29.1.2",
|
||||
"ts-jest": "^29.1.4",
|
||||
"ts-json-schema-generator": "^2.1.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"ts-unused-exports": "^10.0.0",
|
||||
"ts-unused-exports": "^10.1.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^5.2.11",
|
||||
"vite-node": "^1.5.3"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -290,7 +290,6 @@ export type DatabasePanelCommands = {
|
||||
"codeQLVariantAnalysisRepositories.openConfigFile": () => Promise<void>;
|
||||
"codeQLVariantAnalysisRepositories.addNewDatabase": () => Promise<void>;
|
||||
"codeQLVariantAnalysisRepositories.addNewList": () => Promise<void>;
|
||||
"codeQLVariantAnalysisRepositories.setupControllerRepository": () => Promise<void>;
|
||||
|
||||
"codeQLVariantAnalysisRepositories.setSelectedItem": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
|
||||
"codeQLVariantAnalysisRepositories.setSelectedItemContextMenu": TreeViewContextSingleSelectionCommandFunction<DbTreeViewItem>;
|
||||
|
||||
@@ -112,7 +112,9 @@ export function hasEnterpriseUri(): boolean {
|
||||
* Does the uri look like GHEC-DR?
|
||||
*/
|
||||
function isGhecDrUri(uri: Uri | undefined): boolean {
|
||||
return uri !== undefined && uri.authority.toLowerCase().endsWith(".ghe.com");
|
||||
return (
|
||||
uri !== undefined && !uri.authority.toLowerCase().endsWith("github.com")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -591,27 +593,7 @@ export const NO_CACHE_CONTEXTUAL_QUERIES = new Setting(
|
||||
// Settings for variant analysis
|
||||
const VARIANT_ANALYSIS_SETTING = new Setting("variantAnalysis", ROOT_SETTING);
|
||||
|
||||
/**
|
||||
* The name of the "controller" repository that you want to use with the "Run Variant Analysis" command.
|
||||
* Note: This command is only available for internal users.
|
||||
*
|
||||
* This setting should be a GitHub repository of the form `<owner>/<repo>`.
|
||||
*/
|
||||
const REMOTE_CONTROLLER_REPO = new Setting(
|
||||
"controllerRepo",
|
||||
VARIANT_ANALYSIS_SETTING,
|
||||
);
|
||||
|
||||
export function getRemoteControllerRepo(): string | undefined {
|
||||
return REMOTE_CONTROLLER_REPO.getValue<string>() || undefined;
|
||||
}
|
||||
|
||||
export async function setRemoteControllerRepo(repo: string | undefined) {
|
||||
await REMOTE_CONTROLLER_REPO.updateValue(repo, ConfigurationTarget.Global);
|
||||
}
|
||||
|
||||
export interface VariantAnalysisConfig {
|
||||
controllerRepo: string | undefined;
|
||||
showSystemDefinedRepositoryLists: boolean;
|
||||
/**
|
||||
* This uses a URL instead of a URI because the URL class is available in
|
||||
@@ -632,10 +614,6 @@ export class VariantAnalysisConfigListener
|
||||
);
|
||||
}
|
||||
|
||||
public get controllerRepo(): string | undefined {
|
||||
return getRemoteControllerRepo();
|
||||
}
|
||||
|
||||
public get showSystemDefinedRepositoryLists(): boolean {
|
||||
return !hasEnterpriseUri();
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ import type { DbManager } from "../db-manager";
|
||||
import { DbTreeDataProvider } from "./db-tree-data-provider";
|
||||
import type { DbTreeViewItem } from "./db-tree-view-item";
|
||||
import { getGitHubUrl } from "./db-tree-view-item-action";
|
||||
import { getControllerRepo } from "../../variant-analysis/run-remote-query";
|
||||
import { getErrorMessage } from "../../common/helpers-pure";
|
||||
import type { DatabasePanelCommands } from "../../common/commands";
|
||||
import type { App } from "../../common/app";
|
||||
import { QueryLanguage } from "../../common/query-language";
|
||||
@@ -74,9 +72,6 @@ export class DbPanel extends DisposableObject {
|
||||
this.addNewRemoteDatabase.bind(this),
|
||||
"codeQLVariantAnalysisRepositories.addNewList":
|
||||
this.addNewList.bind(this),
|
||||
"codeQLVariantAnalysisRepositories.setupControllerRepository":
|
||||
this.setupControllerRepository.bind(this),
|
||||
|
||||
"codeQLVariantAnalysisRepositories.setSelectedItem":
|
||||
this.setSelectedItem.bind(this),
|
||||
"codeQLVariantAnalysisRepositories.setSelectedItemContextMenu":
|
||||
@@ -427,22 +422,4 @@ export class DbPanel extends DisposableObject {
|
||||
|
||||
await this.app.commands.execute("vscode.open", Uri.parse(githubUrl));
|
||||
}
|
||||
|
||||
private async setupControllerRepository(): Promise<void> {
|
||||
try {
|
||||
// This will also validate that the controller repository is valid
|
||||
await getControllerRepo(this.app.credentials);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof UserCancellationException) {
|
||||
return;
|
||||
}
|
||||
|
||||
void showAndLogErrorMessage(
|
||||
this.app.logger,
|
||||
`An error occurred while setting up the controller repository: ${getErrorMessage(
|
||||
e,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,11 +83,6 @@ export class DbTreeDataProvider
|
||||
}
|
||||
|
||||
private createTree(): DbTreeViewItem[] {
|
||||
// Returning an empty tree here will show the welcome view
|
||||
if (!this.variantAnalysisConfig.controllerRepo) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const dbItemsResult = this.dbManager.getDbItems();
|
||||
|
||||
if (dbItemsResult.isFailure) {
|
||||
|
||||
@@ -717,12 +717,13 @@ async function installOrUpdateThenTryActivate(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const PACK_GLOBS = [
|
||||
const CLEAR_PACK_CACHE_ON_EDIT_GLOBS = [
|
||||
"**/codeql-pack.yml",
|
||||
"**/qlpack.yml",
|
||||
"**/queries.xml",
|
||||
"**/codeql-pack.lock.yml",
|
||||
"**/qlpack.lock.yml",
|
||||
"**/*.dbscheme",
|
||||
".codeqlmanifest.json",
|
||||
"codeql-workspace.yml",
|
||||
];
|
||||
@@ -769,7 +770,7 @@ async function activateWithInstalledDistribution(
|
||||
ctx,
|
||||
);
|
||||
|
||||
for (const glob of PACK_GLOBS) {
|
||||
for (const glob of CLEAR_PACK_CACHE_ON_EDIT_GLOBS) {
|
||||
const fsWatcher = workspace.createFileSystemWatcher(glob);
|
||||
ctx.subscriptions.push(fsWatcher);
|
||||
|
||||
|
||||
@@ -48,11 +48,6 @@ function mapVariantAnalysisDtoToDto(
|
||||
): VariantAnalysisDto {
|
||||
return {
|
||||
id: variantAnalysis.id,
|
||||
controllerRepo: {
|
||||
id: variantAnalysis.controllerRepo.id,
|
||||
fullName: variantAnalysis.controllerRepo.fullName,
|
||||
private: variantAnalysis.controllerRepo.private,
|
||||
},
|
||||
query: {
|
||||
name: variantAnalysis.query.name,
|
||||
filePath: variantAnalysis.query.filePath,
|
||||
|
||||
@@ -48,12 +48,12 @@ function mapVariantAnalysisToDomainModel(
|
||||
): VariantAnalysis {
|
||||
return {
|
||||
id: variantAnalysis.id,
|
||||
controllerRepo: {
|
||||
id: variantAnalysis.controllerRepo.id,
|
||||
fullName: variantAnalysis.controllerRepo.fullName,
|
||||
private: variantAnalysis.controllerRepo.private,
|
||||
},
|
||||
language: mapQueryLanguageToDomainModel(variantAnalysis.query.language),
|
||||
controllerRepo: {
|
||||
id: 0,
|
||||
fullName: "",
|
||||
private: false,
|
||||
},
|
||||
query: {
|
||||
name: variantAnalysis.query.name,
|
||||
filePath: variantAnalysis.query.filePath,
|
||||
|
||||
@@ -15,11 +15,6 @@ export interface QueryHistoryVariantAnalysisDto {
|
||||
|
||||
export interface VariantAnalysisDto {
|
||||
id: number;
|
||||
controllerRepo: {
|
||||
id: number;
|
||||
fullName: string;
|
||||
private: boolean;
|
||||
};
|
||||
query: {
|
||||
name: string;
|
||||
filePath: string;
|
||||
|
||||
@@ -15,28 +15,28 @@ export async function extractRawResults(
|
||||
const bqrsInfo = await cliServer.bqrsInfo(filePath);
|
||||
const resultSets = bqrsInfo["result-sets"];
|
||||
|
||||
if (resultSets.length < 1) {
|
||||
if (resultSets.length === 0) {
|
||||
throw new Error("No result sets found in results file.");
|
||||
}
|
||||
if (resultSets.length > 1) {
|
||||
void logger.log(
|
||||
"Multiple result sets found in results file. Only one will be used.",
|
||||
"Multiple result sets found in results file. Using the first one.",
|
||||
);
|
||||
}
|
||||
|
||||
// Always prefer #select over any other result set. #select is usually the result the user
|
||||
// wants to see since it contains the outer #select.
|
||||
// Prefer `#select` result set; otherwise, use the first available set.
|
||||
const schema =
|
||||
resultSets.find((resultSet) => resultSet.name === SELECT_TABLE_NAME) ??
|
||||
resultSets[0];
|
||||
resultSets.find((r) => r.name === SELECT_TABLE_NAME) ?? resultSets[0];
|
||||
|
||||
const chunk = await cliServer.bqrsDecode(filePath, schema.name, {
|
||||
pageSize: MAX_RAW_RESULTS,
|
||||
});
|
||||
|
||||
const resultSet = bqrsToResultSet(schema, chunk);
|
||||
|
||||
const capped = !!chunk.next;
|
||||
|
||||
return { resultSet, fileLinkPrefix, sourceLocationPrefix, capped };
|
||||
return {
|
||||
resultSet,
|
||||
fileLinkPrefix,
|
||||
sourceLocationPrefix,
|
||||
capped: !!chunk.next,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ async function exportVariantAnalysisAnalysisResults(
|
||||
expectedAnalysesResultsCount: number,
|
||||
exportFormat: "gist" | "local",
|
||||
commandManager: AppCommandManager,
|
||||
credentials: Credentials,
|
||||
_credentials: Credentials,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
) {
|
||||
@@ -191,7 +191,6 @@ async function exportVariantAnalysisAnalysisResults(
|
||||
markdownFiles,
|
||||
exportFormat,
|
||||
commandManager,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
@@ -236,7 +235,6 @@ async function exportResults(
|
||||
markdownFiles: MarkdownFile[],
|
||||
exportFormat: "gist" | "local",
|
||||
commandManager: AppCommandManager,
|
||||
credentials: Credentials,
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
@@ -249,7 +247,6 @@ async function exportResults(
|
||||
description,
|
||||
markdownFiles,
|
||||
commandManager,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
@@ -268,7 +265,6 @@ async function exportToGist(
|
||||
description: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
commandManager: AppCommandManager,
|
||||
credentials: Credentials,
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
@@ -291,7 +287,7 @@ async function exportToGist(
|
||||
{} as { [key: string]: { content: string } },
|
||||
);
|
||||
|
||||
const gistUrl = await createGist(credentials, description, gistFiles);
|
||||
const gistUrl = await createGist(description, gistFiles);
|
||||
if (gistUrl) {
|
||||
// This needs to use .then to ensure we aren't keeping the progress notification open. We shouldn't await the
|
||||
// "Open gist" button click.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { OctokitResponse } from "@octokit/types/dist-types";
|
||||
import type { Credentials } from "../../common/authentication";
|
||||
import { getGitHubInstanceUrl } from "../../config";
|
||||
import type { VariantAnalysisSubmission } from "../shared/variant-analysis";
|
||||
import type {
|
||||
VariantAnalysis,
|
||||
@@ -7,84 +6,142 @@ import type {
|
||||
VariantAnalysisSubmissionRequest,
|
||||
} from "./variant-analysis";
|
||||
import type { Repository } from "./repository";
|
||||
import { extLogger } from "../../common/logging/vscode";
|
||||
|
||||
export async function submitVariantAnalysis(
|
||||
credentials: Credentials,
|
||||
submissionDetails: VariantAnalysisSubmission,
|
||||
): Promise<VariantAnalysis> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
|
||||
const { actionRepoRef, language, pack, databases, controllerRepoId } =
|
||||
submissionDetails;
|
||||
|
||||
const data: VariantAnalysisSubmissionRequest = {
|
||||
action_repo_ref: actionRepoRef,
|
||||
language,
|
||||
query_pack: pack,
|
||||
repositories: databases.repositories,
|
||||
repository_lists: databases.repositoryLists,
|
||||
repository_owners: databases.repositoryOwners,
|
||||
};
|
||||
|
||||
const response: OctokitResponse<VariantAnalysis> = await octokit.request(
|
||||
"POST /repositories/:controllerRepoId/code-scanning/codeql/variant-analyses",
|
||||
{
|
||||
controllerRepoId,
|
||||
data,
|
||||
},
|
||||
);
|
||||
|
||||
return response.data;
|
||||
function getOctokitBaseUrl(): string {
|
||||
let apiUrl = getGitHubInstanceUrl().toString();
|
||||
if (apiUrl.endsWith("/")) {
|
||||
apiUrl = apiUrl.slice(0, -1);
|
||||
}
|
||||
if (apiUrl.startsWith("https://")) {
|
||||
apiUrl = apiUrl.replace("https://", "http://");
|
||||
}
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
export async function submitVariantAnalysis(
|
||||
submissionDetails: VariantAnalysisSubmission,
|
||||
): Promise<VariantAnalysis> {
|
||||
try {
|
||||
console.log("Getting base URL...");
|
||||
const baseUrl = getOctokitBaseUrl();
|
||||
void extLogger.log(`Base URL: ${baseUrl}`);
|
||||
|
||||
const { actionRepoRef, language, pack, databases, controllerRepoId } =
|
||||
submissionDetails;
|
||||
|
||||
const data: VariantAnalysisSubmissionRequest = {
|
||||
action_repo_ref: actionRepoRef,
|
||||
language,
|
||||
query_pack: pack,
|
||||
repositories: databases.repositories,
|
||||
repository_lists: databases.repositoryLists,
|
||||
repository_owners: databases.repositoryOwners,
|
||||
};
|
||||
|
||||
void extLogger.log(
|
||||
`Sending fetch request with data: ${JSON.stringify(data)}`,
|
||||
);
|
||||
|
||||
void extLogger.log(
|
||||
`Fetch request URL: ${baseUrl}/repositories/${controllerRepoId}/code-scanning/codeql/variant-analyses`,
|
||||
);
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}/repositories/${controllerRepoId}/code-scanning/codeql/variant-analyses`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
},
|
||||
);
|
||||
|
||||
void extLogger.log(`Response status: ${response.status}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Error submitting variant analysis: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
const responseData = await response.json();
|
||||
void extLogger.log(`Response data: ${responseData}`);
|
||||
|
||||
return responseData;
|
||||
} catch (error) {
|
||||
void extLogger.log(`Error: ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
export async function getVariantAnalysis(
|
||||
credentials: Credentials,
|
||||
controllerRepoId: number,
|
||||
variantAnalysisId: number,
|
||||
): Promise<VariantAnalysis> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
const baseUrl = getOctokitBaseUrl();
|
||||
|
||||
const response: OctokitResponse<VariantAnalysis> = await octokit.request(
|
||||
"GET /repositories/:controllerRepoId/code-scanning/codeql/variant-analyses/:variantAnalysisId",
|
||||
const response = await fetch(
|
||||
`${baseUrl}/repositories/${controllerRepoId}/code-scanning/codeql/variant-analyses/${variantAnalysisId}`,
|
||||
{
|
||||
controllerRepoId,
|
||||
variantAnalysisId,
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return response.data;
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error getting variant analysis: ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export async function getVariantAnalysisRepo(
|
||||
credentials: Credentials,
|
||||
controllerRepoId: number,
|
||||
variantAnalysisId: number,
|
||||
repoId: number,
|
||||
): Promise<VariantAnalysisRepoTask> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
const baseUrl = getOctokitBaseUrl();
|
||||
|
||||
const response: OctokitResponse<VariantAnalysisRepoTask> =
|
||||
await octokit.request(
|
||||
"GET /repositories/:controllerRepoId/code-scanning/codeql/variant-analyses/:variantAnalysisId/repositories/:repoId",
|
||||
{
|
||||
controllerRepoId,
|
||||
variantAnalysisId,
|
||||
repoId,
|
||||
const response = await fetch(
|
||||
`${baseUrl}/repositories/${controllerRepoId}/code-scanning/codeql/variant-analyses/${variantAnalysisId}/repositories/${repoId}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
return response.data;
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Error getting variant analysis repo: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export async function getRepositoryFromNwo(
|
||||
credentials: Credentials,
|
||||
owner: string,
|
||||
repo: string,
|
||||
): Promise<Repository> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
const baseUrl = getOctokitBaseUrl();
|
||||
|
||||
const response = await octokit.rest.repos.get({ owner, repo });
|
||||
return response.data as Repository;
|
||||
const response = await fetch(`${baseUrl}/repos/${owner}/${repo}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error getting repository: ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,22 +149,29 @@ export async function getRepositoryFromNwo(
|
||||
* Returns the URL of the created gist.
|
||||
*/
|
||||
export async function createGist(
|
||||
credentials: Credentials,
|
||||
description: string,
|
||||
files: { [key: string]: { content: string } },
|
||||
): Promise<string | undefined> {
|
||||
const octokit = await credentials.getOctokit();
|
||||
const response = await octokit.request("POST /gists", {
|
||||
description,
|
||||
files,
|
||||
public: false,
|
||||
const baseUrl = getOctokitBaseUrl();
|
||||
|
||||
const response = await fetch(`${baseUrl}/gists`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
description,
|
||||
files,
|
||||
public: false,
|
||||
}),
|
||||
});
|
||||
if (response.status >= 300) {
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Error exporting variant analysis results: ${response.status} ${
|
||||
response?.data || ""
|
||||
}`,
|
||||
`Error creating gist: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
return response.data.html_url;
|
||||
|
||||
const data = await response.json();
|
||||
return data.html_url;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { CancellationToken } from "vscode";
|
||||
import { Uri, window } from "vscode";
|
||||
import { Uri } from "vscode";
|
||||
import { join, sep, basename, relative } from "path";
|
||||
import { dump, load } from "js-yaml";
|
||||
import { copy, writeFile, readFile, mkdirp } from "fs-extra";
|
||||
@@ -7,26 +7,17 @@ import type { DirectoryResult } from "tmp-promise";
|
||||
import { dir, tmpName } from "tmp-promise";
|
||||
import { tmpDir } from "../tmp-dir";
|
||||
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
|
||||
import type { Credentials } from "../common/authentication";
|
||||
import type { CodeQLCliServer } from "../codeql-cli/cli";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
import {
|
||||
getActionBranch,
|
||||
getRemoteControllerRepo,
|
||||
setRemoteControllerRepo,
|
||||
} from "../config";
|
||||
import { getActionBranch } from "../config";
|
||||
import type { ProgressCallback } from "../common/vscode/progress";
|
||||
import { UserCancellationException } from "../common/vscode/progress";
|
||||
import type { RequestError } from "@octokit/types/dist-types";
|
||||
import type { QueryMetadata } from "../common/interface-types";
|
||||
import { getErrorMessage, REPO_REGEX } from "../common/helpers-pure";
|
||||
import { getRepositoryFromNwo } from "./gh-api/gh-api-client";
|
||||
import type { RepositorySelection } from "./repository-selection";
|
||||
import {
|
||||
getRepositorySelection,
|
||||
isValidSelection,
|
||||
} from "./repository-selection";
|
||||
import type { Repository } from "./shared/repository";
|
||||
import type { DbManager } from "../databases/db-manager";
|
||||
import {
|
||||
getQlPackFilePath,
|
||||
@@ -285,13 +276,11 @@ interface PreparedRemoteQuery {
|
||||
base64Pack: string;
|
||||
modelPacks: ModelPackDetails[];
|
||||
repoSelection: RepositorySelection;
|
||||
controllerRepo: Repository;
|
||||
queryStartTime: number;
|
||||
}
|
||||
|
||||
export async function prepareRemoteQueryRun(
|
||||
cliServer: CodeQLCliServer,
|
||||
credentials: Credentials,
|
||||
qlPackDetails: QlPackDetails,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
@@ -322,8 +311,6 @@ export async function prepareRemoteQueryRun(
|
||||
message: "Determining controller repo",
|
||||
});
|
||||
|
||||
const controllerRepo = await getControllerRepo(credentials);
|
||||
|
||||
progress({
|
||||
maxStep: 4,
|
||||
step: 3,
|
||||
@@ -367,7 +354,6 @@ export async function prepareRemoteQueryRun(
|
||||
base64Pack: generatedPack.base64Pack,
|
||||
modelPacks: generatedPack.modelPacks,
|
||||
repoSelection,
|
||||
controllerRepo,
|
||||
queryStartTime,
|
||||
};
|
||||
}
|
||||
@@ -494,84 +480,6 @@ export function getQueryName(
|
||||
return queryMetadata?.name ?? basename(queryFilePath);
|
||||
}
|
||||
|
||||
export async function getControllerRepo(
|
||||
credentials: Credentials,
|
||||
): Promise<Repository> {
|
||||
// Get the controller repo from the config, if it exists.
|
||||
// If it doesn't exist, prompt the user to enter it, check
|
||||
// whether the repo exists, and save the nwo to the config.
|
||||
|
||||
let shouldSetControllerRepo = false;
|
||||
let controllerRepoNwo: string | undefined;
|
||||
controllerRepoNwo = getRemoteControllerRepo();
|
||||
if (!controllerRepoNwo || !REPO_REGEX.test(controllerRepoNwo)) {
|
||||
void extLogger.log(
|
||||
controllerRepoNwo
|
||||
? "Invalid controller repository name."
|
||||
: "No controller repository defined.",
|
||||
);
|
||||
controllerRepoNwo = await window.showInputBox({
|
||||
title:
|
||||
"Controller repository in which to run GitHub Actions workflows for variant analyses",
|
||||
placeHolder: "<owner>/<repo>",
|
||||
prompt:
|
||||
"Enter the name of a GitHub repository in the format <owner>/<repo>. You can change this in the extension settings.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
if (!controllerRepoNwo) {
|
||||
throw new UserCancellationException("No controller repository entered.");
|
||||
} else if (!REPO_REGEX.test(controllerRepoNwo)) {
|
||||
// Check if user entered invalid input
|
||||
throw new UserCancellationException(
|
||||
"Invalid repository format. Must be a valid GitHub repository in the format <owner>/<repo>.",
|
||||
);
|
||||
}
|
||||
|
||||
shouldSetControllerRepo = true;
|
||||
}
|
||||
|
||||
void extLogger.log(`Using controller repository: ${controllerRepoNwo}`);
|
||||
const controllerRepo = await getControllerRepoFromApi(
|
||||
credentials,
|
||||
controllerRepoNwo,
|
||||
);
|
||||
|
||||
if (shouldSetControllerRepo) {
|
||||
void extLogger.log(
|
||||
`Setting the controller repository as: ${controllerRepoNwo}`,
|
||||
);
|
||||
await setRemoteControllerRepo(controllerRepoNwo);
|
||||
}
|
||||
|
||||
return controllerRepo;
|
||||
}
|
||||
|
||||
async function getControllerRepoFromApi(
|
||||
credentials: Credentials,
|
||||
nwo: string,
|
||||
): Promise<Repository> {
|
||||
const [owner, repo] = nwo.split("/");
|
||||
try {
|
||||
const controllerRepo = await getRepositoryFromNwo(credentials, owner, repo);
|
||||
void extLogger.log(`Controller repository ID: ${controllerRepo.id}`);
|
||||
return {
|
||||
id: controllerRepo.id,
|
||||
fullName: controllerRepo.full_name,
|
||||
private: controllerRepo.private,
|
||||
};
|
||||
} catch (e) {
|
||||
if ((e as RequestError).status === 404) {
|
||||
throw new Error(`Controller repository "${owner}/${repo}" not found`);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Error getting controller repository "${owner}/${repo}": ${getErrorMessage(
|
||||
e,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeWorkspaceRefs(qlpack: QlPackFile) {
|
||||
if (!qlpack.dependencies) {
|
||||
return;
|
||||
|
||||
@@ -373,16 +373,19 @@ export class VariantAnalysisManager
|
||||
);
|
||||
}
|
||||
|
||||
// log to extLogger
|
||||
void this.app.logger.log(
|
||||
`Running variant analysis with query: ${queryName}, language: ${variantAnalysisLanguage}`,
|
||||
);
|
||||
|
||||
const {
|
||||
actionBranch,
|
||||
base64Pack,
|
||||
modelPacks,
|
||||
repoSelection,
|
||||
controllerRepo,
|
||||
queryStartTime,
|
||||
} = await prepareRemoteQueryRun(
|
||||
this.cliServer,
|
||||
this.app.credentials,
|
||||
qlPackDetails,
|
||||
progress,
|
||||
token,
|
||||
@@ -399,12 +402,15 @@ export class VariantAnalysisManager
|
||||
count: qlPackDetails.queryFiles.length,
|
||||
};
|
||||
|
||||
// log that submitting
|
||||
void this.app.logger.log("Submitting variant analysis");
|
||||
|
||||
const variantAnalysisSubmission: VariantAnalysisSubmission = {
|
||||
startTime: queryStartTime,
|
||||
actionRepoRef: actionBranch,
|
||||
controllerRepoId: controllerRepo.id,
|
||||
language: variantAnalysisLanguage,
|
||||
pack: base64Pack,
|
||||
controllerRepoId: 0,
|
||||
query: {
|
||||
name: queryName,
|
||||
filePath: firstQueryFile,
|
||||
@@ -422,7 +428,6 @@ export class VariantAnalysisManager
|
||||
let variantAnalysisResponse: ApiVariantAnalysis;
|
||||
try {
|
||||
variantAnalysisResponse = await submitVariantAnalysis(
|
||||
this.app.credentials,
|
||||
variantAnalysisSubmission,
|
||||
);
|
||||
} catch (e: unknown) {
|
||||
@@ -431,9 +436,17 @@ export class VariantAnalysisManager
|
||||
e instanceof RequestError &&
|
||||
handleRequestError(e, this.config.githubUrl, this.app.logger)
|
||||
) {
|
||||
// log
|
||||
void this.app.logger.log(
|
||||
`Error submitting variant analysis: ${getErrorMessage(e)}`,
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// throwing
|
||||
void this.app.logger.log(
|
||||
`Error submitting variant analysis: ${getErrorMessage(e)}`,
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -806,8 +819,7 @@ export class VariantAnalysisManager
|
||||
let repoTask: VariantAnalysisRepositoryTask;
|
||||
try {
|
||||
const repoTaskResponse = await getVariantAnalysisRepo(
|
||||
this.app.credentials,
|
||||
variantAnalysis.controllerRepo.id,
|
||||
0,
|
||||
variantAnalysis.id,
|
||||
scannedRepo.repository.id,
|
||||
);
|
||||
|
||||
@@ -62,7 +62,6 @@ export class VariantAnalysisMonitor extends DisposableObject {
|
||||
try {
|
||||
await this._monitorVariantAnalysis(
|
||||
variantAnalysis.id,
|
||||
variantAnalysis.controllerRepo.id,
|
||||
variantAnalysis.executionStartTime,
|
||||
variantAnalysis.query.name,
|
||||
variantAnalysis.language,
|
||||
@@ -74,7 +73,6 @@ export class VariantAnalysisMonitor extends DisposableObject {
|
||||
|
||||
private async _monitorVariantAnalysis(
|
||||
variantAnalysisId: number,
|
||||
controllerRepoId: number,
|
||||
executionStartTime: number,
|
||||
queryName: string,
|
||||
language: QueryLanguage,
|
||||
@@ -97,11 +95,7 @@ export class VariantAnalysisMonitor extends DisposableObject {
|
||||
|
||||
let variantAnalysisSummary: ApiVariantAnalysis;
|
||||
try {
|
||||
variantAnalysisSummary = await getVariantAnalysis(
|
||||
this.app.credentials,
|
||||
controllerRepoId,
|
||||
variantAnalysisId,
|
||||
);
|
||||
variantAnalysisSummary = await getVariantAnalysis(0, variantAnalysisId);
|
||||
} catch (e) {
|
||||
const errorMessage = getErrorMessage(e);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[
|
||||
"v2.17.3",
|
||||
"v2.17.5",
|
||||
"v2.16.6",
|
||||
"v2.15.5",
|
||||
"v2.14.6",
|
||||
|
||||
@@ -20,7 +20,7 @@ export default defineConfig({
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://localhost:8080",
|
||||
baseURL: "http://server:8080",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
|
||||
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "vscode-codeql",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
26
vscode-codeql.code-workspace
Normal file
26
vscode-codeql.code-workspace
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"typescript.tsdk": "./extensions/ql-vscode/node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"terminal.integrated.env.linux": {
|
||||
"LANG": "en-US",
|
||||
"TZ": "UTC"
|
||||
},
|
||||
"terminal.integrated.env.osx": {
|
||||
"LANG": "en-US",
|
||||
"TZ": "UTC"
|
||||
},
|
||||
"terminal.integrated.env.windows": {
|
||||
"LANG": "en-US",
|
||||
"TZ": "UTC"
|
||||
},
|
||||
"github.copilot.advanced": {},
|
||||
"github-enterprise.uri": "http://server:8080"
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user