Skip to content

Commit

Permalink
[GM-833] Add support for APOLLO_KEY; deprecate ENGINE_API_KEY (#1851)
Browse files Browse the repository at this point in the history
* Support APOLLO_KEY, deprecate ENGINE_API_KEY

This supports a more modern name for the API key and adds deprecation
messages for the (now legacy) ENGINE_API_KEY. Much in the same spirit
as #1849, the goal
is to modernize our documentation to no longer use the out-of-date name
"engine". This also modifies tests to support the new version and adds a
test that ensures an error is thrown when a user sets _both_ keys.
  • Loading branch information
zionts authored Mar 30, 2020
1 parent 626fbae commit fe1ec25
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Upcoming

- `apollo`
- https://github.com/apollographql/apollo-tooling/pull/1851
- Support APOLLO_KEY and deprecate ENGINE_API_KEY for .env support
- https://github.com/apollographql/apollo-tooling/pull/1849
- Update all commands that supported --tag to prefer --variant and indicate a deprecation warning for --tag
- All usages of --tag will continue to work
Expand Down
48 changes: 41 additions & 7 deletions packages/apollo-language-server/src/config/__tests__/loadConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DefaultServiceConfig,
DefaultEngineConfig
} from "../config";
import { Debug } from "../../utilities";

const makeNestedDir = dir => {
if (fs.existsSync(dir)) return;
Expand Down Expand Up @@ -279,7 +280,7 @@ describe("loadConfig", () => {
it("finds .env in config path & parses for key", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env": `ENGINE_API_KEY=service:harambe:54378950jn`
".env": `APOLLO_KEY=service:harambe:54378950jn`
});

const config = await loadConfig({
Expand All @@ -293,7 +294,7 @@ describe("loadConfig", () => {
it("finds .env.local in config path & parses for key", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env.local": `ENGINE_API_KEY=service:harambe:54378950jn`
".env.local": `APOLLO_KEY=service:harambe:54378950jn`
});

const config = await loadConfig({
Expand All @@ -307,23 +308,56 @@ describe("loadConfig", () => {
it("finds .env and .env.local in config path & parses for key, preferring .env.local", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env": `ENGINE_API_KEY=service:hamato:54378950jn`,
".env": `APOLLO_KEY=service:hamato:54378950jn`,
".env.local": `APOLLO_KEY=service:yoshi:65489061ko`
});

const config = await loadConfig({
configPath: dirPath,
configFileName: "my.config.js"
});

expect(config.client.service).toEqual("yoshi");
});

it("Allows setting ENGINE_API_KEY with a deprecation warning", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env.local": `ENGINE_API_KEY=service:yoshi:65489061ko`
});

const spy = jest.spyOn(Debug, "warning");

const config = await loadConfig({
configPath: dirPath,
configFileName: "my.config.js"
});

expect(config.client.service).toEqual("yoshi");
expect(spy).toHaveBeenCalledWith(
expect.stringMatching(/Deprecation warning/i)
);
});

it("Throws when .env defined legacy and new key", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env.local": `ENGINE_API_KEY=service:yoshi:65489061ko\nAPOLLO_KEY=service:yoshi:65489061ko`
});

const loadConfigPromise = loadConfig({
configPath: dirPath,
configFileName: "my.config.js"
});

await expect(loadConfigPromise).rejects.toThrow(/Cannot set both/);
});

