GitLab CI artifacts usage via the DEB-package build and publishing example

GitLab CI provides a convenient mechanism for storing build artifacts in GitLab. An artifact is any file that a developer wants to store for a long time after a build completes successfully. This mechanism can be used to store distributions and various build logs. Artifacts are easy-to-use. In this article, using the example of publishing a built DEB-package that is downloadable from GitLab we will show how artifacts storing is implemented.

GitLab CI artifacts are not always convenient to use. Sometimes you may need to enable FTP, SFTP, publishing to Nexus or other artifacts management systems. However, often it is just enough to have a storage that enables the access to build results.

Let’s look into the feature implementation on the example of a simple .gitlab-ci.yml build scenario presented below:

image: python:2.7

variables:
  PACKAGE: private-package

stages:
  - build

before_script:
  - pip install --user -r requirements.txt

build:
  stage: build
  script:
    - export PATH=$PATH:/root/.local/bin
    - export PACKAGE_VERSION=$(cat version)
    - export BUILDTIME=$(date +"%s")
    - make
    - cp -R deb/* $PACKAGE
    - "echo \"Package: $PACKAGE\" >> $PACKAGE/DEBIAN/control"
    - "echo \"Version: $PACKAGE_VERSION\" >> $PACKAGE/DEBIAN/control"
    - "echo >> $PACKAGE/DEBIAN/control"
    - dpkg-deb --build $PACKAGE
    - mkdir -p releases
    - mv $PACKAGE.deb releases/$PACKAGE-$PACKAGE_VERSION-$BUILDTIME-all.deb
  artifacts:
    paths:
    - releases/*.deb
    expire_in: 1 month

In this scenario a Python project is being built using Pyinstaller. The whole work is done in Makefile that is omitted here.

Basic tasks to build a DEB-package are thoroughly described in the official documentation. We will dive into some aspects in detail:

The DEBIAN directory with the control file containing the text below must be placed to the root of the intended package:

Maintainer: BWSoft Management, LLC
Architecture: all
Description: Private Package
Package: private-package
Version: 0.1

The last two lines of the control file in our build script are formed dynamically using the following code:

    - export PACKAGE_VERSION=$(cat version)
    - "echo \"Package: $PACKAGE\" >> $PACKAGE/DEBIAN/control"
    - "echo \"Version: $PACKAGE_VERSION\" >> $PACKAGE/DEBIAN/control"
    - "echo >> $PACKAGE/DEBIAN/control"

You may decide to avoid getting a package version from the version file as shown in the example but use a variable for the GitLab project group instead. However, in this case we consider the suggested approach to be more suitable. The DEB builder requires an empty line at the end of the file.

Then, we build the DEB-package in a common way, rename it and put it into a correct directory that will be used for artifacts search:

    - dpkg-deb --build $PACKAGE
    - mkdir -p releases
    - mv $PACKAGE.deb releases/$PACKAGE-$PACKAGE_VERSION-$BUILDTIME-all.deb

Artifact publishing is performed using the artifacts section:

  artifacts:
    paths:
    - releases/*.deb
    expire_in: 1 month

Everything is clear here. We define the paths to artifacts – these are all files with *.deb extension placed in the “releases” directory in our case. By expire_in we also define the artifacts to be kept in GitLab for a month.

After the build finishes the artifacts can be accessed via the right sidebar of the project. You can download the artifacts archive or browse its contents.

Conclusion

In the provided example we have illustrated a simple approach that can be used to store build artifacts to GitLab server. This approach is not quite convenient in such cases when artifacts are required to be automatically provided to the third parties. Though, if an artifact user is an authorized GitLab user, the approach can be successfully implemented in commercial development. However, GitLab provides API to access build artifacts. It can be used to provide access for the third parties or to export artifacts to external storages.

If you like this post and find it useful, please, share it with friends.