Since the release of GitHub actions I always wanted to setup a continuous integration using GitHub actions as described in their documentation.
Why even use GitHub actions? π The less tools I have to use to do the job (coding), the better. So if GitHub is now providing a way to not have to use external tools like Travis CI or CircleCI then I am happy with it. And later on if GitHub also starts providing cloud services, and they are good, I'll just use that too.
Table of contents:
- Requirements
- Full workflow example
- Optional step: secrets as environment variables
- Opinions and current issues with GitHub actions
Requirements
I currently work on a Rails 6 application using PostgreSQL so I needed a workflow that would allow me to build and test a Rails 6 application using GitHub actions. Since actions are a recent feature (released publicly on August 8, 2019), it took me a bit more time than usual to have it working completely.
I like reproducible environments and so I needed a workflow that would:
- Install the ruby version specified in
.ruby-version
, along with Bundler - Install the Node.js version (for webpacker) specified in
.nvmrc
along with Yarn - Easily allow me to have a PostgreSQL database
- Cache steps as much as possible (node_modules, bundler) so that I have a fast build
Full workflow example
GitHub workflows are a set of GitHub actions and are stored in your code, inside the .github/workflows
directory. GitHub actions can either be from the official GitHub actions or from their actions marketplace.
The first step to testing your Rails application with GitHub actions is to create a file at .github/workflows/test.yml
and paste in it the content of this gist:
.github/workflows/test.yml:
Then commit and push, here's the result:
Optional step: secrets as environment variables
If you are using Rails credentials then you need the content of the file master.key
as a GitHub secret named RAILS_MASTER_KEY
. To create secrets in GitHub, just go in your repository settings in the secret
tab.
Then if you look at the previous gist, you'll see this:
- name: Rails test
env: # Or as an environment variable
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
Which will add the RAILS_MASTER_KEY
environment variable for your Rails application to decrypt Rails credentials.
Opinions and current issues with GitHub actions
While I enjoy the fact of having a continuous integration system that is builtin into GitHub, since GitHub actions are so new, they lack the attention to detail and experience of other tools for now. I will list the main ones from my point of view and I advise you to follow their associated GitHub issues if any, if you want to follow their progress:
-
no support for package.json's engines field or
.nvmrc
(to specify which version of Node.js to install) in the defaultsetup-node
action from GitHub.
engines support #94
Hello, It would be great if setup-node would automatically pick the correct version specified in our package.json engines property.
We're using github actions for 7 packages now and while all have an .nvmrc & specified engines still have to use the workaround provided in: https://github.com/actions/setup-node/issues/32#issuecomment-525791142
Related to: #32, #26
Support .nvmrc #32
It would be nice if setup-node
understood an .nvmrc file (even if it does not use nvm under the hood, the idea is the node-version
is just the contents of the file).
If GitHub Actions as a whole could read the contents of a file as part of an expression, I could do something like
uses: setup-node@v1
with:
node-version: {{ contents(.nvmrc) }}
But I don't know where to log that type of feature request!
Perhaps '.nvmrc' could be used as a special placeholder, so that:
uses: setup-node@v1
with:
node-version: '.nvmrc'
Instructs this action to read the contents and treat the contents as the desired version?
-
no support for
.ruby-version
files (to specify which version of Ruby to install) in the official action/setup-ruby action GitHub.
Support .ruby-version #31
Many ruby projects include a .ruby-version
file in the root directory, containing the version of Ruby needed.
Tools such as rvm
, rbenv
and chruby
all recognise and use this file.
This is not unlike the .nvmrc
file often used in Node projects, and the setup-node
action has a discussion on potentially using the contents of that file as the node version if no with:
argument is specified. (https://github.com/actions/setup-node/issues/32)
I would suggest that setup-ruby
might consider a similar approach, where if no explicit ruby version is given, look for a .ruby-version
file and use the version contained within.
- For some libraries, like ged/ruby-pg you have to apt-get install the
libpq-dev
package while this should be a default.
Add libpq-dev #12
Tool information
- Tool name: libpq-dev
- Add or update? add
- Desired version: whatever is latest
- Approximate size:
- If this is an add request:
- Brief description of tool:
libpq-dev
is a C library for interfacing with Postgres; it is commonly needed for Ruby/Rails environments that create and interact with a database as part of test suites - URL for tool's homepage: https://www.postgresql.org/docs/9.5/libpq.html
- Brief description of tool:
Virtual environments affected
- [ ] macOS 10.14
- [x] Ubuntu 16.04 LTS
- [x] Ubuntu 18.04 LTS
- [ ] Windows Server 2016 R2
- [ ] Windows Server 2019
Can this tool be installed during the build?
Current workaround is to install manually via apt-get
-- this adds 1-2 minutes to the workflow time and has to be repeated for every build
- Actions are versionned but it would be great if there was a way to be notified of new versions easily. Or even better, to have GitHub bots opening pull requests to upgrade the versions of the actions. So that you always have the latest features available
- no way to manually trigger workflows
π That's it!
π Thank you for reading.
Thanks to Benoit Daloze and Masatoshi Iwasaki for their help on Ruby and Bundler setup in GitHub workflows.
Did you enjoy this post? Any advice as for GitHub actions and Rails configuration? Add your thank you note or advice in the comments and I'll reply :)
Click below to share this post:
Vincent Voyer@vvoyerUse #github actions continuous integration features to test your #rubyonrails π application (+ PostgreSQL, Ruby, Bundler, Node.js, Yarn): A complete workflow setup.
πdev.to/vvo/a-rails-anβ¦
Enjoy this friday reading ππ10:19 AM - 10 Jan 2020
Top comments (15)
Docker Compose is definitely installed on GitHub actions, not sure what you mean by "no support".
Here's the Workflow that uses
make
tasks to run thedocker-compose
commands: github.com/weathermen/soundstorm/b...And the Makefile, which runs them: github.com/weathermen/soundstorm/b...
Thanks for that! I just removed that part. I tried to use it though and ran into issues mostly because my setup is not fully docker-compose based. I use docker-compose only for services, my Rails code runs in the ubuntu container from GitHub.
So the issue I get is this one:
My docker-compose.yml:
The volume is mounted with a user/permission that is different from the one used when I run the
rails test
command. I tried to work around that without luck, if you have any idea let me know. From what I can tell I think your whole infra runs in a docker container while me I always run Ruby/Rails locally and only use compose for services (good or bad that's how I do it for now).Thanks again!
Hi, I've found tricky solution for the manual trigger and also others completed my answer on stack overflow: stackoverflow.com/questions/589331...
Oh wow that's very clever, and I read also the comment on SO from someone saying you could also limit that to the repository owner.
Do you know what it would take to update my current gist to allow for the repository owner, when they star the repo, to trigger a build?
Right now I have:
what do I need to change? I am new to the syntax :D
Alright, you can try this :
Notice you may have to reindent but I hope it would be fine :)
Thanks, I guess the last step is on how to combine what you propose with an already in place workflow that gets executed at push time.
For now I have:
But if I change that to what you propose then my workflow is no more executed at push time.
Do you know if we can combine both manual trigger trick + usual push testing in a single or a combination of workflows maybe? Let me know!
Yes, I set just the beginning but you can adapt it for an existing workflow or a new one.
Yes you can !
For your example it will be like that :
I din't try out yet this but I've already tried to setup a workflow with push event and cron, so it should be fine !
Hi,
I was working on a very similar article (Actually, I'm not sure that I'll publish it now XD).
In my workflow, I set up two tests. The first one uses Rubocop to do static analysis of the code, and the second one uses RSpec and then generate a report using SimpleCov.
You can check my yaml file here
I also noticed another issue when I was trying to use environment variable to specify the version of the operating system that will be used for the tests.
Great job, thanks for sharing.
Hey there, thanks for the comment. Indeed I haven't yet setup multiple steps with dependencies in my setup. I might have to and your example will be very useful, thanks!
Nice posts!. Don't you have in your bag a tuto on how to setup correctly a dockerized React + Rails API using Sidekiq/Redis? As a newbie, developing an app is not so difficult, but deploying it, env variables, the database config.. all these kind of things is a real nightmare.
Hey there, sorry I do not have that (also, I stopped my Rails learning and went back to Node.js!).
Good luck though, thanks for your comment
So helpful! Thank you!
Awesome guide! Thanks so much!
Do you have any experience with using environment credentials in Github actions? Or should the master.key override the test.key anyway?
I have no experience but this post: stackoverflow.com/questions/614445... suggest using a test key and uploading it to GitHub I guess