A template repository for building Ruby applications, services, and libraries.
This project heavily leverages GitHub's architecture patterns such as:
- Scripts to Rule them All
- Dependency Vendoring (
vendor/cache/
) - Usage of rbenv
All of the scripts defined below follow GitHub's Scripts to Rule them All pattern. This pattern is a set of well-defined scripts that are used to perform common tasks such as bootstrapping, testing, linting, and more. These scripts are defined in the script/
directory.
First, ensure you have rbenv installed
To bootstrap the project and install all dependencies (RubyGems), run the following command:
script/bootstrap
You can also alter this command to only install gems for production builds/environments:
RUBY_ENV=production script/bootstrap
Gems will be installed locally into the vendor/gems/
directory at the root of this repository.
After bootstrapping the project, you can run the test suite:
script/test
By default, this project enforces 100% code coverage. After running script/test
, you can view the code coverage report in the coverage/
directory at the root of the repository.
To lint the project, run the following command:
script/lint
The linter that this project uses is rubocop and its configuration is defined in the .rubocop.yml
file.
Build a Docker image:
script/docker-build
The result of this command will be a Docker image built with the name ruby-template:latest
.
This script:
- Builds a Docker image using the
Dockerfile
in the root of the repository. - Tags the image with the
latest
tag.
To build a tarball of the application for deployment, run the following command:
script/tarball
This will build a docker container and run the script/build-deploy-tarball
script inside the container. The result will be a tarball in the tarballs/
directory at the root of the repository.
Tarballs are popular for atomic deployments where the deployment is a simple matter of extracting the tarball to the correct location on the target machine and running the new version of the application. Tarball deploys help to shift the complexity of the deployment process from the target machine to the build server (in this case, the CI server - Actions).
This script:
- Builds a Docker image using the
Dockerfile
in the root of the repository. - Inside of the Docker container it:
- Install all dependencies
- Creates a compressed tarball with all the source code and dependencies. The dependenices are even pre-installed to save time when deploying the application. This means that the
vendor/cache/*.gem
files have been installed via bundler into thevendor/gems/
directory. - Adds commit metadata to the tarball by dropping
BUILD_SHA
andBUILD_BRANCH
files in the root of the tarball
- Drops the tarball in the
tarballs/
directory at the root of the repository.
From this point, you would have a file named tarballs/linux-aarch64-bookworm-sha123abc.tar.gz
(just an example) that would exist either on your local machine (or in a CI system) that you could use to deploy the application to a server.
See the Dockerfile.tarball file for an example of how to unpack this pre-built tarball and run the application. It doesn't even require script/bootstrap
to be called or apt-get
packages to be installed (in most cases) - neat!
Remember, this is just a template repository so this command won't really do anything. This template is a simple app that adds two numbers together. Run it with the following command:
script/server 1 2 # result: 3
Define the specific build steps in the script/build
script.
A build script for Ruby might look something like this.
The script/release
script is a starting point for pushing and tagging new releases on GitHub.
This project adopts a "vendor everything" approach to dependencies. This means that all dependencies are vendored into the repository. This is done to ensure that the build is reproducible and that the build is not dependent on the availability of external dependencies (e.g. RubyGems.org).
All Ruby Gems are committed to version control and stored in the vendor/cache/
directory.
This behavior is further controlled by the .bundle/config
file.