Skip to Content
Technical Articles
Author's profile photo Alexander Tsybulsky

Automatic checking of your ABAP code in Github/Gitlab with CI and abaplint

Merry Christmas !

This post is not about ABAP directly but about tooling around it. You probably know about abapGit written by Lars Hvam (regards!). You might also know about another tool from him called abaplint – a static code analyzer. In a nutshell, it is a kind of SCI but written in javascript and so can be run outside of an SAP system. I won’t describe abaplint itself in detail. You can search a couple of posts here at SCN and also visit homepage of the product for this. The post is about automatic running of it using CI tools.

Since the availability of abapGit more and more CI scenarios becomes possible for ABAP. Keeping ABAP code in git repositories slowly becomes the mainstream. As well as different CI (continuous integration) scenarios around it. One of scenarios is automatic code check which abaplint makes possible.

Let’s focus on 2 popular git providers – Github and Gitlab.

Github is widely used for open-source. Recently there have been a rise of open-source ABAP packages (thanks to abapGit). Open-source projects are open for everyone to contribute, but how to ensure that the coding style for the project remain unified. Like variable naming conventions, indentation, case of key words, etc. This can be heavily assisted by automatic CI script which would run for each pull request from a contributor.

Gitlab is more enterprise oriented. It supports free private repositories and also a possibility to install it on premises. This makes it a good candidate for local git system role for teams and companies who are willing to embrace and benefit from modern development practices.

In this post I’ll share a sample configuration of how to run abaplint automatically for your repositories in both providers.


First let’s start from Github. The service itself does not have a CI functionality, you have to use external one. Most popular is probably Travis.

1. let’s assume you have a repository with some code. Example github repo can be found here.

2. Create an account in Travis and link it to you Github account. If you don’t have it – all you need to go to (or better, see UPD2 at the bottom) and press sign-in with Github. On the way it will ask to authorize Travis for certain operations and monitoring of you code – you can allow it – this is how Travis automatically finds out about changes to your repositories and makes it’s job.

In your Github account you can see this connection in your account setting – Application settings. Here you can revoke the access if you would like to stop it later.

Travis will automatically find all your repositories and propose to choose ones to do the CI builds for. But let’s first prepare our repo files for this.

3. In order to run abaplint for your repository you have to add 2 additional files there.

