Skip to Content
Technical Articles
Author's profile photo Jacek Wozniczak

gCTS with Gogs, Github Actions (and some thoughts)

gCTS is now an option for transporting and storing the codebase using a git-based server. One of the key point to realize is the fact that gCTS is CTS plus “g(it)”. It is still the good old transport system, but backed up by Git which adds some benefits. Comparing to abapGit, gCTS it is not so feature rich but might be easier for teams not accustomed to Git specifics and when they are using traditional single-server dev environment. abapGit has much more “usual” Git inside, giving you much more control over the code you want to commit (patch, diff, tags etc.).

From my not-so long journey with gCTS what I observed is:

  • the way you want to start to use gCTS matters. For totally new projects it is easier, for existing ones you need to plan the migration – switching packages to a new transport layer is one thing (as far as I know there is no tool for doing this automagically for the package hierarchy, you need to go to each one package and adjust), the other headaches I had was not paying attention that some objects from packages switched to gCTS were still locked in transports with my old transport layer. The best is to have all required objects released and then do the switch.
  • pay attention to the logs accessible in Activities tab and clicking on the transport (or request ID in the after-dev systems).

  • what happens if you use the same vSID for another repository? Here is a scenario – I have ZSAMPLE_1 package configured with vSID RE1. Then added ZSAMPLE_2 to another, new repo with RE1 vSID. Packages were also added to ZRE1 transport layer. When you release the transport dedicated for ZSAMPLE_2, changes will be commited to the repo of ZSAMPLE_1 too. The first sign you will find in the log of the transport: As you see there are 2 VCS Checkin and imports. In the repo for ZSAMPLE_2 I have my objects (from A4HK900065) as expected:…but the repo for ZSAMPLE_1 package also gets the changes for ZSAMPLE_2:So pay attention about these vSIDs/transport layers. The CDS below can be used to check packages assignment to gCTS generated ones.
@AbapCatalog.sqlViewName: 'ZVSID'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'vSIDs and packages'
define view z_vsid
  as select from tmscsys
  association [1..*] to tdevc as _packages on $projection.TransportLayer = _packages.pdevclass
  concat('Z', sysnam) as TransportLayer,
  sysnam              as vSID,

       systyp =    'N'
    or systyp =    'V'
  and  systxt like 'gCTS%';
  • as a remote repo server not only major vendor ones can be used – I was playing around with Gogs (as a container), it was working without problems and it is nice option if you don’t want to mess with your Github/other online account. The setup I have for Docker-compose:
        container_name: gogs
        hostname: gogs
          - "10022:22"
          - "10880:3000"
        image: gogs/gogs
          - "gogs_data:/data"‚Äč

    The quickest Gogs setup is to use SQLite as db, no SSH, user + password as authentication. Then in gCTS just use HTTP, in my case when I’m running ABAP Trial also from Docker, so using internal (Docker) ports:

  • if the hosting provider of your choice offers workflow/processing features, then you can use it to fill some gaps of missing Git features and use it to bring more interesting post-processing steps. Here are sample actions like echo-ing only changed ABAP files with git diff and creating a pull request to the main branch on push to the dev branch.

Github action file:

      - dev
    name: Create pull request
    runs-on: ubuntu-latest
      - uses: actions/checkout@v2
      - name: Create PR
        uses: repo-sync/pull-request@v2
          github_token: ${{ secrets.GITHUB_TOKEN }}
          destination_branch: "main"
          pr_title: "${{ github.event.commits[0].message }}"
          pr_body: ":crown: *An automated PR*"
          pr_label: "auto-pr"
# Log changed ABAP files
# Set the changed files as output for another step
    name: Changed ABAP files
    runs-on: ubuntu-latest
      abap: ${{ steps.changes.outputs.abap }}
      - name: Checkout repository
        uses: actions/checkout@v2
          fetch-depth: 2
      - name: Changed files
        id: changes
        run: |
          git diff --name-only --diff-filter=ACMRT HEAD~1 | grep .abap | sed -E 's/objects(.*)/\1/'
          echo "::set-output name=abap::$(git diff --name-only --diff-filter=ACMRT HEAD~1 | grep .abap | sed -E 's/objects(.*)/\1/' | xargs)"          
# Sample - use output from previous step  
    runs-on: ubuntu-latest
    name: Changed ABAP files from other step
    needs: changed_files
      - name: Print changed files
        run: |
          echo " Changed ABAP files:"
          echo ${{needs.changed_files.outputs.abap}}

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Marcello Urbani
      Marcello Urbani


      What does your workflow look like?

      What I always find confusing about gCTS messaging is that seems to advocate git based workflow with a single dev system shared between all developers, which IMHO:

      • kills 90% of GIT's usefulness
      • makes pull requests pointless

      Also, what's the point on detecting abap changes?

      Once you have the code in a git repository you can simply download a local copy and vscode+gitlens will give you file and line based histopry out of the box

      I usually do that with ABAPGIT even if I'm still using transports for development:

      This is abapGit, but I do the same with my work projects