Introduction
In programming, people often use packages to extend the functionalities of a language. By using packages, developers can save their time since it removes a necessity for them to create packages by themselves and also achieve reliability as they can carry out research and only use safe ones. However, when the package you need does not exist, you may decide to develop one. Once you’ve created your new package, you might run into the challenge of figuring out how to publish and efficiently use it across different resources. This article discusses the package publication cycle for Ruby and the best options available.
Before we get started, check out Packagecloud. Packagecloud allows its users to easily create and manage consistent package repositories at a large scale with top notch security. You can use our API and CLI to interact with your packages across different operating systems and environments. This happens without disrupting your base environment since it works with the systems you already use.
What is RubyGems?
To understand RubyGems, you first need to know what Ruby is. Ruby is a programming language that was developed in the mid-1990s by Yukihiro Matsumoto in Japan. It is a high-level and general-purpose programming language. The language embraced multiple programming principles such as procedural, object-oriented, and functional programming. Ruby is known for simplicity and productivity thanks to its efficient syntax and easy-to-understand coding style.
RubyGems is a package manager for Ruby. With RubyGems, you can distribute Ruby programs and libraries in a contained format called “gem”. This allows users to easily manage installation and distribution of gems. RubyGems was not developed by Ykihiro but by Chad Fowler, Jim Weirich, David Alan Black, Paul Brannan and Richard Kilmer. Interacting with RubyGems can be done through gem - which is its command-line tool. Using this tool, developers can install and manage libraries. In Ruby a library is called a gem (or gems for multiple libraries).
With RubyGems, you can find and load installed gems from library folders. When it comes to a repository, you can choose either private or public repo, however, many people tend to use public repos for package management. The public repository makes it easier to find gems, resolve dependencies, and install libraries.
Make RubyGems
There can be situations where you want to make RubyGems by yourself. Whether you cannot find a package that suits your needs or you want to build one that is specific for your team or organization, creating your own can increase overall efficiency. Your colleagues can use the same package, which prevents them from writing redundant and duplicate code. Also, you can have an inheritance pattern where a change to the package can become effective to all the areas that use the gem.
In addition to these benefits, building your own RubyGems is an enjoyable process thanks to Bundler - the Ruby’s package building tool that makes the process simple and easy. For your understanding, we will just use “helloworld” for the meta file name and Ruby file. If you want to push the package, we would recommend you make its name unique and distinguishable instead.
Structures
Let’s start with package structure. The following shows the basic package structure:
root
├── helloworld.gemspec
└── lib
└── helloworld.rb
In the package, we have one Ruby file for the helloworld gem. Of course, you can try any other name. Your ruby code for the package will be located in the lib folder. Ruby’s naming convention recommends you have one Ruby file with the same name as your gem. This allows users to load your package when they require ‘helloworld’.
Code
For this example, the code file is simple. When executed, it will print out “Hello world!”. The cat command will create the ruby file:
% cat lib/helloworld.rb
class HelloWorld
def self.hi
puts "Hello world!"
end
end
gemspec
The gemspec file contains the details of what’s inside the gem. It includes the author and the version of the package. The gemspec file also serves as an interface to RubyGems.org. If you have any experience using a gem, you may have seen the details about it. That comes from this gemspec file:
% cat helloworld.gemspec
Gem::Specification.new do |s|
s.name = helloworld
s.version = '0.0.1'
s.summary = "Say hello to the world!"
s.description = "A simple hello world gem"
s.authors = ["Test Author"]
s.email = 'testauthor@email.com'
s.files = ["lib/helloworld.rb"]
s.homepage =
'https://RubyGems.org/gems/hola'
s.license = 'MIT'
end
Copy and paste the whole snippet above in your bash command. This will create a gemspec file. The syntax style for gemspec follows the same rules as normal Ruby coding style. In addition to the fields above, you can find further available fields in this reference.
Build
Now that you have prepared your code and package meta file, you can start building it. In your bash command, execute the gem build command as below which will give you output like this:
% gem build helloworld.gemspec
Successfully built RubyGem
Name: helloworld
Version: 0.0.1
File: helloworld-0.0.1.gem
% gem install ./helloworld-0.0.1.gem
Successfully installed helloworld-0.0.1
1 gem installed
After the build, make sure you run a test:
% irb
>> require 'helloworld'
=> true
>> HelloWorld.hi
Hello world!
If you can successfully import ‘helloworld’ ruby and see the “Hello world!” message, then you succeeded in building your first RubyGem. Congrats!
Publishing your RubyGem
You have just created your first RubyGem. You can now publish it for the rest of the Ruby community. The publishing process is straightforward. You first need to have an account on the RubyGems.org website. Once you have an account, execute the following command:
$ curl -u yourusername https://RubyGems.org/api/v1/api_key.yaml >
~/.gem/credentials; chmod 0600 ~/.gem/credentials
Enter host password for user 'yourusername':
After this set up, you can push your gem by:
% gem push helloworld-0.0.1.gem
Pushing gem to RubyGems.org...
Successfully registered gem: helloworld (0.0.1)
After this, anyone will be able to use your gem. You can also go search your package at RubyGems.org. Or, you can switch to any computer with Ruby environment and run:
% gem list -r helloworld
*** REMOTE GEMS ***
helloworld (0.0.1)
% gem install helloworld
Successfully installed helloworld-0.0.1
1 gem installed
The whole process itself from preparing your package structure to publishing your RubyGem is not complicated.
How to publish RubyGems
We have learned how to make RubyGems and publish it to RubyGems.org. For simplicity, we shared the method of publishing it to the public Ruby website. However, if you want to publish it elsewhere, there are some other options. Before you decide to push your RubyGems to the public website, you need to consider several factors. Since anyone can install your package from RubyGems.org, you need to ensure not to contain sensitive data or logic inside the package. Once published to the website, anyone can look inside your package and use it.
Also, you will want to check the compatibility of your package across all team members. Quite often, developers in the same team can have different settings including operating system, version of OS, dependent package versions, and more. This means when you make RubyGems in your environment and publish for your team members, it may not work normally in their environments.
Publish to Packagecloud
From a DevOps perspective, it is not an easy task to make sure all users can reliably utilize your packages. Packagecloud can resolve that issue. In Packagecloud, you can create a containerized environment with the RubyGems you built. You can maintain different containers with different OS but with the same RubyGems. Then, your team members can simply use that container, which allows them to have a consistent environment across the team.
Packagecloud provides package_cloud gem for pushing your RubyGem to Packagecloud in terminal and packagecloud-ruby gem for programmatically pushing gem using our Ruby package. This guide, “Pushing packages to packagecloud”, gives you a quick rundown on how this process works.
Publish to git repository
You can consider setting up your public or private git repository and push your RubyGems there. This can help you track changes and source-control your packages. However if you do this, it will become the users’ responsibility to resolve any dependent and incompatibility issues. Also, when you have multiple RubyGems it can be tricky for a user to git clone and pull to get the new and updated gems.
Publish to private RubyGem server
For security, you can set up a private RubyGem server. To do this, you will need to do some research to find a third-party vendor. If you decide to go this route, you will want to make sure to avoid accidental push to the public server since the process can be similar. Furthermore, while most vendors provide a repository, their solutions are not as secure as Packagecloud’s containerized environments.
Wrapping up
In this article, we discussed how to make RubyGems and publish them using various options. The process of building your gem itself is not difficult. What you do have to consider is where you want to publish your important gems. You can study and experiment with the publishing process to the public website. However, for your gems you want to keep private, using Packagecloud can help you achieve the efficiency, scalability, and security you need. Check out Packagecloud today and start a 14 day trial.