ci: use tunnelApplicationName (#164257)

fix location of tunnel command in CI and in code
This commit is contained in:
Martin Aeschlimann 2022-10-23 19:12:23 +02:00 committed by GitHub
parent 0091bcae20
commit f10e84118b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 71 additions and 40 deletions

View file

@ -203,11 +203,9 @@ steps:
set -e
ARCHIVE_NAME=$(ls "$(Build.ArtifactStagingDirectory)/cli" | head -n 1)
unzip "$(Build.ArtifactStagingDirectory)/cli/$ARCHIVE_NAME" -d "$(Build.ArtifactStagingDirectory)/cli"
mv "$(Build.ArtifactStagingDirectory)/cli/code" "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel"
chmod +x "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel"
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel" "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel-$(VSCODE_QUALITY)"
fi
CLI_APP_NAME=$(node -p "require(\"$(APP_PATH)/Contents/Resources/app/product.json\").tunnelApplicationName")
mv "$(Build.ArtifactStagingDirectory)/cli/code" "$(APP_PATH)/Contents/Resources/app/bin/$CLI_APP_NAME"
chmod +x "$(APP_PATH)/Contents/Resources/app/bin/$CLI_APP_NAME"
displayName: Make CLI executable
- ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}:

View file

@ -282,10 +282,8 @@ steps:
- script: |
set -e
tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(Build.ArtifactStagingDirectory)/cli
mv $(Build.ArtifactStagingDirectory)/cli/code $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
mv "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel" "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel-$(VSCODE_QUALITY)"
fi
CLI_APP_NAME=$(node -p "require(\"$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/resources/app/product.json\").tunnelApplicationName")
mv $(Build.ArtifactStagingDirectory)/cli/code $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/$CLI_APP_NAME
displayName: Make CLI executable
- ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}:

View file

@ -219,13 +219,9 @@ steps:
$ErrorActionPreference = "Stop"
$ArtifactName = (gci -Path "$(Build.ArtifactStagingDirectory)/cli" | Select-Object -last 1).FullName
Expand-Archive -Path $ArtifactName -DestinationPath "$(Build.ArtifactStagingDirectory)/cli"
Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/code.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel.exe"
if ("$(VSCODE_QUALITY)" -ne "stable")
{
Move-Item -Path "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel-$(VSCODE_QUALITY).exe"
}
$AppProductJson = Get-Content -Raw -Path "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)\resources\app\product.json" | ConvertFrom-Json
$CliAppName = $AppProductJson.tunnelApplicationName
Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/code.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/$CliAppName.exe"
displayName: Move VS Code CLI
- ${{ if eq(parameters.VSCODE_PUBLISH, true) }}:

View file

@ -554,6 +554,10 @@ pub struct TunnelServeArgs {
/// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists
#[clap(long, hide = true)]
pub parent_process_id: Option<String>,
/// If set, the user accepts the server license terms and the server will be started without a user prompt.
#[clap(long)]
pub accept_server_license_terms: bool,
}
#[derive(Args, Debug, Clone)]

View file

@ -121,7 +121,7 @@ pub async fn service(
.await?;
// likewise for license consent
legal::require_consent(&ctx.paths)?;
legal::require_consent(&ctx.paths, false)?;
let current_exe =
std::env::current_exe().map_err(|e| wrap(e, "could not get current exe"))?;
@ -220,7 +220,7 @@ pub async fn serve(ctx: CommandContext, gateway_args: TunnelServeArgs) -> Result
log, paths, args, ..
} = ctx;
legal::require_consent(&paths)?;
legal::require_consent(&paths, gateway_args.accept_server_license_terms)?;
let csa = (&args).into();
serve_with_csa(paths, log, gateway_args, csa, None).await

View file

