The problem
I am maintaining the rh_cloud plugin that has a hard dependency on Katello. The plugin uses GH Actions to test my PRs. Katello requires certain OS dependencies, like qpid e.t.c. The problem starts with the fact that GH Actions runs on ubuntu, but Katello dependencies are not available there.
Intermediate solution: Run containerized GH action.
This is a good solution that enables us to run our work on a centos-like environment. PR for reference: gh_actions to container by ShimShtein Ā· Pull Request #639 Ā· theforeman/foreman_rh_cloud Ā· GitHub. The only thing that makes me uncomfortable with this solution is the time it takes to run: since we need to build the container from scratch, it takes ~20 minutes to run the tests from which ~15 minutes is the setup, and this is too much for my taste.
Proposed solution: build a custom container for GH action.
The idea is to use a prebuilt container instead of an empty centos7 container.
Advantages:
- We can use the image as cache - we can prebuild as much as possible during the container build, leaving only the tests for the actual run phase.
- We can run the tests locally exactly the same way they run on CI, so it would be much easier to debug CI failures
- We can run the tests without installing heavy OS dependencies, for example if we use a distro that is not rh-derived.
- We can run the tests using different versions of foreman and katello. In case of rh_cloud plugin, I have to maintain at least two versions of the plugin for each foreman version. Now itās easy to run the tests against different foreman+katello combinations on the same machine.
Method:
I have added a Dockerfile
that will be used to build the base container. We want it to start with an empty centos container, then add the missing packages: in my case I have added scl-ed git, postgres and node plus the dev dependencies needed for the tests to run. Next I have cloned foreman, katello and rh_cloud repos. And lastly, I have run bundle install
and npm i
to cache the packages.
Now at runtime we can bind the correct plugin code (the one that we actually want to test), rerun bundle install
that would be quick, since the delta from the stable version is mostly small, rerun npm i
to do the same for our js packages and finally run the tests.
PR for reference:
One unresolved issue that I see, is the fact that npm i
is not using local cache similar to bundler, so this step take longer than I want it to.
Suggestions, comments e.t.c. would be appreciated.
If you think this is a useful way, I would be glad to work on a more generic version of the container to accommodate also other plugins.