Build on ABAP

How to build an ABAP project with abapGit

Open ABAP work is a package in a Git repository that abapGit can install into any system. What follows is how abapGit, the ABAP documentation and the Clean ABAP guide describe it.

Guidance, not rules. Each project's own contributing guide wins. Links read 2026-09-29

01Work with an agent

The skills written for ABAP teach an agent how to build with it, and the atlas is not part of what they read. The atlas's MCP server and its skill answer a different question, what exists, whether it is alive and where it stops, and carry no procedure for code, so the two sit side by side. It reads; it never opens an issue or a pull request. How the atlas serves agents

Skills indexed in ABAP

READMEs on record for 15 of 15. None of them names the atlas.

Any MCP client: the endpoint

The atlas over streamable HTTP, stateless, answered from the bundled graph.

claude mcp add --transport http onedevatlas https://onedevatlas.dev/mcp

02How ABAP is extended

ABAP work is shared as code in packages, moved between systems with abapGit, and extended where SAP leaves a door open: released APIs, BAdIs and RAP extensions. Work that uses them survives an upgrade of the system around it.

abapGit repository: .abapgit.xml

Standard ABAPABAP Cloud
.abapgit.xml

abapGit maps SAP packages and sub-packages to folders in a git repository, and a repository's settings live in .abapgit.xml at its root: the starting folder where deserialization starts, the folder logic, the main language, ignored files and an optional version constant. abapGit repositories store no SAP package names; the installer picks the target package, and abapGit creates sub-packages with the settings of the top package.

Packages in ABAP 54
xmlAdapted from github.com ↗
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
 <asx:values>
  <DATA>
   <NAME>abapGit</NAME>
   <MASTER_LANGUAGE>E</MASTER_LANGUAGE>
   <STARTING_FOLDER>/src/</STARTING_FOLDER>
   <FOLDER_LOGIC>PREFIX</FOLDER_LOGIC>
   <VERSION_CONSTANT>ZIF_ABAPGIT_VERSION=&gt;C_ABAP_VERSION</VERSION_CONSTANT>
  </DATA>
 </asx:values>
</asx:abap>

abapGit folder logic and package prefixes

Standard ABAPABAP Cloud
FOLDER_LOGIC (PREFIX, FULL, MIXED)

With PREFIX, abapGit's documentation says a package name must contain its parent package name as a prefix, which lets a repository be installed under different parent packages on different systems. FULL accepts any package name and forces installation into packages with identical names, which the page notes may be a problem for contributors who need specific prefixes; MIXED uses the root package as a prefix for all sub-packages without concatenating recursively.

textAdapted from docs.abapgit.org ↗
ZFOO
  ZFOO_BAR
    ZFOO_BAR_QUX

abapGit ABAP language version setting

Standard ABAPABAP Cloud
ABAP language version: Any, Ignore, Standard ABAP, ABAP for Key Users, ABAP for Cloud Development

abapGit's documentation lists five settings for how a repository handles the ABAP language version, and marks the feature as experimental. It states that Ignore is recommended for cross-platform repositories with code running on-premises and on BTP, because the version is then not serialized and is set from the target package on import.

Packages and package interfaces

Standard ABAPABAP Cloud
package, package interface

The ABAP Keyword Documentation defines a package as a repository object that encapsulates repository objects in self-contained units and connects them to the Change and Transport System. Components usable outside the package must be published in a package interface, and a package that accesses another package's objects must declare this and have its permission.

BAdIs in enhancement spots

Standard ABAPABAP Cloud
BAdI, enhancement spot, GET BADI, CALL BADI

A BAdI consists of a BAdI interface, a set of filters and settings, and is the basis for enhancements whose methods in object plug-ins are called from ABAP programs, with filter values selecting the implementations used. BAdI definitions live in BAdI enhancement spots, which ADT creates with a wizard; GET BADI creates the BAdI object and CALL BADI calls the method in all object plug-ins it refers to.

abapAdapted from help.sap.com ↗
GET BADI { badi [FILTERS f1 = x1 f2 = x2 ...] }
       | { badi TYPE (name)
              [{FILTERS f1 = x1 f2 = x2 ...}
              |{FILTER-TABLE ftab}] }
              [CONTEXT con].

CALL BADI { badi->meth parameter_list }
        | { badi->(meth_name) {parameter_list
                              |parameter_tables} }.

Interfaces for reuse and replaceable dependencies

Standard ABAPABAP Cloud
INTERFACES, constructor injection

Clean ABAP states that public instance methods should be part of an interface, because this decouples dependencies and simplifies mocking them in unit tests. Its Injection section describes handing all dependencies to the constructor and advises against setter and FRIENDS injection.

