I have a node webapp that I run locally to run test specs. I use mocha and karma as a spec runner. Here are one of my npm commands to run a test suite:
{
"scripts": {
"test-jobs-once-docker": "mocha --reporter spec "server/**/*.spec.js""
}
}
When I run docker-compose up locally, the command works and the specs run in the docker container.
Here is my docker-compose.yml
:
version: "3"
services:
mongo:
image: mongo:3.4
ports:
- 27017:27017
restart: always
redis:
image: redis:7.0.8
ports:
- 6379:6379
restart: always
webapp:
build:
context: .
args:
- NODE_ENV=dockerTest
platform: linux/amd64
ports:
- 9000:9000
depends_on:
- redis
environment:
- PORT=9000
- NODE_ENV=dockerTest
- REDIS_URL=redis://redis:6379
command: ['npm', 'run', 'test-jobs-once-docker']
Here is the Dockerfile
:
FROM --platform=linux/amd64 ubuntu:20.04
ENV APP_HOME="/app"
WORKDIR /app
USER root
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
&& apt-get install -y curl
&& apt-get -y autoclean
ENV NODE_VERSION=12.9.0
ENV NVM_DIR /usr/local/nvm
ENV CHROME_BIN=/usr/bin/google-chrome
RUN mkdir -p /usr/local/nvm/ &&
curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash
RUN /bin/bash -c "source $NVM_DIR/nvm.sh
&& nvm install $NODE_VERSION
&& nvm alias default $NODE_VERSION
&& nvm use default"
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN apt-get install python -y
RUN apt-get install libkrb5-dev -y
RUN apt-get install libpng-dev -y
RUN apt-get install libfontconfig1 fontconfig libfontconfig1-dev -y
RUN apt-get install build-essential -y
COPY ./package*.json ./
COPY .npmrc ./
RUN npm install
COPY . /app
RUN touch ./server/config/local.env.js
ENV PORT=9000
EXPOSE 8080
EXPOSE 9000
However, when I run this in GitHub Actions it says:
mocha: command not found
Here is my workflow:
name: Run Test Suite
on: [push, pull_request]
jobs:
run-tests-docker:
runs-on: ubuntu-20.04
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Build Docker Containers & Run Test Specs
run: docker-compose -f "docker-compose.yml" up -d --build
- name: Run Test Specs
run: npm run test-jobs-once-docker
env:
NODE_ENV: dockerTest
- name: Stop Containers
if: always()
run: docker-compose -f "docker-compose.yml" down
When I run this on GitHub Actions, I comment out the command
property on the webapp in the docker-compose.yml
so the command is executed in the job on GitHub Actions instead of when the container builds. I feel like this is the problem. I am not sure how to inspect the container that is built and used in GitHub Actions to see if the node_modules
exists.
Does anybody know how I can get access to the mocha
executable so I can run my tests in GitHub Actions?
Update:
I noticed that the node_modules
folder is not in the directory the rest of my app is in. I’m going to guess this is part of the problem, this is the $PATH
variable and files in the directory after the environment builds in github actions (also note the Dockerfile
and nvm
/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/snap/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Dockerfile
Gemfile
Gemfile.lock
Procfile
README.md
app.json
bower.json
client
database.json
docker-compose.yml
e2e
karma.conf.js
package-lock.json
package.json
server
shared
webpack-dev.config.js
webpack-production.config.js
webpack.common.js
3
Answers
Your problem seems to be related to the context in which the
mocha
command is being executed.mocha
command inside your Docker container, it has access to thenode_modules
directory that was installed during the Docker build process (sincenpm install
is executed in the Dockerfile).mocha
directly from your GitHub Actions workflow, it does not have access to thosenode_modules
as it is outside the Docker container context.Make sure that
node_modules
is correctly installed: If you want to keep running the tests from the GitHub Actions workflow, you could ensure that thenode_modules
directory is correctly installed. You can do this by runningnpm install
in your GitHub Actions workflow:However, keep in mind that this might not work if your tests rely on other aspects of your Docker environment that are not replicated in your GitHub Actions runner.
And make sure the working directory is correct: Make sure that the GitHub Actions runner is in the correct directory when it tries to run
npm run test-jobs-once-docker
. If it is not in the right directory, it might not find thenode_modules
directory. You can use theworking-directory
option in your GitHub Actions workflow to ensure that the runner is in the correct directory:Replace
/path/to/your/app
with the actual path to your app in the runner’s filesystem.The alternative approach would be to run the tests within the Docker container**: Instead of trying to run
npm run test-jobs-once-docker
from the GitHub Actions workflow, you could run the tests within the Docker container itself. This would ensure that themocha
command has access to thenode_modules
directory. You can do this by modifying your GitHub Actions workflow to execute the command inside the Docker container. Here is an example of how you could do that:Note that
<container-id>
should be replaced with the ID or name of your Docker container. You can get this information from the output ofdocker-compose up -d --build
.You can get the container ID of your Docker container by using the
docker ps
command with a filter for the container name. The filter matches on all or part of a container’s name.This is how you could use it in your GitHub Actions workflow:
In this step, the command
docker ps -aqf "name=webapp"
lists all containers and filters for the one named "webapp". The-aq
flags stand for "all" and "quiet" respectively, meaning the command will return all containers (not just the running ones) and will only print their container IDs.The
echo "CONTAINER_ID=$(docker ps -aqf "name=webapp")" >> $GITHUB_ENV
command writes the output (the container ID) to theGITHUB_ENV
file, which makes it available as an environment variable in subsequent steps of the workflow.You can then use this container ID in subsequent steps like so:
In order to have
mocha
and/orkarma
within your image, so you can run them, in yourDockerfile
after:add:
this will make mocha and karma available as commands in your PATH, so you can then run "mocha –reporter spec "server/**/*.spec.js""
the
mocha
command is not found because it is not available in the environment where you try to run it:While there is an
npm
command available and the filepackage.json
accessible for it, it effectively executes the npm package script calledtest-jobs-once-docker
, specifically:The subshell
npm
invokes then is not able to findmocha
resulting in the error message in question.This just to understand the error message.
The rest is not entirely clear from your question. And this effects the environment that you need to execute the
mocha
command line successfully. The fitting environment, which you also confirm working, you specifically reject:The rationale you give:
And then:
Indeed! The whole setup is done to run this command but then you disable the command because you do the whole setup?
This makes no sense. Indeed you want to run it when it builds, you have this in your pipeline, even named:
Just do it. Don’t comment out the command. Otherwise you’re starting the container but without running the command. The command you want to run.
It is either the misunderstanding running the setup in background, or it is fine, but then you need to execute the command in the running container (and keep the command in the compose config commented):