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: { configurationFile: {
input: 'configurationFile', input: 'configurationFile',
env: 'RENOVATE_CONFIG_FILE', env: 'RENOVATE_CONFIG_FILE',
optional: true,
}, },
token: { token: {
input: 'token', input: 'token',
env: 'RENOVATE_TOKEN', env: 'RENOVATE_TOKEN',
optional: false,
}, },
} as const; } as const;
readonly token: Readonly<EnvironmentVariable>;
private readonly _environmentVariables: Map<string, string>; private readonly _environmentVariables: Map<string, string>;
private readonly _configurationFile: Readonly<EnvironmentVariable>;
constructor() { constructor() {
this._environmentVariables = new Map( this._environmentVariables = new Map(
@ -28,27 +32,35 @@ class Input {
) )
); );
this.setEnvironmentVariable( this.token = this.get(
this.options.token.input, 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.input,
this.options.configurationFile.env this.options.configurationFile.env,
this.options.configurationFile.optional
); );
} }
configurationFile(): string { configurationFile(): EnvironmentVariable | null {
return path.resolve( if (this._configurationFile.value !== '') {
this._environmentVariables.get(this.options.configurationFile.env) return {
); key: this._configurationFile.key,
value: path.resolve(this._configurationFile.value),
};
}
return null;
} }
/** /**
* Convert to environment variables. * Convert to environment variables.
* *
* @note The environment variable for the configuration file is filtered out * @note The environment variables listed below are filtered out.
* and is available with `configurationFile()` instead. * - Token, available with the `token` property.
* - Configuration file, available with the `configurationFile()` method.
*/ */
toEnvironmentVariables(): EnvironmentVariable[] { toEnvironmentVariables(): EnvironmentVariable[] {
return [...this._environmentVariables].map(([key, value]) => ({ return [...this._environmentVariables].map(([key, value]) => ({
@ -57,9 +69,15 @@ class Input {
})); }));
} }
private setEnvironmentVariable(input: string, env: string) { private get(
const optionalInput = core.getInput(input); input: string,
if (optionalInput === '' && !this._environmentVariables.has(env)) { env: string,
optional: boolean
): EnvironmentVariable {
const fromInput = core.getInput(input);
const fromEnv = this._environmentVariables.get(env);
if (fromInput === '' && fromEnv === undefined && !optional) {
throw new Error( throw new Error(
[ [
`'${input}' MUST be passed using its input or the '${env}'`, `'${input}' MUST be passed using its input or the '${env}'`,
@ -68,9 +86,11 @@ class Input {
); );
} }
if (optionalInput !== '') { this._environmentVariables.delete(env);
this._environmentVariables.set(env, optionalInput); 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> { async runDockerContainer(): Promise<void> {
const renovateDockerUser = 'ubuntu'; const renovateDockerUser = 'ubuntu';
const dockerArguments = [ const dockerArguments = this.input
...this.input.toEnvironmentVariables(), .toEnvironmentVariables()
{ .map((e) => `--env ${e.key}`)
key: this.input.options.configurationFile.env, .concat([`--env ${this.input.token.key}=${this.input.token.value}`]);
value: this.configFileMountPath(),
}, if (this.input.configurationFile() !== null) {
] const baseName = path.basename(this.input.configurationFile().value);
.map((e) => { const mountPath = path.join(this.configFileMountDir, baseName);
const quotedValue = /\s/.test(e.value) ? `'${e.value}'` : e.value; dockerArguments.push(
return `--env ${e.key}=${quotedValue}`; `--env ${this.input.configurationFile().key}=${mountPath}`,
}) `--volume ${this.input.configurationFile().value}:${mountPath}`
.concat([ );
`--volume ${this.input.configurationFile()}:${this.configFileMountPath()}`, }
'--volume /var/run/docker.sock:/var/run/docker.sock',
'--volume /tmp:/tmp', dockerArguments.push(
`--user ${renovateDockerUser}:${this.getDockerGroupId()}`, '--volume /var/run/docker.sock:/var/run/docker.sock',
'--rm', '--volume /tmp:/tmp',
this.docker.image(), `--user ${renovateDockerUser}:${this.getDockerGroupId()}`,
]); '--rm',
this.docker.image()
);
const command = `docker run ${dockerArguments.join(' ')}`; const command = `docker run ${dockerArguments.join(' ')}`;
@ -77,20 +79,21 @@ class Renovate {
} }
private validateArguments(): void { 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( 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; export default Renovate;