image of packagecloud repo containing a npm package

Using CircleCI to publish your software to the Packagecloud repository

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 hereOnce 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’


undefined

                      2. In the ‘Create a repository’ modal, fill in the details as follows:
undefined

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’


undefined

                      2. Fork the repository to another GitHub account


undefined

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’

undefined

                      2. Once you are logged in, look for your GitHub repository and set it up as a project


undefined

                      3. Select the branch ‘master’ and CircleCI will automatically detect the ‘.circleci/config.yml’ and use it


undefined

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

undefined


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: 


undefined

                      2.Go to circleci.com project settings


undefined

                      3. Add the environment variable NPM_TOKEN (note that you don’t use the preceding ‘$’)


undefined

                      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>/

undefined

You should see your package.

Hungry for more knowledge?

Related posts