abapAdapted from github.com ↗
METHODS constructor
  IMPORTING
    customizing_reader TYPE REF TO if_fra_cust_obj_model_reader.

METHOD constructor.
  me->customizing_reader = customizing_reader.
ENDMETHOD.

APACK manifest for dependencies

ABAP CloudStandard ABAP
ZIF_APACK_MANIFEST, .apack-manifest.xml

A class implementing ZIF_APACK_MANIFEST in the top-level package advertises metadata in the Maven POM style (group_id, artifact_id, version, git_url, dependencies), and abapGit writes it to .apack-manifest.xml at the repository root. abapGit's documentation states that APACK including dependencies is currently only supported by abapGit for ABAP Development Tools (ADT).

Packages in ABAP 54

03Tests, checks, types and releases

Each as ABAP's own documentation describes it, with the pages to read. Where a source recommends something, the recommendation is its own.

Unit tests with ABAP Unit

ABAP UnitCL_ABAP_UNIT_ASSERTADT

ABAP Unit is the test framework built into the ABAP runtime: tests are test methods in local test classes declared FOR TESTING, transported with the production code but not generated in production systems, and they check results with CL_ABAP_UNIT_ASSERT. Runs start from the tool, the ABAP Unit Browser or the ABAP Test Cockpit, and coverage is measured with the Coverage Analyzer.

abapAdapted from help.sap.com ↗
CLASS mytest DEFINITION FOR TESTING RISK LEVEL HARMLESS.
  PRIVATE SECTION.
    METHODS mytest FOR TESTING.
ENDCLASS.

CLASS mytest IMPLEMENTATION.
  METHOD mytest.
    myclass=>set_text_to_x( ).
    cl_abap_unit_assert=>assert_equals( act = myclass=>text
                                        exp = 'X' ).
  ENDMETHOD.
ENDCLASS.

Test isolation: test doubles for classes, SQL, CDS and RAP

cl_abap_testdoublecl_osql_test_environmentcl_cds_test_environmentcl_botd_txbufdbl_bo_test_envcl_botd_mockemlapi_bo_test_envTEST-SEAM

SAP-samples/abap-test-isolation-examples shows one test class per isolation tool: the ABAP OO test double framework (cl_abap_testdouble), function module test doubles, the ABAP SQL and CDS test double frameworks, authority-check helpers, and RAP transactional buffer doubles and mock EML API, each with its first release. Clean ABAP points to that repository and describes test seams as a temporary workaround while code is refactored into a testable form.

abapAdapted from github.com ↗
method class_setup.
  " ABAP CDS Test Double Framework
  g_cds_environment = cl_cds_test_environment=>create( 'ZATI_CDS_ENTITY' ).
endmethod.

method setup.
  g_cds_environment->clear_doubles( ).
  m_cut = zati_cl_factory=>get_code_under_test( ).
endmethod.

Static checks in the system: ABAP Test Cockpit

ATCADTCode Inspector

SAP Help describes the ABAP Test Cockpit (ATC) as the standard tool for checking ABAP development objects with static checks, usable in ADT during development and at transport release. SAP's released and classic API list in SAP/abap-atc-cr-cv-s4hc is the content for the ATC check "Usage of Released APIs (Cloudification Repository)", which analyses custom code for use of released and non-released APIs.

Static checks outside the system: abaplint

@abaplint/cliabaplint.jsonvscode-abaplintrules.abaplint.org

abaplint is an open-source linter for ABAP that runs on Node.js without an SAP system, on code serialized with abapGit; rules are switched on and off in abaplint.json. Its getting-started guide suggests starting with the syntax-check rules and shows configurations for on-premise releases and for ABAP Cloud (language "Cloud" with a released-API dependency).

jsonAdapted from github.com ↗
{
  "global": { "files": "/src/**/*.*" },
  "syntax": {
    "version": { "release": "v793", "language": "Normal" },
    "errorNamespace": "^(Z|Y|LCL_|TY_|LIF_)"
  },
  "rules": {
    "check_syntax": true,
    "parser_error": true,
    "unknown_types": true
  }
}

Style: Clean ABAP and its checks

Clean ABAPcode pal for ABAPcode pal for ABAP CloudabapOpenChecksabaplint

Clean ABAP is SAP's adaptation of Robert C. Martin's Clean Code for ABAP, published under CC BY 3.0; its own advice is to start with Booleans, Conditions, Ifs and Methods and leave Comments, Names and Formatting for later. Its "How to Check Automatically" section names code pal for ABAP (a Clean ABAP check suite for Code Inspector and ATC, with a separate Cloud Edition), abapOpenChecks and abaplint.

