brainsteam.co.uk/brainsteam/content/posts/2024/01/20/Gitea_Forgejo Actions and P...

107 lines
5.0 KiB
Markdown
Raw Normal View History

2024-09-08 15:00:57 +01:00
---
categories:
- Software Development
date: '2024-01-20 14:05:07'
draft: false
tags:
- ci
- django
- docker
- gitea
title: Gitea/Forgejo Actions and PostgreSQL Tests
type: posts
2024-09-08 17:23:07 +01:00
url: /2024/01/20/gitea-forgejo-actions-and-postgresql-tests/
2024-09-08 15:00:57 +01:00
---
<!-- wp:paragraph -->
<p>I am<a href="https://brainsteam.co.uk/2023/11/13/gastronaut-fediverse-recipe-app/"> building a recipe app in django</a> and I want to be able to test the app within the CI pipelines when I push to my self-hosted gitea repository.</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The Problem</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Github actions already has a postgresql action but this crashes when you run Gitea's Action runner via docker:</p>
<!-- /wp:paragraph -->
<!-- wp:preformatted -->
<pre class="wp-block-preformatted">initdb: error: cannot be run as root
Please log in (using, e.g., "su") as the (unprivileged) user that will own the server process.</pre>
<!-- /wp:preformatted -->
<!-- wp:paragraph -->
<p>This is because, by default, docker containers don't really enforce users and permissions in the same way that systems installed in the operating system usually do and the action tries to run a load of stuff with the <code>root</code> user that should probably be run under the <code>postgres</code> system user account.</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Finding Another Approach</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>In gitea we can specify the underlying container that we want the action to run in (which is different to github where actions typically run in <a href="https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners">full VMs</a> rather than containers). Although the vanilla gitea container is reasonably good, I replaced it with <code>catthehacker/ubuntu:act-latest</code> so that <a href="https://brainsteam.co.uk/2023/11/18/gitea-actions-and-pdm/">I could get the setup pdm action to work</a>. This container effectively contains a basic set of stuff you'd find in a default ubuntu install including apt for managing packages. Ubuntu ships with a PostgreSQL server package so I went ahead and installed it which also initialises the relevant data files and service user accounts inside the container. </p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Then, I started the service with <code>service postgresql start</code>. Normally this would be a weird thing to do inside a docker container since best practice is typically to have a separate container per service. However, for testing purposes it's probably ok. </p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>The next step is to set a password for the postgres user which is used by the django app to log in and do the tests. We can use the <code>psql</code> command to do this and we use <code>sudo -u postgres</code> to authenticate against the <code>postgres</code> user before the password is set.</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Our final gitea actions yaml looks something like this:</p>
<!-- /wp:paragraph -->
<!-- wp:enlighter/codeblock {"language":"yaml"} -->
<pre class="EnlighterJSRAW" data-enlighter-language="yaml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">name: Run Tests
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on: [push]
jobs:
run_tests:
runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest
steps:
- name: Checkout Codebase
uses: actions/checkout@v3
- name: Configure and install postgres
run: |
apt update
apt install -y postgresql
service postgresql start
sudo -u postgres -s psql -U postgres -d postgres -c "alter user postgres with password 'test123';"
- uses: pdm-project/setup-pdm@v3
with:
python-version: 3.10
token: ${{ secrets.GH_TOKEN }}
- name: Install dependencies
run: cd ${{ gitea.workspace }} && pdm install
- name: Run Django tests
env:
DB_HOST: 127.0.0.1
DB_NAME: gastronaut
DB_USER: postgres
DB_PASSWORD: test123
run: |
cd ${{ gitea.workspace }} && pdm run manage.py test
</pre>
<!-- /wp:enlighter/codeblock -->
<!-- wp:paragraph -->
<p>Hopefully this will work out of the box. The whole thing is pretty efficient with a good internet connection, my run taks just under 2 minutes with about 25 seconds needed to install and configure the postgres db:</p>
<!-- /wp:paragraph -->
<!-- wp:image {"id":1576,"sizeSlug":"large","linkDestination":"none"} -->
2024-09-08 17:23:07 +01:00
<figure class="wp-block-image size-large"><img src="/media/image-2-1024x304_1cd16993.png" alt="a screenshot of the gitea actions CI log for the flow set out above and with indicative timings. The whole run takes 1m 47s and the postgres config step takes 25s" class="wp-image-1576"/></figure>
2024-09-08 15:00:57 +01:00
<!-- /wp:image -->