// this doesn't work right now :)
xit("finds .env in cwd & parses for key", async () => {
writeFilesToDir(dir, {
"dir/my.config.js": `module.exports = { client: { name: 'hello' } }`,
".env": `ENGINE_API_KEY=service:harambe:54378950jn`
".env": `APOLLO_KEY=service:harambe:54378950jn`
});
process.chdir(dir);
const config = await loadConfig({
Expand Down Expand Up @@ -382,7 +416,7 @@ describe("loadConfig", () => {
it("lets config service name take precedence for client project", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { service: 'hello' } }`,
".env": `ENGINE_API_KEY=service:harambe:54378950jn`
".env": `APOLLO_KEY=service:harambe:54378950jn`
});

const config = await loadConfig({
Expand All @@ -397,7 +431,7 @@ describe("loadConfig", () => {
it("lets name passed in take precedence over env var", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { } }`,
".env": `ENGINE_API_KEY=service:harambe:54378950jn`
".env": `APOLLO_KEY=service:harambe:54378950jn`
});

const config = await loadConfig({
Expand All @@ -412,7 +446,7 @@ describe("loadConfig", () => {
it("uses env var to determine service name when no other options", async () => {
writeFilesToDir(dir, {
"my.config.js": `module.exports = { client: { } }`,
".env": `ENGINE_API_KEY=service:harambe:54378950jn`
".env": `APOLLO_KEY=service:harambe:54378950jn`
});

const config = await loadConfig({
Expand Down
17 changes: 15 additions & 2 deletions packages/apollo-language-server/src/config/loadConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ const loaders = {
}
};

export const legacyKeyEnvVar = "ENGINE_API_KEY";
export const keyEnvVar = "APOLLO_KEY";

export interface LoadConfigSettings {
// the current working directory to start looking for the config
// config loading only works on node so we default to
Expand Down Expand Up @@ -123,9 +126,19 @@ export async function loadConfig({
const env: { [key: string]: string } = require("dotenv").parse(
readFileSync(dotEnvPath)
);
if (env["ENGINE_API_KEY"]) {
apiKey = env["ENGINE_API_KEY"];
const legacyKey = env[legacyKeyEnvVar];
const key = env[keyEnvVar];
if (legacyKey && key) {
throw new Error(
`Cannot set both ${legacyKeyEnvVar} and ${keyEnvVar}. Please only set ${keyEnvVar}`
);
}
if (legacyKey) {
Debug.warning(
`[Deprecation warning] Setting the key via ${legacyKeyEnvVar} is deprecated and will not be supported in future versions.`
);
}
apiKey = key || legacyKey;
}
});

Expand Down
4 changes: 2 additions & 2 deletions packages/apollo-language-server/src/project/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { GraphQLDocument, extractGraphQLDocuments } from "../document";

import { LoadingHandler } from "../loadingHandler";
import { FileSet } from "../fileSet";
import { ApolloConfig } from "../config";
import { ApolloConfig, keyEnvVar } from "../config";
import {
schemaProviderFromConfig,
GraphQLSchemaProvider,
Expand Down Expand Up @@ -136,7 +136,7 @@ export abstract class GraphQLProject implements GraphQLSchemaProvider {
// handle error states for missing engine config
// all in the same place :tada:
if (!this.engineClient) {
throw new Error("Unable to find ENGINE_API_KEY");
throw new Error(`Unable to find ${keyEnvVar}`);
}
return this.engineClient!;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NotificationHandler } from "vscode-languageserver";
import gql from "graphql-tag";
import { GraphQLSchema, buildClientSchema } from "graphql";
import { ApolloEngineClient, ClientIdentity } from "../../engine";
import { ClientConfig, parseServiceSpecifier } from "../../config";
import { ClientConfig, keyEnvVar, parseServiceSpecifier } from "../../config";
import { getServiceFromKey, isServiceKey } from "../../config";
import {
GraphQLSchemaProvider,
Expand Down Expand Up @@ -36,7 +36,9 @@ export class EngineSchemaProvider implements GraphQLSchemaProvider {
// create engine client
if (!this.client) {
if (!engine.apiKey) {
throw new Error("ENGINE_API_KEY not found");
throw new Error(
`No API key found. Please set ${keyEnvVar} or use --key`
);
}
this.client = new ApolloEngineClient(
engine.apiKey,
Expand Down
2 changes: 1 addition & 1 deletion packages/apollo/src/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export abstract class ProjectCommand extends Command {
key: flags.string({
description:
"The API key to use for authentication to Apollo Graph Manager",
default: () => process.env.ENGINE_API_KEY
default: () => process.env.APOLLO_KEY || process.env.ENGINE_API_KEY
}),
engine: flags.string({
description: "URL for a custom Apollo Graph Manager deployment",
Expand Down
20 changes: 10 additions & 10 deletions packages/apollo/src/commands/client/__tests__/check.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it("is turned on after summit", () => {});

// import { fs as mockFS, vol } from "apollo-codegen-core/lib/localfs";
// const test = setup.do(() => mockConsole());
// const ENGINE_API_KEY = "service:test:1234";
// const APOLLO_KEY = "service:test:1234";
// const hash = "12345";

// const dummyOperations = [
Expand All @@ -26,7 +26,7 @@ it("is turned on after summit", () => {});

// const engineSuccess = ({ operations, tag, results } = {}) => nock => {
// nock
// .matchHeader("x-api-key", ENGINE_API_KEY)
// .matchHeader("x-api-key", APOLLO_KEY)
// .post("/", {
// operationName: "CheckOperations",
// variables: {
Expand Down Expand Up @@ -85,7 +85,7 @@ it("is turned on after summit", () => {});
// test
// .do(() => vol.fromJSON(files))
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["queries:check"])
// .exit(1)
Expand All @@ -103,7 +103,7 @@ it("is turned on after summit", () => {});
// "apollo": {
// "schemas": {
// "default": {
// "engineKey": "${ENGINE_API_KEY}"
// "engineKey": "${APOLLO_KEY}"
// }
// }
// }
Expand Down Expand Up @@ -132,7 +132,7 @@ it("is turned on after summit", () => {});
// "apollo": {
// "schemas": {
// "default": {
// "engineKey": "${ENGINE_API_KEY}"
// "engineKey": "${APOLLO_KEY}"
// }
// }
// }
Expand All @@ -156,7 +156,7 @@ it("is turned on after summit", () => {});
// .do(() => vol.fromJSON(files))
// .nock(ENGINE_URI, engineSuccess())
// .stdout()
// .command(["queries:check", `--key=${ENGINE_API_KEY}`])
// .command(["queries:check", `--key=${APOLLO_KEY}`])
// .exit(1)
// .it("allows custom api key", () => {
// expect(stdout).toContain("FAILURE");
Expand All @@ -166,7 +166,7 @@ it("is turned on after summit", () => {});
// test
// .do(() => vol.fromJSON(files))
// .nock(ENGINE_URI, engineSuccess({ results: [] }))
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["queries:check"])
// .it(
Expand All @@ -187,7 +187,7 @@ it("is turned on after summit", () => {});
// vol.fromJSON(nested);
// })
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["queries:check", "--queries=./client/*.graphql"])
// .exit(1)
Expand All @@ -203,7 +203,7 @@ it("is turned on after summit", () => {});
// "https://engine.example.com",
// engineSuccess({ engine: "https://engine.example.com" })
// )
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command(["queries:check", "--engine=https://engine.example.com"])
// .exit(1)
// .it("compares against a schema from a custom registry", std => {
Expand All @@ -214,7 +214,7 @@ it("is turned on after summit", () => {});
// test
// .do(() => vol.fromJSON(files))
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["queries:check", "--json"])
// .exit(1)
Expand Down
22 changes: 11 additions & 11 deletions packages/apollo/src/commands/service/__tests__/check.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ describe("service:check", () => {
// import { vol, fs as mockFS } from "apollo-codegen-core/lib/localfs";

// const test = setup.do(() => captureApplicationOutput());
// const ENGINE_API_KEY = "service:test:1234";
// const APOLLO_KEY = "service:test:1234";
// const hash = "12345";
// const schemaContents = fs.readFileSync(
// path.resolve(__dirname, "./fixtures/schema.graphql"),
Expand All @@ -874,7 +874,7 @@ describe("service:check", () => {

// const engineSuccess = ({ schema, tag, results } = {}) => nock => {
// nock
// .matchHeader("x-api-key", ENGINE_API_KEY)
// .matchHeader("x-api-key", APOLLO_KEY)
// .post("/", {
// operationName: "CheckSchema",
// variables: {
Expand Down Expand Up @@ -936,7 +936,7 @@ describe("service:check", () => {
// test
// .nock("http://localhost:4000", localSuccess)
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["schema:check"])
// .exit(1)
Expand All @@ -950,7 +950,7 @@ describe("service:check", () => {
// .nock("http://localhost:4000", localSuccess)
// .nock(ENGINE_URI, engineSuccess())
// .stdout()
// .command(["schema:check", `--key=${ENGINE_API_KEY}`])
// .command(["schema:check", `--key=${APOLLO_KEY}`])
// .exit(1)
// .it("allows custom api key", () => {
// expect(stdout).toContain("FAILURE");
Expand All @@ -961,7 +961,7 @@ describe("service:check", () => {
// test
// .nock("http://localhost:4000", localSuccess)
// .nock(ENGINE_URI, engineSuccess({ results: [] }))
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["schema:check"])
// .it(
Expand All @@ -975,7 +975,7 @@ describe("service:check", () => {
// .stdout()
// .nock("https://staging.example.com", localSuccess)
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command(["schema:check", "--endpoint=https://staging.example.com/graphql"])
// .exit(1)
// .it("compares against a schema from a custom remote", () => {
Expand All @@ -991,7 +991,7 @@ describe("service:check", () => {
// "https://engine.example.com",
// engineSuccess({ engine: "https://engine.example.com" })
// )
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command(["schema:check", "--engine=https://engine.example.com"])
// .exit(1)
// .it("compares against a schema from a custom registry", std => {
Expand All @@ -1014,7 +1014,7 @@ describe("service:check", () => {
// .reply(200, { data: fullSchema });
// })
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command([
// "schema:check",
// "--endpoint=https://staging.example.com/graphql",
Expand All @@ -1039,7 +1039,7 @@ describe("service:check", () => {
// )
// .stdout()
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command(["schema:check", "--endpoint=introspection-result.json"])
// .exit(1)
// .it(
Expand All @@ -1059,7 +1059,7 @@ describe("service:check", () => {
// )
// .stdout()
// .nock(ENGINE_URI, engineSuccess({ schema: fullSchema.__schema }))
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .command(["schema:check", "--endpoint=schema.graphql"])
// .exit(1)
// .it(
Expand All @@ -1074,7 +1074,7 @@ describe("service:check", () => {
// test
// .nock("http://localhost:4000", localSuccess)
// .nock(ENGINE_URI, engineSuccess())
// .env({ ENGINE_API_KEY })
// .env({ APOLLO_KEY })
// .stdout()
// .command(["schema:check", "--json"])
// .exit(1)
Expand Down
Loading

0 comments on commit fe1ec25

Please sign in to comment.