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

[Issue #2819] disable ga in test #3001

Merged
merged 7 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions documentation/frontend/environments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
The Simpler Grants Next application is deployed and used in a number of environments. Here is how those environments, and the data required by each environment, are managed.

## General Things

Note that Next applications follow a set heirarchy for evaluating environment variable precedence, as noted [in documentation here](https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#environment-variable-load-order).

Secret environment variables, and others that should be controlled specifically based on deployed environment, are specified in terraform, which pulls them from SSM and sets them on the service definition, which passes them from the ECS task definition to the Next container. See [code referenced here](https://github.com/HHS/simpler-grants-gov/blob/main/infra/frontend/app-config/env-config/environment-variables.tf).

All environment variables referenced in the app should be handled in the [environments file here](https://github.com/HHS/simpler-grants-gov/blob/main/frontend/src/constants/environments.ts)].

## NODE_ENV

NextJS will set the Node `NODE_ENV` variable automatically depending on how you start the server.

- `next dev` - "development"
- `next build && next start` - "production"

Next hasn't documented this behavior super well - the best reference I can find is in [this discussion thread](https://github.com/vercel/next.js/discussions/13410#discussioncomment-18760).

This behavior means that, since we use `build & start` in all of our deployed environments and E2E test runs, we cannot use rely on `NODE_ENV` to give us a meaningful value about which environment the process is running in. To work around this, any environment variables that should be dependent on the deployed environment (ie "dev", "staging", "prod"), should likely be referenced as a secret from SSM as described above.

## Local

Environment variables are gathered from the .env.development file.

When running Next in a non-dockerized situation, variables are also pulled directly from your command line or environment. Ex. `API_URL=http://google.com next run dev`.

Since the .env.development file is tracked in git, any sensitive environment variables used for local development or testing - for example to connect to a non-dev API instance - **SHOULD NOT** be entered into this file, even temporarily. Instead, pass any necessary env vars directly from the command line or look into something like [direnv](https://direnv.net/).

## Test (and testing)

Unit testing by Jest is always done in the "test" environment by default. See [Jest's docs](https://jestjs.io/docs/environment-variables#node_env). As a result, all Jest runs will reference the .env.test or .env.local (which is used in CI).

E2E tests are run against a running Next server, so the environment used there is determined by the environment used on by whatever type of Next server is running.

In CI E2E tests use `npx playwright test`, which will run `next start` pointing at a production build of the application. To work aroudn this our CI code copies .env.development values into a .env.local file that will take precedence over .env.production. Note that NODE_ENV will still be set to "production".

See [our CI code](https://github.com/HHS/simpler-grants-gov/blob/1b85220c7369d40ab2f690050ece41be91c91b7f/.github/workflows/ci-frontend-e2e.yml#L58) for more details.

## Development / Staging / Production

Note that, as mentioned above, NODE_ENV will be set to "production" here due to use of `npm run build && npm start`.

As a result, environment variables are gathered from the .env.production file.
3 changes: 0 additions & 3 deletions frontend/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
# env vars when running `next dev` only.
# Learn more: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables

# This is used to determin if this is a prod or a non prod environment for deployed environments. Currently used for noindex and google tag manager logic
NEXT_PUBLIC_ENVIRONMENT=dev

# If you deploy to a subpath, change this to the subpath so relative paths work correctly.
NEXT_PUBLIC_BASE_PATH=

Expand Down
3 changes: 0 additions & 3 deletions frontend/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
# env vars when running `next dev` only.
# Learn more: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables

# This is used to determin if this is a prod or a non prod environment for deployed environments. Currently used for noindex and google tag manager logic
NEXT_PUBLIC_ENVIRONMENT=prod

# If you deploy to a subpath, change this to the subpath so relative paths work correctly.
NEXT_PUBLIC_BASE_PATH=

Expand Down
12 changes: 0 additions & 12 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@ COPY *.config.js .
COPY *.d.ts .
COPY src ./src

# Environment variables must be present at build time
# https://github.com/vercel/next.js/discussions/14030
# ARG ENV_VARIABLE
# ENV ENV_VARIABLE=${ENV_VARIABLE}
# ARG NEXT_PUBLIC_ENV_VARIABLE
# ENV NEXT_PUBLIC_ENV_VARIABLE=${NEXT_PUBLIC_ENV_VARIABLE}

ARG NEXT_PUBLIC_ENVIRONMENT
ENV NEXT_PUBLIC_ENVIRONMENT=${NEXT_PUBLIC_ENVIRONMENT}

ENV NEXT_TELEMETRY_DISABLED 1

# Skip lint because it should have happened in the CI already
Expand Down Expand Up @@ -117,8 +107,6 @@ ARG SENDY_API_URL
ENV SENDY_API_URL=${SENDY_API_URL}
ARG SENDY_LIST_ID
ENV SENDY_LIST_ID=${SENDY_LIST_ID}
ARG NEXT_PUBLIC_ENVIRONMENT
ENV NEXT_PUBLIC_ENVIRONMENT=${NEXT_PUBLIC_ENVIRONMENT}

ENV NEXT_TELEMETRY_DISABLED 1
ENV PORT 3000
Expand Down
3 changes: 0 additions & 3 deletions frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ endif
export RUN_USER
export RUN_UID

ENVIRONMENT ?= dev

##################################################
# Release
##################################################
Expand All @@ -33,7 +31,6 @@ release-build:
--platform=linux/amd64 \
--build-arg RUN_USER=$(RUN_USER) \
--build-arg RUN_UID=$(RUN_UID) \
--build-arg NEXT_PUBLIC_ENVIRONMENT=${ENVIRONMENT} \
$(OPTS) \
.

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GoogleAnalytics } from "@next/third-parties/google";
* @see https://nextjs.org/docs/app/api-reference/file-conventions/layout
*/
import { Metadata } from "next";
import { environment, PUBLIC_ENV } from "src/constants/environments";
import { environment } from "src/constants/environments";

import "src/styles/styles.scss";

Expand Down Expand Up @@ -43,7 +43,7 @@ export default async function LocaleLayout({ children, params }: Props) {
return (
<html lang={locale} suppressHydrationWarning>
<head>
<GoogleAnalytics gaId={PUBLIC_ENV.GOOGLE_ANALYTICS_ID} />
<GoogleAnalytics gaId={environment.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID} />
</head>
<body>
<NextIntlClientProvider messages={messages}>
Expand Down
28 changes: 5 additions & 23 deletions frontend/src/constants/environments.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
/**
* Define environment variables that you need exposed in the client-side bundle.
* These should not include sensitive secrets!
*/
const PUBLIC_ENV_VARS_BY_ENV = {
development: {
GOOGLE_ANALYTICS_ID: "G-GWJZD3DL8W",
},
test: {
GOOGLE_ANALYTICS_ID: "G-6MDCC5EZW2",
},
production: {
GOOGLE_ANALYTICS_ID: "G-6MDCC5EZW2",
},
} as const;

const NEXT_ENVS = ["development", "test", "production"] as const;
export type NextPublicAppEnv = (typeof NEXT_ENVS)[number];

const {
NODE_ENV,
NEXT_PUBLIC_BASE_PATH,
Expand All @@ -27,12 +8,12 @@ const {
API_URL,
API_AUTH_TOKEN = "",
NEXT_PUBLIC_BASE_URL,
// for deployed envs it will come from ECS task def env var
// it will not be populated locally, or in Jest or E2E tests
// if it is needed locally or tests, add it in .env.local or command line
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID = "",
} = process.env;

const CURRENT_ENV = NODE_ENV ?? "development";

export const PUBLIC_ENV = PUBLIC_ENV_VARS_BY_ENV[CURRENT_ENV];

// home for all interpreted server side environment variables
export const environment: { [key: string]: string } = {
LEGACY_HOST:
Expand All @@ -47,4 +28,5 @@ export const environment: { [key: string]: string } = {
API_URL: API_URL || "",
API_AUTH_TOKEN,
NEXT_PUBLIC_BASE_URL: NEXT_PUBLIC_BASE_URL || "http://localhost:3000",
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID,
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ locals {
API_AUTH_TOKEN = {
manage_method = "manual"
secret_store_name = "/${var.app_name}/${var.environment}/api-auth-token"
},
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID = {
manage_method = "manual"
secret_store_name = "/${var.app_name}/${var.environment}/google-analytics-id"
}
}
}