Skip to content

Commit 36e04eb

Browse files
authored
Create a mechanism to fail the CD when required environment variables are missing | issue#257 - 2 (#285)
* issue#257 | Madge changes to fail CD when required env are missing * use loadEnv method in register.ts * rename to env in register.ts * renamed env in inedx.ts * renamed variables * removed unnecessary comments * removed redundant comments * fixed code format * format fix
1 parent bd4d987 commit 36e04eb

File tree

7 files changed

+131
-13
lines changed

7 files changed

+131
-13
lines changed

.github/workflows/register-commands-production.yaml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,36 @@ on:
33
push:
44
branches: main
55
jobs:
6+
Environment-Variables-Check:
7+
runs-on: ubuntu-latest
8+
environment: production
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: actions/setup-node@v4
12+
with:
13+
node-version: 18.18.2
14+
- run: npm install
15+
- run: npm run env-var-check
16+
env:
17+
CURRENT_ENVIRONMENT: production
18+
DISCORD_APPLICATION_ID: ${{secrets.DISCORD_APPLICATION_ID}}
19+
DISCORD_GUILD_ID: ${{secrets.DISCORD_GUILD_ID}}
20+
DISCORD_TOKEN: ${{secrets.DISCORD_TOKEN}}
21+
DISCORD_PUBLIC_KEY: ${{secrets.DISCORD_PUBLIC_KEY}}
22+
CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}}
23+
CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
24+
BOT_PRIVATE_KEY: ${{secrets.BOT_PRIVATE_KEY}}
25+
RDS_SERVERLESS_PUBLIC_KEY: ${{secrets.RDS_SERVERLESS_PUBLIC_KEY}}
26+
CRON_JOBS_PUBLIC_KEY: ${{secrets.CRON_JOBS_PUBLIC_KEY}}
27+
IDENTITY_SERVICE_PUBLIC_KEY: ${{secrets.IDENTITY_SERVICE_PUBLIC_KEY}}
28+
629
Register-Commands:
30+
needs: [Environment-Variables-Check]
731
runs-on: ubuntu-latest
832
environment: production
933
steps:
10-
- uses: actions/checkout@v2
11-
- uses: actions/setup-node@v3
34+
- uses: actions/checkout@v4
35+
- uses: actions/setup-node@v4
1236
with:
1337
node-version: 18.18.2
1438
- run: npm install
@@ -22,7 +46,7 @@ jobs:
2246
runs-on: ubuntu-latest
2347
environment: production
2448
steps:
25-
- uses: actions/checkout@v2
49+
- uses: actions/checkout@v4
2650
- run: npm install
2751
- uses: cloudflare/[email protected]
2852
with:

.github/workflows/register-commands-staging.yaml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,36 @@ on:
33
push:
44
branches: develop
55
jobs:
6+
Environment-Variables-Check:
7+
runs-on: ubuntu-latest
8+
environment: staging
9+
steps:
10+
- uses: actions/checkout@v4
11+
- uses: actions/setup-node@v4
12+
with:
13+
node-version: 18.18.2
14+
- run: npm install
15+
- run: npm run env-var-check
16+
env:
17+
CURRENT_ENVIRONMENT: staging
18+
DISCORD_APPLICATION_ID: ${{secrets.DISCORD_APPLICATION_ID}}
19+
DISCORD_GUILD_ID: ${{secrets.DISCORD_GUILD_ID}}
20+
DISCORD_TOKEN: ${{secrets.DISCORD_TOKEN}}
21+
DISCORD_PUBLIC_KEY: ${{secrets.DISCORD_PUBLIC_KEY}}
22+
CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}}
23+
CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
24+
BOT_PRIVATE_KEY: ${{secrets.BOT_PRIVATE_KEY}}
25+
RDS_SERVERLESS_PUBLIC_KEY: ${{secrets.RDS_SERVERLESS_PUBLIC_KEY}}
26+
CRON_JOBS_PUBLIC_KEY: ${{secrets.CRON_JOBS_PUBLIC_KEY}}
27+
IDENTITY_SERVICE_PUBLIC_KEY: ${{secrets.IDENTITY_SERVICE_PUBLIC_KEY}}
28+
629
Register-Commands:
30+
needs: [Environment-Variables-Check]
731
runs-on: ubuntu-latest
832
environment: staging
933
steps:
10-
- uses: actions/checkout@v2
11-
- uses: actions/setup-node@v3
34+
- uses: actions/checkout@v4
35+
- uses: actions/setup-node@v4
1236
with:
1337
node-version: 18.18.2
1438
- run: npm install
@@ -22,7 +46,7 @@ jobs:
2246
runs-on: ubuntu-latest
2347
environment: staging
2448
steps:
25-
- uses: actions/checkout@v2
49+
- uses: actions/checkout@v4
2650
- run: npm install
2751
- uses: cloudflare/[email protected]
2852
with:

