Skip to content
Snippets Groups Projects

GitLab CI template for Angular

This project implements a generic GitLab CI template Angular based projects.

It provides several features, usable in different modes (by configuration).

Usage

In order to include this template in your project, add the following to your gitlab-ci.yml:

include:
  - project: 'to-be-continuous/angular'
    ref: '3.0.1'
    file: '/templates/gitlab-ci-angular.yml'

Global configuration

The Angular template uses some global configuration used throughout all jobs.

Name description default value
NG_CLI_IMAGE The Docker image used to run Angular-CLI (ng)
⚠️ set the version required by your project
trion/ng-cli-karma:latest
NPM_CONFIG_REGISTRY NPM registry none (defaults to https://registry.npmjs.org)
NPM_CONFIG_SCOPED_REGISTRIES Space separated list of NPM scoped registries (formatted as @somescope:https://some.npm.registry/some/repo @anotherscope:https://another.npm.registry/another/repo) none
NG_WORKSPACE_DIR Angular workspace directory .

Jobs

ng-lint job

The Angular template features a job ng-lint that performs Angular source code lint.

It is bound to the check stage, and uses the following variable:

Name description default value
NG_LINT_ARGS Angular ng lint arguments lint

ng-build job

The Angular template features a job ng-build that performs build and tests all at once.

Those stages are performed in a single job for optimization purpose (it saves time) and also for jobs dependency reasons (some jobs such as SONAR analysis have a dependency on test results).

Those stage are bound to the build stage, and uses the following variable:

Name description default value
NG_TEST_ARGS Angular ng test arguments test --code-coverage --reporters progress,junit
NG_BUILD_ARGS Angular ng build arguments build --prod

The next chapters presents some requirements related to your unit tests (using Karma).

Use a headless browser

To be able to launch unit tests with Angular CLI, the Angular template requires a headless browser within the Docker image NG_CLI_IMAGE (it is the case with the default image, docker-ng-cli-karma).

Code Coverage

In order to be able to compute and enable GitLab code coverage integration, the Angular template expects the following in your karma.conf.js (this is done by default if your project was generated with ng new command).

Add the karma-coverage package:

  require('karma-coverage'),

Add the config section:

  // [to be continuous]: karma-coverage configuration (needs 'text-summary' to let GitLab grab coverage from stdout)
  coverageReporter: {
    dir: 'reports',
    subdir: '.',
    file: 'ng-coverage.lcov.info',
    reporters: [{ type: "lcovonly" }, { type: "text-summary" }],
  },

JUnit report

In order to be able to integrate your test reports to GitLab, the Angular template expects the following in your karma.conf.js.

Add the karma-junit-reporter package as dev dependency:

npm install --save-dev karma-junit-reporter

In your karma.conf.js, add the plugin:

  require('karma-junit-reporter'),

Add the config section:

  // [to be continuous]: karma-junit-reporter configuration (report needs to be in 'reports/ng-test.xunit.xml')
  junitReporter: {
    outputDir: 'reports',
    outputFile: 'ng-test.xunit.xml',
    useBrowserName: false,
    ...
  }

SonarQube report

If you're using SonarQube and if you want to generate a test report compatible with SonarQube, the Angular template expects the following.

By default Angular CLI do not allow to generate test report compatible with Sonar to do so, you need to add karma-sonarqube-execution-reporter to your project as a dev dependency:

npm install --save-dev karma-sonarqube-execution-reporter

In your karma.conf.js, add the plugin:

  require('karma-sonarqube-execution-reporter')

Add the config section:

  // [to be continuous]: karma-sonarqube-execution-reporter configuration (report needs to be in 'reports/ng-test.sonar.xml')
  sonarQubeExecutionReporter: {
    outputDir: 'reports',
    outputFile: 'ng-test.sonar.xml',
    ...
  }

Finally add the sonarqubeUnit reporter in the reporters parameter of the NG_TEST_ARGS variable :

NG_TEST_ARGS:  test --reporters junit,sonarqubeUnit`

ng-e2e job

The Angular template features a job ng-e2e that performs protractor tests This stage is bound to the test stage and uses the following variables :

Name description default value
NG_E2E_ARGS Angular ng e2e arguments e2e
NG_E2E_ENABLED set to trueto enable the e2e tests execution none (disabled by default)

Implementation rely on the official Angular CLI tool (ng build and ng test commands).

To enable JUnit reporting on this job, you'll need to add jasmine-reporters dependency to your project and add the following snippet to your protractor config file :

const { JUnitXmlReporter } = require('jasmine-reporters');

exports.config = {
  ...
    onPrepare() {
    jasmine.getEnv().addReporter(new JUnitXmlReporter({
      consolidateAll: true,
      savePath: 'reports',
      filePrefix: 'ng-e2e.xunit'
    }));
  }
  ...
}

ng-publish job

The Angular template features a ng-publish job to publish the built project.

This job is bound to the publish stage, and uses the following variable:

Name description default value
NG_PUBLISH_ENABLED Set variable to true to enable the publish job none (disabled)
NG_PUBLISH_PROJECTS Space separated list of projects to publish If no project is specified, the value of angular.json defaultProject property is used
NG_PUBLISH_ARGS NPM publish arguments --verbose
NPM_PUBLISH_REGISTRY NPM registry to publish to uses GitLab project npm packages registry
🔒 NPM_PUBLISH_TOKEN NPM publication registry authentication token none

⚠️ When using the gitlab registry (which is the default behavior), your NPM package name must be in the format of @scope/package-name:

  • The @scope is the root namespace of the GitLab project. It must match exactly, including the case.
  • The package-name can be whatever you want.

For example, if your project is https://gitlab.example.com/my-org/engineering-group/team-amazing/analytics, the root namespace is my-org. When you publish a package, it must have my-org as the scope. For more details see Package naming convention.

⚠️ Don't forget to specify the publication registry in the project(s) to publish package.json file (not the workspace top-level one).

{
  "name": "@my-org/hello-world",
  "version": "0.0.6",
  "peerDependencies": {
    "@angular/common": "^10.1.6",
    "@angular/core": "^10.1.6"
  },
  "dependencies": {
    "tslib": "^2.0.0"
  },
  "publishConfig": {
    "@my-org:registry": "https://<publication-registry-url>"
  }
}

ℹ️ When using the GitLab registry, the registry publication url looks like https://<gitlab-host>/api/v4/projects/<your_project_id>/packages/npm/, with:

  • <gitlab-host> is your GitLab host domain name.
  • <your_project_id> is your project ID, found on the project’s home page.

SonarQube analysis

If you're using the SonarQube template to analyse your Angular code, here is a sample sonar-project.properties file:

# see: https://docs.sonarqube.org/latest/analysis/languages/typescript/
# set your source directory(ies) here (relative to the sonar-project.properties file)
sonar.sources=app
# exclude unwanted directories and files from being analysed
sonar.exclusions=node_modules/**,dist/**,**/*.spec.ts

# set your tests directory(ies) here (relative to the sonar-project.properties file)
sonar.tests=app
sonar.test.inclusions=**/*.spec.ts

# tests report: generic format
# set the path configured with karma-sonarqube-execution-reporter
sonar.testExecutionReportPaths=reports/ng-test.sonar.xml
# lint report: TSLint JSON
sonar.typescript.tslint.reportPaths=reports/ng-lint.tslint.json
# coverage report: LCOV format
# set the path configured with karma-coverage-istanbul-reporter
sonar.typescript.lcov.reportPaths=reports/ng-coverage.lcov.info

More info: