Code review for SAP transports, with GitHub pull requests
A transport request moves objects from one SAP system to the next. It does not tell you much more than that. When someone asks "when was this released, what exactly changed, who looked at it and why was it made?", the honest answer in many landscapes is a search through transport logs, version management and somebody's memory.
We built a solution that answers all four questions, and we published it as open source. It connects the SAP transport system to GitHub pull requests, so that a change cannot leave the development system before a second person has reviewed it.
What you get
| Question | Where the answer is |
|---|---|
| What changed? | The diff of the pull request: every object, line by line, one commit for each released task |
| Who made the change? | The commits, and the pull request, opened under the developer's own GitHub account |
| Who reviewed and approved it? | The reviews on the pull request: comments, requested changes and the approval, each with the person and the time |
| When was it released? | The pull request description, with the release stamp SAP writes when a task is released, and the merge commit |
| Why was it made? | The issue key at the start of the request text, in every commit and in the issue tracker |
| Which transport carried it? | The request number in every commit message and in the pull request title |
The aim is clean code and controlled releases. A change that nobody else has looked at does not get out.
How it works
Developers keep working as they do today, in SAP GUI or in Eclipse ADT. The request text starts with the issue key, for example ABC-123 Fix posting date check.
- Release a task. A background job commits the objects of that task to the branch
review/<request>and opens a pull request under the developer's own GitHub account. The link arrives in the SAP inbox. - Review on GitHub. abaplint checks the code on the pull request, and GitHub Copilot can review the diff if you turn it on. A colleague reads the change, comments and approves. The author cannot approve their own pull request.
- Rework, if the reviewer asks for changes. The developer creates a new task in the same request, makes the change and releases it. The job adds a new commit to the same pull request, earlier approvals are dismissed, and the reviewer looks again.
- Release the request. SAP refuses the release until the pull request is approved and nothing changed since. Then the release goes on.
- The merge happens from SAP, never on GitHub. When the request is released, a job squashes and merges the pull request into the base branch. A rule on the repository lets only that release, or an administrator, update the base branch. The reason is simple: the base branch must contain only what has been released. If someone could merge an approved pull request while the request is still open, a new task with an unreviewed change could be released after the merge, and Git would no longer show what was reviewed and what the transport delivers.
- Transport as before. The request moves to the other systems the way your landscape does it today. Git holds the reviewed copy; it does not deploy.
Issue trackers do the rest. Jira, Linear, Azure Boards and GitHub Issues can all read the issue key from the pull request title and the commit message, so the pull request and its merge appear on the issue.
What abapGit cannot write
abapGit turns repository objects into files, but a transport also carries table rows, report variants, authorization profiles, old OTR texts and ALV layouts. The solution writes those as JSON files in the same commit, so the reviewer sees them too. A report brings them into another system, with a test run first and a request that records every change. Whatever cannot be written is listed in the pull request under "Not in Git". By default that is a note; with one setting the release of such a request is refused.
Exceptions are explicit
#NOREVIEWin the request text releases one request without the review. The marker stays in the request description, where it can be listed.- One setting switches the whole solution off for a system.
- If the check itself fails, for example because GitHub cannot be reached, the release is never stopped.
- The optional translation check has its own markers:
#DELIVERYmarks a transport for a customer, which is always refused while a translation is missing, and#NOTRANSLreleases a request without the translation check in an emergency. Each check reads only its own marker, and markers can be combined.
What changed for us in practice
We have used this flow in a real project for some time, and the effect showed from the first day:
- Visibility, without logging in to SAP. The product owner, functional consultants and the development lead no longer need an SAP user or SAP GUI to see which transports are in development, what changed, who changed it and when it was released. They open the pull request on GitHub or the issue in Jira.
- Jira follows automatically. The pull request appears on the issue as soon as a task or request is in GitHub.
- No more black box. Everybody in the team can see what is being changed, and questions go to the pull request, not to the developer.
- Better code review. The reviewer works on a diff, not on a list of object names, so details are no longer lost.
- GitHub Copilot reviews every pull request. We turned on Copilot code review, so when a task is released the diff is reviewed automatically before a colleague opens it. It has already caught many problems that were quick to fix, and we have far fewer avoidable bugs. Its review is a comment; the approval still comes from a person.
- Fewer accidents. A change that nobody checked cannot be released by mistake, because the release waits for the approval.
The result is more control and better quality, with a process that everybody can see and verify.
Where it works, and where it does not
It is written for SAP NetWeaver 7.40 SP08 and newer, on-premise or private cloud. The classes and reports compile without errors on 7.40 SP25 and on S/4HANA 2023, and the unit tests pass on S/4HANA 2023. Other releases are expected to work but are not tested yet.
It is not for S/4HANA Cloud Public Edition or the BTP ABAP environment. There SAP's own gCTS is the way, and the plan for the cloud is gCTS with a branch rule on GitHub. gCTS also does not exist on 7.40 and commits when the request is released, so it has no gate at the release. This solution is the answer for the systems where that matters.
Try it, and help improve it
The code, the installation guide and the documentation are on GitHub: catafeidi/abap-transport-review. It is MIT licensed. You need abapGit and a GitHub App, and the guide takes you through the setup in order, with the expected result of every step. There is also a guide for systems that already have released and open transports.
A translation check now runs at the same release: missing texts are listed, can be translated on the spot, and show up in the pull request. See A translation check for SAP transports.
It is a young project and we want it tested on more releases. If you find an object that is not supported, or something that does not work as documented, please open an issue; there is a form for exactly that. If you want to change or add something, fork the repository and open a pull request. Everyone is welcome.
If you want this set up in your own landscape, or need experienced ABAP developers for a project, get in touch.