config/config.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,48 @@ import {
1919
DISCORD_PROFILE_SERVICE_STAGING_HELP_GROUP,
2020
DISCORD_PROFILE_SERVICE_DEVELOPMENT_HELP_GROUP,
2121
} from "../src/constants/variables";
22+
import { config as configFromDotEnv } from "dotenv";
23+
24+
export function loadEnv(env: env, fromWorkerEnv: boolean): env {
25+
const Env: env = {
26+
CURRENT_ENVIRONMENT: fromWorkerEnv
27+
? env.CURRENT_ENVIRONMENT
28+
: process.env.CURRENT_ENVIRONMENT || "",
29+
DISCORD_APPLICATION_ID: fromWorkerEnv
30+
? env.DISCORD_APPLICATION_ID
31+
: process.env.DISCORD_APPLICATION_ID || "",
32+
DISCORD_GUILD_ID: fromWorkerEnv
33+
? env.DISCORD_GUILD_ID
34+
: process.env.DISCORD_GUILD_ID || "",
35+
DISCORD_TOKEN: fromWorkerEnv
36+
? env.DISCORD_TOKEN
37+
: process.env.DISCORD_TOKEN || "",
38+
DISCORD_PUBLIC_KEY: fromWorkerEnv
39+
? env.DISCORD_PUBLIC_KEY
40+
: process.env.DISCORD_PUBLIC_KEY || "",
41+
CLOUDFLARE_API_TOKEN: fromWorkerEnv
42+
? env.CLOUDFLARE_API_TOKEN
43+
: process.env.CLOUDFLARE_API_TOKEN || "",
44+
CLOUDFLARE_ACCOUNT_ID: fromWorkerEnv
45+
? env.CLOUDFLARE_ACCOUNT_ID
46+
: process.env.CLOUDFLARE_ACCOUNT_ID || "",
47+
BOT_PRIVATE_KEY: fromWorkerEnv
48+
? env.BOT_PRIVATE_KEY
49+
: process.env.BOT_PRIVATE_KEY || "",
50+
RDS_SERVERLESS_PUBLIC_KEY: fromWorkerEnv
51+
? env.RDS_SERVERLESS_PUBLIC_KEY
52+
: process.env.RDS_SERVERLESS_PUBLIC_KEY || "",
53+
CRON_JOBS_PUBLIC_KEY: fromWorkerEnv
54+
? env.CRON_JOBS_PUBLIC_KEY
55+
: process.env.CRON_JOBS_PUBLIC_KEY || "",
56+
IDENTITY_SERVICE_PUBLIC_KEY: fromWorkerEnv
57+
? env.IDENTITY_SERVICE_PUBLIC_KEY
58+
: process.env.IDENTITY_SERVICE_PUBLIC_KEY || "",
59+
};
60+
return Env;
61+
}
62+
63+
configFromDotEnv();
2264

2365
const config = (env: env) => {
2466
const environment: environment = {

config/envVarCheck.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { env } from "../src/typeDefinitions/default.types";
2+
import { loadEnv } from "./config";
3+
4+
/**
5+
* Validate if all the required environment variables are set to a non empty value
6+
* else throw an error
7+
* ---
8+
*/
9+
export function validateEnv() {
10+
const env: env = loadEnv({}, false);
11+
const missingEnvVariables = Object.keys(env).filter((key) => env[key] == "");
12+
13+
if (missingEnvVariables.length > 0) {
14+
throw new Error(
15+
`Missing environment variables: ${missingEnvVariables.join(", ")}`
16+
);
17+
} else {
18+
console.log("All required environment variables are set.");
19+
}
20+
}
21+
22+
validateEnv();

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"format-fix": "prettier --write .",
1616
"fix": "npm run lint-fix && npm run format-fix",
1717
"ngrok": "ngrok http 8787",
18-
"register": "ts-node-esm src/register.ts"
18+
"register": "ts-node-esm src/register.ts",
19+
"env-var-check": "ts-node-esm config/envVarCheck.ts"
1920
},
2021
"keywords": [],
2122
"author": "",

src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { generateInviteLink } from "./controllers/generateDiscordInvite";
2222
import { sendProfileBlockedMessage } from "./controllers/profileHandler";
2323
import { sendTaskUpdatesHandler } from "./controllers/taskUpdatesHandler";
2424

25-
import config from "./../config/config";
25+
import config, { loadEnv } from "./../config/config";
2626

2727
const router = Router();
2828

@@ -107,10 +107,12 @@ export default {
107107
return new JSONResponse(response.BAD_SIGNATURE, { status: 401 });
108108
}
109109
}
110-
return router.handle(request, env, ctx);
110+
const Env: env = loadEnv(env, true);
111+
return router.handle(request, Env, ctx);
111112
},
112113

113114
async scheduled(req: Request, env: env, ctx: ExecutionContext) {
114-
ctx.waitUntil(send(env));
115+
const Env: env = loadEnv(env, true);
116+
ctx.waitUntil(send(Env));
115117
},
116118
};

src/register.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { config } from "dotenv";
1515
import { DISCORD_BASE_URL } from "./constants/urls";
1616
import { registerCommands } from "./utils/registerCommands";
17+
import { loadEnv } from "../config/config";
1718

1819
config();
1920

@@ -56,8 +57,10 @@ async function registerGuildCommands(
5657
}
5758
}
5859

60+
const env = loadEnv({}, false);
61+
5962
registerGuildCommands(
60-
process.env.DISCORD_TOKEN,
61-
process.env.DISCORD_APPLICATION_ID,
62-
process.env.DISCORD_GUILD_ID
63+
env.DISCORD_TOKEN,
64+
env.DISCORD_APPLICATION_ID,
65+
env.DISCORD_GUILD_ID
6366
);

0 commit comments

Comments
 (0)