Welcome to part 8 of this blog series introducing
abap2UI5 — an open-source project for developing UI5 apps purely in ABAP.
This post delves into the repository organization of abap2UI5 and its utilization of
GitHub,
abapGit,
abaplint and
open-abap. In my prior experience, I was mainly working on projects following classic CTS and only occasionally using abapGit to pull in open-source projects. However, this project offered a valuable opportunity to understand how to establish a thoroughly tested Git repository for the ABAP community, and it was a great learning experience! While seasoned ABAP developers might be familiar with these tools, my aim is to introduce them to those less acquainted with them.
This post will lead you through the abap2UI5 repository setup, step by step, beginning with abapGit, and then progressively introducing additional settings and tools.
Blog Series & More
You can find all the information about this project on
GitHub and stay up-to-date by following on
Twitter. Also, make sure to explore the other articles in this blog series.
Content
This post covers the following areas:
- Git - GitHub & abapGit
- GitHub - Working with Separated Branches
- abaplint - Syntax Check & Code Compatibility
- abaplint - Static Code Analysis
- abaplint - Quickfixes
- abaplint - Cross Checks
- abaplint - Dashboard
- GitHub - Contribution with Forks & Pull Requests
- GitHub - Branch Protection
- open-abap - Downport Functionality
- open-abap - Unit Testing
- open-abap - abap2UI5-web
- Conclusion
Let’s begin with the first topic.
1. Git - GitHub & abapGit
The codebase of abap2UI5 is version-controlled in a public Git repository on
GitHub. This means that the code is not managed on an SAP system, as is typically done with ABAP projects and from where it can be transported to other systems. Instead, it is centrally stored in a public repository, allowing the current state of the project to be accessible at any time to everyone and installable on any system:
GitHub - Public Repository of abap2UI5
Before making changes, the current code state is initially pulled (downloaded) onto a private ABAP system and after implementing the changes, the updated code is always pushed back to the public GitHub repository. The current coding state on the ABAP system is thus used solely as temporary storage:
GitHub - Code Changes of the public abap2UI5 repository
And the leading and authoritative code version is the one stored on GitHub:
GitHub - Source Code of abap2UI5
In addition to public accessibility, this approach offers the advantage that the entire project exists independently of an ABAP system, and changes can be developed periodically on various systems, such as shared ABAP Cloud Trial, ABAP Dev Edition, or S/4. For instance, a significant portion of the project was created using the shared ABAP Cloud Trial on which you cannot guarantee that no one will modify your code or that your changes won't be removed after a few days. But storing the code on GitHub solves this concern.
Furthermore, all the features of GitHub can now be utilized. To highlight just two examples, take a closer look at the
issue management:
GitHub - Overview of Issues
Or tracking code changes with the
commit history:
GitHub - Commit History
This significantly enhances the transparency of the entire project! Changes can be retraced, actual problems are documented in issues, new requirements can be collected and evaluated. This is only possible because of the open-source project
abapGit, which integrates every ABAP system from version 702 and higher with GitHub.
abapGit - Git Client for ABAP
If you're new to Git and
abapGit, the following
blog post is a good starting point. A big thank you to this excellent tool and and the
team behind it.
2. GitHub - Working with Separated Branches
Given this setup, a question arises: what happens when I pause my work and fail to complete my current task? It's possible that I've just begun making a change but have been unable to test and finish it, which leaves the code in an incomplete state. Pushing this into the main branch would result in a scenario where everyone could potentially download a non-functional abap2UI5 version containing errors.
To address this, the code within each git repository can be segmented into multiple branches. For simplicity, we'll only divide the repository into two branches now. The initial repository stands as our main branch, housing the latest functioning "stable" version and remains available for others to download. The second branch assumes the role of a
development branch ("dev"), which is a duplicate of the code and is intended for active changes:
GitHub - Separated Development Branch for working on a New Feature
The "dev" branch contains the changes until the new feature is ready. Upon completion, it is merged into the main branch with a Pull Request (PR), making the feature accessible to everyone:
GitHub Pull Request - Incorporating Changes from the Dev Branch into the Main Branch
Repository after Merge - Both Branches Now Contain the Updated Source Code
As you can see the separate branch ensures that only finalized and tested features find their way into the main branch.
3. abaplint - Syntax Check and Code Compatibility
But how can we guarantee that the code we push to the main branch, tested on one system, will function across all the other ABAP systems it's downloaded to?
As previously mentioned, a significant portion of abap2UI5 is developed on a shared ABAP Cloud Trial System, containing types and functions that are unavailable on lower releases like NetWeaver v7.50. Additionally, there are two language flavors: 'Standard ABAP' and 'ABAP for Cloud,' both requiring consideration. Fortunately, the open-source project
abaplint addresses these concerns:
abaplint - Static Code Analysis
The tool
abaplint can be setup in various ways; in the case of abap2UI5, it is used as a GitHub Addon:
abaplint - Installation as a GitHub Add-on
For the project-specific setup, simply add an
abaplint.json file to the repository. This file contains all settings and is structured as follows:
abaplint - Configuration via abaplint.json
First we aim to ensure that the written code is executable down to Netweaver version 7.50 by configuring the following option in line 12:
"syntax": {
"version": "v750",
You can choose the version that suits your needs. With this setup, abaplint now checks the source code after each change, ensuring syntax validity down to ABAP v7.50:
abaplint - Checking the ABAP code
abaplint - Identifying Incompatible Syntax
In this case we used the "cmis_string" type, which is unavailable in NetWeaver 7.50 and causing findings:
abaplint - Detailed Overview of Identified Issues
These checks provide us with the opportunity to address issues before they are integrated into the main branch and preventing potential problems during the installation on other systems. This serves as an aid in identifying mistakes at an early stage and reduces significantly the effort required to solve them. After fixing the error, abaplint performs another check:
abaplint - Checks Passed Succesfully
This time, no issues are found anymore, and the code changes can be merged into the main branch with confidence it'll function on any release down to NW 7.50. The setup now appears as follows:
abap2UI5 Setup - Repository with abaplint Syntax Check for Different ABAP Systems
But this was just the beginning; abaplint is more than only a syntax checking tool to regain control over all the different ABAP releases and language flavors (although this alone would be impressive enough) -- it is a static code analysis tool with a lot of more possibilities, which we'll delve into next.
4. abaplint - Static Code Analysis
When developing new features, static code checks play a significant role in enhancing code quality. We can achieve this using abaplint and have access to over 159 distinct rules. You can check them
here:
abaplint - Rules for Static Code Analysis
The
configuration file shows which ones are activated for the project:
abaplint - Rule Configuration via Package.json
For example, classic checks like "no database access in loops"
(here):
"db_operation_in_loop": true,
Or
ABAP Style Guideline-influenced recommendations, such as better boolean usage
(here):
"prefer_xsdbool": true,
Checks for unused variables and types (in cases where we might have overlooked this in Eclipse)
(here):
"unused_types": true,
"unused_variables": {
"severity": "Error",
"exclude": ["z2ui5_cl_fw_utility.clas.testclasses.abap"],
"skipNames": ["lv_dummy", "i_mv_editor"]
},
Analyses of the overall code complexity of functions, for example the
cyclomatic complexity (here):
"cyclomatic_complexity": {
"exclude": [],
"severity": "Error",
"max": 20
}
Or checks enhancing readibilty, like avoiding 'exporting' in method calls
(here):
"exporting" : true
I recommend reviewing all of these rules; some are vital for quality maintenance, while others suit personal or project-specific needs. Collectively, they elevate the codebase significantly. With activated rules and abaplint as a GitHub AddOn, the code is checked now with each push to the main branch:
abaplint - Pull Request successfully checked with abaplint
Of course, this isn't a guarantee that everything will function flawlessly, but it does provide a robust additional safeguard. The project setup appears with this as follows:
abap2UI5 Setup - Repository Organization with Static Code Checks using abaplint
But why not perform this directly in Eclipse and conduct static code analysis with ATC? One downside is that ATC checks are system-dependent, which means that if I want to make changes today on system A and continue tomorrow on system B, I have to set up ATC again. This can also pose challenges when different people on various systems collaborate. With abaplint, we can carry out centralized static code checks at the repository level on GitHub, which is a significant advantage over ATC.
5. abaplint - Quickfixes
Abaplint also provides Quickfixes as we know them from ATC. They are accessible directly on GitHub:
abaplint - Quickfixes on GitHub
Alternatively, they can be accessed via the command line. In the following example, we use GitHub Spaces. After installing abaplint, we can add a new check and execute automated Quickfixes:
abaplint - Installation and Automated Quickfixes (Part I)
abaplint - Installation and Automated Quickfixes (Part II)
In this case, a fix is added to remove double spaces (more complex fixes are also available). You can observe abaplint's code adjustments:
abaplint - Code Adjusted by abaplint
Lastly, we simply need to merge these modifications back into the _dev branch concluding the process -- everything only takes a few moments. Visit the
repository and explore for yourself! Begin by initiating a new GitHub Codespace and executing the following commands in the terminal:
- Install the abaplint CLI globally by running:
npm install @abaplint/cli -g
- Perform automated code fixing by entering:
But might we be encompassing functionalities that are also offered, for example, by
ABAP Cleaner? While ABAP Cleaner is unquestionably a valuable tool, abaplint boasts a multitude of capabilities beyond code verification and aesthetics, as we'll explore further later on. But the reason I once again prefer abaplint is because of its project-level configuration on GitHub, which eliminates the requirement to install and set up a local Eclipse AddOn (a step that would also be necessary for everyone undertaking a code modification) which saves a lot of time.
For further information on setting up abaplint you can also check out this
blog post and now let's delve into another very useful feature of this tool: its cross-checks.
6. abaplint - Cross Checks
The
abap2UI5-samples repository depends on artifacts from abap2UI5. For example, when both are installed on an ABAP server, syntax checks verify method calls and API compatibility. But how to manage these dependencies when both repositories are on GitHub, and changes occur independently in different systems? The abaplint Cross Check offers a solution for this. Project dependencies can be customized in the abalint.json file of each repository, as demonstrated
here:
abaplint - Define Dependencies
Now, modifying a method in the main abap2UI5 repository automatic triggers checks for syntax compatibility of the samples repository. To illustrate, we change the importing parameters of an abap2UI5 method:
abap2UI5 - Incompatible Code Change in the Main Repository
Attempting to update the abap2UI5 main branch with a PR now encounters abaplint cross-check failures and triggers errors:
abaplint - Cross Check Failures due to Missing Importing Parameter used by the Samples Repository
The more apps utilizing abap2UI5, the harder managing dependencies gets. Cross-checks significantly assist in handling this complexity. If you have a GitHub project using abap2UI5, set up abaplint and customize a dependency to abap2UI5. This way, you will receive early warnings about incompatible changes. The repository configuration is now as follows:
abap2UI5 Setup - Repository with abaplint Cross-Checks
For more details about cross-checks, refer also to this
blog post.
7. abaplint - Dashboard
Abaplint is powerful, with much more to explore, while we only focused on a few aspects. For a good overview of all features you can also take a look at the
dashboards of public ABAP projects using abaplint:
All these charts and statistics provide a comprehensive and transparent overview of the code quality of each project. This can also help you make informed decisions when you are uncertain about public repositories and whether you want to download it or not.
8. GitHub - Contribution with Forks & Pull Requests
Abap2UI5 is open source and developed alongside other projects or during free time. Contributions to this project are greatly appreciated, check out this
contribution guideline. But what happens when someone wants to make a modification to the actual source code of the project? In this case they can create a Fork of the repository, obtaining a personal copy of the complete repository to implement changes:
GitHub - Create a new Fork
Upon completion, they open a Pull Request, notifying the abap2UI5 repository owner about the change:
GitHub - Create a Pull Request from a new Fork
The changes can now be reviewed by the repository owner and additionally abaplint runs its checks. Very useful: The PR creator is also promptly notified about the abaplint results upon opening the PR:
GitHub - abaplint checks Pull Requests
On this way the contributor gains access to all the essential information regarding the required Code Standards of the project and is enabled to improve the code of the Pull Request also by himself. The inclusion of abaplint checks on GitHub streamlines this contribution process and significantly reduces coordination efforts. The whole setup appears now as follows:
abap2UI5 Setup - Contribution with Forks
Check out all Forks of abap2UI5
here and see who already contributed to the project
here.
9. GitHub - Branch Protection
When collaborating, another feature enhances teamwork. All abaplint checks configured thus far (syntax check, static code checks, cross checks) can be made mandatory. This prevents accidental pushing of changes to the main branch or bypassing these tests. This feature is provided by GitHub's branch protection rules:
GitHub - Setup Branch Protection Rules
Now, merging is deactivated until all tests run successfully, and the repository setup appears as follows:
abap2UI5 Setup - Repository with Branch Protection
10. open-abap - Unit Testing
Now, returning to code quality: Good code quality encompasses more than just static checks and one important aspect we haven't examined yet are unit tests. ABAP unit tests are typically executed on the ABAP Server (initiated through Eclipse or a background job):
abap2UI5 - Unit Tests running on an ABAP Server
But how do we ensure Pull Request submitters perform unit tests, confirming their changes are well-tested? Therefore, in addition to conducting static code checks, it is essential to run unit tests on GitHub as well. The challenge lies in being able to run these tests in a non-ABAP environment and automating this process.
To achieve automation, we can leverage GitHub Actions and for running unit tests we can use the open-source project
open-abap:
open-abap - Any platform ABAP, serverless ABAP, ABAP on Node.js
Open-abap transpiles ABAP code into JavaScript, enabling its execution on a Node.js server. This capability permits us to run unit tests on Node.js directly on GitHub within a GitHub Action. The configuration for this action looks like
this:
GitHub Action - Unit Tests with open-abap
With each code change the unit tests are now running as you can see for example
here:
GitHub Action - Running Unit Tests with open-abap
This feature is truly remarkable! It decouples the entire testing process from any specific ABAP server and ensures that only thoroughly tested code makes its way to the main branch. The project setup is as follows now:
abap2UI5 Setup - Running Unit Tests with open-abap
11. abaplint - Downport Functionality
After configuring multiple static checks and unit tests, we now circle back to where we began: Syntax checking for different systems. While we have ensured compatibility down to ABAP 750, let's now delve into what I consider one of abaplint's most valuable features: its downport functionality.
It's somewhat discreetly accessible as a quick fix, yet it holds a strong functionality playing a significant importance for the project. This function facilitates automatic downporting from higher releases to lower ones. In practical terms, this means we can maintain the main branch using 750 syntax with all its new language features, while still ensuring the project remains installable on an ABAP 702 system through abaplint's downport capability.
The function can be executed by adjusting the syntax to 702 in the abaplint configuration and then initiating the downport via automated quickfixes. You can see a demonstration here:
abaplint - Downporting 7.50 Syntax down to 7.02 Syntax (Part I)
abaplint - Downporting 7.50 Syntax down to 7.02 Syntax (Part II)
Check the
downport repository to see that all new language features are downported to compatible 702 syntax:
|
|
Before: 7.50 Syntax |
After: 7.02 Syntax |
Furthermore, to eliminate manual effort, this process can be also automated using a GitHub Action, similar to what we have already employed for unit tests. We establish an additional
downport repository that automatically receives updates with every code change from the abap2UI5 main branch. The GitHub Action responsible for this task is configured
here:
GitHub Action - Automated Downporting with abaplint
And the downported code is stored here:
abap2UI5 - Downport Repository
This is once again an impressive feature! Attempting to downport every abap2UI5 version manually would remain unfeasible especially in a hobby-like project. And beginning development entirely in 702 would render the code quite challenging to understand and maintain (not to mention, it would also be unenjoyable to write).
Ultimately, we add now one final GitHub Action which tests and guarantees the error-free downportability of the code before merging it into the main branch. As a result, the definitive setup for abap2UI5 is as follows:
abap2UI5 Setup - Final Configuration
12. abap2UI5-web with open-abap
Details of the tools' inner workings are beyond this article's scope. Essentially, during unit tests, code is initially downported to version 702 and transpiled to JavaScript. It's then executed on a Node.js server. However, if it's executable there, why not directly use Node.js to use abap2UI5?
As a final showcase, let's turn our attention to the project
abap2UI5-web, which demonstrates the capabilities of all the tools we've utilized in this blog post. In this project, the complete abap2UI5 source code is transpiled and executed on a Node.js server. This enables the launch of abap2UI5 apps directly from GitHub Codespaces without any reliance on an ABAP server.
Don't miss to try this out yourself! Simply navigate to the
repository and initiate a new GitHub Codespace. Then, open a new terminal and execute the following commands:
npm install
npm test
And that's it! You can now try abap2UI5 apps on a Node.js server. Explore this final demonstration:
abap2UI5-web - Running abap2UI5 on Node.js (Part I)
abap2UI5-web - Running abap2UI5 on Node.js (Part II)
The ABAP Server is now entirely bypassed! Regard this as an experiment, yet it underscores the potential that these tools hold for the future. Can we also create UIs in ABAP using browser based
playgrounds similar to those found in UI5? The capability to directly modify and execute ABAP code in a browser is still available as you can try
here and
here:
ABAP Code transpiled to JavaScript (Demo)
abaplint running on open-abap (Demo)
If you want to learn more about this topic, check out this
blog post.
13. Conclusion
This concludes the journey through the tooling utilized by abap2UI5. As you have likely gathered from this article, I am truly impressed! I never anticipated such seamless integration of these tools (abapGit, abaplint, open-abap) with ABAP, a language deeply intertwined with SAP's proprietary environments and solutions (SE80, ADT, CTS or gCTS).
Going the open-source way and configuring these tools on GitHub for an ABAP project has been an enlightening experience! Many thanks to
lars.hvam for the exceptional work and support in setting this up, as well as to all other contributors who have played a role in developing these tools.
🙏
Their continuous efforts over the years in developing these tools have not only made organizing an ABAP Project on GitHub possible but have also elevated Static Code Checks and DevOps to a very high standard. Attempting to achieve all of this without these tools or solely on an ABAP Server would have required much more effort (or maybe even been impossible).
I hope that this article sparked your interest and motivated you to give these tools a try. Perhaps you now also want to manage your upcoming ABAP project with abapGit and abaplint? Feel free to share your ideas and experiences, or if there's something I missed out on, I welcome your insights.
In the
next part, we'll explore various new features added over recent months to abap2UI5.
Thank you for reading! Your questions, comments and wishes for this project are always welcome, leave a comment or create an
issue.