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

feat: Use yarn v4 #905

Draft
wants to merge 10 commits into
base: master
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
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- name: Enable Corepack
run: corepack enable
- name: Install
run: yarn install
- name: Build
Expand All @@ -43,6 +45,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- name: Enable Corepack
run: corepack enable
- run: yarn install
- name: Run Linter
run: yarn lint
Expand All @@ -61,6 +65,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- name: Enable Corepack
run: corepack enable
- run: yarn install
- name: Run Unit Tests
timeout-minutes: 10
Expand All @@ -82,6 +88,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version-file: 'package.json'
- name: Enable Corepack
run: corepack enable
- run: yarn install
- name: Run E2E Tests
timeout-minutes: 30
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Expand Down
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nodeLinker: node-modules
enableHardenedMode: false
41 changes: 14 additions & 27 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,11 @@
"access": "public"
},
"scripts": {
"prebuild": "yarn clean && node scripts/update-version.js",
"build": "rollup --config rollup.config.mjs",
"postbuild": "node scripts/check-exports.mjs",
"clean": "rimraf --glob coverage common esm main preload renderer index.* sentry-electron*.tgz .eslintcache",
"prelint": "node scripts/update-version.js",
"lint": "run-s lint:prettier lint:eslint",
"lint:prettier": "prettier --check \"{src,test}/**/*.ts\"",
"lint:eslint": "eslint . --cache --format stylish",
"fix": "run-s fix:eslint fix:prettier",
"fix:prettier": "prettier --write \"{src,test}/**/*.ts\"",
"fix:eslint": "eslint . --format stylish --fix",
"update-electron-versions": "electron-latest-versions --start 15 --beta > ./test/e2e/versions.json",
"update-sdk-versions": "node ./scripts/update-sdk-versions.mjs",
"pretest": "yarn build",
"test": "vitest run --root=./test/unit",
"pree2e": "rimraf --glob test/e2e/dist/**/node_modules/@sentry/** test/e2e/dist/**/yarn.lock test/e2e/dist/**/package-lock.json && node scripts/clean-cache.js && yarn build && npm pack",
"e2e": "xvfb-maybe vitest run --root=./test/e2e --silent=false --disable-console-intercept"
"start": "node scripts/start.mjs",
"build": "node scripts/start.mjs build",
"test": "node scripts/start.mjs test",
"lint": "node scripts/start.mjs lint",
"e2e": "node scripts/start.mjs e2e"
},
"dependencies": {
"@sentry/browser": "8.13.0",
Expand Down Expand Up @@ -82,18 +70,17 @@
"koa-bodyparser": "^4.3.0",
"koa-tree-router": "^0.12.1",
"latest-version": "^7.0.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",
"rimraf": "^5.0.5",
"tmp": "^0.2.1",
"rollup": "^4.13.1",
"rimraf": "^5.0.7",
"rollup": "^4.18.0",
"tmp": "^0.2.3",
"typescript": "^4.9.5",
"vitest": "^1.4.0",
"vitest": "^1.6.0",
"xvfb-maybe": "^0.2.1",
"yaml": "^2.2.1"
"yaml": "^2.4.5"
},
"volta": {
"node": "20.12.0",
"yarn": "1.22.19"
}
}
"node": "20.15.0"
},
"packageManager": "[email protected]"
}
41 changes: 21 additions & 20 deletions scripts/check-exports.mjs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import * as browser from '@sentry/browser';
import * as renderer from '../esm/renderer/index.js';

import * as node from '@sentry/node';

