Skip to content

Improve CI speed #474

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

Merged
merged 2 commits into from
Apr 17, 2025
Merged

Improve CI speed #474

merged 2 commits into from
Apr 17, 2025

Conversation

OskarDamkjaer
Copy link
Collaborator

@OskarDamkjaer OskarDamkjaer commented Apr 16, 2025

Based on #461

  • Splits e2e jobs to run in parallel
  • Adds cache on commit to avoid rebuilding
  • Cancel old jobs on the same pull request
  • Fixes parameter can't be set on system flaky test by improving the UX. We not instantly give the error (same as when disconnected), instead of letting the user fill in all the values and then giving an error ✨

On flakyness:

  • Ideally each test should be as isolated as possible. This is so they can run / re-run in parallel, etc. This means they need to ensure their own connection etc in a beforeEach. I'm not sure if this applies to the vscode tests though as it's not got multiple browser windows like playwright tests do 🤔

Copy link

changeset-bot bot commented Apr 16, 2025

⚠️ No Changeset found

Latest commit: de0cad3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@OskarDamkjaer OskarDamkjaer requested a review from ncordon April 16, 2025 12:26
@OskarDamkjaer OskarDamkjaer marked this pull request as ready for review April 16, 2025 12:26
Comment on lines +20 to +22
# todo verify caching works well here too
- name: Setup and build project
uses: ./.github/actions/setup-and-build
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how to best check for this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just make a card and check the next time we do a VSCode release?

use: { ...devices['Desktop Firefox'] },
},
],
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it makes sense to create a test suite dedicated for webkit + safari at a later stage and avoid the flakyness from firefox now. also happy to add firefox back if you prefer

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have firefox here because at some point we broke something in the semantic analysis that was firefox specific. To avoid regressions I think it'd be nice to still keep it in the CI?

Copy link
Collaborator Author

@OskarDamkjaer OskarDamkjaer Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't fix the semantic analysis in firefox, it's still not working. I'll add it back and we can add skips if any test is very flaky in firefox only 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't fix the semantic analysis in firefox, it's still not working.

Not completely you are right. But it does work in my Firefox, when it wasn't before. We definitely fixed something that wasn't working at some point that had to do with us setting the schema eagerly.

@@ -28,7 +28,7 @@
"test": "vitest run",
"test:e2e": "playwright test -c playwright-ct.config.ts",
"test:e2e-ui": "playwright test -c playwright-ct.config.ts --ui",
"benchmark": "BENCHMARKING=true npx playwright test -c playwright-ct.config.ts -g \"benchmarking & performance test session\""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need pnpx here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pnpx will always download the latest from the internet and not use the locally installed version

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For calling dependencies, we don't need a prefix (see how we call eslint, esbuild, playwright in the above command etc)

Comment on lines -429 to -430
"test:apiAndUnit": "pnpm build:dev && rm -rf .vscode-test/user-data && node ./dist/tests/runApiAndUnitTests.js",
"test:webviews": "pnpm build:dev && wdio run ./dist/tests/runWebviewTests.js"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this use a cached build? The reason why this builds the extension is to avoid to have to do that manually when developing locally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache isn't as aggressive as turborepo, so this will rebuild. It's also rebuilding a dev build instead of a production build so we're not testing the same behavior that we'd send out to production.

For convenience locally it'd make more sense to have a new command, maybe test:webviews:watch or test:webviews:dev which rebuilds a development build and then runs the tests in some easy to debug mode

Comment on lines +60 to +61
'Parameters cannot be added when on the system database. Please connect to a user database.',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a message in the evaluateParameter which is slightly different:

'Parameters cannot be evaluated against a system database. Please connect to a user database.',

Probably it'd make sense to extract that to the constants.ts and have the same message everywhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I made them slightly different was because the evaluating is at a later stage, differentiating between trying to add something and trying to validate the type of something while adding. Not sure if anyone really cares about the difference, so we could make both say "cannot be added"

Comment on lines +117 to +119
void window.showErrorMessage(
'Parameters cannot be edited when on the system database. Please connect to a user database.',
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also extract this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense 👍

Comment on lines +72 to 75
void browser.executeWorkbench((vscode) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
await vscode.commands.executeCommand('neo4j.internal.forceDisconnect');
void vscode.commands.executeCommand('neo4j.internal.forceDisconnect');
});
Copy link
Collaborator

@ncordon ncordon Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point I was using the voids as well, but that meant we had a notification that unless closed, the method wasn't finishing?

I think we should just swap all of the:

await window.showErrorMessage

for:

void window.showErrorMessage