abaplint.json – the configuration for abaplint so it knows what to check. Some documentation can be found on abaplint homepage. But let’s focus on our example. The given rules are checking: indentation, capital keywords and maximal length of the line (there are more rules available but let’s focus these for simplicity).

  "global": {
    "version": "v702"
  "rules": {
    "keywords_upper": {
      "enabled": true,
      "ignoreExceptions": true
    "line_length": {
      "enabled": true,
      "length": 80
    "start_at_tab": {
      "enabled": true

Let’s also consider our repository files. There is a program and an include for it. Include contains this code

CLASS lcl_name_factory DEFINITION FINAL.
    CLASS-METHODS get_greeting
        iv_name TYPE string
        value(rv_greeting) TYPE string.
CLASS lcl_name_factory IMPLEMENTATION.
  METHOD get_greeting.
   rv_greeting = |Hello { iv_name }|.

And if you look attentively you would find 2 violation of the rules defined above: value keyword is in lower case and wrong indentation of method code (just one space at the beginning). This is expected to be found by our test scenario. Stay tuned.

Second file to add to the repo is .travis.yml – this is a configuration for Travis so that it knows how to check the code.

language: node_js
  - "10"
  email: false
  - npm install -g abaplint
  - abaplint "src/**/*.*"
    - master

In a nutshell it specifies that:

  • in order to run the check it uses node.js environment. Abaplint is written on javascript (typescript to be more precise, but it does not matter for the example)
  • Travis does not send email on check (or maybe you want – then set true)
  • before starting the script it installs abaplint globally with node package manager (npm)
  • the check script itself contains just one command – abaplint – which is runs over all files in all subdirectories of “src” folder in the repository
  • the check is executed just for the master branch (so writing draft code in other branches will not generate annoying errors)

4. After you committed the above files to your repository let’s get back to Travis configuration page we left at point 2. It list all your repositories and allows you to enable Travis for each repository individually. Let’s do this for our repository

Let’s double check the settings

There is nothing to change here for our example, however one setting to notice – build pushed pull requests – above we limited the check to the master branch only. How about pull requests? They are not the master yet! This setting forces Travis build for pull requests to master although they were not explicitly mentioned in the configuration file.

These are all settings! Now try pushing something to the repository right to the master branch.Travis sees the new push to master automatically and runs the job according to the configuration file. You can find it in Build history tab.

The build has failed as we intended. Let’s check the details

The log show output of the script with the abaplint messages. You can see the files and lines where the errors had been detected.

OK, but it does not seem very convenient to always go to the Travis site to see the result, should I always do it? Not exactly.

  • Well, Firstly you can enable emails we blocked above – the report will come to your mailbox
  • Secondly you can add a special banner to you repo readme. In order to do it click on the banner in Travis near your repository name – it will open a nice dialog which gives you the banner code. Choose Markdown format. And copy-paste the chunk at the beginning of your readme file in the repository

  • After commit the banner will be rendered automatically based on last build status

  • And the last but not the least. The linter will be executed for pull requests. Let’s try to create a pull request with some mistakes. Upon created pull request the Travis will automatically re-run the test and if it failed it would display it right there, in the pull request flow.

  • … and the log …

“So sorry, but cannot merge, please fix your code first”. This is probably the most useful part of this CI script – Travis and abaplint controls the basic quality of the code with no effort from your side. Programming can and must be convenient.


If you’re not tired from reading yet let’s see how this works in Gitlab. Most of the flow is the same so it will be briefer, just some details differ. First of all Gitlab has own CI out of the box, no need to connect with external tools. See the example gitlab repository here.

The CI is enabled by default. You don’t need to activate anything. But just in case check that Shared runners in Runners subsections of CD/CI settings are not disabled. In the enterprise environment you will probably have dedicated runners setup in the left part of this screen. But this is a different story for next times.

In order instruct Gitlab CI what how to run the check you have to commit CI configuration file. The file is called .gitlab-ci.yml and should contain this.

image: node:10-alpine
        - node_modules/
    - lint
    stage: lint
        - master
        - npm install -g abaplint
        - abaplint "src/**/*.*"

It looks very similar to Travis config. But let’s skim through:

  • same node.js environment (alpine is a special tiny sized docker container, I won’t stop on it here)
  • cache specifies that node-modules folder should be preserved between builds for performance reason
  • stages allow to specify several steps of the test pipeline. For the example we just need one, let’s call it “lint”
  • finally the script “run_abaplint” have very similar attributes to the Travis one. It runs only for master, installs abaplint globally at start and then runs it for all files in “src” folder

One note: abaplint is being actively developed and new features/improvements come often. Maybe you don’t want to use the cache above and always use the latest version – then just remove the cache section. Or maybe in opposite, you want to fix the version you know works well and avoid newborn bugs – then you can pin the version adding it to the end of install command e.g. “npm install -g abaplint@1.5.1

After file commit you will see the build status icon near the repo header.

Our build predictably failed. Clicking on the status icon will show the reasons (you’ll have to drill down twice – to stages).

I hope you find this useful for your development flow.

Happy automatic code checking !

UPD: there are plans to lint not only abap code in the future but also data elements, structures and table types. So the latest recommendation is to mask all the available files for the check: abaplint “src/**/*.*

UPD2: Travis is migrating their open source part of the service from to So their official recommendation is to use “com” address for new repositories. See more here and here. The screenshots in this post are done from “org” so pictures may look just a bit different at “com” version.


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Nabheet Madan
      Nabheet Madan

      Great and interesting stuff!

      Author's profile photo Peter Langner
      Peter Langner

      Thank you for figuring it out. If works like a charm ...


      Author's profile photo Jeorge Waters
      Jeorge Waters

      I am just starting to get familiar with all those tools and I am really like that on the web it’s possible to find so much useful info like your article. Otherwise I don’t even know what would I do…

      Author's profile photo Sérgio Fraga
      Sérgio Fraga

      Hello Alexander Tsybulsky

      Thank you for this great post!

      I was playing around to create a rule that checks if there are unused variables in the code when submitting a PR.

      Do you know how to achieve this with abaplint + Travis?

      Thanks again


      Author's profile photo Lars Hvam
      Lars Hvam

      the command line interface has been moved to package "@abaplint/cli", install it instead of "abaplint"

      Author's profile photo Gregor Wolf
      Gregor Wolf

      Hi Alexander Tsybulsky,

      would be great if you can update the package. Otherwise everyone following your blog will not benefit from the improvements made until Lars switched.

      Best regards

      Author's profile photo Alexander Tsybulsky
      Alexander Tsybulsky
      Blog Post Author

      Will try to find time for this. And probably also for a new post for github actions (if noone posted it yet ...)