I’m having trouble with my GitHub Actions CI/CD pipeline when it comes to connecting to MongoDB. The connection works perfectly in my local environment, but when I run the tests in GitHub Actions, I encounter the following error:
Error connecting to MongoDB: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined".
Here are the steps I’ve taken to debug the issue:
Here’s a snippet of my server.ts where the MongoDB connection is handled:
import mongoose from 'mongoose';
// Log the MongoDB URI to check if it is being set correctly
console.log("MongoDB Connection String (from env):", process.env.DBHOST);
// Temporary hardcoded URI for debugging purposes
const hardcodedUri = "your-hardcoded-mongodb-uri";
console.log("Using hardcoded MongoDB URI:", hardcodedUri);
// Use the hardcoded URI for debugging, replace `process.env.DBHOST` with `hardcodedUri` if needed
mongoose.connect(hardcodedUri, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("Connected to MongoDB successfully"))
.catch((error) => console.error("Error connecting to MongoDB:", error));
And here’s the relevant part of my GitHub Actions main.yml:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use Node.JS ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: |
cd backend
npm install
env:
DBHOST: ${{ secrets.DBHOST }}
- name: Log MongoDB URI
run: |
echo "MongoDB URI: $DBHOST" # Log the MongoDB URI to ensure it is set
- name: Run tests
run: |
cd backend
npx mocha --config .mocharc.json
server.ts:
// Connect to MongoDB using Mongoose
mongoose.set("strictQuery", false);
mongoose
.connect(process.env.DBHOST as string)
.catch((error) => console.log("Error connecting to MongoDB:" + error));
.mocharc.json:
{
"diff": true,
"extension": ["ts"],
"ignore": ["test/ignore/**"],
"package": "./package.json",
"reporter": "spec",
"slow": 75,
"timeout": 5000,
"ui": "bdd",
"spec": "src/test/**/*.test.ts",
"require": "ts-node/register",
"watch-files": ["src/lib/**/*.ts", "src/test/**/*.ts"],
"watch-ignore": ["lib/vendor"]
}
My Setup:
• Node.js: v20.x
• Mongoose: ^6.1.7
• dotenv-flow: ^4.1.0
• GitHub Actions: Runner on ubuntu-latest
What I’ve Tried:
• Verifying that the environment variables match between local and GitHub Secrets.
• Hardcoding the MongoDB URI for testing.
• Logging the URI in the CI pipeline to ensure it’s being set.
Any help or suggestions would be greatly appreciated!
NOTE: Just recently I started using a TypeScript and before with JavaScript I never encountered similar issue.
UPDATE: Incorporating .env VARs only in run tests as suggested bellow indeed helped overvcome the originall issue. However it gets stuck on performing the tests and two of them are apparentnly failling despite that locally everythings passes...
Actions log:
> cross-env NODE_ENV=test mocha --require ts-node/register
[dotenv-flow@4.1.0]: ".env*" files loading failed: no ".env*" files matching pattern ".env[.test][.local]" in "/home/runner/work/slavic.media-2.0/slavic.media-2.0/backend" dir undefined
[dotenv-flow@4.1.0]: ".env*" files loading failed: no ".env*" files matching pattern ".env[.test][.local]" in "/home/runner/work/slavic.media-2.0/slavic.media-2.0/backend" dir undefined
Server is running on port: 4000
Document workflow tests
Connected successfully to MongoDB
1) should register + login a user, create document and verify 1 in DB
2) should register + login a user, create document and delete it from DB
✔ Invalid user input test
1 passing (2s)
2 failing
1) Document workflow tests
should register + login a user, create document and verify 1 in DB:
Uncaught AssertionError: expected 400 to equal 201
+ expected - actual
-400
+201
at fn (src/test/workflow.test.ts:64:42)
at Test.callback (node_modules/superagent/src/node/index.js:913:12)
at fn (node_modules/superagent/src/node/index.js:1166:18)
at IncomingMessage.<anonymous> (node_modules/superagent/src/node/parsers/json.js:19:7)
at IncomingMessage.emit (node:events:531:35)
at IncomingMessage.emit (node:domain:488:12)
at endReadableNT (node:internal/streams/readable:1696:12)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
2) Document workflow tests
should register + login a user, create document and delete it from DB:
Uncaught AssertionError: expected 400 to equal 201
+ expected - actual
-400
+201
at fn (src/test/workflow.test.ts:145:42)
at Test.callback (node_modules/superagent/src/node/index.js:913:12)
at fn (node_modules/superagent/src/node/index.js:1166:18)
at IncomingMessage.<anonymous> (node_modules/superagent/src/node/parsers/json.js:19:7)
at IncomingMessage.emit (node:events:531:35)
at IncomingMessage.emit (node:domain:488:12)
at endReadableNT (node:internal/streams/readable:1696:12)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
You don't need env
for dependencies installation
- name: Install dependencies
run: |
cd backend
npm install
env:
DBHOST: ${{ secrets.DBHOST }} ❌
You have to configure it in run tests step
- name: Run tests
run: |
cd backend
npx mocha --config .mocharc.json
env:
DBHOST: ${{ secrets.DBHOST }} ✅
Each step are isolated process, so they don't share env across them
If you want to use one env variable for all steps, check out this github-action env