Many companies implement a continuous integration (CI) strategy to deploy, build, test and release code incrementally. Once a release is ready, it will be tagged with a version and published to a repository where it can be easily installed with a few clicks by the user. There is no simpler and better repository than packagecloud.io for 2 reasons:
- Packagecloud.io has integrations with many CI platforms with step-by-step instructions like this one for CircleCI
- Users can easilyy install those packages with packagecloud.io’s install scripts, removing the need to understand the operating system or the packaging system for a programming language where the package will be installed
To integrate your CircleCI workflow with packagecloud.io, here are the steps:
1. Sign in to Packagecloud, and then create a repository to store the software package that we build
2. Add/modify your CircleCI config, to contain instructions to build and publish the software package
3. Configure CircleCI to use the config to continuously build and publish the package when a new version is created/tagged
4. Retrieve the Packagecloud API key and add to CircleCI environment variable to enable CircleCI to access to Packagecloud
Nomenclature
We use the word repository to refer to code repository, e.g., github.com, and also package repository, e.g., Packagecloud.io.
We use the term package to refer to both software or programming libraries that maintainers/creators create for usage by others, with the subtle difference being the former refers to a piece of software that the end-user can use, e.g., a Slack desktop client, and the latter can be used as building blocks by developers to create software.
Create an Account & Repository
You can create a new Packagecloud account here. Once you’ve created an account, there is a simple wizard that will guide you through to create a repository to store your packages. If you have already completed the wizard before and would like to create a new repository, login and go here: https://packagecloud.io
1. Click ‘Create a repository’
2. In the ‘Create a repository’ modal, fill in the details as follows:
Add/Modify CircleCI config to the codebase
Your CircleCI Experience
You could be in one of three situations here:
1. Case 1: You already use CircleCI to continuously build and test your code so you already have the ‘.circleci’ directory with a file ‘config.yml’ in it. You are looking to push your package to packagecloud.io for distribution to your end-users.
2. Case 2: You have a codebase that can build a package but have no continuous integration to continuously build, test and push your package to packagecloud.io for distribution to your end-users.
3. Case 3: You don’t have a codebase to build a package, but want to get an idea of what such a codebase and continuous integration with CircleCI looks like.
For Cases 1 & 2, please skip ahead to the next subsection.
Create (Copy) a codebase that creates a package
For Case 3, you can ‘fork’ a packagecloud.io GitHub code repository that we created to build an npm test package.
1. Go to the repository and click ‘fork’
2. Fork the repository to another GitHub account
Add/Modify CircleCI config
Here is a sample config of how to integrate CircleCI into your codebase to build and publish your package to packagecloud.io.
For Case 1, adapt this to the existing ‘.circleci/config.yml’ while for Case 2 & Case 3, create ‘.circleci’ directory and create ‘config.yml’ file in the directory.
There are 2 important changes that you need to make. They are marked in bold italic and encapsulated by angular brackets ‘<’ and ‘>’.
- <PACKAGECLOUD_USER>
- Packagecloud username that you created
- <PACKAGECLOUD_NAME>
- Packagecloud repository name that you created
Also note the line in the config (shown just below for ease of reference)
command: echo "//packagecloud.io/<PACKAGECLOUD_USERNAME>/<PACKAGECLOUD_REPONAME>/npm/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
CircleCI needs the $NPM_TOKEN environment variable to be set up so that it has access to push packages to packagecloud.io. Keep this in mind as we will do this in the next steps.
# Javascript Node CircleCI 2.0 configuration file
#
# Check {{ '/2.0/language-javascript/' | docs_url }} for more details
#
version: 2
defaults: &defaults
working_directory: ~/repo
docker:
- image: circleci/node:8.9.1
jobs:
test:
<<: *defaults
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-
- run: npm install
- run:
name: Run tests
command: npm test
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- persist_to_workspace:
root: ~/repo
paths: .
deploy:
<<: *defaults
steps:
- attach_workspace:
at: ~/repo
- run:
name: Set registry URL
command: npm set registry https://packagecloud.io/<PACKAGECLOUD_USERNAME>/<PACKAGECLOUD_REPONAME>/npm/
- run:
name: Authenticate with registry
command: echo "//packagecloud.io/<PACKAGECLOUD_USERNAME>/<PACKAGECLOUD_REPONAME>/npm/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
- run:
name: Publish package
command: npm publish
workflows:
version: 2
test-deploy:
jobs:
- test
- deploy:
requires:
- test
filters:
tags:
only: /^v.*/
Commit this config to your github repository.
-
-
git add .circleci/config.yml
-
git commit -m “Add CircleCI config”
-
git push origin master
-
Configure CircleCI to use the config
Next you need to add your GitHub repository to CircleCI.
1. Click here and click ‘Log in with Github’
2. Once you are logged in, look for your GitHub repository and set it up as a project
3. Select the branch ‘master’ and CircleCI will automatically detect the ‘.circleci/config.yml’ and use it
You will notice that CircleCI will run, and it will fail, in the ‘deploy’ step. There are 2 steps in the CircleCI workflow ‘test’ and ‘deploy:
-
- test: Run unit/integration tests
- deploy: Push built package to packagecloud.io
It is failing because we have not set the $NPM_TOKEN environment variable, which is required to grant CircleCI access to push to packagecloud.io, as discussed in the previous step.
Retrieve packagecloud.io API key and add to CircleCI environment variable
1. Login to packagecloud.io and click here to retrieve the API key:
2.Go to circleci.com project settings
3. Add the environment variable NPM_TOKEN (note that you don’t use the preceding ‘$’)
4.Trigger Package Build
Since previously the build failed, you can re-run the failed build.
In normal circumstances, when you are ready to push a new version of the package
- Tag the new version
- Change the tag “v1.0” and the message “Version 1.0” as necessary
- git tag -a “v1.0” -m “Version 1.0”
- Push the tag to github code repository
- This will trigger CircleCI
- git push origin “v1.0”
The reason why a new tag beginning with ‘v’ triggers a build is, in the ‘.circleci/config.yml’ there is this code (see bold):
workflows:
version: 2
test-deploy:
jobs:
- test
- deploy:
requires:
- test
filters:
tags:
only: /^v.*/
Confirm package push
Go to your packagecloud.io repository with the url: https://packagecloud.io/<PACKAGECLOUD_USERNAME>/<PACKAGECLOUD_REPONAME>/
You should see your package.