-
Notifications
You must be signed in to change notification settings - Fork 253
chore(web): add a script to spawn evergreen patch that runs compass-web with Atlas e2e tests COMPASS-10227 #7861
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
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
f6a46f8
chore(web): add a script to spawn evergreen patch that runs compass-w…
gribnoysup 69e92b4
chore(web): use completely random tmp folder; tighten file modes
gribnoysup 13a60b8
chore(web): check > test-web-sandbox-atlas-cloud
gribnoysup fdaec03
chore(web): add test step to the publish task
gribnoysup 8d380f2
Merge remote-tracking branch 'origin/main' into COMPASS-10227-add-eve…
gribnoysup eeb5912
fix(web): map arch name when downloading
gribnoysup 960f45d
fix(ci): do a full checkout
gribnoysup 5ee2300
fix(ci): try with actionsbot user
gribnoysup 09c9c26
fix(web): always use HOME override as a way to set up evergreen confi…
gribnoysup 2fe02f5
chore(web): remove brackets from debug log to fix the link
gribnoysup ddbf8e4
fix(web): explicitly provide commit ref for spawned tests to make sur…
gribnoysup aa9f171
chore(web): allow to skip e2e test during deploy
gribnoysup edc5e44
fix(ci): fix typo in input description key
gribnoysup File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
213 changes: 213 additions & 0 deletions
213
packages/compass-web/scripts/spawn-e2e-with-atlas-cloud.mts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,213 @@ | ||
| import fs from 'fs'; | ||
| import { spawnSync } from 'child_process'; | ||
| import type { SpawnSyncOptions } from 'child_process'; | ||
| import path from 'path'; | ||
| import os from 'os'; | ||
| import { Readable, promises } from 'stream'; | ||
| import type { ReadableStream as ReadableStreamWeb } from 'stream/web'; | ||
|
|
||
| const { | ||
| EVG_USER, | ||
| EVG_API_KEY, | ||
| EVG_API_SERVER = 'https://evergreen.mongodb.com/api', | ||
| EVG_UI_SERVER = 'https://evergreen.mongodb.com', | ||
| } = process.env; | ||
|
|
||
| const RELEASE_COMMIT = | ||
| process.env.COMPASS_WEB_RELEASE_COMMIT || | ||
| spawnSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).stdout.trim(); | ||
|
|
||
| if (!EVG_USER || !EVG_API_KEY) { | ||
| throw new Error('Evergreen credentials missing'); | ||
| } | ||
|
|
||
| function mapArchNameToEvgAssetName(arch = os.arch()) { | ||
| switch (arch) { | ||
| case 'x64': | ||
| return 'amd64'; | ||
| default: | ||
| return arch; | ||
| } | ||
| } | ||
|
|
||
| const OS = os.type().toLowerCase(); | ||
| const ARCH = mapArchNameToEvgAssetName(os.arch()); | ||
| const CLI_DIR = path.join(os.tmpdir(), crypto.randomUUID()); | ||
| const EVERGREEN_CONFIG = path.join(CLI_DIR, '.evergreen.yml'); | ||
|
|
||
| await fs.promises.mkdir(CLI_DIR, { recursive: true, mode: 0o700 }); | ||
|
|
||
| function cleanup() { | ||
| console.debug('cleaning up...'); | ||
| fs.rmSync(CLI_DIR, { recursive: true, force: true }); | ||
| } | ||
|
|
||
| process.on('beforeExit', cleanup); | ||
| process.on('uncaughtExceptionMonitor', cleanup); | ||
|
|
||
| await fs.promises.writeFile( | ||
| EVERGREEN_CONFIG, | ||
| ` | ||
| user: ${EVG_USER} | ||
| api_key: ${EVG_API_KEY} | ||
| api_server_host: ${EVG_API_SERVER} | ||
| ui_server_host: ${EVG_UI_SERVER} | ||
| do_not_run_kanopy_oidc: true | ||
| `.trimStart() | ||
| ); | ||
|
|
||
| const EVERGREEN_CLI_BIN = path.join(CLI_DIR, 'evergreen'); | ||
|
|
||
| function spawnEvergreenSync( | ||
| args: string[], | ||
| extraOptions?: Omit<SpawnSyncOptions, 'encoding'> | ||
| ) { | ||
| const res = spawnSync( | ||
| EVERGREEN_CLI_BIN, | ||
| [ | ||
| '--level', | ||
| 'error', // Only allow important logs to reduce the output noise | ||
| ...args, | ||
| ], | ||
| { | ||
| encoding: 'utf-8', | ||
| ...extraOptions, | ||
| env: { | ||
| ...process.env, | ||
| // in theory there is a `--config` flag, but it doesn't seem to work | ||
| // specifically with the `user` commands, so we override the HOME to | ||
| // make sure that our config is picked up from the "default" dir | ||
| // correctly for all cases | ||
| HOME: CLI_DIR, | ||
| ...extraOptions?.env, | ||
| }, | ||
| } | ||
| ); | ||
| if (res.error) { | ||
| throw res.error; | ||
| } | ||
| if (res.status !== 0) { | ||
| throw Object.assign( | ||
| new Error('Evergreen CLI exited with a non-zero status code'), | ||
| { | ||
| args, | ||
| code: res.status, | ||
| signal: res.signal, | ||
| stdout: res.stdout, | ||
| stderr: res.stderr, | ||
| } | ||
| ); | ||
| } | ||
| return res; | ||
| } | ||
|
|
||
| console.debug( | ||
| 'downloading evergreen cli for %s %s to %s...', | ||
| OS, | ||
| ARCH, | ||
| CLI_DIR | ||
| ); | ||
|
|
||
| await fetch(`https://evergreen.mongodb.com/clients/${OS}_${ARCH}/evergreen`, { | ||
| headers: { | ||
| 'Api-User': EVG_USER, | ||
| 'Api-Key': EVG_API_KEY, | ||
| }, | ||
| }).then((res) => { | ||
| if (!res.ok || !res.body) { | ||
| throw new Error( | ||
| `Failed to download evergreen cli: ${res.status} (${res.statusText})` | ||
| ); | ||
| } | ||
| return promises.pipeline( | ||
| Readable.fromWeb( | ||
| // node `streamWeb.ReadableStream` and dom `ReadableStream` are currently | ||
| // not fully compatible, but actually work together okay for our case. | ||
| // When this issue goes away, typescript will highlight this as a | ||
| // unnecessary assertion | ||
| res.body as ReadableStreamWeb<Uint8Array<ArrayBuffer>> | ||
| ), | ||
| fs.createWriteStream(EVERGREEN_CLI_BIN) | ||
| ); | ||
| }); | ||
|
|
||
| await fs.promises.chmod(EVERGREEN_CLI_BIN, 0o700); | ||
|
|
||
| console.debug(spawnEvergreenSync(['--version']).stdout.trimEnd()); | ||
|
|
||
| console.debug( | ||
| 'current user: %s', | ||
| spawnEvergreenSync(['client', 'user']).stdout.trimEnd() | ||
| ); | ||
|
|
||
| const ATLAS_CLOUD_ENV = | ||
| process.env.COMPASS_E2E_ATLAS_CLOUD_ENVIRONMENT ?? 'dev'; | ||
|
|
||
| const patchInfoStr = spawnEvergreenSync([ | ||
| 'patch', | ||
| '--project', | ||
| '10gen-compass-main', | ||
| '--variants', | ||
| 'test-web-sandbox-atlas-cloud', | ||
| '--tasks', | ||
| 'test-web-sandbox-atlas-cloud', | ||
| '--description', | ||
| process.env.COMPASS_WEB_E2E_TEST_EVERGREEN_PATCH_DESCRIPTION ?? | ||
| `Test compass-web with Atlas Cloud against ${ATLAS_CLOUD_ENV} environment`, | ||
| '--param', | ||
| `compass_web_publish_environment=${ATLAS_CLOUD_ENV}`, | ||
| '--ref', | ||
| RELEASE_COMMIT, | ||
| '--json', | ||
| '--finalize', | ||
| ]).stdout; | ||
|
|
||
| const patchInfo = JSON.parse(patchInfoStr); | ||
|
|
||
| console.debug( | ||
| 'created evergreen patch https://evergreen.mongodb.com/version/%s', | ||
| patchInfo.patch_id | ||
| ); | ||
|
|
||
| const startTime = Date.now(); | ||
| // 2 hours: this is more than our global evergreen config timeout, evergreen | ||
| // will fail first and this will abort the loop, but just in case something goes | ||
| // really wrong we will also have the timeout here making sure this is not | ||
| // running forever | ||
| const timeoutMs = 1000 * 60 * 60 * 60 * 2; | ||
|
|
||
| const intervalId = setInterval(() => { | ||
| const currentPatchInfoStr = spawnEvergreenSync([ | ||
| 'list-patches', | ||
| '--id', | ||
| patchInfo.patch_id, | ||
| '--json', | ||
| ]).stdout; | ||
| const currentPatchInfo = JSON.parse(currentPatchInfoStr); | ||
|
|
||
| if (currentPatchInfo.status === 'success') { | ||
| console.debug('finished running the patch successfully'); | ||
| clearInterval(intervalId); | ||
| return; | ||
| } | ||
|
|
||
| if (currentPatchInfo.status === 'failed') { | ||
| throw Object.assign( | ||
| new Error( | ||
| `Patch https://evergreen.mongodb.com/version/${currentPatchInfo.patch_id} failed` | ||
| ), | ||
| { patch: currentPatchInfo } | ||
| ); | ||
| } | ||
|
|
||
| if (Date.now() - startTime >= timeoutMs) { | ||
| throw Object.assign( | ||
| new Error( | ||
| `Patch https://evergreen.mongodb.com/version/${currentPatchInfo.patch_id} failed due to the timeout` | ||
| ), | ||
| { patch: currentPatchInfo } | ||
| ); | ||
| } | ||
|
|
||
| console.debug('current patch status: %s', currentPatchInfo.status); | ||
| }, 60_000); // no need to check too often | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.