---
tags: gitlab, docker
---
# Running the Gitlab CI locally

Sometimes, I need to change how the continuous integration is setup, and I find
myself pushing to a branch to test if my changes are working. Oftentimes, it
takes me multiple commits to find the correct configuration, which is…
suboptimal.

I discovered today [Gitlab CI
local](https://github.com/firecow/gitlab-ci-local) which makes it possible to
run the CI actions locally, without having to push to the remote CI. The same
thing exists for [Microsoft Github](https://github.com/nektos/act).

Under the hood, it's using Docker, so you need to have it running on your
system, but once it's done, you just have to issue a simple command to see the
results. Very helpful :-)

Here is an example :

```bash
$ gitlab-ci-local test
parsing and downloads finished in 41 ms
test  starting python:3.8-alpine (test)
test  copied to docker volumes in 4.05 s
test  $ apk update && apk add make libsass gcc musl-dev g++
test  > fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/main/aarch64/APKINDEX.tar.gz
test  > fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/community/aarch64/APKINDEX.tar.gz
test  > v3.18.3-55-g2ee93b9273a [https://dl-cdn.alpinelinux.org/alpine/v3.18/main]
test  > v3.18.3-56-g4a3b0382caa [https://dl-cdn.alpinelinux.org/alpine/v3.18/community]
test  > OK: 19939 distinct packages available
test  > (1/17) Installing libgcc (12.2.1_git20220924-r10)
test  > (2/17) Installing libstdc++ (12.2.1_git20220924-r10)
test  > (3/17) Installing libstdc++-dev (12.2.1_git20220924-r10)
test  > (4/17) Installing zstd-libs (1.5.5-r4)
test  > (5/17) Installing binutils (2.40-r7)
test  > (6/17) Installing libgomp (12.2.1_git20220924-r10)
test  > (7/17) Installing libatomic (12.2.1_git20220924-r10)
test  > (8/17) Installing gmp (6.2.1-r3)
test  > (9/17) Installing isl26 (0.26-r1)
test  > (10/17) Installing mpfr4 (4.2.0_p12-r0)
test  > (11/17) Installing mpc1 (1.3.1-r1)
test  > (12/17) Installing gcc (12.2.1_git20220924-r10)
test  > (13/17) Installing musl-dev (1.2.4-r1)
test  > (14/17) Installing libc-dev (0.7.2-r5)
test  > (15/17) Installing g++ (12.2.1_git20220924-r10)
test  > (16/17) Installing libsass (3.6.5-r0)
test  > (17/17) Installing make (4.4.1-r1)
test  > Executing busybox-1.36.1-r2.trigger
test  > OK: 246 MiB in 55 packages
test  $ pip install -r requirements.txt
test  > Collecting pelican
test  >   Downloading pelican-4.8.0-py3-none-any.whl (1.4 MB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 539.9 kB/s eta 0:00:00
test  > Collecting markdown
test  >   Downloading Markdown-3.4.4-py3-none-any.whl (94 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 94.2/94.2 kB 540.1 kB/s eta 0:00:00
test  > Collecting typogrify
test  >   Downloading typogrify-2.0.7.tar.gz (12 kB)
test  >   Preparing metadata (setup.py): started
test  >   Preparing metadata (setup.py): finished with status 'done'
test  > Collecting pelican-search
test  >   Downloading pelican_search-1.1.0-py3-none-any.whl (6.6 kB)
test  > Collecting pelican-neighbors
test  >   Downloading pelican_neighbors-1.2.0-py3-none-any.whl (16 kB)
test  > Collecting pelican-webassets
test  >   Downloading pelican_webassets-2.0.0-py3-none-any.whl (5.8 kB)
test  > Collecting libsass
test  >   Downloading libsass-0.22.0.tar.gz (316 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 316.3/316.3 kB 552.1 kB/s eta 0:00:00
test  >   Preparing metadata (setup.py): started
test  >   Preparing metadata (setup.py): finished with status 'done'
test  > Collecting docutils>=0.16
test  >   Downloading docutils-0.20.1-py3-none-any.whl (572 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 572.7/572.7 kB 549.2 kB/s eta 0:00:00
test  > Collecting rich>=10.1
test  >   Downloading rich-13.5.2-py3-none-any.whl (239 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 239.7/239.7 kB 485.3 kB/s eta 0:00:00
test  > Collecting jinja2>=2.7
test  >   Downloading Jinja2-3.1.2-py3-none-any.whl (133 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 133.1/133.1 kB 342.6 kB/s eta 0:00:00
test  > Collecting pytz>=2020.1
test  >   Downloading pytz-2023.3-py2.py3-none-any.whl (502 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 502.3/502.3 kB 547.3 kB/s eta 0:00:00
test  > Collecting pygments>=2.6
test  >   Downloading Pygments-2.16.1-py3-none-any.whl (1.2 MB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 551.4 kB/s eta 0:00:00
test  > Collecting unidecode>=1.1
test  >   Downloading Unidecode-1.3.6-py3-none-any.whl (235 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 235.9/235.9 kB 554.2 kB/s eta 0:00:00
test  > Collecting blinker>=1.4
test  >   Downloading blinker-1.6.2-py3-none-any.whl (13 kB)
test  > Collecting python-dateutil>=2.8
test  >   Downloading python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 247.7/247.7 kB 235.7 kB/s eta 0:00:00
test  > Collecting feedgenerator>=1.9
test  >   Downloading feedgenerator-2.1.0-py3-none-any.whl (21 kB)
test  > Collecting importlib-metadata>=4.4
test  >   Downloading importlib_metadata-6.8.0-py3-none-any.whl (22 kB)
test  > Collecting smartypants>=1.8.3
test  >   Downloading smartypants-2.0.1-py2.py3-none-any.whl (9.9 kB)
test  > Collecting rtoml<0.10.0,>=0.9.0
test  >   Downloading rtoml-0.9.0-cp38-cp38-musllinux_1_1_aarch64.whl (846 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 846.2/846.2 kB 503.7 kB/s eta 0:00:00
test  > Collecting webassets<3.0,>=2.0
test  >   Downloading webassets-2.0-py3-none-any.whl (142 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 142.9/142.9 kB 551.8 kB/s eta 0:00:00
test  > Collecting zipp>=0.5
test  >   Downloading zipp-3.16.2-py3-none-any.whl (7.2 kB)
test  > Collecting MarkupSafe>=2.0
test  >   Downloading MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl (30 kB)
test  > Collecting six>=1.5
test  >   Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
test  > Collecting markdown-it-py>=2.2.0
test  >   Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB)
test  >      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 87.5/87.5 kB 561.7 kB/s eta 0:00:00
test  > Collecting typing-extensions<5.0,>=4.0.0
test  >   Downloading typing_extensions-4.7.1-py3-none-any.whl (33 kB)
test  > Collecting mdurl~=0.1
test  >   Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB)
test  > Building wheels for collected packages: typogrify, libsass
test  >   Building wheel for typogrify (setup.py): started
test  >   Building wheel for typogrify (setup.py): finished with status 'done'
test  >   Created wheel for typogrify: filename=typogrify-2.0.7-py2.py3-none-any.whl size=13452 sha256=4ce329903e807671102eab7fd2bc49765b6efc3a4ae68c82053318b62789083c
test  >   Stored in directory: /root/.cache/pip/wheels/0b/e9/98/c888501e8dd2166da059e4f8418694de9b50b48a7192712be9
test  >   Building wheel for libsass (setup.py): started
test  >   Building wheel for libsass (setup.py): still running...
test  >   Building wheel for libsass (setup.py): finished with status 'done'
test  >   Created wheel for libsass: filename=libsass-0.22.0-cp38-abi3-linux_aarch64.whl size=13710320 sha256=3dcb4ce97c1aafc179a6343e0f312c17df88e56c4eb647ab54b09ead5ee00b92
test  >   Stored in directory: /root/.cache/pip/wheels/95/64/fa/47638d5037df216387cdc168e9871d5d9851fc995d636bd108
test  > Successfully built typogrify libsass
test  > Installing collected packages: webassets, smartypants, pytz, zipp, unidecode, typogrify, typing-extensions, six, rtoml, pygments, mdurl, MarkupSafe, libsass, feedgenerator, docutils, blinker, python-dateutil, markdown-it-py, jinja2, importlib-metadata, rich, markdown, pelican, pelican-webassets, pelican-search, pelican-neighbors
test  > Successfully installed MarkupSafe-2.1.3 blinker-1.6.2 docutils-0.20.1 feedgenerator-2.1.0 importlib-metadata-6.8.0 jinja2-3.1.2 libsass-0.22.0 markdown-3.4.4 markdown-it-py-3.0.0 mdurl-0.1.2 pelican-4.8.0 pelican-neighbors-1.2.0 pelican-search-1.1.0 pelican-webassets-2.0.0 pygments-2.16.1 python-dateutil-2.8.2 pytz-2023.3 rich-13.5.2 rtoml-0.9.0 six-1.16.0 smartypants-2.0.1 typing-extensions-4.7.1 typogrify-2.0.7 unidecode-1.3.6 webassets-2.0 zipp-3.16.2
test  > WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
test  >
test  > [notice] A new release of pip is available: 23.0.1 -> 23.2.1
test  > [notice] To update, run: pip install --upgrade pip
test  $ make publish
test  > "pelican" "/gcl-builds/content" -o "/gcl-builds/public" -s "/gcl-builds/publishconf.py"
test  > Done: Processed 5 articles, 0 drafts, 0 hidden articles, 2 pages, 0 hidden pages
test  > and 0 draft pages in 0.50 seconds.
test  finished in 6 min
PASS  test
```
