File: /var/www/html/wp-content/mu-plugins/ethnic-ci-cd-pipeline-setup-page.php
<?php
/**
* Plugin Name: Ethnic CI/CD Pipeline Setup Page
* Description: Creates and renders the CI/CD Pipeline Setup sub-service page under DevOps Services.
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_parent_id' ) ) {
function ethnic_ci_cd_pipeline_setup_page_parent_id() {
static $parent_id = null;
if ( null !== $parent_id ) {
return $parent_id;
}
$page = function_exists( 'ethnic_devops_services_page_get_target_page' )
? ethnic_devops_services_page_get_target_page()
: get_page_by_path( 'services/devops-services' );
if ( $page instanceof WP_Post ) {
$parent_id = (int) $page->ID;
} else {
$fallback = get_page_by_path( 'devops-services' );
$parent_id = $fallback instanceof WP_Post ? (int) $fallback->ID : 0;
}
return $parent_id;
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_get_target_page' ) ) {
function ethnic_ci_cd_pipeline_setup_page_get_target_page() {
static $page = false;
if ( false !== $page ) {
return $page instanceof WP_Post ? $page : null;
}
$page = get_page_by_path( 'services/devops-services/ci-cd-pipeline-setup' );
if ( ! ( $page instanceof WP_Post ) ) {
$fallback = get_page_by_path( 'ci-cd-pipeline-setup' );
if ( $fallback instanceof WP_Post && (int) $fallback->post_parent === ethnic_ci_cd_pipeline_setup_page_parent_id() ) {
$page = $fallback;
}
}
return $page instanceof WP_Post ? $page : null;
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_ensure_page' ) ) {
function ethnic_ci_cd_pipeline_setup_page_ensure_page() {
static $did_run = false;
if ( $did_run ) {
return;
}
$did_run = true;
$parent_id = ethnic_ci_cd_pipeline_setup_page_parent_id();
if ( ! $parent_id ) {
return;
}
$postarr = array(
'post_type' => 'page',
'post_title' => 'CI/CD Pipeline Setup',
'post_name' => 'ci-cd-pipeline-setup',
'post_parent' => $parent_id,
'post_status' => 'publish',
'post_content' => '',
'comment_status' => 'closed',
'ping_status' => 'closed',
);
$page = get_page_by_path( 'services/devops-services/ci-cd-pipeline-setup' );
if ( $page instanceof WP_Post ) {
$needs_update = 'CI/CD Pipeline Setup' !== $page->post_title
|| (int) $page->post_parent !== $parent_id
|| 'publish' !== $page->post_status;
if ( $needs_update ) {
wp_update_post(
array_merge(
$postarr,
array(
'ID' => (int) $page->ID,
)
)
);
clean_post_cache( (int) $page->ID );
}
return;
}
$fallback = get_page_by_path( 'ci-cd-pipeline-setup' );
if ( $fallback instanceof WP_Post ) {
wp_update_post(
array_merge(
$postarr,
array(
'ID' => (int) $fallback->ID,
)
)
);
clean_post_cache( (int) $fallback->ID );
return;
}
wp_insert_post( $postarr );
}
add_action( 'init', 'ethnic_ci_cd_pipeline_setup_page_ensure_page', 5 );
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_is_target' ) ) {
function ethnic_ci_cd_pipeline_setup_page_is_target() {
if ( is_admin() ) {
return false;
}
$page = ethnic_ci_cd_pipeline_setup_page_get_target_page();
if ( ! ( $page instanceof WP_Post ) ) {
return false;
}
return (int) get_queried_object_id() === (int) $page->ID || is_page( (int) $page->ID );
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_url' ) ) {
function ethnic_ci_cd_pipeline_setup_page_url( $path ) {
return home_url( '/' . ltrim( (string) $path, '/' ) . '/' );
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_contact_url' ) ) {
function ethnic_ci_cd_pipeline_setup_page_contact_url( $args = array() ) {
return ethnic_consultation_route_contact_url( $args, ethnic_ci_cd_pipeline_setup_page_url( 'contact-us' ) );
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_parent_url' ) ) {
function ethnic_ci_cd_pipeline_setup_page_parent_url() {
$parent_id = ethnic_ci_cd_pipeline_setup_page_parent_id();
if ( $parent_id ) {
$permalink = get_permalink( $parent_id );
if ( $permalink ) {
return $permalink;
}
}
return ethnic_ci_cd_pipeline_setup_page_url( 'services/devops-services' );
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_data' ) ) {
function ethnic_ci_cd_pipeline_setup_page_data() {
static $data = null;
if ( null !== $data ) {
return $data;
}
$data = array(
'metaTitle' => 'CI/CD Pipeline Setup Services | Deployment Automation, Quality Controls & Rollback Strategy',
'metaDescription' => 'Looking for CI/CD pipeline setup services? We help businesses automate deployments, manage environments, improve release quality, design rollback strategies, and implement practical CI/CD workflows.',
'heroTitle' => 'CI/CD Pipeline Setup',
'heroText' => 'We help businesses automate builds, testing, deployments, and release workflows so software can move faster with better consistency, stronger controls, and more dependable delivery across environments.',
'heroPoints' => array(
'Automated deployment workflows',
'Better release consistency across environments',
'Quality controls and rollback readiness',
),
'overviewParagraphs' => array(
'Our CI/CD pipeline setup services support startups, SMBs, and enterprise engineering teams that need a more dependable way to automate code integration, build processes, testing workflows, deployment pipelines, and release operations.',
'That includes practical help improving delivery speed, release consistency, and operational confidence with automation workflows shaped around how the team actually builds, tests, approves, and deploys software.',
'We focus on pipelines that fit team workflows, environments, release controls, and long-term maintainability with support from review and design through implementation, optimization, and ongoing improvement.',
),
'overviewFeatures' => array(
array(
'icon' => 'pipeline',
'title' => 'Practical Pipeline Design',
'copy' => 'Shape CI/CD pipeline setup around real application workflows, release frequency, and delivery constraints instead of generic automation templates.',
),
array(
'icon' => 'deploy',
'title' => 'Automated Release Workflows',
'copy' => 'Automate builds, testing, approvals, deployment sequencing, and release movement with clearer delivery control.',
),
array(
'icon' => 'environment',
'title' => 'Environment-Aware Delivery',
'copy' => 'Align development, QA, staging, and production release flows so automation supports cleaner environment management.',
),
array(
'icon' => 'rollback',
'title' => 'Quality and Rollback Controls',
'copy' => 'Build validation, release checks, and rollback readiness into the workflow so speed does not come at the cost of stability.',
),
),
'overviewMetrics' => array(
array(
'label' => 'Build Flow',
'value' => 'Automatable',
),
array(
'label' => 'Release Status',
'value' => 'Controlled',
),
array(
'label' => 'Environment Path',
'value' => 'Tracked',
),
array(
'label' => 'Rollback Readiness',
'value' => 'Planned',
),
),
'environmentLadder' => array( 'Dev', 'QA', 'Staging', 'Production' ),
'deploymentParagraphs' => array(
'Deployment automation reduces manual release effort and improves delivery consistency by moving key build, test, validation, and deployment steps into a cleaner repeatable workflow.',
'Automated workflows can support code integration, build execution, test steps, deployment sequencing, approvals, and post-release validation while still matching the team’s application architecture, release frequency, and control needs.',
'The goal is not automation for its own sake. Deployment automation should improve speed without sacrificing stability or creating workflows the team cannot maintain over time.',
),
'deploymentFlow' => array( 'Commit', 'Pipeline Run', 'Validation', 'Deploy', 'Monitor' ),
'deploymentAreas' => array(
array(
'icon' => 'build',
'title' => 'Automated Build Workflows',
'copy' => 'Standardize build execution so release artifacts are created more consistently with less manual effort.',
),
array(
'icon' => 'workflow',
'title' => 'Deployment Sequencing',
'copy' => 'Control the order of validation, approval, and deployment steps so releases move through a structured path.',
),
array(
'icon' => 'trigger',
'title' => 'Trigger-Based Releases',
'copy' => 'Use commits, merges, tags, or controlled triggers to start the right parts of the pipeline at the right time.',
),
array(
'icon' => 'approval',
'title' => 'Approval Gates Where Needed',
'copy' => 'Preserve governance with release checkpoints and approval stages where operational control matters most.',
),
array(
'icon' => 'monitor',
'title' => 'Post-Deploy Validation Support',
'copy' => 'Add health checks, smoke validation, and monitoring signals after deployment to improve release confidence.',
),
array(
'icon' => 'chart',
'title' => 'Release Consistency Improvement',
'copy' => 'Reduce avoidable release variation by standardizing the automation path teams use for software delivery.',
),
),
'environmentParagraphs' => array(
'CI/CD pipelines often depend on clean environment structure and release discipline. When development, QA, staging, and production do not follow a consistent pattern, deployment automation becomes harder to trust.',
'Environment management helps teams test changes more confidently before production while standardized flows across environments improve reliability and reduce deployment confusion.',
'Environment-aware pipelines support configuration consistency, environment-specific deployment logic, and clearer release rules that fit how the product actually moves toward production.',
),
'environmentAreas' => array(
array(
'icon' => 'environment',
'title' => 'Development Environment Flow',
'copy' => 'Support faster iteration and earlier validation while keeping the first release stage aligned to the broader pipeline.',
),
array(
'icon' => 'quality',
'title' => 'QA and Testing Environment Support',
'copy' => 'Make it easier to validate builds and deployment behavior before changes move further down the release path.',
),
array(
'icon' => 'review',
'title' => 'Staging Validation Workflows',
'copy' => 'Use staging as a more dependable rehearsal point for release checks, approvals, and production readiness.',
),
array(
'icon' => 'deploy',
'title' => 'Production Release Controls',
'copy' => 'Apply stronger checkpoints, approvals, and sequencing where release impact is highest.',
),
array(
'icon' => 'layers',
'title' => 'Configuration Consistency',
'copy' => 'Reduce drift and confusion by improving how environments are structured and aligned across the release lifecycle.',
),
array(
'icon' => 'workflow',
'title' => 'Environment-Specific Deployment Logic',
'copy' => 'Shape the pipeline so different environments can follow the right rules without creating unnecessary friction.',
),
),
'rollbackParagraphs' => array(
'Reliable pipelines should account for what happens if a release creates issues. Rollback strategy matters because faster releases only build confidence when teams also have clearer recovery paths.',
'Rollback planning, release checkpoints, validation stages, and failure detection awareness help reduce operational risk during deployment and support safer production changes.',
),
'rollbackAreas' => array(
array(
'icon' => 'rollback',
'title' => 'Rollback Planning',
'copy' => 'Define the fallback path before release so recovery does not depend on rushed decision-making after deployment.',
),
array(
'icon' => 'approval',
'title' => 'Release Checkpoints',
'copy' => 'Add gates and validation moments that make it easier to pause, confirm, or reverse a risky release.',
),
array(
'icon' => 'monitor',
'title' => 'Failure Detection Awareness',
'copy' => 'Use signals from validation checks, monitoring, or application behavior to surface release problems earlier.',
),
array(
'icon' => 'quality',
'title' => 'Deployment Validation',
'copy' => 'Confirm release health through post-deploy checks that support a safer decision between success and rollback.',
),
array(
'icon' => 'shield',
'title' => 'Safer Production Releases',
'copy' => 'Improve confidence in production delivery by combining automation speed with stronger safety controls.',
),
array(
'icon' => 'support',
'title' => 'Operational Recovery Readiness',
'copy' => 'Prepare the team for cleaner recovery if a change needs to be reversed after deployment.',
),
),
'qualityParagraphs' => array(
'Quality controls inside the delivery pipeline can include automated tests, validation checks, code quality gates, security-related checks, environment validation, and release approval steps.',
'CI/CD should help teams ship faster while keeping quality visible. The right pipeline quality controls depend on the application’s risk level, release frequency, and the operational confidence the business needs before production changes go live.',
),
'qualityAreas' => array(
array(
'icon' => 'test',
'title' => 'Automated Testing Steps',
'copy' => 'Run validation inside the pipeline so defects are more likely to be caught before production release.',
),
array(
'icon' => 'build',
'title' => 'Build Validation',
'copy' => 'Check that release artifacts are created correctly and remain dependable across repeated pipeline runs.',
),
array(
'icon' => 'quality',
'title' => 'Quality Gates',
'copy' => 'Use pass or fail checkpoints to prevent low-confidence changes from moving too far down the delivery path.',
),
array(
'icon' => 'approval',
'title' => 'Release Approval Flows',
'copy' => 'Apply human or workflow approvals where additional visibility or governance is required before deployment.',
),
array(
'icon' => 'environment',
'title' => 'Environment Checks',
'copy' => 'Validate configuration and deployment conditions so pipelines move through environments with fewer avoidable surprises.',
),
array(
'icon' => 'monitor',
'title' => 'Deployment Confidence Signals',
'copy' => 'Use readiness indicators, validation outcomes, and release status visibility to support safer decisions.',
),
),
'qualityWidgets' => array(
array(
'label' => 'Test Pass Rate',
'value' => 'Visible',
),
array(
'label' => 'Build Health',
'value' => 'Healthy',
),
array(
'label' => 'Deployment Readiness',
'value' => 'Ready',
),
array(
'label' => 'Release Status',
'value' => 'Tracked',
),
array(
'label' => 'Approval Stage',
'value' => 'Controlled',
),
),
'toolsParagraphs' => array(
'The right CI/CD tools depend on team workflow, hosting setup, application architecture, compliance or security needs, and delivery maturity. Tooling decisions should support maintainability and operational fit rather than becoming a brand checklist.',
'We work with practical CI/CD tools across source workflow, automation platforms, containers and delivery, cloud deployment, and quality validation while keeping the implementation aligned to the way the team actually ships software.',
),
'toolGroups' => array(
array(
'title' => 'Source / Workflow',
'items' => array( 'GitHub', 'GitLab', 'Bitbucket placeholders' ),
),
array(
'title' => 'CI/CD Platforms',
'items' => array( 'GitHub Actions', 'GitLab CI/CD', 'Jenkins', 'CircleCI placeholders' ),
),
array(
'title' => 'Containers / Delivery',
'items' => array( 'Docker', 'Kubernetes placeholders', 'Artifact repositories placeholders' ),
),
array(
'title' => 'Cloud / Deployment',
'items' => array( 'AWS', 'Azure', 'Google Cloud', 'Hosting platform placeholders' ),
),
array(
'title' => 'Quality / Validation',
'items' => array( 'Automated test tooling placeholders', 'Code quality tools placeholders', 'Security scan tooling placeholders' ),
),
),
'toolchainStages' => array(
array(
'title' => 'Source',
'tools' => array( 'GitHub', 'GitLab', 'Bitbucket placeholders' ),
),
array(
'title' => 'CI',
'tools' => array( 'GitHub Actions', 'GitLab CI/CD', 'Jenkins' ),
),
array(
'title' => 'Test',
'tools' => array( 'Automated tests', 'Quality gates', 'Security scan placeholders' ),
),
array(
'title' => 'Artifact',
'tools' => array( 'Docker', 'Artifact repositories placeholders' ),
),
array(
'title' => 'Deploy',
'tools' => array( 'AWS', 'Azure', 'Google Cloud', 'Kubernetes placeholders' ),
),
array(
'title' => 'Monitor',
'tools' => array( 'Release indicators', 'Alerts', 'Runtime visibility' ),
),
),
'ctaTitle' => 'Looking for CI/CD Pipeline Setup Services?',
'ctaText' => 'Discuss deployment automation, environment management, rollback readiness, release quality controls, or CI/CD tooling improvements with a team focused on practical pipeline design and more dependable software delivery.',
'ctaHighlights' => array(
'CI/CD pipeline setup services shaped around real release workflows, environments, and operational control needs',
'Support for deployment automation, environment management, rollback strategy, and quality controls',
'Practical guidance from review and design through implementation, refinement, and ongoing improvement',
),
'ctaSteps' => array(
array(
'title' => 'Review the current release process',
'copy' => 'Share where manual deployments, environment issues, or inconsistent validation are slowing delivery or increasing risk.',
),
array(
'title' => 'Define the right pipeline model',
'copy' => 'Map the automation, quality gates, environment flow, and rollback controls that fit your team and application.',
),
array(
'title' => 'Plan implementation and improvement',
'copy' => 'Leave with clearer next steps for CI/CD pipeline setup, tooling fit, release control, and long-term workflow refinement.',
),
),
);
return $data;
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_heading' ) ) {
function ethnic_ci_cd_pipeline_setup_page_heading( $eyebrow, $title, $copy = '' ) {
if ( function_exists( 'ethnic_devops_services_page_heading' ) ) {
return ethnic_devops_services_page_heading( $eyebrow, $title, $copy );
}
ob_start();
?>
<div class="ethnic-devops-heading">
<?php if ( $eyebrow ) : ?>
<p class="ethnic-devops-heading__eyebrow"><?php echo esc_html( $eyebrow ); ?></p>
<?php endif; ?>
<h2 class="ethnic-devops-heading__title"><?php echo esc_html( $title ); ?></h2>
<?php if ( $copy ) : ?>
<p class="ethnic-devops-heading__copy"><?php echo esc_html( $copy ); ?></p>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_icon' ) ) {
function ethnic_ci_cd_pipeline_setup_page_icon( $icon ) {
ob_start();
switch ( $icon ) {
case 'pipeline':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<circle cx="5.4" cy="12" r="1.9" />
<circle cx="12" cy="12" r="1.9" />
<circle cx="18.6" cy="12" r="1.9" />
<path d="M7.3 12h2.8" />
<path d="M13.9 12h2.8" />
</svg>
<?php
break;
case 'source':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<circle cx="7" cy="7.2" r="2.1" />
<circle cx="17" cy="16.8" r="2.1" />
<circle cx="17" cy="7.2" r="2.1" />
<path d="M8.8 7.2h6.1" />
<path d="M8.4 8.5 15.6 15.5" />
</svg>
<?php
break;
case 'build':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="m6.2 9.2 5.8-5.8 5.8 5.8" />
<path d="M12 4.2v11.2" />
<rect x="5" y="15.2" width="14" height="4.6" rx="1.4" />
</svg>
<?php
break;
case 'test':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<rect x="4.8" y="5.4" width="14.4" height="13.2" rx="2" />
<path d="m8.2 12.2 2.1 2.1 4.8-5" />
</svg>
<?php
break;
case 'review':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<rect x="4.4" y="5.2" width="15.2" height="11.6" rx="2" />
<path d="M8 9.2h8" />
<path d="M8 12.6h5" />
<path d="m10.4 18.2 1.6 2 2.8-3.5" />
</svg>
<?php
break;
case 'monitor':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M5 18.5h14" />
<path d="M6.5 14.8 9.4 11l2.4 2.9 4.2-5.4 1.5 2" />
<rect x="4.8" y="5.2" width="14.4" height="11.8" rx="2" />
</svg>
<?php
break;
case 'environment':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<rect x="6.2" y="4.4" width="11.6" height="4.2" rx="1.2" />
<rect x="6.2" y="10" width="11.6" height="4.2" rx="1.2" />
<rect x="6.2" y="15.6" width="11.6" height="4.2" rx="1.2" />
</svg>
<?php
break;
case 'rollback':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M8 8.2 4.8 11.4 8 14.6" />
<path d="M5 11.4h7.8a4.8 4.8 0 1 1 0 9.6H9.8" />
</svg>
<?php
break;
case 'quality':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M12 4.2 18.2 6.4v5.6c0 4.2-2.6 6.7-6.2 7.8-3.6-1.1-6.2-3.6-6.2-7.8V6.4Z" />
<path d="m9.3 12.1 1.8 1.8 3.6-3.7" />
</svg>
<?php
break;
case 'trigger':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<circle cx="6.2" cy="12" r="2" />
<path d="M8.2 12h8.4" />
<path d="m14.6 8.6 3.4 3.4-3.4 3.4" />
</svg>
<?php
break;
case 'approval':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<rect x="4.6" y="5.4" width="14.8" height="13.2" rx="2" />
<path d="m8.6 12.1 2.1 2.1 4.8-5" />
<path d="M8.2 8.4h7.6" />
</svg>
<?php
break;
case 'artifact':
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="m12 4.1 6.8 3.4v8.9L12 19.9l-6.8-3.5V7.5Z" />
<path d="M12 4.1v8.4" />
<path d="m5.2 7.5 6.8 3.4 6.8-3.4" />
</svg>
<?php
break;
default:
if ( function_exists( 'ethnic_devops_services_page_icon' ) ) {
ob_end_clean();
return ethnic_devops_services_page_icon( $icon );
}
?>
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="8.5" />
<path d="M8.6 12.3 10.8 14.5 15.4 9.9" />
</svg>
<?php
break;
}
return ob_get_clean();
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_render' ) ) {
function ethnic_ci_cd_pipeline_setup_page_render() {
$data = ethnic_ci_cd_pipeline_setup_page_data();
$consultation_url = ethnic_ci_cd_pipeline_setup_page_contact_url(
array(
'intent' => 'consultation',
'service' => 'ci-cd-pipeline-setup',
)
);
$team_url = ethnic_ci_cd_pipeline_setup_page_contact_url(
array(
'intent' => 'team',
'service' => 'ci-cd-pipeline-setup',
)
);
$quote_url = ethnic_ci_cd_pipeline_setup_page_contact_url(
array(
'intent' => 'quote',
'service' => 'ci-cd-pipeline-setup',
)
);
$parent_url = ethnic_ci_cd_pipeline_setup_page_parent_url();
ob_start();
?>
<div class="ethnic-devops-page ethnic-ci-cd-page">
<section class="ethnic-devops-section ethnic-devops-section--hero">
<div class="ethnic-devops-shell">
<div class="ethnic-devops-hero">
<div class="ethnic-devops-hero__copy">
<p class="ethnic-ci-cd-breadcrumb">
<a href="<?php echo esc_url( $parent_url ); ?>">DevOps Services</a>
<span>/</span>
<span>CI/CD Pipeline Setup</span>
</p>
<p class="ethnic-devops-kicker">Release Automation Systems</p>
<h1 class="ethnic-devops-hero__title"><?php echo esc_html( $data['heroTitle'] ); ?></h1>
<p class="ethnic-devops-hero__lead"><?php echo esc_html( $data['heroText'] ); ?></p>
<div class="ethnic-devops-actions">
<a class="ethnic-devops-button ethnic-devops-button--primary" href="<?php echo esc_url( $consultation_url ); ?>">Book a Free Consultation</a>
<a class="ethnic-devops-button ethnic-devops-button--secondary" href="<?php echo esc_url( $team_url ); ?>">Talk to Our Team</a>
</div>
<ul class="ethnic-devops-hero__points" aria-label="CI/CD pipeline setup highlights">
<?php foreach ( (array) $data['heroPoints'] as $point ) : ?>
<li><?php echo esc_html( $point ); ?></li>
<?php endforeach; ?>
</ul>
</div>
<div class="ethnic-devops-hero__visual" aria-hidden="true">
<div class="ethnic-devops-visual">
<div class="ethnic-devops-visual__window">
<div class="ethnic-devops-visual__window-bar">
<span></span>
<span></span>
<span></span>
</div>
<div class="ethnic-devops-visual__window-body">
<div class="ethnic-devops-visual__nav">
<span>Source</span>
<span>Pipeline</span>
<span>Release</span>
</div>
<div class="ethnic-devops-visual__hero-card">
<div class="ethnic-devops-visual__product-shot ethnic-ci-cd-pipeline-shot">
<div class="ethnic-ci-cd-pipeline-hero">
<?php foreach ( array( 'Source Code', 'Build', 'Test', 'Review', 'Deploy', 'Monitor' ) as $index => $stage ) : ?>
<div class="ethnic-ci-cd-pipeline-hero__stage">
<span class="ethnic-ci-cd-pipeline-hero__status <?php echo 3 >= $index ? 'is-ready' : 'is-waiting'; ?>"></span>
<strong><?php echo esc_html( $stage ); ?></strong>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="ethnic-devops-visual__product-copy">
<span class="ethnic-devops-visual__eyebrow">CI/CD pipeline illustration</span>
<strong>Turn source changes into controlled release movement with clearer build, test, deployment, and monitoring stages.</strong>
<p>Placeholder pipeline visuals represent connected build and deployment stages with status indicators, approvals, and release monitoring checkpoints.</p>
<div class="ethnic-devops-visual__tags">
<span>Build</span>
<span>Test</span>
<span>Deploy</span>
<span>Monitor</span>
</div>
</div>
</div>
<div class="ethnic-devops-visual__catalog">
<div class="ethnic-devops-visual__catalog-item">
<small>Automation lane</small>
<strong>Commit-triggered workflow execution with environment-aware release steps and validation controls</strong>
</div>
<div class="ethnic-devops-visual__catalog-item">
<small>Operations lane</small>
<strong>Release indicators, approvals, rollback awareness, and monitoring visibility after deployment</strong>
</div>
</div>
</div>
</div>
<div class="ethnic-devops-visual__floating ethnic-devops-visual__floating--ops ethnic-ci-cd-floating">
<p class="ethnic-devops-visual__floating-label">Pipeline state</p>
<strong>Automated deployment workflows with validation, release controls, and post-deploy health awareness.</strong>
<div class="ethnic-ci-cd-floating__metrics">
<div>
<small>Stage flow</small>
<strong>Connected</strong>
</div>
<div>
<small>Rollback</small>
<strong>Ready</strong>
</div>
</div>
</div>
<div class="ethnic-devops-visual__floating ethnic-devops-visual__floating--checkout">
<p class="ethnic-devops-visual__floating-label">Release focus</p>
<strong>Pipeline design aligned to automated delivery, environment management, and quality-aware releases.</strong>
<ul>
<li>Approval gates</li>
<li>Environment flow</li>
<li>Monitoring signals</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section" id="overview">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Service Overview', 'CI/CD pipeline setup services built for dependable automation, cleaner releases, and more confident software delivery.', 'We help teams create release workflows that fit their architecture, environments, control needs, and long-term delivery maturity instead of forcing automation that does not match the way they work.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-overview">
<div class="ethnic-ci-cd-overview__content">
<div class="ethnic-devops-prose">
<?php foreach ( (array) $data['overviewParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--overview">
<?php foreach ( (array) $data['overviewFeatures'] as $feature ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( $feature['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $feature['title'] ); ?></h3>
<p><?php echo esc_html( $feature['copy'] ); ?></p>
</article>
<?php endforeach; ?>
</div>
</div>
<aside class="ethnic-ci-cd-dashboard" aria-label="Release dashboard summary">
<div class="ethnic-ci-cd-dashboard__header">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( 'monitor' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<div>
<p class="ethnic-ci-cd-dashboard__eyebrow">Mini release dashboard</p>
<h3>Build-to-deploy visibility with environment flow and release controls.</h3>
</div>
</div>
<div class="ethnic-ci-cd-dashboard__metrics">
<?php foreach ( (array) $data['overviewMetrics'] as $metric ) : ?>
<div class="ethnic-ci-cd-dashboard__metric">
<small><?php echo esc_html( $metric['label'] ); ?></small>
<strong><?php echo esc_html( $metric['value'] ); ?></strong>
</div>
<?php endforeach; ?>
</div>
<div class="ethnic-ci-cd-dashboard__ladder">
<?php foreach ( (array) $data['environmentLadder'] as $item ) : ?>
<span><?php echo esc_html( $item ); ?></span>
<?php endforeach; ?>
</div>
</aside>
</div>
</div>
</section>
<section class="ethnic-devops-section ethnic-devops-section--soft" id="deployment-automation">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Deployment Automation', 'Deployment automation reduces manual release effort while improving delivery consistency and operational confidence.', 'CI/CD pipeline setup should automate the right build, test, deployment, approval, and validation steps without making the release path harder to understand or maintain.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-automation">
<div class="ethnic-ci-cd-automation__intro">
<div class="ethnic-devops-prose">
<?php foreach ( (array) $data['deploymentParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-ci-cd-flow" aria-label="Deployment flow graphic">
<p class="ethnic-ci-cd-flow__eyebrow">Deployment flow graphic</p>
<div class="ethnic-ci-cd-flow__steps">
<?php foreach ( (array) $data['deploymentFlow'] as $step ) : ?>
<div class="ethnic-ci-cd-flow__step">
<span></span>
<strong><?php echo esc_html( $step ); ?></strong>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--deployment">
<?php foreach ( (array) $data['deploymentAreas'] as $area ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( $area['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $area['title'] ); ?></h3>
<p><?php echo esc_html( $area['copy'] ); ?></p>
</article>
<?php endforeach; ?>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section" id="environment-management">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Environment Management', 'Cleaner environment structure makes CI/CD pipelines easier to trust across development, QA, staging, and production.', 'Environment management helps standardize release flow, reduce deployment confusion, and support environment-aware pipelines that fit the operational needs of the product.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-environments">
<div class="ethnic-ci-cd-environments__content">
<div class="ethnic-devops-prose">
<?php foreach ( (array) $data['environmentParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--environment">
<?php foreach ( (array) $data['environmentAreas'] as $area ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( $area['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $area['title'] ); ?></h3>
<p><?php echo esc_html( $area['copy'] ); ?></p>
</article>
<?php endforeach; ?>
</div>
</div>
<div class="ethnic-ci-cd-environment-stack" aria-label="Environment stack visual">
<p class="ethnic-ci-cd-environment-stack__eyebrow">Environment stack visual</p>
<div class="ethnic-ci-cd-environment-stack__items">
<?php foreach ( array( 'Dev', 'QA', 'Staging', 'Production' ) as $stage ) : ?>
<div class="ethnic-ci-cd-environment-stack__item">
<strong><?php echo esc_html( $stage ); ?></strong>
<small><?php echo esc_html( $stage ); ?> release path</small>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section ethnic-devops-section--soft" id="rollback-strategy">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Rollback Strategy', 'Rollback readiness helps teams move faster because the release process includes a clearer recovery path when something goes wrong.', 'Reliable CI/CD pipeline setup should account for validation, failure signals, release checkpoints, and the ability to recover cleanly if production issues appear after deployment.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-rollback">
<div class="ethnic-ci-cd-rollback__content">
<div class="ethnic-devops-prose">
<?php foreach ( (array) $data['rollbackParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--rollback">
<?php foreach ( (array) $data['rollbackAreas'] as $area ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( $area['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $area['title'] ); ?></h3>
<p><?php echo esc_html( $area['copy'] ); ?></p>
</article>
<?php endforeach; ?>
</div>
</div>
<div class="ethnic-ci-cd-rollback-diagram" aria-label="Cutover and rollback diagram">
<p class="ethnic-ci-cd-rollback-diagram__eyebrow">Cutover and rollback diagram</p>
<div class="ethnic-ci-cd-rollback-diagram__flow">
<div class="ethnic-ci-cd-rollback-diagram__node"><strong>Deploy</strong><small>Release moves live</small></div>
<div class="ethnic-ci-cd-rollback-diagram__node"><strong>Validate</strong><small>Checks and health review</small></div>
<div class="ethnic-ci-cd-rollback-diagram__node ethnic-ci-cd-rollback-diagram__node--success"><strong>Success Path</strong><small>Release continues</small></div>
</div>
<div class="ethnic-ci-cd-rollback-diagram__fallback">
<span>Fallback / rollback path stays ready if post-deploy validation signals a release problem.</span>
</div>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section" id="quality-controls">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Quality Controls', 'Quality controls keep faster delivery visible, measurable, and safer inside the pipeline itself.', 'The right validation steps depend on release risk, application behavior, and the level of confidence the team needs before a change moves into production.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-quality">
<div class="ethnic-ci-cd-quality-dashboard" aria-label="Pipeline quality dashboard visual">
<div class="ethnic-ci-cd-quality-dashboard__header">
<p class="ethnic-ci-cd-quality-dashboard__eyebrow">Pipeline quality dashboard</p>
<h3>Release control center for test health, build readiness, approvals, and deployment confidence.</h3>
</div>
<div class="ethnic-ci-cd-quality-dashboard__grid">
<?php foreach ( (array) $data['qualityWidgets'] as $widget ) : ?>
<div class="ethnic-ci-cd-quality-dashboard__tile">
<small><?php echo esc_html( $widget['label'] ); ?></small>
<strong><?php echo esc_html( $widget['value'] ); ?></strong>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="ethnic-ci-cd-quality__content">
<div class="ethnic-devops-prose">
<?php foreach ( (array) $data['qualityParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--quality">
<?php foreach ( (array) $data['qualityAreas'] as $area ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( $area['icon'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $area['title'] ); ?></h3>
<p><?php echo esc_html( $area['copy'] ); ?></p>
</article>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section ethnic-devops-section--soft" id="common-tools">
<div class="ethnic-devops-shell">
<?php echo ethnic_ci_cd_pipeline_setup_page_heading( 'Common Tools', 'The right CI/CD tools depend on workflow, hosting setup, application architecture, and delivery maturity.', 'We choose the toolchain based on practical implementation fit so the pipeline remains understandable, maintainable, and aligned to the way the team ships software.' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class="ethnic-ci-cd-tools">
<div class="ethnic-devops-prose ethnic-ci-cd-tools__intro">
<?php foreach ( (array) $data['toolsParagraphs'] as $paragraph ) : ?>
<p><?php echo esc_html( $paragraph ); ?></p>
<?php endforeach; ?>
</div>
<div class="ethnic-ci-cd-toolchain" aria-label="Toolchain architecture block">
<p class="ethnic-ci-cd-toolchain__eyebrow">Toolchain architecture block</p>
<div class="ethnic-ci-cd-toolchain__stages">
<?php foreach ( (array) $data['toolchainStages'] as $stage ) : ?>
<div class="ethnic-ci-cd-toolchain__stage">
<strong><?php echo esc_html( $stage['title'] ); ?></strong>
<div class="ethnic-ci-cd-toolchain__badges">
<?php foreach ( (array) $stage['tools'] as $tool ) : ?>
<span><?php echo esc_html( $tool ); ?></span>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="ethnic-devops-card-grid ethnic-ci-cd-card-grid--tools">
<?php foreach ( (array) $data['toolGroups'] as $group ) : ?>
<article class="ethnic-devops-card ethnic-ci-cd-tool-card">
<div class="ethnic-devops-card__icon">
<?php echo ethnic_ci_cd_pipeline_setup_page_icon( 'artifact' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<h3><?php echo esc_html( $group['title'] ); ?></h3>
<div class="ethnic-ci-cd-tool-card__badges">
<?php foreach ( (array) $group['items'] as $item ) : ?>
<span><?php echo esc_html( $item ); ?></span>
<?php endforeach; ?>
</div>
</article>
<?php endforeach; ?>
</div>
</div>
</div>
</section>
<section class="ethnic-devops-section ethnic-devops-section--cta" id="cta">
<div class="ethnic-devops-shell">
<div class="ethnic-devops-cta ethnic-ci-cd-cta">
<div class="ethnic-devops-cta__copy">
<div class="ethnic-devops-cta__intro">
<p class="ethnic-devops-kicker ethnic-devops-kicker--light">Ready to Talk</p>
<p class="ethnic-devops-cta__note">Planning around deployment automation, environment management, rollback readiness, and release quality controls.</p>
</div>
<h2><?php echo esc_html( $data['ctaTitle'] ); ?></h2>
<p class="ethnic-devops-cta__lead"><?php echo esc_html( $data['ctaText'] ); ?></p>
<div class="ethnic-devops-actions">
<a class="ethnic-devops-button ethnic-devops-button--primary" href="<?php echo esc_url( $team_url ); ?>">Talk to Our Team</a>
<a class="ethnic-devops-button ethnic-devops-button--secondary" href="<?php echo esc_url( $quote_url ); ?>">Get a Free Quote</a>
</div>
<ul class="ethnic-devops-cta__highlights" aria-label="CI/CD pipeline setup CTA highlights">
<?php foreach ( (array) $data['ctaHighlights'] as $highlight ) : ?>
<li><?php echo esc_html( $highlight ); ?></li>
<?php endforeach; ?>
</ul>
</div>
<aside class="ethnic-devops-cta__panel ethnic-ci-cd-cta__panel" aria-label="What happens next">
<div class="ethnic-ci-cd-cta__visual">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="ethnic-devops-cta__panel-header">
<p class="ethnic-devops-cta__panel-eyebrow">What Happens Next</p>
<h3 class="ethnic-devops-cta__panel-title">Build a CI/CD pipeline setup that improves release speed without losing delivery control.</h3>
</div>
<ol class="ethnic-devops-cta__steps">
<?php foreach ( (array) $data['ctaSteps'] as $index => $step ) : ?>
<li class="ethnic-devops-cta__step">
<span class="ethnic-devops-cta__step-number"><?php echo esc_html( sprintf( '%02d', $index + 1 ) ); ?></span>
<div class="ethnic-devops-cta__step-copy">
<strong><?php echo esc_html( $step['title'] ); ?></strong>
<p><?php echo esc_html( $step['copy'] ); ?></p>
</div>
</li>
<?php endforeach; ?>
</ol>
<div class="ethnic-devops-cta__panel-note"><strong>Focus:</strong> deployment automation, environment management, rollback strategy, quality controls, and practical CI/CD tools.</div>
</aside>
</div>
</div>
</section>
</div>
<?php
return ob_get_clean();
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_styles' ) ) {
function ethnic_ci_cd_pipeline_setup_page_styles() {
$base_styles = function_exists( 'ethnic_devops_services_page_styles' ) ? ethnic_devops_services_page_styles() : '';
return $base_styles . <<<'CSS'
.ethnic-ci-cd-page {
--ethnic-devops-accent: #22c55e;
--ethnic-devops-accent-dark: #15803d;
--ethnic-devops-cyan: #86efac;
--ethnic-devops-lime: #dcfce7;
}
.ethnic-ci-cd-page .ethnic-devops-section--hero {
background:
radial-gradient(circle at 18% 18%, rgba(34, 197, 94, 0.2), transparent 24%),
radial-gradient(circle at 84% 18%, rgba(14, 165, 233, 0.14), transparent 18%),
linear-gradient(180deg, #08151c, #0d2833 56%, #133646);
}
.ethnic-ci-cd-page .ethnic-devops-hero__title {
max-width: 8ch;
}
.ethnic-ci-cd-page .ethnic-devops-hero__lead {
max-width: 60ch;
}
.ethnic-ci-cd-breadcrumb {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
margin: 0 0 18px;
color: rgba(255, 255, 255, 0.72);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.12em;
line-height: 1.4;
text-transform: uppercase;
}
.ethnic-ci-cd-breadcrumb a {
color: #ffffff;
text-decoration: none;
}
.ethnic-ci-cd-breadcrumb a:hover,
.ethnic-ci-cd-breadcrumb a:focus-visible {
color: rgba(255, 255, 255, 0.82);
}
.ethnic-ci-cd-page .ethnic-devops-visual__window-body {
background:
radial-gradient(circle at top right, rgba(34, 197, 94, 0.14), transparent 28%),
linear-gradient(180deg, rgba(255, 255, 255, 0.97), rgba(241, 252, 246, 0.98));
}
.ethnic-ci-cd-page .ethnic-devops-visual__nav span,
.ethnic-ci-cd-page .ethnic-devops-visual__tags span {
background: rgba(34, 197, 94, 0.08);
color: #15803d;
}
.ethnic-ci-cd-page .ethnic-devops-visual__product-shot {
background:
radial-gradient(circle at 28% 28%, rgba(255, 255, 255, 0.92), transparent 22%),
linear-gradient(150deg, rgba(34, 197, 94, 0.14), rgba(22, 163, 74, 0.08)),
linear-gradient(180deg, #effcf3, #dcfce7);
}
.ethnic-ci-cd-page .ethnic-devops-visual__product-shot::before {
background: linear-gradient(180deg, #ffffff, #f3fff7);
border: 1px solid rgba(34, 197, 94, 0.14);
}
.ethnic-ci-cd-page .ethnic-devops-visual__product-shot::after {
background: rgba(34, 197, 94, 0.12);
}
.ethnic-ci-cd-pipeline-shot {
display: grid;
place-items: center;
overflow: hidden;
}
.ethnic-ci-cd-pipeline-hero {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
width: min(100%, 320px);
}
.ethnic-ci-cd-pipeline-hero__stage {
position: relative;
display: grid;
gap: 10px;
padding: 16px 14px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.88);
border: 1px solid rgba(34, 197, 94, 0.12);
box-shadow: 0 12px 24px rgba(15, 23, 42, 0.06);
}
.ethnic-ci-cd-pipeline-hero__stage::after {
content: "";
position: absolute;
right: -12px;
top: 50%;
width: 12px;
height: 1px;
background: rgba(21, 128, 61, 0.24);
}
.ethnic-ci-cd-pipeline-hero__stage:nth-child(3n)::after {
display: none;
}
.ethnic-ci-cd-pipeline-hero__status {
display: inline-flex;
width: 12px;
height: 12px;
border-radius: 50%;
}
.ethnic-ci-cd-pipeline-hero__status.is-ready {
background: #22c55e;
box-shadow: 0 0 0 5px rgba(34, 197, 94, 0.14);
}
.ethnic-ci-cd-pipeline-hero__status.is-waiting {
background: rgba(21, 128, 61, 0.18);
box-shadow: 0 0 0 5px rgba(21, 128, 61, 0.08);
}
.ethnic-ci-cd-pipeline-hero__stage strong {
color: var(--ethnic-devops-text);
font-size: 12px;
font-weight: 700;
line-height: 1.3;
}
.ethnic-ci-cd-floating__metrics {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
margin-top: 18px;
}
.ethnic-ci-cd-floating__metrics div {
padding: 12px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.ethnic-ci-cd-floating__metrics small {
display: block;
color: rgba(255, 255, 255, 0.74);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
line-height: 1.4;
text-transform: uppercase;
}
.ethnic-ci-cd-floating__metrics strong {
display: block;
margin-top: 8px;
color: #ffffff;
font-size: 18px;
font-weight: 700;
line-height: 1.1;
}
.ethnic-ci-cd-page .ethnic-devops-visual__floating li::before,
.ethnic-ci-cd-page .ethnic-devops-checklist li::before,
.ethnic-ci-cd-page .ethnic-devops-cta__highlights li::before,
.ethnic-ci-cd-rollback-diagram__fallback span::before {
background: var(--ethnic-devops-accent);
box-shadow: 0 0 0 5px rgba(34, 197, 94, 0.14);
}
.ethnic-ci-cd-page .ethnic-devops-visual__floating--ops {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.04)),
linear-gradient(180deg, #103847, #0d2731);
}
.ethnic-ci-cd-page .ethnic-devops-card__icon {
background: rgba(34, 197, 94, 0.08);
color: #15803d;
}
.ethnic-ci-cd-page .ethnic-devops-cta::before {
background:
linear-gradient(90deg, rgba(34, 197, 94, 0.05) 1px, transparent 1px),
linear-gradient(0deg, rgba(34, 197, 94, 0.05) 1px, transparent 1px);
}
.ethnic-ci-cd-page .ethnic-devops-kicker--light,
.ethnic-ci-cd-page .ethnic-devops-heading__eyebrow {
border-color: rgba(34, 197, 94, 0.18);
color: #15803d !important;
-webkit-text-fill-color: #15803d;
}
.ethnic-ci-cd-overview,
.ethnic-ci-cd-environments,
.ethnic-ci-cd-rollback,
.ethnic-ci-cd-quality {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(360px, 0.92fr);
gap: clamp(28px, 4vw, 44px);
align-items: start;
}
.ethnic-ci-cd-overview__content,
.ethnic-ci-cd-environments__content,
.ethnic-ci-cd-rollback__content,
.ethnic-ci-cd-quality__content,
.ethnic-ci-cd-automation,
.ethnic-ci-cd-tools {
display: grid;
gap: 24px;
}
.ethnic-ci-cd-card-grid--overview,
.ethnic-ci-cd-card-grid--deployment,
.ethnic-ci-cd-card-grid--environment,
.ethnic-ci-cd-card-grid--rollback,
.ethnic-ci-cd-card-grid--quality,
.ethnic-ci-cd-card-grid--tools {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.ethnic-ci-cd-dashboard,
.ethnic-ci-cd-flow,
.ethnic-ci-cd-environment-stack,
.ethnic-ci-cd-rollback-diagram,
.ethnic-ci-cd-quality-dashboard,
.ethnic-ci-cd-toolchain {
border-radius: 28px;
border: 1px solid var(--ethnic-devops-border);
box-shadow: var(--ethnic-devops-shadow);
padding: 24px;
background:
radial-gradient(circle at top right, rgba(34, 197, 94, 0.08), transparent 26%),
linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(243, 252, 246, 0.98));
}
.ethnic-ci-cd-dashboard__header,
.ethnic-ci-cd-quality-dashboard__header {
display: grid;
grid-template-columns: 52px 1fr;
gap: 16px;
align-items: start;
}
.ethnic-ci-cd-dashboard__eyebrow,
.ethnic-ci-cd-flow__eyebrow,
.ethnic-ci-cd-environment-stack__eyebrow,
.ethnic-ci-cd-rollback-diagram__eyebrow,
.ethnic-ci-cd-quality-dashboard__eyebrow,
.ethnic-ci-cd-toolchain__eyebrow {
display: inline-flex;
align-items: center;
width: fit-content;
min-height: 32px;
margin: 0 0 10px;
padding: 8px 14px;
border-radius: 999px;
background: rgba(34, 197, 94, 0.08);
border: 1px solid rgba(34, 197, 94, 0.12);
color: #15803d;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
line-height: 1;
text-transform: uppercase;
}
.ethnic-ci-cd-dashboard h3,
.ethnic-ci-cd-quality-dashboard h3,
.ethnic-ci-cd-toolchain strong,
.ethnic-ci-cd-tool-card h3 {
color: var(--ethnic-devops-text);
font-family: "Plus Jakarta Sans", "Figtree", sans-serif;
}
.ethnic-ci-cd-dashboard h3,
.ethnic-ci-cd-quality-dashboard h3 {
margin: 0;
font-size: 24px;
font-weight: 700;
line-height: 1.25;
letter-spacing: -0.04em;
}
.ethnic-ci-cd-dashboard__metrics,
.ethnic-ci-cd-quality-dashboard__grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
margin-top: 22px;
}
.ethnic-ci-cd-dashboard__metric,
.ethnic-ci-cd-quality-dashboard__tile {
padding: 16px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.84);
border: 1px solid rgba(34, 197, 94, 0.12);
}
.ethnic-ci-cd-dashboard__metric small,
.ethnic-ci-cd-quality-dashboard__tile small {
display: block;
color: #15803d;
font-size: 11px;
font-weight: 800;
letter-spacing: 0.08em;
line-height: 1.3;
text-transform: uppercase;
}
.ethnic-ci-cd-dashboard__metric strong,
.ethnic-ci-cd-quality-dashboard__tile strong {
display: block;
margin-top: 10px;
color: var(--ethnic-devops-text);
font-size: 22px;
font-weight: 700;
line-height: 1.1;
}
.ethnic-ci-cd-dashboard__ladder {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
margin-top: 18px;
}
.ethnic-ci-cd-dashboard__ladder span,
.ethnic-ci-cd-environment-stack__item {
display: grid;
gap: 6px;
padding: 14px;
border-radius: 18px;
background: rgba(34, 197, 94, 0.08);
border: 1px solid rgba(34, 197, 94, 0.12);
color: var(--ethnic-devops-text);
font-size: 12px;
font-weight: 700;
line-height: 1.3;
}
.ethnic-ci-cd-automation__intro {
display: grid;
grid-template-columns: minmax(0, 0.96fr) minmax(340px, 0.88fr);
gap: 24px 28px;
align-items: start;
}
.ethnic-ci-cd-flow__steps {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 10px;
}
.ethnic-ci-cd-flow__step {
position: relative;
display: grid;
gap: 10px;
padding-top: 20px;
}
.ethnic-ci-cd-flow__step::before {
content: "";
position: absolute;
left: 0;
top: 10px;
right: 0;
height: 2px;
background: rgba(21, 128, 61, 0.2);
}
.ethnic-ci-cd-flow__step span {
position: relative;
z-index: 1;
display: inline-grid;
place-items: center;
width: 40px;
height: 40px;
border-radius: 14px;
background: rgba(34, 197, 94, 0.12);
box-shadow: 0 0 0 6px rgba(34, 197, 94, 0.08);
}
.ethnic-ci-cd-flow__step strong {
color: var(--ethnic-devops-text);
font-size: 13px;
font-weight: 700;
line-height: 1.4;
}
.ethnic-ci-cd-environment-stack__items {
display: grid;
gap: 12px;
}
.ethnic-ci-cd-environment-stack__item strong {
color: var(--ethnic-devops-text);
font-size: 14px;
font-weight: 700;
line-height: 1.3;
}
.ethnic-ci-cd-environment-stack__item small {
color: #15803d;
font-size: 11px;
font-weight: 700;
line-height: 1.4;
}
.ethnic-ci-cd-rollback-diagram__flow {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.ethnic-ci-cd-rollback-diagram__node {
position: relative;
display: grid;
gap: 6px;
padding: 18px 16px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.84);
border: 1px solid rgba(34, 197, 94, 0.12);
}
.ethnic-ci-cd-rollback-diagram__node strong {
color: var(--ethnic-devops-text);
font-size: 14px;
font-weight: 700;
line-height: 1.4;
}
.ethnic-ci-cd-rollback-diagram__node small {
color: #15803d;
font-size: 11px;
font-weight: 700;
line-height: 1.4;
}
.ethnic-ci-cd-rollback-diagram__node--success {
background:
radial-gradient(circle at top right, rgba(34, 197, 94, 0.08), transparent 26%),
linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(240, 253, 244, 0.98));
}
.ethnic-ci-cd-rollback-diagram__fallback {
position: relative;
margin-top: 20px;
padding-top: 20px;
}
.ethnic-ci-cd-rollback-diagram__fallback::before {
content: "";
position: absolute;
left: 14%;
top: 0;
width: 36%;
height: 12px;
border-left: 2px dashed rgba(239, 68, 68, 0.35);
border-bottom: 2px dashed rgba(239, 68, 68, 0.35);
border-bottom-left-radius: 16px;
}
.ethnic-ci-cd-rollback-diagram__fallback span {
position: relative;
display: inline-flex;
align-items: center;
padding: 10px 14px 10px 34px;
border-radius: 999px;
background: rgba(239, 68, 68, 0.07);
border: 1px solid rgba(239, 68, 68, 0.12);
color: #991b1b;
font-size: 12px;
font-weight: 700;
line-height: 1.4;
}
.ethnic-ci-cd-rollback-diagram__fallback span::before {
content: "";
position: absolute;
left: 14px;
top: 50%;
width: 10px;
height: 10px;
border-radius: 50%;
transform: translateY(-50%);
}
.ethnic-ci-cd-toolchain__stages {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 12px;
}
.ethnic-ci-cd-toolchain__stage {
position: relative;
display: grid;
gap: 12px;
padding: 16px;
border-radius: 18px;
background: rgba(255, 255, 255, 0.86);
border: 1px solid rgba(34, 197, 94, 0.12);
}
.ethnic-ci-cd-toolchain__stage::after {
content: "";
position: absolute;
right: -12px;
top: 50%;
width: 12px;
height: 1px;
background: rgba(21, 128, 61, 0.2);
}
.ethnic-ci-cd-toolchain__stage:last-child::after {
display: none;
}
.ethnic-ci-cd-toolchain__stage strong {
display: block;
font-size: 14px;
font-weight: 700;
line-height: 1.3;
}
.ethnic-ci-cd-toolchain__badges,
.ethnic-ci-cd-tool-card__badges {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.ethnic-ci-cd-toolchain__badges span,
.ethnic-ci-cd-tool-card__badges span {
display: inline-flex;
align-items: center;
min-height: 30px;
padding: 0 10px;
border-radius: 999px;
background: rgba(34, 197, 94, 0.08);
border: 1px solid rgba(34, 197, 94, 0.12);
color: #15803d;
font-size: 11px;
font-weight: 700;
line-height: 1.3;
}
.ethnic-ci-cd-cta__visual {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 12px;
margin-bottom: 18px;
}
.ethnic-ci-cd-cta__visual span {
position: relative;
display: block;
height: 18px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.ethnic-ci-cd-cta__visual span::after {
content: "";
position: absolute;
right: -12px;
top: 50%;
width: 12px;
height: 1px;
background: rgba(255, 255, 255, 0.16);
}
.ethnic-ci-cd-cta__visual span:last-child::after {
display: none;
}
@media (max-width: 1200px) {
.ethnic-ci-cd-overview,
.ethnic-ci-cd-environments,
.ethnic-ci-cd-rollback,
.ethnic-ci-cd-quality,
.ethnic-ci-cd-automation__intro {
grid-template-columns: 1fr;
}
.ethnic-ci-cd-dashboard,
.ethnic-ci-cd-environment-stack,
.ethnic-ci-cd-rollback-diagram,
.ethnic-ci-cd-quality-dashboard {
order: -1;
}
.ethnic-ci-cd-toolchain__stages {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.ethnic-ci-cd-toolchain__stage:nth-child(3n)::after {
display: none;
}
}
@media (max-width: 1024px) {
.ethnic-ci-cd-card-grid--overview,
.ethnic-ci-cd-card-grid--deployment,
.ethnic-ci-cd-card-grid--environment,
.ethnic-ci-cd-card-grid--rollback,
.ethnic-ci-cd-card-grid--quality,
.ethnic-ci-cd-card-grid--tools,
.ethnic-ci-cd-dashboard__ladder,
.ethnic-ci-cd-flow__steps,
.ethnic-ci-cd-rollback-diagram__flow {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 767px) {
.ethnic-ci-cd-breadcrumb {
gap: 6px;
font-size: 11px;
}
.ethnic-ci-cd-pipeline-hero,
.ethnic-ci-cd-dashboard__metrics,
.ethnic-ci-cd-dashboard__ladder,
.ethnic-ci-cd-flow__steps,
.ethnic-ci-cd-card-grid--overview,
.ethnic-ci-cd-card-grid--deployment,
.ethnic-ci-cd-card-grid--environment,
.ethnic-ci-cd-card-grid--rollback,
.ethnic-ci-cd-card-grid--quality,
.ethnic-ci-cd-card-grid--tools,
.ethnic-ci-cd-rollback-diagram__flow,
.ethnic-ci-cd-quality-dashboard__grid,
.ethnic-ci-cd-toolchain__stages {
grid-template-columns: 1fr;
}
.ethnic-ci-cd-pipeline-hero__stage::after,
.ethnic-ci-cd-toolchain__stage::after,
.ethnic-ci-cd-rollback-diagram__fallback::before,
.ethnic-ci-cd-cta__visual span::after {
display: none;
}
.ethnic-ci-cd-floating__metrics {
grid-template-columns: 1fr;
}
.ethnic-ci-cd-toolchain__badges,
.ethnic-ci-cd-tool-card__badges {
display: grid;
}
}
CSS;
}
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_body_class' ) ) {
function ethnic_ci_cd_pipeline_setup_page_body_class( $classes ) {
if ( ethnic_ci_cd_pipeline_setup_page_is_target() ) {
$classes[] = 'ethnic-devops-development-target';
$classes[] = 'ethnic-devops-services-target';
$classes[] = 'ethnic-ci-cd-pipeline-setup-target';
}
return $classes;
}
add_filter( 'body_class', 'ethnic_ci_cd_pipeline_setup_page_body_class' );
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_print_head_assets' ) ) {
function ethnic_ci_cd_pipeline_setup_page_print_head_assets() {
if ( ! ethnic_ci_cd_pipeline_setup_page_is_target() ) {
return;
}
$data = ethnic_ci_cd_pipeline_setup_page_data();
?>
<style id="ethnic-ci-cd-pipeline-setup-page-inline-css" type="text/css">
<?php echo ethnic_ci_cd_pipeline_setup_page_styles(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</style>
<meta name="description" content="<?php echo esc_attr( $data['metaDescription'] ); ?>" />
<?php
}
add_action( 'wp_head', 'ethnic_ci_cd_pipeline_setup_page_print_head_assets', 120 );
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_document_title' ) ) {
function ethnic_ci_cd_pipeline_setup_page_document_title( $title ) {
if ( ethnic_ci_cd_pipeline_setup_page_is_target() ) {
$data = ethnic_ci_cd_pipeline_setup_page_data();
return $data['metaTitle'];
}
return $title;
}
add_filter( 'pre_get_document_title', 'ethnic_ci_cd_pipeline_setup_page_document_title', 50 );
}
if ( ! function_exists( 'ethnic_ci_cd_pipeline_setup_page_replace_content' ) ) {
function ethnic_ci_cd_pipeline_setup_page_replace_content( $content ) {
if ( ! ethnic_ci_cd_pipeline_setup_page_is_target() || ! in_the_loop() || ! is_main_query() ) {
return $content;
}
static $rendered = false;
if ( $rendered ) {
return $content;
}
$rendered = true;
return ethnic_ci_cd_pipeline_setup_page_render();
}
add_filter( 'the_content', 'ethnic_ci_cd_pipeline_setup_page_replace_content', 1000 );
}