Versioning with abapGit: pull, stage, commit, branches

abapGit (ZABAPGIT)abapGit for ADT

abapGit compares local and remote code and offers pull when the remote changed; changes are staged, reviewed and committed from the stage page, and the docs say to check the URL (original or fork) and branch before continuing. The repository head can be a branch, tag, commit or pull request (default refs/heads/main), and the docs advise a new SAP package for each repository.

CI: abaplint on GitHub

abaplint/actions-abaplintabaplint.app

The abaplint GitHub action lints a repository on push and pull request and reports results through GitHub's Checks API; the action's README points to abaplint.app for additional features. abapGit's development guidelines state that abaplint checks every pull request for syntax compatible with 7.02.

yamlAdapted from github.com ↗
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: abaplint
      uses: abaplint/actions-abaplint@main
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dependencies and requirements

.abapgit.xml requirementsAPACKabaplint dependencies

The Requirements section of .abapgit.xml lists software components and minimum releases and patch levels the target system must have before installation. Dependencies between repositories are declared with an APACK manifest, which abapGit's documentation says is currently resolved only by abapGit for ADT; abaplint takes other repositories as "dependencies" in abaplint.json so that code against them can be checked.

04Using open source

Taking open source into a project, and publishing your own under an open licence, as ABAP's projects and documentation describe it. Every artifact in the atlas carries the same readings, maintenance and licence among them, before it goes into a project.

Installing an open-source project with abapGit

abapGit

abapGit installs a project either as an online repository (a Git URL plus a target package, then Pull) or as an offline repository filled from a ZIP file. Its documentation advises a new SAP package for each abapGit repository and not to use packages that already hold other objects. The SAP tutorial on moving code to SAP BTP, ABAP environment tells readers to arrange with their system administrator before installing ZABAPGIT.

Reviewing code before import

abapGit

The abapGit documentation's Security section says abapGit lets a developer do in bulk what a developer key already allows by hand, and tells users to review all code in remote repositories before importing it into the target system, which is possible because abapGit stores plain text rather than transport files. It also notes that automated security checks run on abapGit's own code report many findings by design, since the tool imports, overwrites and changes ABAP objects.

Licences: what abapGit does with a LICENSE file

abapGit

abapGit does not pull a repository's LICENSE file into the SAP system. Its documentation says that where the licence requires it, the licence terms go into comments in the main source file, or the licence can be referenced with an SPDX licence identifier. Files outside the starting folder (by default /src/) are ignored automatically, and the Ignore Files setting lists further paths such as readme, changelog and licence files.

Namespaces, prefixes and the source system

abapGit

abapGit serializes a namespace as an NSPC object carrying the repair licence key but not the developer key; the namespace can also be created beforehand in SE03. Imported namespaced objects need workbench, correction or repair tasks depending on the source system and namespace role. With only a repair key, abapGit assigns imported objects to SAP and they cannot be modified unless the repository's Source System setting is SID, which the docs name as the typical case for open-source projects using a namespace.

Dependencies: APACK and minimum requirements

abapGitAPACK

A class implementing ZIF_APACK_MANIFEST in the top-level package declares APACK metadata (group_id, artifact_id, version, git_url, dependencies), which abapGit writes to .apack-manifest.xml; automatic dependency resolution relies on each dependency's git_url and is, per the docs, currently supported only by abapGit for ADT. ZIF_APACK_MANIFEST is created in $TMP, so transporting an implementation class requires the interface in each follow-on system. Separately, the Requirements section of .abapgit.xml lists software components and minimum release and patch levels for installation.

Publishing: licence and the dotabap list

abapGitdotabap

The dotabap-list README sets its requirements for listed projects: a public repository on GitHub, ABAP as primary language, English, around 500 or more lines of ABAP, abapGit based, and an open-source licence from opensource.org or the SAP sample code license. Projects are added by pull request to list.json; related projects that do not meet the requirements go in related.json, and unmotivated forks are not accepted. abapGit itself is MIT-licensed and declares per-file licences in REUSE.toml, and its PR pipeline includes a compliance check that every file is associated with a licence.

Contribution terms and security policy files

abapGit

abapGit's CONTRIBUTING asks contributors to open an issue before significant development and to keep pull requests small, and its docs describe contributing to any abapGit project by forking, cloning the fork into the SAP system, branching and opening a pull request. abapGit's SECURITY.md routes vulnerability reports to GitHub's private 'Report a Vulnerability' advisory form. For repositories under github.com/SAP, SAP's organisation CONTRIBUTING requires accepting the Linux Foundation's Developer Certificate of Origin, and SAP's repository template defaults to Apache 2.0 with REUSE metadata.