@ -15,12 +15,19 @@ struct PersistedConsent {
pub consented: Option<bool>,
}
pub fn require_consent(paths: &LauncherPaths) -> Result<(), AnyError> {
pub fn require_consent(
paths: &LauncherPaths,
accept_server_license_terms: bool,
) -> Result<(), AnyError> {
match LICENSE_TEXT {
Some(t) => println!("{}", t.replace("\\n", "\r\n")),
None => return Ok(()),
}
if accept_server_license_terms {
return Ok(());
}
let prompt = match LICENSE_PROMPT {
Some(p) => p,
None => return Ok(()),

View file

@ -61,7 +61,7 @@ export async function main(argv: string[]): Promise<any> {
} else {
const tunnelCommand = join(dirname(process.execPath), 'bin', `${product.tunnelApplicationName}${isWindows ? '.exe' : ''}`);
const tunnelArgs = argv.slice(3);
tunnelProcess = spawn(tunnelCommand, tunnelArgs);
tunnelProcess = spawn(tunnelCommand, ['tunnel', ...tunnelArgs]);
}
tunnelProcess.stdout.on('data', data => {
console.log(data.toString());

View file

@ -69,6 +69,9 @@ export interface IEnvironmentService {
editSessionId?: string;
editSessionsLogResource: URI;
// remote tunnel
remoteTunnelLogResource: URI;
// --- extension development
debugExtensionHost: IExtensionHostDebugParams;
isExtensionDevelopment: boolean;

View file

@ -85,6 +85,9 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
@memoize
get editSessionsLogResource(): URI { return URI.file(join(this.logsPath, 'editSessions.log')); }
@memoize
get remoteTunnelLogResource(): URI { return URI.file(join(this.logsPath, 'remoteTunnel.log')); }
@memoize
get sync(): 'on' | 'off' | undefined { return this.args.sync; }

View file

@ -13,13 +13,12 @@ import { URI } from 'vs/base/common/uri';
import { dirname, join } from 'vs/base/common/path';
import { ChildProcess, spawn } from 'child_process';
import { IProductService } from 'vs/platform/product/common/productService';
import { isWindows } from 'vs/base/common/platform';
import { isMacintosh, isWindows } from 'vs/base/common/platform';
import { CancelablePromise, createCancelablePromise, Delayer } from 'vs/base/common/async';
import { ISharedProcessLifecycleService } from 'vs/platform/lifecycle/electron-browser/sharedProcessLifecycleService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { localize } from 'vs/nls';
import { hostname } from 'os';
import { hostname, homedir } from 'os';
type RemoteTunnelEnablementClassification = {
owner: 'aeschli';
@ -56,6 +55,8 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ
private _tunnelStatus: TunnelStatus = TunnelStates.disconnected;
private _startTunnelProcessDelayer: Delayer<void>;
private _tunnelCommand: string | undefined;
constructor(
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IProductService private readonly productService: IProductService,
@ -65,8 +66,7 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super();
const logFileUri = URI.file(join(dirname(environmentService.logsPath), 'remoteTunnel.log'));
this._logger = this._register(loggerService.createLogger(logFileUri, { name: 'remoteTunnel' }));
this._logger = this._register(loggerService.createLogger(environmentService.remoteTunnelLogResource, { name: 'remoteTunnel' }));
this._startTunnelProcessDelayer = new Delayer(100);
this._register(sharedProcessLifecycleService.onWillShutdown(e => {
@ -103,7 +103,25 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ
this._logger.error(e);
}
}
}
private getTunnelCommandLocation() {
if (!this._tunnelCommand) {
let binParentLocation;
if (isMacintosh) {
// appRoot = /Applications/Visual Studio Code - Insiders.app/Contents/Resources/app
// bin = /Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin
binParentLocation = this.environmentService.appRoot;
} else {
// appRoot = C:\Users\<name>\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app
// bin = C:\Users\<name>\AppData\Local\Programs\Microsoft VS Code Insiders\bin
// appRoot = /usr/share/code-insiders/resources/app
// bin = /usr/share/code-insiders/bin
binParentLocation = dirname(dirname(this.environmentService.appRoot));
}
this._tunnelCommand = join(binParentLocation, 'bin', `${this.productService.tunnelApplicationName}${isWindows ? '.exe' : ''}`);
}
return this._tunnelCommand;
}
private async updateTunnelProcess(): Promise<void> {
@ -130,7 +148,7 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ
this.setTunnelStatus(TunnelStates.disconnected);
return;
}
const args = ['--parent-process-id', String(process.pid)];
const args = ['--parent-process-id', String(process.pid), '--accept-server-license-terms'];
const hostName = this.getHostName();
if (hostName) {
args.push('--name', hostName);
@ -183,13 +201,18 @@ export class RemoteTunnelService extends Disposable implements IRemoteTunnelServ
tunnelProcess.kill();
}
});
this._logger.info(`${logLabel} appRoot ${this.environmentService.appRoot}`);
this._logger.info(`${logLabel} process.execPath ${process.execPath}`);
if (process.env['VSCODE_DEV']) {
onOutput('Compiling tunnel CLI from sources and run', false);
this._logger.info(`${logLabel} Spawning: cargo run -- tunnel ${commandArgs.join(' ')}`);
tunnelProcess = spawn('cargo', ['run', '--', 'tunnel', ...commandArgs], { cwd: join(this.environmentService.appRoot, 'cli') });
} else {
const tunnelCommand = join(dirname(process.execPath), 'bin', `${this.productService.tunnelApplicationName}${isWindows ? '.exe' : ''}`);
this._logger.info(`${logLabel} Spawning: ${tunnelCommand} ${commandArgs.join(' ')}`);
tunnelProcess = spawn(tunnelCommand, ['tunnel', ...commandArgs]);
onOutput('Running tunnel CLI', false);
const tunnelCommand = this.getTunnelCommandLocation();
this._logger.info(`${logLabel} Spawning: ${tunnelCommand} tunnel ${commandArgs.join(' ')}`);
tunnelProcess = spawn(tunnelCommand, ['tunnel', ...commandArgs], { cwd: homedir() });
}
tunnelProcess.stdout!.on('data', data => {

View file

@ -10,6 +10,7 @@ export const telemetryLogChannelId = 'telemetryLog';
export const extensionTelemetryLogChannelId = 'extensionTelemetryLog';
export const userDataSyncLogChannelId = 'userDataSyncLog';
export const editSessionsLogChannelId = 'editSessionsSyncLog';
export const remoteTunnelLogChannelId = 'remoteTunnelLog';
export const remoteServerLog = 'remoteServerLog';
export const remotePtyHostLog = 'remotePtyHostLog';

View file

@ -50,6 +50,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution {
private registerCommonContributions(): void {
this.registerLogChannel(Constants.userDataSyncLogChannelId, nls.localize('userDataSyncLog', "Settings Sync"), this.environmentService.userDataSyncLogResource);
this.registerLogChannel(Constants.editSessionsLogChannelId, nls.localize('editSessionsLog', "Edit Sessions"), this.environmentService.editSessionsLogResource);
this.registerLogChannel(Constants.remoteTunnelLogChannelId, nls.localize('remoteTunnelLog', "Remote Tunnel"), this.environmentService.remoteTunnelLogResource);
this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), this.environmentService.logFile);
const registerTelemetryChannel = () => {

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { IProductService } from 'vs/platform/product/common/productService';
import { CONFIGURATION_KEY_HOST_NAME, CONFIGURATION_KEY_PREFIX, ConnectionInfo, IRemoteTunnelService } from 'vs/platform/remoteTunnel/common/remoteTunnel';
@ -18,12 +18,10 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IStorageService, IStorageValueChangeEvent, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { ILogger, ILoggerService, ILogService } from 'vs/platform/log/common/log';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { URI } from 'vs/base/common/uri';
import { join } from 'vs/base/common/path';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IStringDictionary } from 'vs/base/common/collections';
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator, QuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { IOutputService, registerLogChannel } from 'vs/workbench/services/output/common/output';
import { IOutputService } from 'vs/workbench/services/output/common/output';
import { IFileService } from 'vs/platform/files/common/files';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
import { IProgress, IProgressService, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress';
@ -34,6 +32,7 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Action } from 'vs/base/common/actions';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import * as Constants from 'vs/workbench/contrib/logs/common/logConstants';
export const REMOTE_TUNNEL_CATEGORY: ILocalizedString = {
original: 'Remote Tunnels',
@ -102,12 +101,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo
) {
super();
const logPathURI = URI.file(join(environmentService.logsPath, 'remoteTunnel.log'));
this.logger = this._register(loggerService.createLogger(logPathURI, { name: 'remoteTunnel' }));
const promise = registerLogChannel('remoteTunnel', localize('remoteTunnel.outputTitle', "Remote Tunnel"), logPathURI, fileService, logService);
this._register(toDisposable(() => promise.cancel()));
this.logger = this._register(loggerService.createLogger(environmentService.remoteTunnelLogResource, { name: 'remoteTunnel' }));
this.connectionStateContext = REMOTE_TUNNEL_CONNECTION_STATE.bindTo(this.contextKeyService);
@ -536,7 +530,7 @@ export class RemoteTunnelWorkbenchContribution extends Disposable implements IWo
async run(accessor: ServicesAccessor) {
const outputService = accessor.get(IOutputService);
outputService.showChannel('remoteTunnel');
outputService.showChannel(Constants.remoteServerLog);
}
}));

View file

@ -111,6 +111,9 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi
@memoize
get editSessionsLogResource(): URI { return joinPath(this.logsHome, 'editSessions.log'); }
@memoize
get remoteTunnelLogResource(): URI { return joinPath(this.logsHome, 'remoteTunnel.log'); }
@memoize
get sync(): 'on' | 'off' | undefined { return undefined; }