Skip to content

Commit

Permalink
fix(app): do not overwrite existing env variables (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasduteil authored Jul 18, 2024
1 parent 565d5df commit cc404f6
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 44 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#

AGENTCONNECT_OIDC_CLIENT_ID="____-____-____-____-____"
AGENTCONNECT_OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG="ES256"
AGENTCONNECT_OIDC_ISSUER="http://localhost:6100/api/v2"
AGENTCONNECT_OIDC_SCOPE="openid given_name usual_name email"
AGENTCONNECT_OIDC_SECRET_ID="________________________"
AGENTCONNECT_OIDC_USERINFO_SIGNED_RESPONSE_ALG="ES256"
ALLOWED_USERS="[email protected]"
API_AUTH_PASSWORD="________________________"
API_AUTH_URL="http://localhost:6300"
API_AUTH_USERNAME="________________________"
CONSOLA_LEVEL="4"
COOKIE_ENCRYPTION_KEY="password_at_least_32_characters_long"
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
ENTREPRISE_API_GOUV_TOKEN="____.____.____"
ENTREPRISE_API_GOUV_URL="http://localhost:6200"
HOST="https://hyyypertool-preprod.moncomptepro.beta.gouv.fr/proxy/localhost:3000"
SENTRY_DNS="https://[email protected]/____"
TZ="Europe/Paris"
ZAMMAD_TOKEN="____"
ZAMMAD_URL="https://support.etalab.gouv.fr"
29 changes: 3 additions & 26 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ jobs:
run:
working-directory: "e2e"

env:
MOCKED_APP_MONCOMPTEPRO_BETA_GOUV_FR: http://127.0.0.1:6300
MOCKED_AUTH_AGENTCONNECT_GOUV_FR: http://127.0.0.1:6100
MOCKED_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
MOCKED_ENTREPRISE_API_GOUV_URL: http://127.0.0.1:6200

steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
Expand All @@ -47,13 +41,13 @@ jobs:
run: |
docker compose ps
echo "Fake https://auth.agentconnect.gouv.fr"
curl -sSf -XGET ${{ env.MOCKED_AUTH_AGENTCONNECT_GOUV_FR }}/readyz
curl -sSf -XGET http://127.0.0.1:6100/readyz
echo
echo "Fake https://entreprise.api.gouv.fr ready"
curl -sSf -XGET ${{ env.MOCKED_ENTREPRISE_API_GOUV_URL }}/readyz
curl -sSf -XGET http://127.0.0.1:6200/readyz
echo
echo "Fake https://app.moncomptepro.beta.gouv.fr ready"
curl -sSf -XGET ${{ env.MOCKED_APP_MONCOMPTEPRO_BETA_GOUV_FR }}/readyz
curl -sSf -XGET http://127.0.0.1:6300/readyz
working-directory: "."

- name: cypress-io/github-action needs package-lock.json
Expand All @@ -63,24 +57,7 @@ jobs:
- name: Cypress run
uses: cypress-io/github-action@8d3918616d8ac34caa2b49afc8b408b6a872a6f5 # v6.7.1
env:
AGENTCONNECT_OIDC_CLIENT_ID: ${{ secrets.AGENTCONNECT_OIDC_CLIENT_ID }}
AGENTCONNECT_OIDC_ISSUER: "${{ env.MOCKED_AUTH_AGENTCONNECT_GOUV_FR }}/api/v2"
AGENTCONNECT_OIDC_SCOPE: "openid given_name usual_name email"
AGENTCONNECT_OIDC_SECRET_ID: ${{ secrets.AGENTCONNECT_OIDC_SECRET_ID }}
CONSOLA_LEVEL: "2"
ALLOWED_USERS: "[email protected]"
API_AUTH_PASSWORD: "???"
API_AUTH_URL: "${{ env.MOCKED_APP_MONCOMPTEPRO_BETA_GOUV_FR }}"
API_AUTH_USERNAME: "???"
DATABASE_URL: "${{ env.MOCKED_DATABASE_URL }}"
DO_NOT_SEND_MAIL: "true"
ENTREPRISE_API_GOUV_TOKEN: "???"
ENTREPRISE_API_GOUV_URL: "${{ env.MOCKED_ENTREPRISE_API_GOUV_URL }}"
HOST: "https://hyyypertool-preprod.moncomptepro.beta.gouv.fr/proxy/localhost:3000"
SENTRY_DNS: "https://[email protected]//XX"
TZ: "Europe/Paris"
ZAMMAD_TOKEN: "???"
ZAMMAD_URL: "https://support.etalab.gouv.fr"
DEPLOY_ENV: "production"
NODE_ENV: "development"
with:
Expand Down
2 changes: 1 addition & 1 deletion e2e/features/users/jean_bon.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ Fonctionnalité: Page utilisateur with moderations

# Scénario: Organisations de Raphael
Alors je vois "Jean est enregistré(e) dans les modérations suivantes :"
* je vois la ligne de table "11/11/2011 11:11:11 AM"
* je vois la ligne de table "11/11/2011 11:11:11"
7 changes: 4 additions & 3 deletions packages/~/app/core/src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { z } from "zod";
//

dotenv.config({
override: true,
path: [".env", ".env.local", `.env.${env["NODE_ENV"]}.local`],
path: [`.env.${process.env.NODE_ENV}.local`, ".env.local", ".env"],
});

const pkg = await import(join(cwd(), "package.json"));
Expand Down Expand Up @@ -61,7 +60,9 @@ export const app_env = z.object({
ENTREPRISE_API_GOUV_URL: z.string().trim().url(),
GIT_SHA: GIT_SHA_SHEMA,
HOST: z.string().trim().url().optional(),
NODE_ENV: z.enum(["development", "production"]).default("development"),
NODE_ENV: z
.enum(["development", "production", "test"])
.default("development"),
PORT: z.coerce.number().default(3000),
SENTRY_DNS: z.string().trim().url().optional(),
VERSION: z.string().default(
Expand Down
81 changes: 81 additions & 0 deletions packages/~/app/middleware/src/set_config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//

import { expect, mock, test } from "bun:test";
import { Hono } from "hono";
import { ZodError } from "zod";
import { parse } from "dotenv";
import { readFile } from "node:fs/promises";
import { set_config } from "./set_config";

//

const default_dotenv = parse(await readFile(".env", { encoding: "utf8" }));

test("should set config", async () => {
const app = new Hono().get(
"/",
set_config(),
async ({ json, var: { config } }) => {
return json(config);
},
);

const res = await app.request("/");

expect(res.status).toBe(200);
expect(await res.json()).toEqual(
expect.objectContaining({
PUBLIC_ASSETS_PATH: expect.stringContaining("/public/built"),
ASSETS_PATH: expect.stringContaining("/assets/"),
DEPLOY_ENV: "preview",
NODE_ENV: "test",
PORT: 3000,
}),
);
});

test("❌ bubble missing env variable", async () => {
mock.module("hono/adapter", () => {
return {
env: () => ({ ...default_dotenv, NODE_ENV: "🌵" }),
};
});

const app = new Hono()
.get("/", set_config(), async ({ json, var: { config } }) => {
return json(config);
})
.onError((e) => {
throw e;
});

expect(async () => {
await app.request("/");
}).toThrow(
new ZodError([
{
received: "🌵",
code: "invalid_enum_value",
options: ["development", "production", "test"],
path: ["env", "NODE_ENV"],
message:
"Invalid enum value. Expected 'development' | 'production' | 'test', received '🌵'",
},
]),
);
});

test("should set mocked config", async () => {
const app = new Hono().get(
"/",
set_config({ VERSION: "🧌" }),
async ({ json, var: { config } }) => {
return json(config);
},
);

const res = await app.request("/");

expect(res.status).toBe(200);
expect(await res.json()).toEqual({ VERSION: "🧌" });
});
15 changes: 5 additions & 10 deletions packages/~/app/middleware/src/set_config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//

import type { App_Config } from "@~/app.core/config";
import dotenv from "dotenv";
import { app_env } from "@~/app.core/config/env";
import type { Env, MiddlewareHandler } from "hono";
import { env } from "node:process";
import { env } from "hono/adapter";

//

Expand All @@ -17,14 +17,9 @@ export function set_config(
};
}

dotenv.config({
override: true,
path: [".env", ".env.local", `.env.${env.NODE_ENV}.local`],
});

return async function set_config_middleware({ set }, next) {
const { app_env } = await import("@~/app.core/config/env");
const app_config = app_env.parse(env, {
return async function set_config_middleware(c, next) {
const { set } = c;
const app_config = app_env.parse(env(c), {
path: ["env"],
});
const ASSETS_PATH = `/assets/${app_config.VERSION}` as const;
Expand Down
6 changes: 3 additions & 3 deletions packages/~/users/api/src/:id/moderations/ModerationTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//

import { LocalTime } from "@~/app.ui/time/LocalTime";
import { row } from "@~/app.ui/table";
import { urls } from "@~/app.urls";
import { moderation_type_to_emoji } from "@~/moderations.lib/moderation_type.mapper";
Expand Down Expand Up @@ -53,9 +54,8 @@ export function ModerationTable({
)
.when(
() => name === "created_at",
(value: string): string => {
const date = new Date(value);
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
(value: string) => {
return <LocalTime date={value}></LocalTime>;
},
)
.otherwise((value) => value)}
Expand Down

0 comments on commit cc404f6

Please sign in to comment.