( fn: (env: object) => Promise<T>, path: string, isBackgroundTask = false, customEnv?: Record<string, string | undefined> )
| 91 | * variables. |
| 92 | */ |
| 93 | export async function withTrampolineEnv<T>( |
| 94 | fn: (env: object) => Promise<T>, |
| 95 | path: string, |
| 96 | isBackgroundTask = false, |
| 97 | customEnv?: Record<string, string | undefined> |
| 98 | ): Promise<T> { |
| 99 | const sshEnv = await getSSHEnvironment() |
| 100 | |
| 101 | return withTrampolineToken(async token => { |
| 102 | isBackgroundTaskEnvironment.set(token, isBackgroundTask) |
| 103 | trampolineEnvironmentPath.set(token, path) |
| 104 | |
| 105 | const existingGitEnvConfig = |
| 106 | customEnv?.['GIT_CONFIG_PARAMETERS'] ?? |
| 107 | process.env['GIT_CONFIG_PARAMETERS'] ?? |
| 108 | '' |
| 109 | |
| 110 | const gitEnvConfigPrefix = |
| 111 | existingGitEnvConfig.length > 0 ? `${existingGitEnvConfig} ` : '' |
| 112 | |
| 113 | // The code below assumes a few things in order to manage SSH key passphrases |
| 114 | // correctly: |
| 115 | // 1. `withTrampolineEnv` is only used in the functions `git` (core.ts) |
| 116 | // 2. Those two functions always thrown an error when something went wrong, |
| 117 | // and just return a result when everything went fine. |
| 118 | // |
| 119 | // With those two premises in mind, we can safely assume that right after |
| 120 | // `fn` has been invoked, we can store the SSH key passphrase for this git |
| 121 | // operation if there was one pending to be stored. |
| 122 | try { |
| 123 | return await fn({ |
| 124 | DESKTOP_PORT: await trampolineServer.getPort(), |
| 125 | DESKTOP_TRAMPOLINE_TOKEN: token, |
| 126 | GIT_ASKPASS: '', |
| 127 | // This warrants some explanation. We're configuring the |
| 128 | // credential helper using environment variables rather than |
| 129 | // arguments (i.e. -c credential.helper=) because we want commands |
| 130 | // invoked by filters (i.e. Git LFS) to be able to pick up our |
| 131 | // configuration. Arguments passed to git commands are not passed |
| 132 | // down to filters. |
| 133 | // |
| 134 | // We're using the undocumented GIT_CONFIG_PARAMETERS environment |
| 135 | // variable over the documented GIT_CONFIG_{COUNT,KEY,VALUE} due |
| 136 | // to an apparent bug either in a Windows Python runtime |
| 137 | // dependency or in a Python project commonly used to manage hooks |
| 138 | // which isn't able to handle the blank environment variables we |
| 139 | // need when using GIT_CONFIG_*. |
| 140 | // |
| 141 | // See https://github.com/desktop/desktop/issues/18945 |
| 142 | // See https://github.com/git/git/blob/ed155187b429a/config.c#L664 |
| 143 | GIT_CONFIG_PARAMETERS: `${gitEnvConfigPrefix}'credential.helper=' 'credential.helper=desktop'`, |
| 144 | |
| 145 | GIT_USER_AGENT: await GitUserAgent(), |
| 146 | ...sshEnv, |
| 147 | }) |
| 148 | } catch (e) { |
| 149 | if (!getIsBackgroundTaskEnvironment(token)) { |
| 150 | // If the operation fails with an SSHAuthenticationFailed error, we |
no test coverage detected