05Security

What ABAP's documentation and its projects state about security, with the pages to read. A project's SECURITY.md, where it has one, says how to report a vulnerability.

Where the keyword documentation covers security

The ABAP Keyword Documentation's ABAP Security Notes summarise the most significant risks in two groups: risks caused by input from outside, and further risks. It states that most security issues come from external input (from a user interface, a parameter interface or a persistent repository) used in dynamically specified statement parts that escape static checks, and that such input is to be checked or escaped. It also notes that back doors planted by developers cannot be found statically and names two-person code inspections as probably the only answer.

Authorization checks with AUTHORITY-CHECK

The keyword documentation lists statements with implicit checks (CALL TRANSACTION WITH AUTHORITY-CHECK, SUBMIT with an authorization group, the file interface) and critical ones without, including SQL reads on database tables; places a user can reach without such a check are to be secured with AUTHORITY-CHECK and sy-subrc evaluated. If the check indicator is set to no check, sy-subrc is 0 as for a successful check. SAP's ABAP cheat sheet adds that in ABAP for Cloud Development the authorization object must be a literal and the FOR USER addition is Standard ABAP only.

abapAdapted from help.sap.com ↗
AUTHORITY-CHECK OBJECT 'S_CARRID'
  ID 'CARRID' FIELD carr
  ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
  RETURN.
ENDIF.

RAP authorization control and CDS access control

In RAP, authorization control is declared per entity in the behavior definition as authorization master (global, instance, or both) or authorization dependent by an association, and implemented in the ABAP behavior pool, for example with authorization objects. For reads, CDS access control evaluates the access conditions of a CDS role (DCL, DEFINE ROLE) implicitly in each ABAP SQL read, unless switched off with @AccessControl.authorizationCheck: #NOT_ALLOWED or WITH PRIVILEGED ACCESS.

abapAdapted from help.sap.com ↗
... authorization master { ( global ) | ( instance ) | ( global, instance ) | ( none ) }
  | authorization dependent by _Assoc ...

SQL injection and dynamic ABAP SQL

The keyword documentation covers SQL injections through dynamic tokens in ABAP SQL, ADBC, AMDP, Object Services and generic programming. For dynamic tokens it says naming an ABAP data object as operand is more secure than inserting a value as a literal, and that externally supplied table names, columns and WHERE or HAVING conditions are to be checked, for example against an include list, and escaped with the methods of CL_ABAP_DYN_PRG such as QUOTE and CHECK_TABLE_NAME_STR.

abapAdapted from help.sap.com ↗
" insecure if input is external and unchecked
DATA(sql_cond1) = `CARRID = '` && input && `'`.
SELECT SINGLE * FROM scarr WHERE (sql_cond1) INTO @wa.

" data object as operand
DATA(sql_cond2) = `CARRID = @input`.
SELECT SINGLE * FROM scarr WHERE (sql_cond2) INTO @wa.

Directory traversal, OS commands, cross-client access and XSS

For file names from outside used in OPEN DATASET, DELETE DATASET or CL_ABAP_FILE_UTILITIES, the documentation calls for validation, for instance with FILE_VALIDATE_NAME against logical file names from transactions FILE or SF01. For operating system commands it names the SXPG framework with predefined logical command names as the only recommended method and says CALL 'SYSTEM' can be deactivated with rdisp/call_system. It treats USING CLIENT or CLIENT SPECIFIED as a critical attack on other clients' data, and for HTML generated directly via ICF names the built-in function escape, with forceEncode for BSP.

Code Vulnerability Analyzer in ATC, and from abapGit

ABAP Test CockpitSAP Code Vulnerability AnalyzerabapGit

The keyword documentation says security checks in the extended program check are provided by the code vulnerability analysis add-on (CVA), licensed separately in customer systems. SAP Community's CVA topic page states that CVA on SAP BTP ABAP environment is part of ATC and needs no separate CVA licence, while on-premise requires one. abapGit can run a Code Inspector or ATC check variant before staging and can block commits on priority 1 and 2 findings; its docs point to SAP Note 1921820 for release-specific CVA checks.

abaplint rules tagged security

abaplint

abaplint tags four rules as security: dangerous_statement (execSQL, kernel calls, SYSTEM-CALL, INSERT REPORT, GENERATE SUBROUTINE and dynamic SQL, among others), no_dynamic_stuff (dynamic constructs, which it says can introduce injection vulnerabilities), call_transaction_authority_check and modify_only_own_db_tables. They run outside the SAP system, for example on a pull request.

