fix: pass existing environment variables to Docker with --env

This commit is contained in:
Jeroen de Bruijn 2021-03-07 15:25:00 +01:00
parent 008f05800b
commit 0d1fe55b45
No known key found for this signature in database
GPG key ID: 94DD99A281A21364
2 changed files with 67 additions and 44 deletions

View file

@ -12,14 +12,18 @@ class Input {
configurationFile: {
input: 'configurationFile',
env: 'RENOVATE_CONFIG_FILE',
optional: true,
},
token: {
input: 'token',
env: 'RENOVATE_TOKEN',
optional: false,
},
} as const;
readonly token: Readonly<EnvironmentVariable>;
private readonly _environmentVariables: Map<string, string>;
private readonly _configurationFile: Readonly<EnvironmentVariable>;
constructor() {
this._environmentVariables = new Map(
@ -28,27 +32,35 @@ class Input {
)
);
this.setEnvironmentVariable(
this.token = this.get(
this.options.token.input,
this.options.token.env
this.options.token.env,
this.options.token.optional
);
this.setEnvironmentVariable(
this._configurationFile = this.get(
this.options.configurationFile.input,
this.options.configurationFile.env
this.options.configurationFile.env,
this.options.configurationFile.optional
);
}
configurationFile(): string {
return path.resolve(
this._environmentVariables.get(this.options.configurationFile.env)
);
configurationFile(): EnvironmentVariable | null {
if (this._configurationFile.value !== '') {
return {
key: this._configurationFile.key,
value: path.resolve(this._configurationFile.value),
};
}
return null;
}
/**
* Convert to environment variables.
*
* @note The environment variable for the configuration file is filtered out
* and is available with `configurationFile()` instead.
* @note The environment variables listed below are filtered out.
* - Token, available with the `token` property.
* - Configuration file, available with the `configurationFile()` method.
*/
toEnvironmentVariables(): EnvironmentVariable[] {
return [...this._environmentVariables].map(([key, value]) => ({
@ -57,9 +69,15 @@ class Input {
}));
}
private setEnvironmentVariable(input: string, env: string) {
const optionalInput = core.getInput(input);
if (optionalInput === '' && !this._environmentVariables.has(env)) {
private get(
input: string,
env: string,
optional: boolean
): EnvironmentVariable {
const fromInput = core.getInput(input);
const fromEnv = this._environmentVariables.get(env);
if (fromInput === '' && fromEnv === undefined && !optional) {
throw new Error(
[
`'${input}' MUST be passed using its input or the '${env}'`,
@ -68,9 +86,11 @@ class Input {
);
}
if (optionalInput !== '') {
this._environmentVariables.set(env, optionalInput);
this._environmentVariables.delete(env);
if (fromInput !== '') {
return { key: env, value: fromInput };
}
return { key: env, value: fromEnv !== undefined ? fromEnv : '' };
}
}

View file

@ -19,25 +19,27 @@ class Renovate {
async runDockerContainer(): Promise<void> {
const renovateDockerUser = 'ubuntu';
const dockerArguments = [
...this.input.toEnvironmentVariables(),
{
key: this.input.options.configurationFile.env,
value: this.configFileMountPath(),
},
]
.map((e) => {
const quotedValue = /\s/.test(e.value) ? `'${e.value}'` : e.value;
return `--env ${e.key}=${quotedValue}`;
})
.concat([
`--volume ${this.input.configurationFile()}:${this.configFileMountPath()}`,
const dockerArguments = this.input
.toEnvironmentVariables()
.map((e) => `--env ${e.key}`)
.concat([`--env ${this.input.token.key}=${this.input.token.value}`]);
if (this.input.configurationFile() !== null) {
const baseName = path.basename(this.input.configurationFile().value);
const mountPath = path.join(this.configFileMountDir, baseName);
dockerArguments.push(
`--env ${this.input.configurationFile().key}=${mountPath}`,
`--volume ${this.input.configurationFile().value}:${mountPath}`
);
}
dockerArguments.push(
'--volume /var/run/docker.sock:/var/run/docker.sock',
'--volume /tmp:/tmp',
`--user ${renovateDockerUser}:${this.getDockerGroupId()}`,
'--rm',
this.docker.image(),
]);
this.docker.image()
);
const command = `docker run ${dockerArguments.join(' ')}`;
@ -77,20 +79,21 @@ class Renovate {
}
private validateArguments(): void {
if (!fs.existsSync(this.input.configurationFile())) {
if (/\s/.test(this.input.token.value)) {
throw new Error('Token MUST NOT contain whitespace');
}
const configurationFile = this.input.configurationFile();
if (
configurationFile !== null &&
(!fs.existsSync(configurationFile.value) ||
!fs.statSync(configurationFile.value).isFile())
) {
throw new Error(
`Could not locate configuration file '${this.input.configurationFile()}'.`
`configuration file '${configurationFile.value}' MUST be an existing file`
);
}
}
private configFileName(): string {
return path.basename(this.input.configurationFile());
}
private configFileMountPath(): string {
return path.join(this.configFileMountDir, this.configFileName());
}
}
export default Renovate;