Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: added sonar action and separated e2e action from the rest #14

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions .github/workflows/lint.yml

This file was deleted.

92 changes: 87 additions & 5 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,67 @@ jobs:
- name: Check Docker Version
run: docker --version

- name: Check Node.js version
run: node -v

- name: Check npm versions
run: npm -v

- name: Cache node_modules
uses: actions/cache@v4
with:
path: |
node_modules
webview-ui/build
webview-ui/node-modules
key: node_modules-${{ matrix.os }}-node-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
node_modules-${{ matrix.os }}-node-${{ matrix.node-version }}

- name: Run clean install
run: npm ci

- run: xvfb-run -a npm test

- name: Run tests on Linux
run: xvfb-run -a npm test
if: runner.os == 'Linux'
- run: npm test
- name: Run tests on macOS and Windows
run: npm test
if: runner.os != 'Linux'

e2e-tests:
needs: build
strategy:
matrix:
# No windows runner, because in this extension, we have a lot of tests that need docker in the WSL.
# Sadly, the setup-wsl (https://github.com/Vampire/setup-wsl) and the current windows runners only support WSL 1.
# Therefore, we can not install and start a docker container in the WSL.

# Currently, no macOS runner, because during the setup of docker, this runner hangs: https://github.com/douglascamata/setup-docker-macos-action/issues/37
node-version: [18.x, 20.x, 22.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Set up JDK for Liquibase CLI
uses: actions/setup-java@v4
with:
java-version: 21
distribution: temurin

- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: |
node_modules
webview-ui/build
webview-ui/node-modules
key: node_modules-${{ matrix.os }}-node-${{ matrix.node-version }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
node_modules-${{ matrix.os }}-node-${{ matrix.node-version }}

- name: run e2e tests
run: xvfb-run -a npm run test:e2e -- --storage ./out/test-resources/${{ matrix.os }}/${{ matrix.node-version }}
if: runner.os == 'Linux'
Expand All @@ -61,3 +108,38 @@ jobs:
path: ./out/test-resources/**/screenshots/**
retention-days: 5
if-no-files-found: ignore

sonar:
name: Run eslint and sonar scanning
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x

- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: |
node_modules
webview-ui/build
webview-ui/node-modules
key: node_modules-ubuntu-latest-node-22.x-${{ hashFiles('package-lock.json') }}
restore-keys: |
node_modules-ubuntu-latest-node-22.x
- name: Run ESLint
run: npm run lint -- --format json --output-file eslint-results.json || true

- name: Analyze with SonarCloud
uses: SonarSource/sonarcloud-github-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: -Dsonar.projectKey=aditosoftware_vscode-liquibase
-Dsonar.organization=aditosoftware
-Dsonar.eslint.reportPaths=eslint-results.json
2 changes: 1 addition & 1 deletion .vscode-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default defineConfig({
launchArgs: ["--disable-extensions", "--profile-temp"],
mocha: {
ui: "tdd",
retries: 3,
retries: 5,
},
coverage: {
// coverage exclusion currently does not work: https://github.com/microsoft/vscode-test-cli/issues/40
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=aditosoftware_vscode-liquibase&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=aditosoftware_vscode-liquibase)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=aditosoftware_vscode-liquibase&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=aditosoftware_vscode-liquibase)
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=aditosoftware_vscode-liquibase&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=aditosoftware_vscode-liquibase)

# Liquibase

A Visual Studio Code extension that supports executing [Liquibase commands](https://docs.liquibase.com/commands/command-list.html) without needing to use the command line.
Expand Down
4 changes: 2 additions & 2 deletions src/cache/CacheHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ export class CacheHandler {
readContexts(connectionLocation: string, changelogLocation: string): ContextSelection {
const existingChangelog = this.getChangelog(connectionLocation, changelogLocation).existingChangelog;

if (existingChangelog && existingChangelog.contexts) {
if (existingChangelog?.contexts) {
// sort any loaded contexts
existingChangelog.contexts.loadedContexts?.sort((a, b) => a.localeCompare(b));

Expand All @@ -287,7 +287,7 @@ export class CacheHandler {
readChangelogs(connectionLocation: string): string[] {
const cache = this.readCache();

if (cache[connectionLocation] && cache[connectionLocation].changelogs) {
if (cache[connectionLocation]?.changelogs) {
return cache[connectionLocation].changelogs
.toSorted((a, b) => b.lastUsed - a.lastUsed)
.map((pChangelog) => pChangelog.path);
Expand Down
8 changes: 4 additions & 4 deletions src/cache/CacheRemover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class CacheRemover {

const toRemove = result.inputValues.get(CacheRemover.removeOption);

if (toRemove && toRemove[0]) {
if (toRemove?.[0]) {
this.handleRemoval(toRemove[0], result);
}
}
Expand Down Expand Up @@ -170,9 +170,9 @@ export class CacheRemover {

// Build the details
let detail = "";
if (toRemove && toRemove[0]) {
if (toRemove?.[0]) {
// add information about the remove option
detail = CacheRemover.removeOptions.get(toRemove[0]) || "";
detail = CacheRemover.removeOptions.get(toRemove[0]) ?? "";
}

if (propertyFiles) {
Expand All @@ -193,7 +193,7 @@ export class CacheRemover {
private shouldShowPropertyFileSelection(currentResults: DialogValues): boolean {
const toRemove = currentResults.inputValues.get(CacheRemover.removeOption);

if (toRemove && toRemove[0]) {
if (toRemove?.[0]) {
return toRemove[0] !== RemoveCacheOptions.WHOLE_CACHE;
} else {
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/configuration/data/DatabaseConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class DatabaseConnection {
if (driver) {
// and extract the url parts
return driver.extractUrlParts(this.url);
} else if (customDriver && customDriver[this.databaseType]) {
} else if (customDriver?.[this.databaseType]) {
return new CustomDriver(customDriver[this.databaseType]).extractUrlParts(this.url);
}

Expand All @@ -100,7 +100,7 @@ export class DatabaseConnection {
* @param pValue - the value that should be set
* @returns the updated element
*/
setValue(pName: keyof DatabaseConnection, pValue: string): DatabaseConnection {
setValue(pName: keyof DatabaseConnection, pValue: string): this {
if (typeof this[pName] === "string") {
(this[pName] as string) = pValue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/configuration/data/LiquibaseConfigurationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class LiquibaseConfigurationData {
}

// and write the reference properties
if (this.referenceDatabaseConnection && this.referenceDatabaseConnection.hasData()) {
if (this.referenceDatabaseConnection?.hasData()) {
this.referenceDatabaseConnection.writeDataForConnection(properties, true, pDisguisePassword);
}

Expand Down
2 changes: 1 addition & 1 deletion src/configuration/handleChangelogSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function chooseFileForChangelog(data: LiquibaseConfigurationData):
},
});

if (result && result[0]) {
if (result?.[0]) {
const chosenFile = result[0].fsPath;

// find out relative path
Expand Down
6 changes: 3 additions & 3 deletions src/executeJar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export function executeJarAsync<ErrorCode extends number>(
}
});

childProcess.on("error", (error) => {
childProcess.on("error", (error: Error) => {
Logger.getLogger().error({ message: "Child process encountered an error", error });
reject(error);
});
Expand Down Expand Up @@ -233,11 +233,11 @@ export async function loadContextsFromChangelogFile(
error: { stack: result.stderr },
notifyUser: true,
});
reject(`Error ${result.status}, ${result.error?.message}\n ${result.stderr}`);
reject(new Error(`Error ${result.status}, ${result.error?.message}\n ${result.stderr}`));
}
} catch (error) {
Logger.getLogger().error({ message: "Error loading contexts", error, notifyUser: true });
reject(error);
reject(error as Error);
}
});
}
Expand Down
22 changes: 2 additions & 20 deletions src/handleChangelogFileInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class HandleChangelogFileInput {
*/
private static getChangelogFileFromProperties(dialogValues: DialogValues): string | undefined {
const propertyFile = dialogValues.inputValues.get(PROPERTY_FILE);
if (propertyFile && propertyFile[0]) {
if (propertyFile?.[0]) {
const changelog = readChangelog(propertyFile[0]);
if (changelog) {
// if there is a changelog in in property-file, return it, so we can show it in the dialog
Expand All @@ -114,24 +114,6 @@ export class HandleChangelogFileInput {
}
}

/**
* Checks if the changelog needs to be put into by an extra open dialog.
*
* @param dialogValues - the current dialog values
* @returns `true` if an OpenDialog is needed for selecting the changelog
*/
private static isChangelogFromOpenDialogNeeded(dialogValues: DialogValues): boolean {
if (this.isExtraQueryForChangelogNeeded(dialogValues)) {
const changelogPreSelection = dialogValues.inputValues.get(this.CHANGELOG_QUICK_PICK_NAME);
if (changelogPreSelection && changelogPreSelection[0]) {
// check, if the correct option was selected
return changelogPreSelection[0] === CHOOSE_CHANGELOG_OPTION;
}
}

return false;
}

/**
* Sets the changelog file from the current dialog correctly as uri (exactly as context menu).
* This will mimic the behavior from a context menu, which is correct in this case.
Expand All @@ -145,7 +127,7 @@ export class HandleChangelogFileInput {

let changelogPath: string | undefined;

if (fileSelection && fileSelection[0]) {
if (fileSelection?.[0]) {
if (fileSelection[0] === CHOOSE_CHANGELOG_OPTION) {
// we are not having a correct values selected, but instead a dialog progression value
// => we do not need to save anything
Expand Down
14 changes: 4 additions & 10 deletions src/handleContexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,7 @@ export function generateContextInputs(): PickPanelConfig[] {
export function generateItemsForContextPreDialog(contextCacheInfo?: ContextCacheInformation): vscode.QuickPickItem[] {
const items: vscode.QuickPickItem[] = [];

if (
contextCacheInfo &&
contextCacheInfo.contexts.loadedContexts &&
contextCacheInfo.contexts.loadedContexts.length !== 0
) {
if (contextCacheInfo?.contexts.loadedContexts && contextCacheInfo?.contexts.loadedContexts.length !== 0) {
const cachedContexts = contextCacheInfo.contexts.loadedContexts.join(", ");
items.push({
label: ContextOptions.USE_RECENTLY_LOADED,
Expand Down Expand Up @@ -132,10 +128,8 @@ export function saveSelectedContexts(dialogValues: DialogValues, contextCacheInf
*/
function generateCmdArgsForPreContextSelection(dialogValues: DialogValues): string[] | undefined {
const selected = dialogValues.inputValues.get(contextPreDialog);
if (selected && selected[0]) {
if (selected[0] === ContextOptions.NO_CONTEXT) {
return [`--contexts=${NO_CONTEXT_USED}`];
}
if (selected?.[0] === ContextOptions.NO_CONTEXT) {
return [`--contexts=${NO_CONTEXT_USED}`];
}
}

Expand Down Expand Up @@ -189,7 +183,7 @@ export function loadCacheForPropertyFile(currentResults: DialogValues): ContextC
function showContextSelection(dialogValues: DialogValues): boolean {
const result = dialogValues.inputValues.get(contextPreDialog);

if (result && result[0]) {
if (result?.[0]) {
return result[0] !== ContextOptions.NO_CONTEXT;
}

Expand Down
2 changes: 1 addition & 1 deletion src/handleLiquibaseSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function getDefaultDatabaseForConfiguration(): string {
NO_PRE_CONFIGURED_DRIVER
);

return defaultDatabaseForConfiguration ? defaultDatabaseForConfiguration : NO_PRE_CONFIGURED_DRIVER;
return defaultDatabaseForConfiguration || NO_PRE_CONFIGURED_DRIVER;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/liquibaseCommandsUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export async function openIndexHtmlAfterCommandExecution(dialogValues: DialogVal
export async function changeAndEmptyOutputDirectory(dialogValues: DialogValues): Promise<void> {
const folder = dialogValues.inputValues.get(folderSelectionName)?.[0];

if (folder && folder.includes(os.tmpdir())) {
if (folder?.includes(os.tmpdir())) {
const propertyFile = dialogValues.inputValues.get(PROPERTY_FILE)?.[0];

let configurationName = "db-doc";
Expand Down
Loading