{"id":82,"date":"2025-12-20T07:01:27","date_gmt":"2025-12-20T07:01:27","guid":{"rendered":"https:\/\/steadyrabbit.in\/blogs\/?p=82"},"modified":"2025-12-20T07:01:27","modified_gmt":"2025-12-20T07:01:27","slug":"zero-downtime-custom-code-cleanup-atc-automation-blue-green-cut-over","status":"publish","type":"post","link":"https:\/\/steadyrabbit.in\/blogs\/zero-downtime-custom-code-cleanup-atc-automation-blue-green-cut-over\/","title":{"rendered":"Zero-Downtime Custom-Code Cleanup: ATC Automation + Blue\/Green Cut-Over"},"content":{"rendered":"\n<h4 class=\"wp-block-heading\">TL;DR (90 w)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Moving to S\/4 fails when millions of Z-lines block ATC checks and Go-Live windows are counted in minutes. We show how a Micro-GCC squad automated <strong>ABAP Test Cockpit (ATC) pipelines<\/strong>, fixed 77 % of findings robotically, and executed a <strong>blue\/green cut-over<\/strong> that kept the plant floor read-only for just <strong>11 minutes<\/strong>. Terraform, Jenkinsfile, and a one-line Python diff-tool are included.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Why Z-Code Haunts S\/4 Projects (170 w)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Every ECC customer has 0.5\u20133 M lines of Z-objects. In theory you:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Run <strong>ATC S\/4HANA readiness check<\/strong>.<br><\/li>\n\n\n\n<li>Fix critical findings.<br><\/li>\n\n\n\n<li>Transport green code to S\/4.<br><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Reality:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>10 000+ ATC findings, mostly low-risk, overwhelm teams.<br><\/li>\n\n\n\n<li>Manual fixes collide with month-end close.<br><\/li>\n\n\n\n<li>6\u201324 h outage windows for SUM (Software Update Manager) are unacceptable for 24 \u00d7 7 plants.<br><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Solution:<\/strong> automate 80 % of fixes and switch traffic using blue\/green so users barely notice.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">ATC Automation Pipeline (290 w)<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Stage<\/strong><\/td><td><strong>Tool<\/strong><\/td><td><strong>Action<\/strong><\/td><\/tr><tr><td><strong>1. Pull<\/strong><\/td><td><strong>abapGit<\/strong><\/td><td>Export Z-packages to Git (gCTS optional).<\/td><\/tr><tr><td><strong>2. Static Fixes<\/strong><\/td><td>Python AST + RegEx<\/td><td>Auto-replace obsolete calls (CL_GUI_ALV_GRID \u2192 CL_SALV_TABLE).<\/td><\/tr><tr><td><strong>3. ATC Batch<\/strong><\/td><td>sapcli atc run<\/td><td>Jenkinsfile executes ATC variant S4H_READINESS.<\/td><\/tr><tr><td><strong>4. Auto-Waive Low-Risk<\/strong><\/td><td>Custom script<\/td><td>Waive findings tagged CUST_SEARCH_HELP.<\/td><\/tr><tr><td><strong>5. MR Creation<\/strong><\/td><td>GitHub API<\/td><td>PR raised with diff + ATC HTML report.<\/td><\/tr><tr><td><strong>6. Peer + Architect Review<\/strong><\/td><td>PR reviewers<\/td><td>Only critical findings need human fix.<\/td><\/tr><tr><td><strong>7. Transport Build<\/strong><\/td><td>Jenkinsfile \u2192 CTS+<\/td><td>Auto-build transport; tag with Git SHA.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Metrics<\/strong> (1.2 M Z-LOC project):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Phase<\/strong><\/td><td><strong>% Findings Closed<\/strong><\/td><td><strong>Time<\/strong><\/td><\/tr><tr><td>Static fixes<\/td><td>42 %<\/td><td>2 h<\/td><\/tr><tr><td>Auto-waive<\/td><td>35 %<\/td><td>&lt; 10 m<\/td><\/tr><tr><td>Human review<\/td><td>23 %<\/td><td>3 work-days<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">ATC report dropped from <strong>10 230 \u00bb 1 855<\/strong> critical issues\u2014sprint scope, not death march.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Blue\/Green Cut-Over Strategy (260 w)<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Blue Environment<\/strong> \u2013 ECC running legacy Z-code.<br><\/li>\n\n\n\n<li><strong>Green Environment<\/strong> \u2013 S\/4HANA 2023 stack + cleaned transports.<br><\/li>\n\n\n\n<li><strong>Replicate Data<\/strong> \u2013 SLT real-time to HANA target; freeze window only for delta.<br><\/li>\n\n\n\n<li><strong>Read-Only Switch<\/strong> \u2013 At T-11 min put ECC in read-only; users see banner.<br><\/li>\n\n\n\n<li><strong>SUM Downtime Phase<\/strong> \u2013 Import final delta transport to Green.<br><\/li>\n\n\n\n<li><strong>Route Traffic<\/strong> \u2013 F5 BIG-IP toggles DNS; UI5 front-end hits Green.<br><\/li>\n\n\n\n<li><strong>Back-Out Plan<\/strong> \u2013 If KPI smoke fails (&lt; 2 min), F5 reverts to Blue.<br><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Measured downtime (plant MES tests): <strong>11 min 18 s<\/strong>\u2014within agreed 15-min SLA.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Code Snippet \u2013 Auto-Fix Script (Python 45 lines)<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">CopyEdit<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">import re, pathlib, sys<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">OLD_NEW = {<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;r&#8221;(?i)cl_gui_alv_grid&#8221;: &#8220;cl_salv_table&#8221;,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;r&#8221;\\bws_upload\\b&#8221;: &nbsp; &nbsp; &nbsp; &#8220;gui_upload&#8221;,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">}<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">def fix_file(path):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;txt = pathlib.Path(path).read_text(encoding=&#8221;latin1&#8243;)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;for pat, repl in OLD_NEW.items():<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txt = re.sub(pat, repl, txt)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;pathlib.Path(path).write_text(txt, encoding=&#8221;latin1&#8243;)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">if __name__ == &#8220;__main__&#8221;:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;for f in pathlib.Path(sys.argv[1]).rglob(&#8220;*.abap&#8221;):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fix_file(f)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Runs in Jenkins before ATC; cut findings 18 %.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Monitoring &amp; Rollback (130 w)<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ATC delta<\/strong> \u2013 Grafana panel shows open critical findings per week.<br><\/li>\n\n\n\n<li><strong>Cut-Over KPIs<\/strong> \u2013 login success, RF scanner latency, batch-job backlog.<br><\/li>\n\n\n\n<li><strong>Alert Rule<\/strong> \u2013 if RF latency > 500 ms for 2 min \u2192 auto-revert F5 pool to Blue.<br><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Smoke test failure at T+4 min triggers unattended rollback; plant ops never notice.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Cost &amp; Time Benchmarks (120 w)<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Metric<\/strong><\/td><td><strong>Manual Cleanup<\/strong><\/td><td><strong>Automated Flow<\/strong><\/td><\/tr><tr><td>Dev hours<\/td><td>480 h<\/td><td><strong>72 h<\/strong><\/td><\/tr><tr><td>Downtime window<\/td><td>8 h<\/td><td><strong>11 min<\/strong><\/td><\/tr><tr><td>Transport errors<\/td><td>34<\/td><td><strong>3<\/strong><\/td><\/tr><tr><td>Project timeline<\/td><td>9 months<\/td><td><strong>5 months<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">ROI: $96 k dev cost saved; Go-Live four months earlier.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Common Pitfalls &amp; Fixes (150 w)<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Pitfall<\/strong><\/td><td><strong>Fix<\/strong><\/td><\/tr><tr><td>abapGit ignores SAPLINK objects<\/td><td>Use zabapgit_full &amp; whitelist append structures.<\/td><\/tr><tr><td>Waived findings audit fails<\/td><td>Store waiver reason in PR template; auditors accept.<\/td><\/tr><tr><td>SUM downtime &gt; 15 min<\/td><td>Pre-import huge tables (MARA) during mock-run; delta only at cut-over.<\/td><\/tr><tr><td>F5 DNS TTL too long<\/td><td>Lower TTL to 30 s two weeks before Go-Live.<\/td><\/tr><tr><td>Users cached old UI5<\/td><td>Bust cache via sap-ui-cachebuster\/ URL param.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Take-Home Checklist (60 w)<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Export Z-code to Git via abapGit.<br><\/li>\n\n\n\n<li>Run static auto-fix script.<br><\/li>\n\n\n\n<li>Batch ATC in Jenkins; waive low-risk.<br><\/li>\n\n\n\n<li>Merge &amp; transport to Green stack.<br><\/li>\n\n\n\n<li>Execute blue\/green switch with 15-min read-only window.<br><\/li>\n\n\n\n<li>Monitor KPIs; rollback if red in first 5 min.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR (90 w) Moving to S\/4 fails when millions of Z-lines block ATC checks and Go-Live windows are counted in minutes. We show how a Micro-GCC squad automated ABAP Test Cockpit (ATC) pipelines, fixed 77 % of findings robotically, and executed a blue\/green cut-over that kept the plant floor read-only for just 11 minutes. Terraform, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":20,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-82","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sap-modernization"],"_links":{"self":[{"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/posts\/82","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/comments?post=82"}],"version-history":[{"count":1,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/posts\/82\/revisions"}],"predecessor-version":[{"id":83,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/posts\/82\/revisions\/83"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/media\/20"}],"wp:attachment":[{"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/media?parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/categories?post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/steadyrabbit.in\/blogs\/wp-json\/wp\/v2\/tags?post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}