Gestion des transports sur SAP BTP

Catégorie
DevOps
Publié
Auteur
Johannes

La gestion des transports sur SAP BTP differe fondamentalement de l’approche classique On-Premise. Au lieu des ordres de transport et du Transport Management System (TMS), un workflow base sur Git est utilise, permettant des pratiques DevOps modernes.

Concepts de transport sur BTP

Sur SAP BTP ABAP Environment, il n’y a plus d’ordres de transport classiques. A la place, la gestion des transports est basee sur les Software Components et les repositories Git :

ConceptClassique (On-Premise)SAP BTP
Unite de transportOrdre de transportCommit Git
Couche de transportConfiguration TMSBranches Git
Outil de transportSTMSManage Software Components
WorkflowLiberer le transportPush/Pull via Git
VersioningLogs de transportHistorique Git
RollbackImport manuelGit Revert/Checkout

Vue d’ensemble de l’architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│ Architecture de transport SAP BTP │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ DEV │ │ QAS │ │ PRD │ │
│ │ Systeme │ │ Systeme │ │ Systeme │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │ Software │ │ │ │ Software │ │ │ │ Software │ │ │
│ │ │ Component│ │ │ │ Component│ │ │ │ Component│ │ │
│ │ └────┬─────┘ │ │ └────┬─────┘ │ │ └────┬─────┘ │ │
│ └──────│───────┘ └──────│───────┘ └──────│───────┘ │
│ │ │ │ │
│ │ Push │ Pull │ Pull │
│ ▼ ▼ ▼ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Repository Git │ │
│ │ │ │
│ │ main ───────────────────────────────────────────────────── │ │
│ │ │ │ │ │
│ │ develop ───────────────────┴─────────────────────────── │ │
│ │ │ │ │
│ │ feature/new-api ───────────┘ │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

gCTS vs. CTS classique

Comparaison

FonctionnaliteCTS classiquegCTS (Git-enabled CTS)
Controle de versionProprietaire SAPGit standard
BranchingPas possibleBranching complet
Merge/DiffLimiteOutils Git standard
Code ReviewNon integrePull Requests
CI/CDComplexeIntegration native
RollbackManuel, complexeGit Revert/Reset
Developpement paralleleConflits frequentsFeature Branches
Piste d’auditLogs de transportHistorique Git

Quand utiliser quel systeme ?

  • gCTS : Standard sur SAP BTP, recommande pour tous les nouveaux projets
  • CTS classique : Uniquement pour les systemes On-Premise sans integration Git

Landscape Management

Paysage systeme typique

Un paysage SAP BTP professionnel se compose de plusieurs ABAP Environments :

┌─────────────────────────────────────────────────────────────────────────────┐
│ SAP BTP Subaccount │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Space : Development │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ABAP Environment Instance : DEV │ │ │
│ │ │ - Developpement libre │ │ │
│ │ │ - Tests locaux │ │ │
│ │ │ - Feature Branches │ │ │
│ │ │ - Branch : develop, feature/* │ │ │
│ │ └───────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Space : Quality │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ABAP Environment Instance : QAS │ │ │
│ │ │ - Tests d'integration │ │ │
│ │ │ - Tests de recette │ │ │
│ │ │ - Preparation des releases │ │ │
│ │ │ - Branch : main (Release Candidates) │ │ │
│ │ └───────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Space : Production │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ABAP Environment Instance : PRD │ │ │
│ │ │ - Exploitation productive │ │ │
│ │ │ - Uniquement code teste │ │ │
│ │ │ - Branch : main (uniquement Tags) │ │ │
│ │ └───────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

Strategie de branches par systeme

SystemeBranchObjectifFrequence de mise a jour
DEVdevelop, feature/*Developpement actifContinue
QASmainTests d’integrationApres merge
PRDmain (Tags)ProductifBase sur les releases

Workflow de transport sur BTP

Etape 1 : Developpement dans le systeme DEV

" Le developpeur travaille sur une branche feature
" 1. Checkout de la branche (via Manage Software Components App)
" 2. Developper et tester le code
" 3. Commiter les modifications
" Convention de message de commit :
" feat: Nouvelle verification d'autorisation ajoutee
" fix: Erreur de calcul dans le prix corrigee
" refactor: Classe Customer-Service restructuree

Etape 2 : Creer une Pull Request

Apres la fin du developpement, une Pull Request est creee dans le repository Git :

┌────────────────────────────────────────────────────────────────────────────┐
│ Pull Request : feature/order-validation → main │
│ │
│ Title : feat: Add order validation before submission │
│ │
│ Description : │
│ - Validates order quantities against stock │
│ - Checks customer credit limit │
│ - Sends notification on validation failure │
│ │
│ Changes : 5 files changed, +234 -12 │
│ │
│ Checks : │
│ ✓ ABAP Unit Tests passed (42/42) │
│ ✓ ATC Check passed (0 errors, 3 warnings) │
│ ✓ Code Coverage : 87% │
│ │
│ Reviewers : │
│ ☑ @senior-developer (approved) │
│ ☐ @tech-lead (pending) │
│ │
│ [Merge Pull Request] [Close] │
└────────────────────────────────────────────────────────────────────────────┘

Etape 3 : Import dans le systeme QAS

┌────────────────────────────────────────────────────────────────────────────┐
│ Manage Software Components - Systeme QAS │
│ │
│ Component : ZCUSTOM_ORDER │
│ Current Branch : main │
│ Current Commit : abc123f "feat: Add order validation..." │
│ │
│ Remote Status : │
│ ⚠ 2 commits behind remote │
│ │
│ New Commits : │
│ - def456g : feat: Add order validation before submission │
│ - 789hij0 : fix: Correct currency conversion │
│ │
│ [Pull] [Checkout Branch] [History] │
└────────────────────────────────────────────────────────────────────────────┘

Etape 4 : Release et deploiement PRD

" Processus de release :
" 1. Tests QAS termines avec succes
" 2. Creer un tag de release dans le repository Git (ex. v1.2.0)
" 3. Checkout du tag dans le systeme PRD
" Creer un tag Git (via GitHub/GitLab UI ou CLI) :
" git tag -a v1.2.0 -m "Release 1.2.0 - Order Validation"
" git push origin v1.2.0

Exemple pratique : Transport de feature

Situation initiale

Une nouvelle fonctionnalite “Verification limite de credit client” doit etre developpee et transportee.

1. Creer et developper la branche feature

" Dans le systeme DEV :
" 1. Ouvrir l'app Manage Software Components
" 2. Selectionner le Component ZCUSTOM_ORDER
" 3. "Checkout Branch" > "Create New Branch"
" 4. Nom de branche : feature/credit-limit-check
CLASS zcl_credit_limit_validator DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_validation_result,
is_valid TYPE abap_bool,
message TYPE string,
credit_limit TYPE wertv8,
credit_used TYPE wertv8,
END OF ty_validation_result.
METHODS:
validate_order
IMPORTING iv_customer_id TYPE kunnr
iv_order_value TYPE wertv8
RETURNING VALUE(rs_result) TYPE ty_validation_result.
ENDCLASS.
CLASS zcl_credit_limit_validator IMPLEMENTATION.
METHOD validate_order.
" Lire la limite de credit client depuis la CDS View
SELECT SINGLE
credit_limit,
credit_used
FROM zi_customer_credit
WHERE customer_id = @iv_customer_id
INTO (@rs_result-credit_limit, @rs_result-credit_used).
IF sy-subrc <> 0.
rs_result-is_valid = abap_false.
rs_result-message = |Client { iv_customer_id } non trouve|.
RETURN.
ENDIF.
" Verifier la limite de credit disponible
DATA(lv_available) = rs_result-credit_limit - rs_result-credit_used.
IF iv_order_value <= lv_available.
rs_result-is_valid = abap_true.
rs_result-message = |Limite de credit OK. Disponible : { lv_available }|.
ELSE.
rs_result-is_valid = abap_false.
rs_result-message = |Limite de credit depassee. Disponible : { lv_available }, Requis : { iv_order_value }|.
ENDIF.
ENDMETHOD.
ENDCLASS.

2. Ecrire les tests unitaires

CLASS zcl_credit_limit_validator_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,
test_valid_credit_limit FOR TESTING,
test_exceeded_credit_limit FOR TESTING,
test_customer_not_found FOR TESTING.
ENDCLASS.
CLASS zcl_credit_limit_validator_test IMPLEMENTATION.
METHOD class_setup.
mo_environment = cl_cds_test_environment=>create_for_multiple_cds(
VALUE #( ( i_for_entity = 'ZI_CUSTOMER_CREDIT' ) )
).
ENDMETHOD.
METHOD class_teardown.
mo_environment->destroy( ).
ENDMETHOD.
METHOD setup.
mo_environment->clear_doubles( ).
" Inserer les donnees de test
DATA(lt_credits) = VALUE zt_customer_credit_t(
( customer_id = '1000' credit_limit = 50000 credit_used = 20000 )
( customer_id = '2000' credit_limit = 10000 credit_used = 9500 )
).
mo_environment->insert_test_data( lt_credits ).
ENDMETHOD.
METHOD test_valid_credit_limit.
" Given
DATA(lo_cut) = NEW zcl_credit_limit_validator( ).
" When - Commande sous la limite disponible
DATA(ls_result) = lo_cut->validate_order(
iv_customer_id = '1000"
iv_order_value = 25000 " 30000 disponible
).
" Then
cl_abap_unit_assert=>assert_true( ls_result-is_valid ).
ENDMETHOD.
METHOD test_exceeded_credit_limit.
" Given
DATA(lo_cut) = NEW zcl_credit_limit_validator( ).
" When - Commande au-dessus de la limite disponible
DATA(ls_result) = lo_cut->validate_order(
iv_customer_id = '2000"
iv_order_value = 1000 " Seulement 500 disponible
).
" Then
cl_abap_unit_assert=>assert_false( ls_result-is_valid ).
cl_abap_unit_assert=>assert_char_cp(
act = ls_result-message
exp = '*depassee*"
).
ENDMETHOD.
METHOD test_customer_not_found.
" Given
DATA(lo_cut) = NEW zcl_credit_limit_validator( ).
" When - Client inconnu
DATA(ls_result) = lo_cut->validate_order(
iv_customer_id = '9999"
iv_order_value = 1000
).
" Then
cl_abap_unit_assert=>assert_false( ls_result-is_valid ).
cl_abap_unit_assert=>assert_char_cp(
act = ls_result-message
exp = '*non trouve*"
).
ENDMETHOD.
ENDCLASS.

3. Commit et Push

Apres les tests locaux reussis :

┌────────────────────────────────────────────────────────────────────────────┐
│ Commit Changes │
│ │
│ Branch : feature/credit-limit-check │
│ │
│ Changed Objects : │
│ ☑ ZCL_CREDIT_LIMIT_VALIDATOR (Class) │
│ ☑ ZCL_CREDIT_LIMIT_VALIDATOR_TEST (Test Class) │
│ ☑ ZI_CUSTOMER_CREDIT (CDS View) │
│ │
│ Commit Message : │
│ ┌────────────────────────────────────────────────────────────────────────┐│
│ │ feat: Add credit limit validation for customer orders ││
│ │ ││
│ │ - Check available credit before order submission ││
│ │ - Return detailed validation result with messages ││
│ │ - Add unit tests with 100% coverage ││
│ └────────────────────────────────────────────────────────────────────────┘│
│ │
│ [Commit] [Commit & Push] [Cancel] │
└────────────────────────────────────────────────────────────────────────────┘

4. Pull Request et Merge

Apres une revue de code reussie, la Pull Request est mergee :

Terminal window
# Dans le repository Git (GitHub/GitLab) :
# 1. Pull Request : feature/credit-limit-check → main
# 2. Le pipeline CI/CD s'execute automatiquement
# 3. Apres approbation : Effectuer le merge

5. Import QAS

┌────────────────────────────────────────────────────────────────────────────┐
│ Manage Software Components - QAS │
│ │
│ Action : Pull latest changes │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐│
│ │ Pull Progress ││
│ │ ████████████████████████████████████████████████████████░░░░ 92% ││
│ │ ││
│ │ - Fetching remote changes... ✓ ││
│ │ - Downloading objects... ✓ ││
│ │ - Importing ABAP objects... ✓ ││
│ │ - Activating objects... ⟳ ││
│ │ - Running post-import checks... ○ ││
│ └────────────────────────────────────────────────────────────────────────┘│
│ │
│ Objects to import : 3 │
│ - ZCL_CREDIT_LIMIT_VALIDATOR │
│ - ZCL_CREDIT_LIMIT_VALIDATOR_TEST │
│ - ZI_CUSTOMER_CREDIT │
│ │
└────────────────────────────────────────────────────────────────────────────┘

Integration CI/CD

Pipeline GitHub Actions

.github/workflows/abap-transport.yml
name: ABAP Transport Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
ABAP_PACKAGE: ZCUSTOM_ORDER
jobs:
# Stage 1 : Build et Tests
test:
name: ABAP Unit Tests & ATC
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run ABAP Unit Tests
uses: SAP/abap-ci-action@v1
with:
abap-endpoint: ${{ secrets.DEV_ENDPOINT }}
username: ${{ secrets.ABAP_USER }}
password: ${{ secrets.ABAP_PASSWORD }}
package: ${{ env.ABAP_PACKAGE }}
- name: Run ATC Checks
uses: SAP/abap-atc-action@v1
with:
abap-endpoint: ${{ secrets.DEV_ENDPOINT }}
username: ${{ secrets.ABAP_USER }}
password: ${{ secrets.ABAP_PASSWORD }}
package: ${{ env.ABAP_PACKAGE }}
variant: Z_CI_CHECKS
# Stage 2 : Deploy vers QAS
deploy-qas:
name: Deploy to QAS
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main"
environment: quality-assurance
steps:
- name: Pull to QAS System
run: |
curl -X POST \
"${{ secrets.QAS_ENDPOINT }}/sap/bc/cts_abapvcs/repository/ZCUSTOM_ORDER/pull" \
-u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \
-H "Content-Type: application/json" \
-d '{"branch": "main"}"
- name: Verify Deployment
run: |
# Attendre l'activation
sleep 30
# Verifier le statut
STATUS=$(curl -s \
"${{ secrets.QAS_ENDPOINT }}/sap/bc/cts_abapvcs/repository/ZCUSTOM_ORDER" \
-u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \
| jq -r '.status')
if [ "$STATUS" != "IMPORTED" ]; then
echo "Deployment failed with status: $STATUS"
exit 1
fi
# Stage 3 : Deploy vers PRD (manuel)
deploy-prd:
name: Deploy to PRD
needs: deploy-qas
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main"
environment: production
steps:
- name: Create Release Tag
run: |
VERSION="v${{ github.run_number }}"
git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"
- name: Pull to PRD System
run: |
curl -X POST \
"${{ secrets.PRD_ENDPOINT }}/sap/bc/cts_abapvcs/repository/ZCUSTOM_ORDER/pull" \
-u "${{ secrets.DEPLOY_USER }}:${{ secrets.DEPLOY_PASSWORD }}" \
-H "Content-Type: application/json" \
-d '{"branch": "main", "tag": "v${{ github.run_number }}"}"

Bonnes pratiques

A faire

RecommandationJustification
Utiliser des Feature BranchesDeveloppement isole, revue facile
Commits conventionnelsHistorique clair (feat:, fix:, refactor:)
Pull Requests pour tous les changementsCode Review, Quality Gates
Tests automatises avant mergeDetecter les erreurs tot
Tags pour les releasesDeploiements reproductibles
Environnements separesSeparation DEV/QAS/PRD
Pipeline CI/CDDeploiements automatises et reproductibles

A eviter

EviterProbleme
Push direct sur mainPas de possibilite de revue
Tests manquantsErreurs decouvertes seulement en production
Deploiements manuelsSujet aux erreurs, non reproductible
Sauter QASCode non teste en production
Strategie de rollback manquanteTemps d’arret prolonges en cas de probleme

Resume

La gestion des transports sur SAP BTP est basee sur des principes DevOps modernes :

  1. Transport base sur Git remplace les ordres de transport classiques
  2. Strategies de branching permettent le developpement parallele
  3. Pull Requests assurent la qualite du code par la revue
  4. Pipelines CI/CD automatisent tests et deploiements
  5. Tags marquent les releases pour des deploiements reproductibles
  6. Rollback possible a tout moment par checkout de tags precedents

La transition du CTS classique vers gCTS peut sembler inhabituelle au debut, mais offre des avantages considerables : meilleure tracabilite, developpement parallele plus simple et integration dans les workflows DevOps modernes.