Skip to content

Commit 607b433

Browse files
committed
CI/CD necessary variable checks:
Added a check in CI/CD environments for `account_id`, `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`. If `account_id` exists in `wrangler.toml` then `CLOUDFLARE_ACCOUNT_ID` is not needed in CI/CD scope. The `CLOUDFLARE_API_TOKEN` is necessary in CI/CD scope and will always error if missing. resolves #827
1 parent 0c582be commit 607b433

File tree

6 files changed

+137
-3
lines changed

6 files changed

+137
-3
lines changed

.changeset/eighty-yaks-jump.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
feat: Added a check in CI/CD environments for `account_id`, `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN`. If `account_id` exists in `wrangler.toml`
6+
then `CLOUDFLARE_ACCOUNT_ID` is not needed in CI/CD scope. The `CLOUDFLARE_API_TOKEN` is necessary in CI/CD scope and will always error if missing.
7+
8+
resolves #827

package-lock.json

+7-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/wrangler/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@types/ws": "^8.5.3",
6363
"@types/yargs": "^17.0.10",
6464
"chokidar": "^3.5.3",
65+
"ci-info": "^3.3.0",
6566
"clipboardy": "^3.0.0",
6667
"cmd-shim": "^4.1.0",
6768
"command-exists": "^1.2.9",
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import ci from "ci-info";
2+
import { mockConsoleMethods } from "./helpers/mock-console";
3+
import { runInTempDir } from "./helpers/run-in-tmp";
4+
import { runWrangler } from "./helpers/run-wrangler";
5+
import writeWranglerToml from "./helpers/write-wrangler-toml";
6+
7+
const std = mockConsoleMethods();
8+
void std; // Keeps the console quiet
9+
runInTempDir();
10+
11+
const ENV_COPY = process.env;
12+
13+
beforeEach(() => {
14+
jest.resetModules();
15+
jest.mock("ci-info");
16+
(ci.isCI as jest.Mocked<boolean>) = true;
17+
});
18+
19+
afterEach(() => {
20+
process.env = ENV_COPY;
21+
});
22+
23+
afterAll(() => {
24+
jest.unmock("ci-info");
25+
});
26+
27+
it("should not throw an error in CI if 'CLOUDFLARE_API_TOKEN' & 'account_id' are in scope", async () => {
28+
writeWranglerToml({
29+
account_id: "IG-88",
30+
});
31+
32+
process.env = {
33+
CLOUDFLARE_API_TOKEN: "123456789",
34+
};
35+
36+
await runWrangler().catch((err) => {
37+
expect(err).toMatchInlineSnapshot(`""`);
38+
});
39+
});
40+
41+
it("should not throw an error if 'CLOUDFLARE_ACCOUNT_ID' & 'CLOUDFLARE_API_TOKEN' are in scope", async () => {
42+
process.env = {
43+
CLOUDFLARE_API_TOKEN: "hunter2",
44+
CLOUDFLARE_ACCOUNT_ID: "IG-88",
45+
};
46+
47+
await runWrangler().catch((err) => {
48+
expect(err).toMatchInlineSnapshot(`""`);
49+
});
50+
});
51+
52+
it("should throw an error in CI if 'account_id' & 'CLOUDFLARE_ACCOUNT_ID' is missing", async () => {
53+
writeWranglerToml({
54+
account_id: undefined,
55+
});
56+
57+
process.env = {
58+
CLOUDFLARE_API_TOKEN: "hunter2",
59+
CLOUDFLARE_ACCOUNT_ID: undefined,
60+
};
61+
62+
await runWrangler().catch((err) => {
63+
expect(err).toMatchInlineSnapshot(
64+
`[Error: Missing "account_id" from "wrangler.toml" and "CLOUDFLARE_ACCOUNT_ID" from CI environment, one is required, please see docs for more info: TBD]`
65+
);
66+
});
67+
});
68+
69+
it("should throw error in CI if 'CLOUDFLARE_API_TOKEN' is missing", async () => {
70+
writeWranglerToml({
71+
account_id: undefined,
72+
});
73+
74+
process.env = {
75+
CLOUDFLARE_API_TOKEN: undefined,
76+
CLOUDFLARE_ACCOUNT_ID: "badwolf",
77+
};
78+
await runWrangler().catch((err) => {
79+
expect(err).toMatchInlineSnapshot(
80+
`[Error: Missing "CLOUDFLARE_API_TOKEN" from CI environment, please see docs for more info: TBD]`
81+
);
82+
});
83+
});
84+
85+
it("should throw errors in CI if 'CLOUDFLARE_API_TOKEN', 'account_id' & 'CLOUDFLARE_ACCOUNT_ID is missing", async () => {
86+
await runWrangler().catch((err) => {
87+
expect(err).toMatchInlineSnapshot(
88+
`[Error: Missing "account_id" from "wrangler.toml" and "CLOUDFLARE_ACCOUNT_ID" "CLOUDFLARE_API_TOKEN" from CI environment, please see docs for more info: TBD]`
89+
);
90+
});
91+
});

packages/wrangler/src/index.tsx

+27
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import path from "node:path";
44
import { setTimeout } from "node:timers/promises";
55
import TOML from "@iarna/toml";
66
import chalk from "chalk";
7+
import ci from "ci-info";
78
import { findUp } from "find-up";
89
import getPort from "get-port";
910
import { render } from "ink";
@@ -203,6 +204,32 @@ function demandOneOfOption(...options: string[]) {
203204
class CommandLineArgsError extends Error {}
204205

205206
export async function main(argv: string[]): Promise<void> {
207+
if (ci.isCI) {
208+
const config = readConfig(undefined, {});
209+
210+
if (
211+
!process.env.CLOUDFLARE_API_TOKEN &&
212+
!config.account_id &&
213+
!process.env.CLOUDFLARE_ACCOUNT_ID
214+
) {
215+
throw new Error(
216+
`Missing "account_id" from "wrangler.toml" and "CLOUDFLARE_ACCOUNT_ID" "CLOUDFLARE_API_TOKEN" from CI environment, please see docs for more info: TBD`
217+
);
218+
}
219+
220+
if (!process.env.CLOUDFLARE_API_TOKEN) {
221+
throw new Error(
222+
`Missing "CLOUDFLARE_API_TOKEN" from CI environment, please see docs for more info: TBD`
223+
);
224+
}
225+
226+
if (!config.account_id && !process.env.CLOUDFLARE_ACCOUNT_ID) {
227+
throw new Error(
228+
`Missing "account_id" from "wrangler.toml" and "CLOUDFLARE_ACCOUNT_ID" from CI environment, one is required, please see docs for more info: TBD`
229+
);
230+
}
231+
}
232+
206233
const wrangler = makeCLI(argv)
207234
.strict()
208235
// We handle errors ourselves in a try-catch around `yargs.parse`.

packages/wrangler/src/reporting.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
Integrations,
1212
setContext,
1313
} from "@sentry/node";
14+
import ci from "ci-info";
1415
import { execaSync } from "execa";
1516
import prompts from "prompts";
1617
import * as pkj from "../package.json";
@@ -92,7 +93,8 @@ function exceptionTransaction(error: Error, origin = "") {
9293
}
9394

9495
export async function reportError(err: Error, origin = "") {
95-
if (!process.stdout.isTTY) return await appendReportingDecision("false");
96+
// If the user has not opted in to error reporting, we don't want to do anything in CI or non-interactive environments
97+
if (!process.stdout.isTTY || ci.isCI) return;
9698

9799
const errorTrackingOpt = await reportingPermission();
98100

0 commit comments

Comments
 (0)