instead of having void here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we had a notification that unless closed, the method wasn't finishing?
what does this mean? This method still blocks like before due to the new await waitUntilNotification below

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not implying we should change anything here but that we should replace the await window.showErrorMessage with void window.showErrorMessage everywhere in the codebase? I don't see any reason why that should block the execution in general of some method when things went wrong

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean the test will fail if the show error message goes wrong no? The very next assertion is waiting for it to fire?

Comment on lines +224 to +229
const notifications = await wb.getNotifications();
for (const notification of notifications) {
await notification.dismiss();
}

const remainingNotifications = await wb.getNotifications();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Why do we need to get notifications twice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing overflowing ones didn't close get dismissed, so I needed to call it more than once. I think it makes sense to take some time and look at the docs to see if there's some "clear notifications" thing we could run instead

Comment on lines +10 to +13
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this because it prevents us from kicking jobs for different commits at the same time, but there's one thing about this I don't quite like: if two different jobs fail for the latest commit, you either have to retrigger them all or re-trigger one, wait for that to pass and re-trigger the second one.

I've looked it up and there's no way to tweak the concurrency per individual job, only per workflow. Any thoughts?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there not a "retry all failed steps" in the UI that works for this?

Copy link
Collaborator

@ncordon ncordon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So excited about this!!!! 🚀

@ncordon ncordon mentioned this pull request Apr 17, 2025
@ncordon
Copy link
Collaborator

ncordon commented Apr 17, 2025

I'm going to merge this, given the CI is super flaky, we can address anything extra in other PRs

@ncordon ncordon merged commit 61ec95d into main Apr 17, 2025
6 checks passed
@ncordon ncordon deleted the faster_ci branch April 17, 2025 09:30
@ncordon ncordon requested a review from Copilot April 22, 2025 19:04
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR aims to improve CI speed by introducing parallel execution, caching to prevent redundant rebuilds, and UX improvements in parameter error handling. Key changes include:

  • Splitting e2e jobs to run in parallel with updated workflow configurations.
  • Introducing caching on commit and replacing legacy build steps with a new "setup-and-build" action.
  • Enhancing error messaging for parameter handling, especially on system databases.

Reviewed Changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/vscode-extension/tests/webviewUtils.ts Improved notification handling by throwing errors instead of returning false and added a recursive dismiss function.
packages/vscode-extension/tests/specs/webviews/params.spec.ts Updated test flows by switching to non-awaited executeWorkbench calls and refining notification waits.
packages/vscode-extension/tests/specs/api/autoCompletion.spec.ts Reordered tests to ensure parameter completions work correctly and fixed variable naming inconsistencies.
packages/vscode-extension/src/commandHandlers/params.ts Added checks to prevent parameter modifications when connected to the system database.
packages/vscode-extension/src/commandHandlers/connection.ts Streamlined disconnect flow by replacing message display calls.
packages/react-codemirror/playwright-ct.config.ts Adjusted configurations for timeout and parallel execution improvements.
.github/workflows/*.yaml and .github/actions/setup-and-build/action.yaml Updated CI workflows to use the new setup-and-build process and improve caching and concurrency.
Files not reviewed (2)
  • packages/react-codemirror/package.json: Language not supported
  • packages/vscode-extension/package.json: Language not supported
Comments suppressed due to low confidence (1)

packages/vscode-extension/tests/webviewUtils.ts:230

  • The recursive call in ensureNotificationsAreDismissed may lead to an infinite loop if notifications persist; consider adding a delay or a maximum retry limit to prevent potential stack overflow.
if (remainingNotifications.length > 0) { return ensureNotificationsAreDismissed(browser); }

Comment on lines +72 to +74
void browser.executeWorkbench((vscode) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
await vscode.commands.executeCommand('neo4j.internal.forceDisconnect');
void vscode.commands.executeCommand('neo4j.internal.forceDisconnect');
Copy link
Preview

Copilot AI Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'void' instead of 'await' here may swallow errors from executeWorkbench; consider awaiting the call to handle possible failures.

Copilot uses AI. Check for mistakes.

}

async function forceConnect(i: number) {
await browser.executeWorkbench(async (vscode, i) => {
void browser.executeWorkbench((vscode, i) => {
Copy link
Preview

Copilot AI Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'void' instead of 'await' here may hide errors from the asynchronous operation; ensure proper error handling by awaiting the executeWorkbench call.

Suggested change
void browser.executeWorkbench((vscode, i) => {
await browser.executeWorkbench((vscode, i) => {

Copilot uses AI. Check for mistakes.

);
const textDocument = await newUntitledFileWithContent(`RETURN `);
const position = new vscode.Position(0, 7);
const expecations: vscode.CompletionItem[] = [
Copy link
Preview

Copilot AI Apr 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The variable name 'expecations' appears to be a typo; consider renaming it to 'expectations'.

Suggested change
const expecations: vscode.CompletionItem[] = [
const expectations: vscode.CompletionItem[] = [

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants