Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

non-TTY required variables checks #852

Merged
merged 2 commits into from
May 4, 2022
Merged

non-TTY required variables checks #852

merged 2 commits into from
May 4, 2022

Conversation

JacobMGEvans
Copy link
Contributor

@JacobMGEvans JacobMGEvans commented Apr 26, 2022

Added a check in non-TTY 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 non-TTY scope. The CLOUDFLARE_API_TOKEN is necessary in non-TTY scope and will always error if missing.

resolves #827

@JacobMGEvans JacobMGEvans added the polish Small improvements to the experience label Apr 26, 2022
@changeset-bot
Copy link

changeset-bot bot commented Apr 26, 2022

🦋 Changeset detected

Latest commit: 40a5f50

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
wrangler Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Apr 26, 2022

A wrangler prerelease is available for testing. You can install this latest build in your project with:

npm install --save-dev https://prerelease-registry.developers.workers.dev/runs/2271600192/npm-package-wrangler-852

You can reference the automatically updated head of this PR with:

npm install --save-dev https://prerelease-registry.developers.workers.dev/prs/852/npm-package-wrangler-852

Or you can use npx with this latest build directly:

npx https://prerelease-registry.developers.workers.dev/runs/2271600192/npm-package-wrangler-852 dev path/to/script.js

@JacobMGEvans JacobMGEvans force-pushed the ci-variable-checks branch 2 times, most recently from 927fa20 to f3f6e6c Compare April 26, 2022 19:00
Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a better way to do this, which is to only throw the error when request. (So, inside getAccountId and getAPIToken. I'm on phone so I can't remember function names exactly). This would also remove any checks for test environments and such.

@JacobMGEvans JacobMGEvans force-pushed the ci-variable-checks branch 3 times, most recently from 1ab1306 to afa1b39 Compare April 26, 2022 19:51
@JacobMGEvans JacobMGEvans changed the title CI/CD necessary variable checks CI/CD required variables checks Apr 26, 2022
@@ -21,10 +22,13 @@ describe("Error Reporting", () => {
jest.mock("@sentry/node");
jest.spyOn(Sentry, "captureException");
process.stdout.isTTY = true;
jest.mock("ci-info");
(ci.isCI as jest.Mocked<boolean>) = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ciCheck function doesn't make sense to modify to handle this use case, directly mocking ci-info
Alternatively we can make a simple wrapper function that is just returns a boolean from, ci.isCI


expect(error_tracking_opt).toBe(false);
expect(error_tracking_opt_date).toBeTruthy();
it("should not prompt in CI/CD environment", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added additional test that handles the change in reporting.ts that checks if its TTY or CI and does nothing now.

Cc: @petebacondarwin

Comment on lines 138 to 140
expect(
fs.existsSync(path.join(os.homedir(), reportingTOMLPath, "utf-8"))
).toBe(false);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to reporting does nothing if in a TTY or CI environment, test reflects that by confirming no Reporting TOML is created.

Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's looking good, marking as blocking so I can test it myself before we land it. thank you @JacobMGEvans!

Copy link
Contributor

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this new ciCheck() we are kind of reproducing work already done in user.tsx.

getAPIToken() and getAccountId() can already handle non-interactive cases, so I think we should just update those to throw errors rather than returning undefined if in non-TTY mode.

For example:

export function getAPIToken(): string | undefined {
  if (LocalState.apiToken) {
    logger.warn(
      "It looks like you have used Wrangler 1's `config` command to login with an API token.\n" +
        "This is no longer supported in the current version of Wrangler.\n" +
        "If you wish to authenticate via an API token then please set the `CLOUDFLARE_API_TOKEN` environment variable."
    );
  }
  if (process.stdin.isTTY) {
    return LocalState.accessToken?.value;
  } else {
    throw new Error(...);
  }
}

and

export async function getAccountId(
  isInteractive = true
): Promise<string | undefined> {
  const apiToken = getAPIToken();
  if (!apiToken) return;

  const accountIdFromEnv = getCloudflareAccountIdFromEnv();
  if (accountIdFromEnv) {
    return accountIdFromEnv;
  } else if (!isInteractive) {
    throw new Error(...);
  }
  ...

packages/wrangler/src/__tests__/ci.test.ts Outdated Show resolved Hide resolved
packages/wrangler/src/ci-check.ts Outdated Show resolved Hide resolved
packages/wrangler/src/ci-check.ts Outdated Show resolved Hide resolved
@JacobMGEvans
Copy link
Contributor Author

JacobMGEvans commented Apr 28, 2022

In this new ciCheck() we are kind of reproducing work already done in user.tsx.

getAPIToken() and getAccountId() can already handle non-interactive cases, so I think we should just update those to throw errors rather than returning undefined if in non-TTY mode.

For example: See quoted message

I don't see the reproducing of work, I can see the value of co-locating the checks, control logic, within the getAccountId and getAPIToken functions rather than having a function that handles checks for both functions and their error handling. My only concern would be mocking the isTTY check in tests throughout except for ci.test?

@caass
Copy link
Contributor

caass commented Apr 28, 2022

I'm confused -- the issue we're trying to close with this PR is that we should enforce the use of an api token via environment variable when in CI, right? So then why are we checking process.stdout.isTTY? That can be false for a variety of reasons, e.g. we're running tests, a user is piping output to another command, etc. I feel like if the issue is one of CI, it makes sense to use something like is-ci (or at the very least, checking process.env.CI)

@JacobMGEvans JacobMGEvans force-pushed the ci-variable-checks branch 2 times, most recently from a3c07af to a3757e9 Compare May 2, 2022 19:33
@JacobMGEvans JacobMGEvans changed the title CI/CD required variables checks non-TTY required variables checks May 2, 2022
Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is missing checks for CLOUDFLARE_ACCOUNT_ID the way it's doing it for API_TOKEN. Did you plan on doing that in a later PR?

packages/wrangler/src/__tests__/publish.test.ts Outdated Show resolved Hide resolved
.toMatchInlineSnapshot(`
[Error: More than one account available but unable to select one in non-interactive mode.
Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
Available accounts are ("<name>" - "<id>"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the message shouldn't be to set the account_id in the toml file, but to prefer setting the CLOUDFLARE_ACCOUNT_ID env var. I also think you can suggest running wrangler whoami to get the account id value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps suggest both options?

@JacobMGEvans JacobMGEvans force-pushed the ci-variable-checks branch 3 times, most recently from 6c3a0e4 to ce9db80 Compare May 4, 2022 16:21
packages/wrangler/src/user.tsx Outdated Show resolved Hide resolved
packages/wrangler/src/user.tsx Outdated Show resolved Hide resolved
Added a check in non-TTY 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 non-TTY scope. The `CLOUDFLARE_API_TOKEN` is necessary in non-TTY scope and will always error if missing.

resolves #827
@JacobMGEvans JacobMGEvans force-pushed the ci-variable-checks branch 4 times, most recently from 16b92d5 to dca0292 Compare May 4, 2022 18:02
Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's getting close! one last note regarding a user without any accounts

@@ -169,10 +171,14 @@ describe("wrangler secret", () => {
mockAccountId({ accountId: null });

it("should error if a user has no account", async () => {
mockGetMemberships({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will ever happen. If a user has no account, then the api will throw a 10000 error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can reproduce this locally with a garbage invalid token.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a preexisting test, I just updated to using a new mock for consistency.

Copy link
Contributor

@threepointone threepointone May 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exisitng test had the right error message tho, this isn't the right mock. It will never return a list with zero memberships.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh hmm I see. Aight never mind then.

await expect(
runWrangler("secret put the-key --name script-name")
).rejects.toThrowErrorMatchingInlineSnapshot(
`"No account id found, quitting..."`
`"Failed to automatically retrieve account IDs for the logged in user. In a non-interactive environment, it is mandatory to specify an account ID, either by assigning its value to CLOUDFLARE_ACCOUNT_ID, or as \`account_id\` in your \`wrangler.toml\` file."`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which will make this error be "No account id found, quitting..."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is occuring in a "non-TTY" block

packages/wrangler/src/__tests__/publish.test.ts Outdated Show resolved Hide resolved
.toMatchInlineSnapshot(`
[Error: More than one account available but unable to select one in non-interactive mode.
Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
Available accounts are ("<name>" - "<id>"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps suggest both options?

Added a check in non-TTY 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 non-TTY scope. The `CLOUDFLARE_API_TOKEN` is necessary in non-TTY scope and will always error if missing.

resolves #827
Copy link
Contributor

@threepointone threepointone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's land it and try this out.

@JacobMGEvans JacobMGEvans merged commit 6283ad5 into main May 4, 2022
@JacobMGEvans JacobMGEvans deleted the ci-variable-checks branch May 4, 2022 18:39
@github-actions github-actions bot mentioned this pull request May 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
polish Small improvements to the experience
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Throw an error if running inside github actions without CLOUDFLARE_API_TOKEN
4 participants