feat: deprecate `REDIS_URL` environment variable when using with the `Probot` constructor. Use `new Probot({ redisConfig: "redis://..." })` instead

This commit is contained in:
Gregor Martynus 2020-11-19 15:44:51 -08:00
parent 514c7645e8
commit 1dbd999982
9 changed files with 49 additions and 25 deletions

View File

@ -31,7 +31,7 @@ program
.option("-a, --app <id>", "ID of the GitHub App", process.env.APP_ID)
.option(
"-P, --private-key <file>",
"Path to certificate of the GitHub App",
"Path to private key file (.pem) for the GitHub App",
process.env.PRIVATE_KEY_PATH
)
.option(

View File

@ -31,7 +31,7 @@ export function readCliOptions(argv: string[]): Options & PinoOptions {
)
.option(
"-P, --private-key <file>",
"Path to certificate of the GitHub App",
"Path to private key file (.pem) for the GitHub App",
process.env.PRIVATE_KEY_PATH
)
.option(
@ -54,13 +54,19 @@ export function readCliOptions(argv: string[]): Options & PinoOptions {
'Set to your Sentry DSN, e.g. "https://1234abcd@sentry.io/12345"',
process.env.SENTRY_DSN
)
.option(
"--redis-url <url>",
'Set to a "redis://" url in order to enable cluster support for request throttling. Example: "redis://:secret@redis-123.redislabs.com:12345/0"',
process.env.REDIS_URL
)
.parse(argv);
const { app: id, privateKey: privateKeyPath, ...options } = program;
const { app: id, privateKey: privateKeyPath, redisUrl, ...options } = program;
return {
privateKey: getPrivateKey({ filepath: privateKeyPath }) || undefined,
id,
redisConfig: redisUrl,
...options,
};
}

View File

@ -16,5 +16,6 @@ export function readEnvOptions() {
logFormat: process.env.LOG_FORMAT as PinoOptions["logFormat"],
logLevelInString: process.env.LOG_LEVEL_IN_STRING === "true",
sentryDsn: process.env.SENTRY_DSN,
redisConfig: process.env.REDIS_URL,
};
}

View File

@ -41,9 +41,9 @@ export function getLog(options: GetLogOptions = { level: "info" }) {
const log = pino(pinoOptions, transform);
if (deprecated.length) {
log.warn(`[probot] ${deprecated.join(
log.warn(`[probot] Using the following environment variable(s) with the Probot constructor is deprecated: ${deprecated.join(
", "
)} environment variable is deprecated. Pass a custom log instance instead
)}. Pass a custom log instance instead:
import { Probot } from "probot";
import pino from "pino";

View File

@ -1,20 +1,32 @@
import Bottleneck from "bottleneck";
import Redis from "ioredis";
import type { Logger } from "pino";
import { Logger } from "pino";
import { Deprecation } from "deprecation";
type Options = {
log: Logger;
redisConfig?: Redis.RedisOptions;
redisConfig?: Redis.RedisOptions | string;
};
export function getOctokitThrottleOptions(options: Options) {
if (!options.redisConfig && !process.env.REDIS_URL) return;
let { log, redisConfig } = options;
if (!redisConfig && process.env.REDIS_URL) {
redisConfig = process.env.REDIS_URL;
log.warn(
new Deprecation(
`[probot] "REDIS_URL" is deprecated when using with the Probot constructor. Use "new Probot({ redisConfig: 'redis://...' })" instead`
)
);
}
if (!redisConfig) return;
const connection = new Bottleneck.IORedisConnection({
client: getRedisClient(options.redisConfig),
client: getRedisClient(options),
});
connection.on("error", (error) => {
options.log.error(Object.assign(error, { source: "bottleneck" }));
log.error(Object.assign(error, { source: "bottleneck" }));
});
return {
@ -23,7 +35,6 @@ export function getOctokitThrottleOptions(options: Options) {
};
}
function getRedisClient(redisConfig?: Redis.RedisOptions): Redis.Redis | void {
if (redisConfig) return new Redis(redisConfig);
if (process.env.REDIS_URL) return new Redis(process.env.REDIS_URL);
function getRedisClient({ log, redisConfig }: Options): Redis.Redis | void {
if (redisConfig) return new Redis(redisConfig as Redis.RedisOptions);
}

View File

@ -13,7 +13,7 @@ type Options = {
githubToken?: string;
appId?: number;
privateKey?: string;
redisConfig?: Redis.RedisOptions;
redisConfig?: Redis.RedisOptions | string;
throttleOptions?: any;
};

View File

@ -17,7 +17,7 @@ export interface Options {
id?: number;
Octokit?: typeof ProbotOctokit;
log?: Logger;
redisConfig?: Redis.RedisOptions;
redisConfig?: Redis.RedisOptions | string;
secret?: string;
webhookPath?: string;
logLevel?: "trace" | "debug" | "info" | "warn" | "error" | "fatal";

View File

@ -277,12 +277,25 @@ describe("Deprecations", () => {
probot.stop();
});
it("LOG_LEVEL and Probot constructor", () => {
it("LOG_LEVEL/LOG_FORMAT/LOG_LEVEL_IN_STRING/SENTRY_DSN and Probot constructor", () => {
process.env.LOG_LEVEL = "debug";
process.env.LOG_FORMAT = "pretty";
process.env.LOG_LEVEL_IN_STRING = "true";
process.env.SENTRY_DSN = "https://1234abcd@sentry.io/12345";
const probot = new Probot({});
// passing { log: pino(streamLogsToOutput) } disables the deprecation message,
// so this is just a reminder
expect(probot.log.level).toEqual("debug");
});
it("REDIS_URL and Probot construtor", () => {
process.env.REDIS_URL = "test";
new Probot({ log: pino(streamLogsToOutput) });
expect(output.length).toEqual(1);
expect(output[0].msg).toContain(
`[probot] "REDIS_URL" is deprecated when using with the Probot constructor. Use "new Probot({ redisConfig: 'redis://...' })" instead`
);
});
});

View File

@ -412,21 +412,14 @@ describe("Probot", () => {
});
});
describe("process.env.REDIS_URL", () => {
beforeEach(() => {
process.env.REDIS_URL = "test";
});
afterEach(() => {
delete process.env.REDIS_URL;
});
describe("options.redisConfig as string", () => {
it("sets throttleOptions", async () => {
expect.assertions(2);
probot = new Probot({
webhookPath: "/webhook",
githubToken: "faketoken",
redisConfig: "test",
Octokit: ProbotOctokit.plugin((octokit, options) => {
expect(options.throttle.Bottleneck).toBe(Bottleneck);
expect(options.throttle.connection).toBeInstanceOf(