abapAdapted from github.com ↗
" bad
CALL TRANSACTION 'FOO'.
" good
TRY.
    CALL TRANSACTION 'FOO' WITH AUTHORITY-CHECK.
  CATCH cx_sy_authorization_error.
ENDTRY.

Credentials: communication arrangements and abapGit logins

abapGit

In SAP BTP, ABAP environment, SAP's tutorial obtains an outbound destination with cl_http_destination_provider=>create_by_comm_arrangement, naming a communication scenario and outbound service; the target host and user sit in a communication system and arrangement maintained by an administrator, not in code. abapGit intentionally stores no Git login data across sessions, because SAP systems are multi-user systems, and its docs point to a password manager or, on single-user systems, an exit.

abapAdapted from developers.sap.com ↗
DATA(lo_destination) = cl_http_destination_provider=>create_by_comm_arrangement(
  comm_scenario = 'ZMDC_OVERPASS_CSCEN'
  service_id    = 'ZMDC_OVERPASS_OBS_REST' ).
DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination(
  i_destination = lo_destination ).

Reporting a vulnerability

abapGit

abapGit's SECURITY.md sends reports to the private GitHub Security Advisory 'Report a Vulnerability' form. SAP's open source security policy, applied across its GitHub organisations, asks reporters not to use public GitHub issues and to use the SAP Trust Center or secure@sap.com instead. abapGit also provides an authorization exit, ZCL_ABAPGIT_AUTH_EXIT implementing ZIF_ABAPGIT_AUTH, to block actions such as uninstall for chosen users.

06Documentation the atlas can read

The atlas records only what a project's own documentation states, and quotes the sentence it rests on. What it looks for:

The stack it serves
A package is listed as an artifact only when its own documentation names the SAP stack it is built for, such as ABAP. A generic library is not, however often a project installs it.
Where it runs
Runtimes and flavors are recorded where a sentence states them, and that sentence is shown beside the value. Where the documentation says nothing, the page says it does not say.
What it needs and talks to
Services it requires and systems it connects to, with the protocol, are edges drawn only from what the documentation names.
Its properties
A capability compares its artifacts on a few declared properties. A value counts only with the sentence it comes from; a property the documentation does not mention stays open.
Releases and a licence
Readings are crawled from the repository and the registry, releases and the last push among them. A README is shown whole only under a licence that permits copying; otherwise its opening and a link.

07Tutorials

Step-by-step material from SAP and the ecosystem, linked where it lives.

08Share it

Where finished ABAP work is published and found, and how it gets into the atlas.

Public GitHub repository installable with abapGit
A repository created on GitHub and cloned in abapGit; objects are added and committed from the system, and others install it as an online repository with a URL and a package of their choice. docs.abapgit.org ↗
Installing someone's repository
What a user of a shared project does: New Online, the repository URL and a new package, then Pull. docs.abapgit.org ↗
Licence in an abapGit repository
abapGit does not pull the LICENSE file into SAP systems; the docs suggest repeating the terms in the main source file or referencing an SPDX identifier. docs.abapgit.org ↗
Listing on dotabap.org
A pull request to list.json; criteria: public, GitHub-hosted, abapGit based, ABAP as primary language, English, around 500+ lines of ABAP, open-source or SAP sample code licence. Projects that do not meet the criteria can go in related.json; merged entries appear within 24 hours. github.com ↗
dotabap.org
The listing of ABAP open-source projects built from dotabap-list. dotabap.org ↗
Contributing to an abapGit-based project
Fork, clone the fork into the SAP system, create a branch, change in SAP, commit to the fork, open a pull request. docs.abapgit.org ↗
Contributing to abapGit itself
Keep pull requests small and open an issue proposing the solution first; good first issue labels for newcomers. github.com ↗
abapGit development guide: Contributing
Install the developer version into a separate package such as $ABAPGIT, commit to the fork, open a pull request; abapmerge builds the standalone report after merge. docs.abapgit.org ↗
abapGit development guidelines
Only classes and interfaces for new objects, zcl_abapgit_/zif_abapgit_ prefixes, ABAP Doc for sub-objects, code compatible with 7.02 checked by abaplint. docs.abapgit.org ↗
abapGit tests and CI
abapGit CI clones, pulls, checks and purges the test repositories in the abapGit-tests organisation; unit tests use dependency lookup through ZCL_ABAPGIT_INJECTOR. docs.abapgit.org ↗
Add it to the atlas
Use Feedback, Add, or open a pull request against the atlas data. A repository URL is enough to start.
Credit
Maintainers and authors are linked to their work.
Corrections
Anyone can correct an entry, through Feedback or a pull request.