Skip to content

feat: add siso configuration support #729

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 4 commits into from
Jun 19, 2025
Merged
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
11 changes: 6 additions & 5 deletions evm-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,20 @@
"type": "string",
"minLength": 1
},
"reclient": {
"description": "Whether to use the Electron RBE infrastructure",
"remoteBuild": {
"description": "Whether to use remote builds and what system to use",
"type": "string",
"enum": [
"remote_exec",
"reclient",
"siso",
"none"
]
},
"reclientHelperPath": {
"rbeHelperPath": {
"description": "Path to alternative reclient credential helper",
"type": "string"
},
"reclientServiceAddress": {
"rbeServiceAddress": {
"description": "Alternative RBE cluster address",
"type": "string"
},
Expand Down
2 changes: 1 addition & 1 deletion example-configs/evm.base.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
root: /path/to/your/developer/folder
reclient: remote_exec
remoteBuild: reclient
preserveSDK: 5
remotes:
electron:
Expand Down
2 changes: 1 addition & 1 deletion example-configs/evm.chromium.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
root: /path/to/chromium/
reclient: remote_exec
remoteBuild: reclient
defaultTarget: chrome
execName: Chromium
gen:
Expand Down
15 changes: 12 additions & 3 deletions src/e-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { color, fatal } = require('./utils/logging');
const depot = require('./utils/depot-tools');
const { ensureDir } = require('./utils/paths');
const reclient = require('./utils/reclient');
const siso = require('./utils/siso');
const { ensureSDK, ensureSDKAndSymlink } = require('./utils/sdk');

function getGNArgs(config) {
Expand Down Expand Up @@ -58,13 +59,21 @@ function ensureGNGen(config) {
}

function runNinja(config, target, ninjaArgs) {
if (reclient.usingRemote && config.reclient !== 'none') {
if (reclient.usingRemote && config.remoteBuild !== 'none') {
reclient.auth(config);

// Autoninja sets this absurdly high, we take it down a notch
if (!ninjaArgs.includes('-j') && !ninjaArgs.find((arg) => /^-j[0-9]+$/.test(arg.trim()))) {
if (
!ninjaArgs.includes('-j') &&
!ninjaArgs.find((arg) => /^-j[0-9]+$/.test(arg.trim())) &&
config.remoteBuild === 'reclient'
) {
ninjaArgs.push('-j', 200);
}

if (config.remoteBuild === 'siso') {
ninjaArgs.push(...siso.flags(config));
}
} else {
console.info(`${color.info} Building ${target} with remote execution disabled`);
}
Expand Down Expand Up @@ -109,7 +118,7 @@ program
);
}

reclient.downloadAndPrepare(config);
reclient.downloadAndPrepareRBECredentialHelper(config);

if (process.platform === 'darwin') {
ensureSDK();
Expand Down
2 changes: 1 addition & 1 deletion src/e-depot-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ program

let cwd;
if (args[0] === 'rbe') {
reclient.downloadAndPrepare(evmConfig.current(), true);
reclient.downloadAndPrepareRBECredentialHelper(evmConfig.current(), true);
args[0] = reclient.helperPath(evmConfig.current());
}

Expand Down
17 changes: 10 additions & 7 deletions src/e-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function createConfig(options) {
// build the `gn gen` args
const gn_args = [`import("//electron/build/args/${options.import}.gn")`];

if (options.reclient !== 'none') {
if (options.remoteBuild !== 'none') {
gn_args.push('use_remoteexec=true');
}

Expand Down Expand Up @@ -58,7 +58,7 @@ function createConfig(options) {

return {
$schema: URI.file(path.resolve(__dirname, '..', 'evm-config.schema.json')).toString(),
reclient: options.reclient,
remoteBuild: options.remoteBuild,
root,
remotes: {
electron,
Expand Down Expand Up @@ -137,11 +137,11 @@ program
.option('--bootstrap', 'Run `e sync` and `e build` after creating the build config.')
.addOption(
new Option(
'--reclient <target>',
`Use Electron's RBE backend. The "remote_exec" mode will fall back to cache-only depending on the auth provided`,
'--remote-build <target>',
`Use Electron's RBE backend. The "reclient" and "siso" modes will fall back to cache-only depending on the auth provided`,
)
.choices(['remote_exec', 'none'])
.default('remote_exec'),
.choices(['reclient', 'siso', 'none'])
.default('reclient'),
)
.option(
'--use-https',
Expand Down Expand Up @@ -201,7 +201,10 @@ program
}

// maybe authenticate with RBE
if (process.env.NODE_ENV !== 'test' && config.reclient === 'remote_exec') {
if (
process.env.NODE_ENV !== 'test' &&
(config.remoteBuild === 'reclient' || config.remoteBuild === 'siso')
) {
childProcess.execFileSync(process.execPath, [e, 'd', 'rbe', 'login'], opts);
}

Expand Down
51 changes: 49 additions & 2 deletions src/evm-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,69 @@ function sanitizeConfig(name, config, overwrite = false) {
}

const remoteExecGnArg = 'use_remoteexec = true';
const useSisoGnArg = 'use_siso = true';
const hasRemoteExecGN = !(
!config.gen ||
!config.gen.args ||
!config.gen.args.find((arg) => /^use_remoteexec ?= ?true$/.test(arg))
);
const hasUseSisoGN = !(
!config.gen ||
!config.gen.args ||
!config.gen.args.find((arg) => /^use_siso ?= ?true$/.test(arg))
);

if (config.reclient !== 'none' && !hasRemoteExecGN) {
if (!config.remoteBuild) {
if (config.reclient) {
config.remoteBuild = config.reclient === 'none' ? 'none' : 'reclient';
changes.push(
`converted ${color.config('reclient')} setting ${color.config('remoteBuild')} property`,
);
delete config.reclient;
} else {
config.remoteBuild = 'none';
changes.push(`added missing explicit ${color.config('remoteBuild')} property`);
}
}

if (config.remoteBuild !== 'none' && !hasRemoteExecGN) {
config.gen ??= {};
config.gen.args ??= [];
config.gen.args.push(remoteExecGnArg);
changes.push(`added gn arg ${color.cmd(remoteExecGnArg)} needed by remoteexec`);
} else if (config.reclient === 'none' && hasRemoteExecGN) {
} else if (config.remoteBuild === 'none' && hasRemoteExecGN) {
config.gen.args = config.gen.args.filter((arg) => !/^use_remoteexec ?= ?true$/.test(arg));
changes.push(`removed gn arg ${color.cmd(remoteExecGnArg)} as remoteexec is disabled`);
}

if (config.remoteBuild === 'siso' && !hasUseSisoGN) {
config.gen ??= {};
config.gen.args ??= [];
config.gen.args.push(useSisoGnArg);
changes.push(
`added gn arg ${color.cmd(useSisoGnArg)} needed by ${color.config('remoteBuild')} siso`,
);
} else if (config.remoteBuild !== 'siso' && hasUseSisoGN) {
config.gen.args = config.gen.args.filter((arg) => !/^use_siso ?= ?true$/.test(arg));
changes.push(`removed gn arg ${color.cmd(useSisoGnArg)} as siso is disabled`);
}

if (!config.rbeHelperPath && config.reclientHelperPath) {
config.rbeHelperPath = config.reclientHelperPath;
changes.push(
`renamed ${color.config('reclientHelperPath')} to ${color.config('rbeHelperPath')}`,
);
delete config.reclientHelperPath;
}

if (!config.rbeServiceAddress && config.reclientServiceAddress) {
config.rbeServiceAddress = config.reclientServiceAddress;
changes.push(
`renamed ${color.config('reclientServiceAddress')} to ${color.config('rbeServiceAddress')}`,
);
delete config.reclientServiceAddress;
}

config.env ??= {};

if (!config.env.CHROMIUM_BUILDTOOLS_PATH) {
Expand Down
1 change: 1 addition & 0 deletions src/utils/depot-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ function depotOpts(config, opts = {}) {
...opts.env,
// Circular reference so we have to delay load
...require('./reclient').env(config),
...require('./siso').env(config),
};

// put depot tools at the front of the path
Expand Down
34 changes: 18 additions & 16 deletions src/utils/reclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,23 @@ const { deleteDir } = require('./paths');

const reclientDir = path.resolve(__dirname, '..', '..', 'third_party', 'reclient');
const reclientTagFile = path.resolve(reclientDir, '.tag');
const reclientHelperPath = path.resolve(
const rbeHelperPath = path.resolve(
reclientDir,
`electron-rbe-credential-helper${process.platform === 'win32' ? '.exe' : ''}`,
);
const rbeServiceAddress = 'rbe.notgoma.com:443';
const RBE_SERVICE_ADDRESS = 'rbe.notgoma.com:443';

const CREDENTIAL_HELPER_TAG = 'v0.5.0';

let usingRemote = true;

function downloadAndPrepareReclient(config) {
if (config.reclient === 'none') return;
function downloadAndPrepareRBECredentialHelper(config) {
if (config.remoteBuild === 'none') return;

// If a custom reclient credentials helper is specified, expect
// that it exists in the specified location
if (config.reclientHelperPath) {
console.log(
`Using custom reclient credentials helper at ${color.path(config.reclientHelperPath)}`,
);
if (config.rbeHelperPath) {
console.log(`Using custom reclient credentials helper at ${color.path(config.rbeHelperPath)}`);
return;
}

Expand Down Expand Up @@ -89,7 +87,7 @@ function downloadAndPrepareReclient(config) {
});

if (process.platform === 'win32') {
fs.renameSync(reclientHelperPath.replace(/\.exe$/, ''), reclientHelperPath);
fs.renameSync(rbeHelperPath.replace(/\.exe$/, ''), rbeHelperPath);
}

deleteDir(tmpDownload);
Expand All @@ -98,12 +96,12 @@ function downloadAndPrepareReclient(config) {
}

function reclientEnv(config) {
if (config?.reclient === 'none' || !usingRemote) {
if (config?.remoteBuild === 'none' || !usingRemote) {
return {};
}

let reclientEnv = {
RBE_service: config.reclientServiceAddress || rbeServiceAddress,
RBE_service: getServiceAddress(config),
RBE_credentials_helper: getHelperPath(config),
RBE_credentials_helper_args: 'print',
RBE_experimental_credentials_helper: getHelperPath(config),
Expand All @@ -117,7 +115,7 @@ function reclientEnv(config) {
reclientEnv.RBE_fail_early_min_fallback_ratio = 0;
}

const result = childProcess.spawnSync(reclientHelperPath, ['flags'], {
const result = childProcess.spawnSync(rbeHelperPath, ['flags'], {
stdio: 'pipe',
});

Expand All @@ -135,7 +133,7 @@ function reclientEnv(config) {
}

function ensureHelperAuth(config) {
const result = childProcess.spawnSync(reclientHelperPath, ['status'], {
const result = childProcess.spawnSync(rbeHelperPath, ['status'], {
stdio: 'pipe',
});
if (result.status !== 0) {
Expand All @@ -150,14 +148,18 @@ function ensureHelperAuth(config) {
}

function getHelperPath(config) {
return config.reclientHelperPath || reclientHelperPath;
return config.rbeHelperPath || rbeHelperPath;
}

function getServiceAddress(config) {
return config.rbeServiceAddress || RBE_SERVICE_ADDRESS;
}

module.exports = {
env: reclientEnv,
downloadAndPrepare: downloadAndPrepareReclient,
downloadAndPrepareRBECredentialHelper,
helperPath: getHelperPath,
serviceAddress: rbeServiceAddress,
serviceAddress: getServiceAddress,
auth: ensureHelperAuth,
usingRemote,
};
2 changes: 0 additions & 2 deletions src/utils/sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,6 @@ function ensureSDK(version) {
evmConfig.setEnvVar(evmConfig.currentName(), 'SDKROOT', eventualVersionedPath);

console.log(`${color.info} Now using SDK version ${color.path(getSDKVersion())}`);
} else {
console.log(`${color.info} SDK version ${color.path(getSDKVersion())} is already in use`);
}

deleteDir(SDKZip);
Expand Down
35 changes: 35 additions & 0 deletions src/utils/siso.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const reclient = require('./reclient');

const SISO_REAPI_INSTANCE = 'projects/electron-rbe/instances/default_instance';
const SISO_PROJECT = SISO_REAPI_INSTANCE.split('/')[1];

const sisoEnv = (config) => {
if (config.remoteBuild !== 'siso') return {};

return {
SISO_PROJECT,
SISO_REAPI_INSTANCE,
SISO_REAPI_ADDRESS: reclient.serviceAddress(config),
SISO_CREDENTIAL_HELPER: reclient.helperPath(config),
};
};

function sisoFlags(config) {
if (config.remoteBuild !== 'siso') return [];

return [
'-remote_jobs',
200,
'-project',
SISO_PROJECT,
'-reapi_instance',
SISO_REAPI_INSTANCE,
'-reapi_address',
reclient.serviceAddress(config),
];
}

module.exports = {
env: sisoEnv,
flags: sisoFlags,
};
2 changes: 1 addition & 1 deletion tests/e-init.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('e-init', () => {

const config = require(configPath);
expect(config).toHaveProperty('$schema');
expect(config.reclient).toStrictEqual('remote_exec');
expect(config.remoteBuild).toStrictEqual('reclient');

expect(config.remotes).toHaveProperty('electron');
expect(config.remotes).not.toHaveProperty('node');
Expand Down
4 changes: 2 additions & 2 deletions tests/evm-config.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const validConfig = {
},
},
preserveSDK: 5,
reclient: 'none',
remoteBuild: 'none',
gen: {
args: [],
out: 'Testing',
Expand Down Expand Up @@ -65,7 +65,7 @@ describe('example configs', () => {
},
},
configValidationLevel: 'strict',
reclient: 'remote_exec',
remoteBuild: 'reclient',
preserveSDK: expect.any(Number),
gen: {
out: 'Testing',
Expand Down