I am using a GitLab CI Runner with Docker.
My dockerfile looks as follows:
FROM node:lts-buster-slim
# Install docker dependencies
RUN apt-get update
RUN apt-get install -y --no-install-recommends
apt-transport-https
build-essential
ca-certificates
curl
gnupg2
dirmngr
software-properties-common
sudo
# Get Docker GPG key
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
# Add Docker Repo
RUN sudo add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/debian
$(lsb_release -cs)
stable"
RUN sudo apt-get update
## Install docker
RUN apt-get install -y --no-install-recommends
docker-ce
docker-ce-cli
containerd.io
docker
rsync
git
openssl
### docker-compose
RUN sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN sudo chmod +x /usr/local/bin/docker-compose
RUN groupadd appuser &&
useradd -r -g appuser ciuser &&
usermod -aG docker ciuser
## copy NPM settings
COPY config/.npmrc /root/
## healthcheck and coverage
ADD scripts /usr/local/bin
RUN mkdir -p /info
ADD VERSION_INFO /info/VERSION_INFO
ADD init/.bashrc /root/.bashrc
RUN chown -R ciuser /info &&
chown -R ciuser /root &&
chown -R ciuser /home &&
chmod -R 755 /usr/local
USER ciuser
Earlier I just used the root user instead of the restricted ciuser, however, my CI includes a test stage which needs a user without root permission, so that file permission test are working properly.
My .gitlab-ci.yml looks as follows:
image: registry.example.com/example/gitlab-javascript-runner:latest
stages:
- test
- release
- publish
before_script:
- source /root/.bashrc
variables:
PACKAGE_CMD: export PACKAGE_VERSION=$(node --eval="process.stdout.write(require('./package.json').version)")
cache:
paths:
- node_modules/
- yarn
test-unit:
stage: test
tags:
- docker
script:
- npm install && npm run test:cobertura
coverage: /Allsfiles.*?s+(d+.d+)/
artifacts:
reports:
cobertura: coverage/cobertura-coverage.xml
allow_failure: false
only:
- merge_requests
- master
- release
release-gl:
stage: release
tags:
- docker
script:
- npm i -g semantic-release && npm i @semantic-release/gitlab
- semantic-release
allow_failure: false
only:
refs:
- release
publish-npm:
stage: publish
tags:
- docker
script:
- npm publish
allow_failure: false
only:
refs:
- release
However, changing from root user to ciuser for proper working of my tests causes the following permission error when running semantic-release:
$ npm i -g semantic-release && npm i @semantic-release/gitlab
npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR! [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'access',
npm ERR! path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/ciuser/.npm/_logs/2020-11-23T17_33_17_081Z-debug.log
$ semantic-release
/bin/bash: line 104: semantic-release: command not found
Cleaning up file based variables
00:01
ERROR: Job failed: exit code 1
I tried adding the following commands before running semantic-release:
- npm set prefix ~/.npm
- PATH="$HOME/.npm/bin:$PATH"
- PATH+="./node_modules/.bin:$PATH"
- source /root/.bashrc
This leads to the situation that semantic-release can be found and executed, but then I get another permission error regarding git:
[10:50:23 AM] [semantic-release] › ℹ Running semantic-release version 17.3.0
[10:50:23 AM] [semantic-release] › ✔ Loaded plugin "verifyConditions" from "@semantic-release/gitlab"
[10:50:23 AM] [semantic-release] › ✔ Loaded plugin "analyzeCommits" from "@semantic-release/commit-analyzer"
[10:50:23 AM] [semantic-release] › ✔ Loaded plugin "publish" from "@semantic-release/gitlab"
[10:50:24 AM] [semantic-release] › ✖ An error occurred while running semantic-release: Error: Command failed with exit code 1: git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release
warning: redirecting to https://git.symptoma.com/symptoma/weblate-properties2json-converter.git/
error: cannot update the ref 'refs/heads/release': unable to append to '.git/logs/refs/heads/release': Permission denied
From https://git.symptoma.com/symptoma/weblate-properties2json-converter
! [new branch] release -> release (unable to update local ref)
at makeError (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/execa/lib/error.js:59:11)
at handlePromise (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/execa/index.js:114:26)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async fetch (/home/ciuser/.npm/lib/node_modules/semantic-release/lib/git.js:120:5)
at async /home/ciuser/.npm/lib/node_modules/semantic-release/lib/branches/index.js:21:5
at async pEachSeries (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/p-each-series/index.js:8:23)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/lib/branches/index.js:20:3)
at async run (/home/ciuser/.npm/lib/node_modules/semantic-release/index.js:57:22)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/index.js:260:22)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/cli.js:55:5) {
shortMessage: 'Command failed with exit code 1: git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release',
command: 'git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: '',
stderr: 'warning: redirecting to https://git.symptoma.com/symptoma/weblate-properties2json-converter.git/n' +
"error: cannot update the ref 'refs/heads/release': unable to append to '.git/logs/refs/heads/release': Permission deniedn" +
'From https://git.symptoma.com/symptoma/weblate-properties2json-convertern' +
' ! [new branch] release -> release (unable to update local ref)',
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
Error: Command failed with exit code 1: git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release
warning: redirecting to https://git.symptoma.com/symptoma/weblate-properties2json-converter.git/
error: cannot update the ref 'refs/heads/release': unable to append to '.git/logs/refs/heads/release': Permission denied
From https://git.symptoma.com/symptoma/weblate-properties2json-converter
! [new branch] release -> release (unable to update local ref)
at makeError (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/execa/lib/error.js:59:11)
at handlePromise (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/execa/index.js:114:26)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async fetch (/home/ciuser/.npm/lib/node_modules/semantic-release/lib/git.js:120:5)
at async /home/ciuser/.npm/lib/node_modules/semantic-release/lib/branches/index.js:21:5
at async pEachSeries (/home/ciuser/.npm/lib/node_modules/semantic-release/node_modules/p-each-series/index.js:8:23)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/lib/branches/index.js:20:3)
at async run (/home/ciuser/.npm/lib/node_modules/semantic-release/index.js:57:22)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/index.js:260:22)
at async module.exports (/home/ciuser/.npm/lib/node_modules/semantic-release/cli.js:55:5) {
shortMessage: 'Command failed with exit code 1: git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release',
command: 'git fetch --tags --update-head-ok https://gitlab-ci-token:[secure]@git.symptoma.com/symptoma/weblate-properties2json-converter +refs/heads/release:refs/heads/release',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: '',
stderr: 'warning: redirecting to https://git.symptoma.com/symptoma/weblate-properties2json-converter.git/n' +
"error: cannot update the ref 'refs/heads/release': unable to append to '.git/logs/refs/heads/release': Permission deniedn" +
'From https://git.symptoma.com/symptoma/weblate-properties2json-convertern' +
' ! [new branch] release -> release (unable to update local ref)',
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
Is there a possibility to use different users for different stages, or what other options are availalbe for running the test stage with a restricted user and release stage with the root user?
2
Answers
I finally solved the issue through:
USER ciuser
from the Dockerfile so that the runner is starting with theroot
user againsudo -H -u ciuser bash -c "npm install && npm run test:cobertura"
so that it is executed by theciuser
as it is described in this post.Removing
USER <username>
in Dockerfile worked for me.