// We need to shim electron to avoid errors when importing the main process code into plain-old-node that doesn't have
// the electron module built-in.
import './electron-shim.mjs';
export default async function () {
// We need to shim electron to avoid errors when importing the main process code into plain-old-node that doesn't have
// the electron module built-in.
await import('./electron-shim.mjs');

const main = await import('../esm/main/index.js');
const renderer = await import('../esm/renderer/index.js');
const main = await import('../esm/main/index.js');

const browserExports = Object.keys(browser);
const rendererExports = Object.keys(renderer);
const nodeExports = Object.keys(node);
const mainExports = Object.keys(main);
const browserExports = Object.keys(browser);
const rendererExports = Object.keys(renderer);
const nodeExports = Object.keys(node);
const mainExports = Object.keys(main);

const ignoredBrowser = [
'SDK_VERSION',
Expand Down Expand Up @@ -46,17 +46,18 @@ const ignoredNode = [
'initWithoutDefaultIntegrations',
];

const missingRenderer = browserExports.filter((key) => !rendererExports.includes(key) && !ignoredBrowser.includes(key));
const missingMain = nodeExports.filter((key) => !mainExports.includes(key) && !ignoredNode.includes(key));
const missingRenderer = browserExports.filter(
(key) => !rendererExports.includes(key) && !ignoredBrowser.includes(key),
);
const missingMain = nodeExports.filter((key) => !mainExports.includes(key) && !ignoredNode.includes(key));

if (missingRenderer.length || missingMain.length) {
if (missingRenderer.length) {
console.error('Missing renderer exports:', missingRenderer);
}
if (missingRenderer.length || missingMain.length) {
if (missingRenderer.length) {
console.error('⚠️ Missing renderer exports ⚠️\n', missingRenderer);
}

if (missingMain.length) {
console.error('Missing main exports:', missingMain);
if (missingMain.length) {
console.error('⚠️ Missing main exports ⚠️\n', missingMain);
}
}

process.exit(1);
}
14 changes: 0 additions & 14 deletions scripts/clean-cache.js

This file was deleted.

49 changes: 49 additions & 0 deletions scripts/start.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import updateVersion from './update-version.mjs';
import updateSdkVersions from './update-sdk-versions.mjs';
import checkPackageExports from './check-exports.mjs';

/**
* Each script is made up of one or more commands.
*
* Commands can be:
* - String commands to be executed in the shell
* - String that refers to another script
* - JavaScript functions (sync or async)
*/
scripts({
clean: 'rimraf --glob coverage common esm main preload renderer index.* sentry-electron*.tgz .eslintcache',
build: ['clean', updateVersion, 'rollup --config rollup.config.mjs', checkPackageExports],
lint: [updateVersion, 'lint:prettier', 'lint:eslint'],
'lint:prettier': 'prettier --check "{src,test}/**/*.ts"',
'lint:eslint': 'eslint . --cache --format stylish',
fix: [updateVersion, 'fix:prettier', 'fix:eslint'],
'fix:prettier': 'prettier --write "{src,test}/**/*.ts"',
'fix:eslint': 'eslint . --cache --format --fix',
'update-electron-versions': 'electron-latest-versions --start 15 --beta > ./test/e2e/versions.json',
'update-sdk-versions': updateSdkVersions,
test: ['build', 'vitest run --root=./test/unit'],
e2e: [
'rimraf --glob test/e2e/dist/**/node_modules/@sentry/** test/e2e/dist/**/yarn.lock test/e2e/dist/**/package-lock.json',
'yarn cache clean',
'build',
'npm pack',
'xvfb-maybe vitest run --root=./test/e2e --silent=false --disable-console-intercept',
],
});

import { execSync } from 'child_process';

function scripts(scripts) {
async function run(cmd) {
for (const next of Array.isArray(scripts[cmd]) ? scripts[cmd] : [scripts[cmd]]) {
if (typeof next === 'function') await next();
else if (next in scripts) await run(next);
else {
console.log(`\n> ${next}`);
execSync(next, { stdio: 'inherit' });
}
}
}

run(process.argv[2]);
}
42 changes: 22 additions & 20 deletions scripts/update-sdk-versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,34 @@ import { fileURLToPath } from 'url';

const __dirname = fileURLToPath(new URL('.', import.meta.url));

const latest = await latestVersion('@sentry/core');
const packageJsonPath = join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, { encoding: 'utf8' }));
const current = packageJson.dependencies['@sentry/core'];
export default async function () {
const latest = await latestVersion('@sentry/core');
const packageJsonPath = join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(readFileSync(packageJsonPath, { encoding: 'utf8' }));
const current = packageJson.dependencies['@sentry/core'];

if (current !== latest) {
console.log(`Updating Sentry deps from ${current} to ${latest}`);
if (current !== latest) {
console.log(`Updating Sentry deps from ${current} to ${latest}`);

const re = /^@sentry(-internal)?\//;
const re = /^@sentry(-internal)?\//;

for (const dep of Object.keys(packageJson.dependencies)) {
if (dep.match(re)) {
packageJson.dependencies[dep] = latest;
for (const dep of Object.keys(packageJson.dependencies)) {
if (dep.match(re)) {
packageJson.dependencies[dep] = latest;
}
}
}

for (const dep of Object.keys(packageJson.devDependencies)) {
if (dep.match(re)) {
packageJson.devDependencies[dep] = latest;
for (const dep of Object.keys(packageJson.devDependencies)) {
if (dep.match(re)) {
packageJson.devDependencies[dep] = latest;
}
}
}

writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));

// Update yarn.lock
spawnSync('yarn', ['install'], { stdio: 'inherit' });
// Update parameter that has the version in it
spawnSync('yarn', ['build'], { stdio: 'inherit' });
// Update lock file
spawnSync('yarn', ['install', '--no-immutable'], { stdio: 'inherit' });
// Update parameter that has the version in it
spawnSync('yarn', ['build'], { stdio: 'inherit' });
}
}
16 changes: 0 additions & 16 deletions scripts/update-version.js

This file was deleted.

21 changes: 21 additions & 0 deletions scripts/update-version.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { join } from 'path';
import { readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';

const __dirname = fileURLToPath(new URL('.', import.meta.url));

export default function () {
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json')));

// SDK_VERSION to 'src/main/version.ts'
const versionPath = join(__dirname, '../src/main/version.ts');
writeFileSync(versionPath, `export const SDK_VERSION = '${packageJson.version}';\n`);

// Write @sentry/core version into options variable name so TypeScript error includes useful hint
const coreVersion = packageJson.dependencies['@sentry/core'];
const coreVersionVar = coreVersion.replace(/[\.-]/g, '_');
const rendererSdkPath = join(__dirname, '../src/renderer/sdk.ts');
let rendererSdk = readFileSync(rendererSdkPath, { encoding: 'utf8' });
rendererSdk = rendererSdk.replace(/version_v\d+_\d+_\d+[a-z_0-9]*/, `version_v${coreVersionVar}`);
writeFileSync(rendererSdkPath, rendererSdk);
}
7 changes: 7 additions & 0 deletions test/e2e/recipe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,20 @@ export class RecipeRunner {
writeFileSync(path, content);
}

// Yarn v4 requires an empty yarn.lock file otherwise it complains that this is not part of the parent workspace
if (!this._recipe.files['yarn.lock']) {
writeFileSync(join(appPath, 'yarn.lock'), '');
}

if (this._recipe.metadata.command) {
log(`Running command '${this._recipe.metadata.command}'`);

const result = spawnSync(this._recipe.metadata.command, {
shell: true,
cwd: appPath,
stdio: process.env.DEBUG ? 'inherit' : 'pipe',
// Yarn v4 fail to install in CI without lock files
env: { ...process.env, YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' },
});

if (result.status) {
Expand Down
1 change: 0 additions & 1 deletion test/unit/getPath-test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"version": "1.0.0",
"main": "main.js",
"scripts": {

"start": "../../../node_modules/.bin/electron ."
}
}
2 changes: 1 addition & 1 deletion test/unit/getPath.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, expect, test } from 'vitest';

describe('app.getPath', () => {
test('not called before init', () => {
const result = spawnSync('yarn', ['start'], { cwd: join(__dirname, 'getPath-test-app') });
const result = spawnSync('npm', ['start'], { cwd: join(__dirname, 'getPath-test-app') });
// status is null on Windows in CI for some unknown reason
if (process.platform !== 'win32') {
expect(result.status).to.equal(0);
Expand Down
Loading
Loading