gCTS (Git-enabled Change and Transport System) et les pipelines CI/CD apportent les pratiques DevOps modernes dans le monde ABAP. Dans cet article, vous apprendrez comment mettre en place un pipeline DevOps complet pour ABAP Cloud - de l’integration Git jusqu’au pipeline de deploiement automatise.
Qu’est-ce que gCTS ?
gCTS connecte le systeme de transport SAP classique avec les repositories Git. Au lieu de deplacer manuellement les ordres de transport entre les systemes, les objets ABAP sont stockes sous forme de fichiers dans Git et synchronises via des operations Git.
Concept principal
+-----------------------------------------------------------------------+| Paysage de developpement avec gCTS || || +-------------+ +-------------+ +-------------+ || | DEV | | QAS | | PRD | || | Systeme | | Systeme | | Systeme | || | +-------+ | | +-------+ | | +-------+ | || | | gCTS | | | | gCTS | | | | gCTS | | || | |Client | | | |Client | | | |Client | | || | +---+---+ | | +---+---+ | | +---+---+ | || +------+------+ +------+------+ +------+------+ || | | | || +--------+---------+--------+---------+ || Push | | Pull || v v || +-------------------------------+ || | Repository Git | || | (GitHub / GitLab / Azure) | || +-------------------------------+ |+-----------------------------------------------------------------------+CTS classique vs. gCTS
| Aspect | CTS classique | gCTS |
|---|---|---|
| Versionnement | Ordres de transport | Commits Git |
| Branching | Impossible | Branching complet |
| Comparaison | Limitee | Diff entre commits |
| Collaboration | Limitee | Pull Requests, Code Review |
| Historique | Logs de transport | Historique Git complet |
| Rollback | Manuel | Git Revert/Reset |
| CI/CD | Difficile | Integration native |
| Outillage | Specifique SAP | Outils Git standard |
gCTS vs. abapGit : Quand utiliser lequel ?
Une question frequente dans la communaute ABAP : Quelle est la difference entre gCTS et abapGit ?
| Critere | gCTS | abapGit |
|---|---|---|
| Origine | Produit SAP (officiel) | Open-Source (Communaute) |
| Public cible | Operations IT & Enterprise | Developpeurs & Equipes |
| Focus | Automatisation des transports | Versionnement du code |
| Integration Git | Push & Pull | Complete (bidirectionnelle) |
| Cout | Licence SAP requise | Gratuit |
| Complexite de setup | Plus elevee (setup Enterprise) | Plus faible (demarrage rapide) |
| Pipeline CI/CD | Integration SAP native | Configurable manuellement |
| Integration transport | Completement integre | Aucune |
| Support SAP | Oui, support officiel | Support communautaire |
Recommandation
- Choisir gCTS : Environnements Enterprise avec paysages systemes productifs, lorsqu’un support SAP officiel est necessaire
- Choisir abapGit : Projets open-source, equipes de developpement, demarrage rapide, flexibilite maximale
- Combinaison : Les deux outils peuvent etre combines - abapGit pour le developpement, gCTS pour les deploiements Enterprise
Pour une introduction detaillee a abapGit, voir l’article tutoriel abapGit.
Concepts CI/CD pour ABAP
L’Integration Continue (CI) et la Livraison Continue (CD) apportent des pratiques DevOps eprouvees dans le developpement ABAP :
| Phase | Sans CI/CD | Avec CI/CD |
|---|---|---|
| Tests | Manuels, souvent oublies | Automatiques a chaque commit |
| Qualite du code | Verifications ATC sporadiques | Verification continue |
| Deploiement | Transport manuel | Automatise & reproductible |
| Feedback | Differe, apres des jours | Immediat, en minutes |
| Risque | Grandes releases, risque eleve | Petits changements, faible risque |
| Rollback | Complexe, manuel | Simple, automatise |
Le pipeline CI/CD pour ABAP
+-----------------------------------------------------------------------------+| Pipeline CI/CD pour ABAP Cloud || || +---------+ +---------+ +---------+ +---------+ +---------+ || | Code | | Build | | Test | | Quality | | Deploy | || | Push |-->| Check |-->| Stage |-->| Gate |-->| Stage | || +---------+ +---------+ +---------+ +---------+ +---------+ || | | | | | || v v v v v || Git Push Syntaxe & ABAP Unit ATC Checks gCTS Pull || Trigger Activation Tests Code Review Transport || Integration Coverage || Tests Securite |+-----------------------------------------------------------------------------+Configurer gCTS : Guide de setup
Prerequis
- SAP S/4HANA ou SAP BTP ABAP Environment
- Repository Git (GitHub, GitLab, Azure DevOps)
- Certificats SSL pour le serveur Git
- Autorisations : S_CTS_ADMI, S_CTS_SADM
Etape 1 : Importer les certificats SSL
Transaction: STRUST
1. Ouvrir SSL Client (Standard)2. Importer le certificat: - GitHub: github.com - GitLab: gitlab.com (ou votre propre domaine)3. Actualiser la liste des certificats4. SauvegarderEtape 2 : Creer un repository gCTS
Dans la transaction GCTS_MAINT ou via l’application Fiori :
+--------------------------------------------------------------+| Configuration du Repository |+--------------------------------------------------------------+| Nom du Repository: Z_MY_PROJECT || URL Distante: https://github.com/company/project.git || Branche: main || || Authentification: || * Base sur token (recommande) || || Nom d'utilisateur: github-service-user || Token: ghp_xxxxxxxxxxxx || || vSID (Virtual System ID): DEV |+--------------------------------------------------------------+Etape 3 : Creer un repository via API (optionnel)
CLASS zcl_gcts_setup DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS create_repository IMPORTING iv_repository_name TYPE string iv_remote_url TYPE string iv_branch TYPE string DEFAULT 'main" RAISING cx_web_http_client_error.ENDCLASS.
CLASS zcl_gcts_setup IMPLEMENTATION. METHOD create_repository. DATA(lo_destination) = cl_http_destination_provider=>create_by_url( i_url = |http://localhost:50000/sap/bc/cts_abapvcs/repository| ).
DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( i_destination = lo_destination ).
DATA: BEGIN OF ls_request, repository TYPE string, url TYPE string, branch TYPE string, role TYPE string VALUE 'SOURCE', END OF ls_request.
ls_request-repository = iv_repository_name. ls_request-url = iv_remote_url. ls_request-branch = iv_branch.
DATA(lv_json) = /ui2/cl_json=>serialize( data = ls_request compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
DATA(lo_request) = lo_client->get_http_request( ). lo_request->set_header_field( i_name = 'Content-Type' i_value = 'application/json' ). lo_request->set_text( lv_json ).
DATA(lo_response) = lo_client->execute( if_web_http_client=>post ).
IF lo_response->get_status( )-code <> 201. RAISE EXCEPTION TYPE cx_web_http_client_error. ENDIF.
lo_client->close( ). ENDMETHOD.ENDCLASS.Etape 4 : Lier le package ABAP au repository
Apres la creation du repository, le package ABAP doit etre lie :
" Dans SE80 ou via ADT:" Package Z_MY_PACKAGE -> Properties -> Attribuer le repository gCTSPipeline GitHub Actions pour ABAP
GitHub Actions offre une flexibilite maximale pour le CI/CD ABAP. Voici un pipeline complet, pret pour la production :
Configuration complete du pipeline
name: ABAP CI/CD Pipeline
on: push: branches: [ main, develop, 'release/**' ] pull_request: branches: [ main, develop ] workflow_dispatch: inputs: deploy_target: description: 'Deployer vers environnement" required: true default: 'dev" type: choice options: - dev - qas - prd
env: ABAP_PACKAGE: ${{ vars.ABAP_PACKAGE }} ATC_VARIANT: ${{ vars.ATC_VARIANT || 'DEFAULT' }}
jobs: # Job 1: Verification syntaxe et activation build: name: Build & Syntax Check runs-on: ubuntu-latest
steps: - name: Checkout Repository uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20"
- name: Verify ABAP Syntax run: | curl -X POST \ "${{ secrets.ABAP_ENDPOINT }}/sap/bc/adt/programs/checks" \ -u "${{ secrets.ABAP_USER }}:${{ secrets.ABAP_PASSWORD }}" \ -H "Content-Type: application/json" \ --fail
# Job 2: Tests unitaires ABAP unit-tests: name: ABAP Unit Tests needs: build runs-on: ubuntu-latest
steps: - name: Run ABAP Unit Tests id: aunit run: | curl -X POST \ "${{ secrets.ABAP_ENDPOINT }}/sap/bc/adt/abapunit/testruns" \ -u "${{ secrets.ABAP_USER }}:${{ secrets.ABAP_PASSWORD }}" \ -H "Content-Type: application/vnd.sap.adt.abapunit.testruns.config.v4+xml" \ -H "Accept: application/vnd.sap.adt.abapunit.testruns.result.v1+xml" \ -d @- << 'EOF' > aunit_results.xml <?xml version="1.0" encoding="UTF-8"?> <aunit:runConfiguration xmlns:aunit="http://www.sap.com/adt/aunit"> <external> <coverage active="true" branchCoverage="true"/> </external> <options> <uriType value="semantic"/> <testDeterminationStrategy sameProgram="true"/> <testRiskCoverage> <harmless active="true"/> <dangerous active="true"/> <critical active="true"/> </testRiskCoverage> <durationCoverage short="true" medium="true" long="true"/> </options> <adtcore:objectSets xmlns:adtcore="http://www.sap.com/adt/core"> <objectSet kind="inclusive"> <adtcore:objectReferences> <adtcore:objectReference adtcore:uri="/sap/bc/adt/vit/wb/object_type/devck/object_name/${{ env.ABAP_PACKAGE }}"/> </adtcore:objectReferences> </objectSet> </adtcore:objectSets> </aunit:runConfiguration> EOF
- name: Parse Test Results run: | if grep -q 'alerts severity="error"' aunit_results.xml; then echo "::error::Les tests unitaires ABAP ont echoue!" exit 1 fi echo "Tous les tests unitaires ABAP ont reussi"
- name: Upload Test Results uses: actions/upload-artifact@v4 with: name: aunit-results path: aunit_results.xml
# Job 3: Verifications qualite ATC atc-checks: name: ATC Quality Checks needs: build runs-on: ubuntu-latest
steps: - name: Run ATC Checks id: atc run: | # Demarrer ATC Run RUN_ID=$(curl -X POST \ "${{ secrets.ABAP_ENDPOINT }}/sap/bc/adt/atc/runs" \ -u "${{ secrets.ABAP_USER }}:${{ secrets.ABAP_PASSWORD }}" \ -H "Content-Type: application/vnd.sap.atc.run.parameters.v1+xml" \ -d @- << EOF | grep -oP 'id="\K[^"]+' | head -1 <?xml version="1.0" encoding="UTF-8"?> <atc:run xmlns:atc="http://www.sap.com/adt/atc"> <checkVariant>${{ env.ATC_VARIANT }}</checkVariant> <objectSets> <objectSet name="run"> <softwareComponent name="${{ env.ABAP_PACKAGE }}"/> </objectSet> </objectSets> </atc:run> EOF )
echo "ATC Run ID: $RUN_ID" sleep 30
# Recuperer les resultats curl -X GET \ "${{ secrets.ABAP_ENDPOINT }}/sap/bc/adt/atc/runs/$RUN_ID/results" \ -u "${{ secrets.ABAP_USER }}:${{ secrets.ABAP_PASSWORD }}" \ -H "Accept: application/vnd.sap.atc.checkresult.v1+xml" \ > atc_results.xml
- name: Evaluate ATC Results run: | ERRORS=$(grep -c 'priority="1"' atc_results.xml || true) WARNINGS=$(grep -c 'priority="2"' atc_results.xml || true)
echo "Resultats ATC: $ERRORS erreurs, $WARNINGS avertissements"
if [ "$ERRORS" -gt 0 ]; then echo "::error::ATC a trouve $ERRORS problemes critiques!" exit 1 fi echo "Les verifications ATC ont reussi"
- name: Upload ATC Results uses: actions/upload-artifact@v4 with: name: atc-results path: atc_results.xml
# Job 4: Deployer vers DEV deploy-dev: name: Deploy to DEV needs: [unit-tests, atc-checks] runs-on: ubuntu-latest if: github.ref == 'refs/heads/develop" environment: development
steps: - name: Pull to DEV System via gCTS run: | curl -X POST \ "${{ secrets.DEV_ENDPOINT }}/sap/bc/cts_abapvcs/repository/${{ vars.GCTS_REPO }}/pull" \ -u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \ -H "Content-Type: application/json" \ -d '{"branch": "develop"}" echo "Deploye vers DEV"
# Job 5: Deployer vers QAS deploy-qas: name: Deploy to QAS needs: [unit-tests, atc-checks] runs-on: ubuntu-latest if: github.ref == 'refs/heads/main" environment: quality-assurance
steps: - name: Pull to QAS System via gCTS run: | curl -X POST \ "${{ secrets.QAS_ENDPOINT }}/sap/bc/cts_abapvcs/repository/${{ vars.GCTS_REPO }}/pull" \ -u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \ -H "Content-Type: application/json" \ -d '{"branch": "main"}" echo "Deploye vers QAS"
# Job 6: Deployer vers PRD (Approbation manuelle) deploy-prd: name: Deploy to PRD needs: deploy-qas runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' && github.event_name == 'workflow_dispatch" environment: production
steps: - name: Pull to PRD System via gCTS run: | curl -X POST \ "${{ secrets.PRD_ENDPOINT }}/sap/bc/cts_abapvcs/repository/${{ vars.GCTS_REPO }}/pull" \ -u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \ -H "Content-Type: application/json" \ -d '{"branch": "main", "tag": "${{ github.sha }}"}" echo "Deploye vers PRD"Integrer des tests automatises
Classe de test ABAP Unit pour CI/CD
CLASS zcl_customer_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PRIVATE SECTION. CLASS-DATA: mo_environment TYPE REF TO if_cds_test_environment.
CLASS-METHODS: class_setup, class_teardown.
METHODS: setup, teardown, test_create_customer_success FOR TESTING, test_create_customer_invalid_email FOR TESTING, test_update_customer_status FOR TESTING.ENDCLASS.
CLASS zcl_customer_test IMPLEMENTATION. METHOD class_setup. " CDS Test Double Framework pour tests isoles mo_environment = cl_cds_test_environment=>create_for_multiple_cds( VALUE #( ( i_for_entity = 'ZI_CUSTOMER' ) ( i_for_entity = 'ZI_ORDER' ) ) ). ENDMETHOD.
METHOD class_teardown. mo_environment->destroy( ). ENDMETHOD.
METHOD setup. mo_environment->clear_doubles( ). " Inserer des donnees mock DATA(lt_customers) = VALUE zt_customer_t( ). mo_environment->insert_test_data( lt_customers ). ENDMETHOD.
METHOD teardown. ROLLBACK WORK. ENDMETHOD.
METHOD test_create_customer_success. " Given DATA(lo_cut) = NEW zcl_customer_service( ). DATA(ls_input) = VALUE zs_customer_create( name = 'New Customer" ).
" When DATA(ls_result) = lo_cut->create_customer( ls_input ).
" Then cl_abap_unit_assert=>assert_not_initial( act = ls_result-customer_id msg = 'L ID client devrait etre genere" ). ENDMETHOD.
METHOD test_create_customer_invalid_email. " Given DATA(lo_cut) = NEW zcl_customer_service( ). DATA(ls_input) = VALUE zs_customer_create( name = 'Invalid Customer" email = 'not-an-email" ).
" When / Then TRY. lo_cut->create_customer( ls_input ). cl_abap_unit_assert=>fail( 'Exception attendue' ). CATCH zcx_customer_error INTO DATA(lx_error). cl_abap_unit_assert=>assert_equals( act = lx_error->error_code exp = 'INVALID_EMAIL" ). ENDTRY. ENDMETHOD.
METHOD test_update_customer_status. " Given DATA(lo_cut) = NEW zcl_customer_service( ).
" When lo_cut->set_customer_status( iv_customer_id = '1' iv_status = 'I' ).
" Then DATA(ls_customer) = lo_cut->get_customer( '1' ). cl_abap_unit_assert=>assert_equals( act = ls_customer-status exp = 'I" msg = 'Le statut devrait etre mis a jour" ). ENDMETHOD.ENDCLASS.Resume des bonnes pratiques
| Theme | Recommandation |
|---|---|
| Isolation des tests | CDS Test Environment pour les tests unitaires |
| Donnees de test | Donnees mock dans les methodes setup |
| Variante ATC | Propre variante CI/CD avec verifications pertinentes |
| Secrets | Utiliser GitHub Secrets / Azure Key Vault |
| Parallelisation | Executer les jobs independants en parallele |
| Environments | GitHub Environments pour les workflows d’approbation |
| Messages de commit | Commits conventionnels (feat:, fix:, etc.) |
| Code Review | Pull Requests avant chaque merge |
| Tagging | Releases avec versionnement semantique |
| Monitoring | Integration Slack/Teams pour les notifications |
Conclusion
gCTS et CI/CD transforment le developpement ABAP des processus de transport manuels vers des workflows DevOps automatises :
- gCTS permet une gestion des transports basee sur Git avec historique complet et branching
- Les pipelines CI/CD automatisent les tests, verifications de qualite et deploiements
- Les tests unitaires ABAP dans le pipeline assurent la qualite du code a chaque commit
- Les verifications ATC empechent les failles de securite ou problemes de performance d’atteindre la production
Prochaines etapes :
- Configurer un repository gCTS pour votre projet ABAP
- Configurer un pipeline GitHub Actions ou Azure DevOps
- Ecrire des tests unitaires ABAP pour la logique metier critique
- Creer une variante ATC personnalisee pour CI/CD
- Former l’equipe aux workflows Git
Articles complementaires
- Tutoriel abapGit - Controle de version pour developpeurs
- gCTS: Git-enabled CTS - Reference gCTS detaillee
- CI/CD avec ABAP Cloud - Configurations de pipeline avancees
- ABAP Unit Testing - Developpement pilote par les tests
- Clean ABAP: Regles et bonnes pratiques - Qualite du code