While doing project, I’m having trouble creating own Github Actions using Dockerized way. During the action run process, I receive the error message Usage Error: Couldn't find the node_modules state file - running an install might help (findPackageLocation)
. But I build it, node_modules
is created in container. So it should be there. I checked other issues on stack but they seems to be only locally, nothing Github Action related.
Here’s an illustration of my Github Actions workflow:
action.yml (in User/my-action@main
)
name: 'Reusable Action'
description: 'Independent Reusable Action'
inputs:
github-token:
description: 'Github token'
required: true
outputs:
some_output:
description: 'Some output'
runs:
using: 'docker'
image: 'Dockerfile'
and here Dockerfile (in User/my-action@main
)
FROM node:16-alpine
WORKDIR /usr/src/app
ENV PATH=/usr/src/app/node_modules/.bin:$PATH
# Install dependencies
RUN apk add --no-cache git openssh-client python3 make g++
# copy project
COPY . .
# Check yarn, should be 3.5.0 (it shows up as 3.5.0)
RUN cat /usr/src/app/.yarnrc.yml
RUN printf "Project yarn version: "; yarn --version
# Install yarn dependencies
RUN yarn install
# build
RUN yarn build
RUN echo "Successfully built"
CMD [ "yarn", "start" ]
here’s how I call for it in workflow (in User/other-repo
)
name: My reusable action in other repo
description: It's reusable
inputs:
secret_token:
required: true
description: Secret to use for authentication
runs:
using: composite
steps:
- name: Do this
id: my-id
uses: User/my-action@main
with:
github-token: ${{ inputs.secret_token }}
- name: Overwrite PR body
id: overwrite_pr_body
uses: AsasInnab/pr-body-action@v1
with:
body: ${{ steps.my-id.outputs.some_output }}
GITHUB_TOKEN: ${{ inputs.secret_token }}
When running it locally (docker build -t my-test-image .
) it pass through… but when running in GitHub Actions it fails with above error code.
What I’ve tried so far besides what we have above:
- Updated project to yarn berry
- Removed due to this issue the yarn.lock
- Specified
usr/src/app
workdir
2
Answers
After some investigation, I found that the issue was with the way I was running the
yarn start
command. I had originally included it in theCMD
orENTRYPOINT
directive in theDockerfile
.However, I found that by moving the
yarn start
command to a separate script and then calling that script from the "ENTRYPOINT" directive, the container started up properly within Github Action.Final look:
And script
/entrypoint.sh
scriptEdited to add;
Per the issue being solved by changing the entry point, it would seem that the
node:16-alpine
entrypoint was trying to run yarn through node, rather than shell.Although you’ve got it working now, it’s good to keep in mind that your entrypoint won’t always be
sh
. Although starting with the entrypoint set to a script is a good pattern, a similar fix to the originalCMD
would beENTRYPOINT ["/bin/sh", "-c"]
.Original
The
docker build
may "complete" fine (read: without error) locally, butyarn install
can fail silently, i.e. it can fail to install properly but exit 0 — so your build can "succeed" without it actually being successful. At a minimum, trydocker run --rm -it my-test-image sh
to jump into a shell in the finished build and confirm that it actually built correctly.I suspect that there is a difference in the version of yarn installed in the base image and the version your configuration may be targetting, so you might need to update yarn before installing, if it failed to install properly.
As a side note, you don’t need to use another repository (
User/other-repo
) to invoke it, you can test / call the action from the repo that contains it,uses: ./
will use anaction.y[a]ml
in./
of your repository. For example. It’s good practice to test the action with a workflow thatuses:
it, that can be a CI workflow on the repository that will publish the action.