> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apinizer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub Actions ve Jenkins ile Apinizer CI/CD Entegrasyonu

> GitHub Actions ve Jenkins kullanarak API'lerinizi otomatik olarak Apinizer'a deploy edin

## Genel Bakış

Bu kılavuz, modern bir CI/CD pipeline'ı kullanarak API'lerinizi otomatik olarak Apinizer'a nasıl deploy edeceğinizi gösterir. Örnek senaryo, GitHub Actions ile Docker image oluşturma, Jenkins ile Kubernetes deployment ve Apinizer üzerinde API proxy yönetimini kapsar.

### Kullanılan Teknolojiler ve Versiyonlar

| Teknoloji | Versiyon |
| - | - |
| Jenkins | `jenkins/jenkins:lts` |
| Apinizer | v2026.01.5 |
| GitHub Actions | — |
| Kubernetes | Ortamınıza bağlı |

### Pipeline Akışı

```
GitHub Push → GitHub Actions (Build & Tag) → Jenkins Trigger → 
Kubernetes Deploy → Health Check → Apinizer API Proxy Sync → Apinizer Deploy
```

## Mimari Genel Bakış

Bu entegrasyon senaryosu şu bileşenleri kullanır:

* **GitHub Actions**: Docker image build ve versiyonlama işlemleri GitHub tarafında yürütülür.
* **Jenkins**: Orchestration ve deployment yönetimi Jenkins sunucunuzda gerçekleşir.
* **Kubernetes**: Container orchestration cluster'ınızda çalışır.
* **Apinizer**: API Gateway ve API proxy yönetimi Apinizer instance'ınız üzerinden yapılır.

## 1. GitHub Actions Workflow

GitHub Actions, her `main` branch'e push işleminde otomatik olarak:

* Yeni bir semantic version oluşturur
* Docker image build eder ve Docker Hub'a push eder
* Jenkins pipeline'ını tetikler

### Workflow Dosyası

Workflow dosyası, projenizin GitHub reposunda yer almalıdır. Yerel geliştirme ortamınızda (IDE veya metin editörü) aşağıdaki dosya yolunda oluşturun ve reponuza push edin:

`.github/workflows/docker-build-push.yml`

```yaml theme={null}
name: Docker Build & Push
on:
  push:
    branches: [ "main" ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          fetch-depth: '0'
      
      # Otomatik versiyon oluşturma
      - name: Bump version and push tag
        id: tag_version
        uses: anothrNick/github-tag-action@1.64.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          WITH_V: true
          DEFAULT_BUMP: patch
      
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      
      # Docker build ve push
      - name: Build and Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/YOUR_IMAGE_NAME:latest
            ${{ secrets.DOCKERHUB_USERNAME }}/YOUR_IMAGE_NAME:${{ steps.tag_version.outputs.new_tag }}
      
      # Jenkins tetikleme
      - name: Trigger Jenkins Pipeline
        run: |
          curl -X POST ${{ secrets.JENKINS_URL }}/job/${{ secrets.JENKINS_JOB_NAME }}/buildWithParameters \
            --user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \
            --data IMAGE_TAG=${{ steps.tag_version.outputs.new_tag }}
```

### GitHub Secrets Yapılandırması

Repository Settings > Secrets and Variables > Actions bölümünden şu secret'ları ekleyin:

| Secret | Açıklama |
| - | - |
| `DOCKERHUB_USERNAME` | Docker Hub kullanıcı adınız |
| `DOCKERHUB_TOKEN` | Docker Hub access token |
| `JENKINS_URL` | Jenkins instance URL'iniz |
| `JENKINS_JOB_NAME` | Jenkins job adı |
| `JENKINS_USER` | Jenkins kullanıcı adı |
| `JENKINS_TOKEN` | Jenkins API token |

## 2. Jenkins Pipeline Yapılandırması

Jenkins pipeline, aşağıdaki aşamaları gerçekleştirir:

1. **K8s Deploy**: Yeni Docker image'ı Kubernetes'e deploy eder
2. **Health Check**: API'nin sağlıklı çalıştığını doğrular
3. **Sync Apinizer API Proxy**: API Proxy'yi günceller veya oluşturur
4. **Deploy to Apinizer**: Proxy'yi belirtilen environment'a deploy eder

### Jenkinsfile

Jenkins pipeline'ı, Jenkins arayüzünden yeni bir Pipeline job oluşturularak tanımlanabilir. Aşağıdaki içeriği Jenkins UI'daki Pipeline script alanında kullanabilirsiniz.

`Jenkinsfile`

```groovy theme={null}
pipeline {
    agent any
    
    parameters {
        string(name: 'IMAGE_TAG', defaultValue: 'latest', description: 'Docker image tag from GitHub Actions')
    }
    
    environment {
        // Kubernetes yapılandırması
        NAMESPACE = "YOUR_NAMESPACE" 
        DEPLOYMENT_NAME = "YOUR_DEPLOYMENT_NAME"
        CONTAINER_NAME = "YOUR_CONTAINER_NAME" 
        DOCKER_IMAGE = "YOUR_DOCKERHUB_USERNAME/YOUR_IMAGE_NAME"
        KUBECTL_PATH = "/usr/local/bin/kubectl"
        
        // API bilgileri
        API_BACKEND_URL = "YOUR_BACKEND_URL"
        API_HEALTH_ENDPOINT = "${API_BACKEND_URL}/health"
        API_SPEC_URL = "${API_BACKEND_URL}/api/v1/openapi.json"
        
        // Apinizer yapılandırması
        APINIZER_BASE_URL = "YOUR_APINIZER_URL"
        APINIZER_GATEWAY_URL = "YOUR_APINIZER_GATEWAY_URL"
        APINIZER_PROJECT = "YOUR_PROJECT_NAME"
        APINIZER_ENVIRONMENT = "YOUR_ENVIRONMENT_NAME"
        APINIZER_PROXY_NAME = "YOUR_PROXY_NAME"
        APINIZER_PROXY_PATH = "YOUR_PROXY_RELATIVE_PATH"
    }
    
    stages {
        stage('K8s Deploy') {
            steps {
                echo "Deploying ${DOCKER_IMAGE}:${params.IMAGE_TAG} to K8s..."
                sh """
                    ${KUBECTL_PATH} set image deployment/${DEPLOYMENT_NAME} \
                        ${CONTAINER_NAME}=${DOCKER_IMAGE}:${params.IMAGE_TAG} \
                        -n ${NAMESPACE}
                    
                    ${KUBECTL_PATH} rollout status deployment/${DEPLOYMENT_NAME} -n ${NAMESPACE}
                """
            }
        }
        
        stage('Health Check') {
            steps {
                echo "Checking API health at ${API_HEALTH_ENDPOINT}..."
                sh """
                    sleep 10
                    curl -f ${API_HEALTH_ENDPOINT}
                """
            }
        }
        
        stage('Sync Apinizer API Proxy') {
            steps {
                withCredentials([string(credentialsId: 'APINIZER_TOKEN', variable: 'TOKEN')]) {
                    script {
                        echo "Checking if API proxy exists..."
                        
                        def proxyCheckCode = sh(
                            script: """
                                curl -s -o /dev/null -w '%{http_code}' \
                                    -H 'Authorization: Bearer ${TOKEN}' \
                                    '${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/${APINIZER_PROXY_NAME}/'
                            """,
                            returnStdout: true
                        ).trim()
                        
                        echo "Proxy check returned: ${proxyCheckCode}"
                        def proxyExists = (proxyCheckCode == '200')
                        
                        if (proxyExists) {
                            echo "API proxy exists, updating spec..."
                            sh """
                                curl -X PUT \
                                    '${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/url/' \
                                    -H 'Authorization: Bearer ${TOKEN}' \
                                    -H 'Content-Type: application/json' \
                                    -d '{
                                        "apiProxyName": "${APINIZER_PROXY_NAME}",
                                        "apiProxyCreationType": "OPEN_API",
                                        "specUrl": "${API_SPEC_URL}",
                                        "clientRoute": {
                                            "relativePathList": ["${APINIZER_PROXY_PATH}"]
                                        },
                                        "reParse": true,
                                        "deploy": false
                                    }'
                            """
                        } else {
                            echo "API proxy doesn't exist, creating..."
                            sh """
                                curl -X POST \
                                    '${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/url/' \
                                    -H 'Authorization: Bearer ${TOKEN}' \
                                    -H 'Content-Type: application/json' \
                                    -d '{
                                        "apiProxyName": "${APINIZER_PROXY_NAME}",
                                        "apiProxyDescription": "Auto-generated proxy",
                                        "apiProxyCreationType": "OPEN_API",
                                        "specUrl": "${API_SPEC_URL}",
                                        "clientRoute": {
                                            "relativePathList": ["${APINIZER_PROXY_PATH}"]
                                        },
                                        "routingInfo": {
                                            "routingAddressList": [
                                                {
                                                    "address": "${API_BACKEND_URL}",
                                                    "weight": 100
                                                }
                                            ]
                                        },
                                        "deploy": false,
                                        "reParse": false
                                    }'
                            """
                        }
                    }
                }
            }
        }
        
        stage('Deploy to Apinizer') {
            steps {
                withCredentials([string(credentialsId: 'APINIZER_TOKEN', variable: 'TOKEN')]) {
                    echo "Deploying API proxy to Apinizer ${APINIZER_ENVIRONMENT}..."
                    sh """
                        curl -X POST \
                            '${APINIZER_BASE_URL}/apiops/projects/${APINIZER_PROJECT}/apiProxies/${APINIZER_PROXY_NAME}/environments/${APINIZER_ENVIRONMENT}/' \
                            -H 'Authorization: Bearer ${TOKEN}'
                    """
                }
            }
        }
    }
    
    post {
        success {
            echo "✅ Pipeline completed! API deployed to K8s and Apinizer successfully."
        }
        failure {
            echo "❌ Pipeline failed! Check logs above."
        }
    }
}
```

### Jenkins Credentials Yapılandırması

Jenkins'de **Manage Jenkins > Credentials** bölümünden şu credential'ı ekleyin:

| Credential ID | Tip | Açıklama |
| - | - | - |
| `APINIZER_TOKEN` | Secret text | Apinizer API token |

<Info>
  Apinizer API token oluşturma hakkında detaylı bilgi için [Token Alma Yöntemleri](/tr/develop/politikalar/token-service/token-alma-yontemleri#token-alma-yoentemleri) dokümanını inceleyebilirsiniz.
</Info>

## 3. Pipeline Aşamalarının Detayları

### Stage 1: Kubernetes Deployment

Bu aşama Jenkins sunucusunda çalışır. GitHub Actions tarafından oluşturulan Docker image Kubernetes cluster'ına deploy edilir. `kubectl set image` komutu kullanılarak deployment güncellenir ve rollout durumu kontrol edilir.

```bash theme={null}
${KUBECTL_PATH} set image deployment/${DEPLOYMENT_NAME} \
    ${CONTAINER_NAME}=${DOCKER_IMAGE}:${params.IMAGE_TAG} \
    -n ${NAMESPACE}

${KUBECTL_PATH} rollout status deployment/${DEPLOYMENT_NAME} -n ${NAMESPACE}
```

### Stage 2: Health Check

API'nin başarıyla deploy edildiğini doğrulamak için health endpoint'i kontrol edilir. Bu adım, Apinizer'a deploy etmeden önce API'nin çalışır durumda olduğundan emin olmak için kritiktir.

`API_HEALTH_ENDPOINT` değişkeni, pipeline'ı uyguladığınız uygulamanın health check endpoint'ini belirtir. Bu adres uygulamanıza özgüdür; örnek:

```
https://YOUR_BACKEND_URL/health
```

Uygulamanızın farklı bir health check endpoint'i varsa `API_HEALTH_ENDPOINT` değişkenini buna göre güncelleyin.

### Stage 3: Apinizer API Proxy Senkronizasyonu

Bu kritik aşamada:

1. **Proxy Kontrolü**: İlgili API Proxy'nin var olup olmadığı kontrol edilir
2. **Güncelleme veya Oluşturma**:
   * Proxy varsa: OpenAPI spec'i güncellenir (`PUT` request)
   * Proxy yoksa: Yeni proxy oluşturulur (`POST` request)

#### Proxy Güncelleme (PUT)

Mevcut bir proxy'yi güncellerken `reParse: true` parametresi ile OpenAPI specification yeniden parse edilir:

```json theme={null}
{
  "apiProxyName": "YOUR_PROXY_NAME",
  "apiProxyCreationType": "OPEN_API",
  "specUrl": "YOUR_BACKEND_URL/api/v1/openapi.json",
  "clientRoute": {
    "relativePathList": ["YOUR_PROXY_RELATIVE_PATH"]
  },
  "reParse": true,
  "deploy": false
}
```

<Info>
  Detaylı bilgi için [Update API Proxy](/api-reference/api-proxies/crud/update-api-proxy) API referansını inceleyebilirsiniz.
</Info>

#### Yeni Proxy Oluşturma (POST)

Yeni proxy oluştururken backend routing bilgileri de tanımlanır:

```json theme={null}
{
  "apiProxyName": "YOUR_PROXY_NAME",
  "apiProxyDescription": "Auto-generated proxy",
  "apiProxyCreationType": "OPEN_API",
  "specUrl": "YOUR_BACKEND_URL/api/v1/openapi.json",
  "clientRoute": {
    "relativePathList": ["YOUR_PROXY_RELATIVE_PATH"]
  },
  "routingInfo": {
    "routingAddressList": [
      {
        "address": "YOUR_BACKEND_URL",
        "weight": 100
      }
    ]
  },
  "deploy": false
}
```

<Info>
  Detaylı bilgi için [Create API Proxy from URL](/api-reference/api-proxies/crud/create-api-proxy-from-url) API referansını inceleyebilirsiniz.
</Info>

<Warning>
  `deploy: false` parametresi ile proxy otomatik olarak deploy edilmez. Bu, bir sonraki stage'de kontrollü deployment yapılmasını sağlar.
</Warning>

### Stage 4: Apinizer Environment'a Deploy

Son aşamada, güncellenen veya yeni oluşturulan proxy belirtilen environment'a deploy edilir. Bu işlem Apinizer'ın deployment API'si kullanılarak gerçekleştirilir:

```bash theme={null}
POST /apiops/projects/{projectName}/apiProxies/{proxyName}/environments/{environmentName}/
```

<Info>
  Detaylı bilgi için [Deploy API Proxy](/api-reference/api-proxies/deployment/deploy-api-proxy) API referansını inceleyebilirsiniz.
</Info>

## Konfigürasyon Parametreleri

### Environment Variables

Pipeline'da kullanılan temel environment variable'lar:

| Değişken | Açıklama | Örnek Değer |
| - | - | - |
| `APINIZER_BASE_URL` | Apinizer platform URL'i | `YOUR_APINIZER_URL` |
| `APINIZER_PROJECT` | Apinizer proje adı | `YOUR_PROJECT_NAME` |
| `APINIZER_ENVIRONMENT` | Deploy edilecek environment | `YOUR_ENVIRONMENT_NAME` |
| `APINIZER_PROXY_NAME` | API Proxy adı | `YOUR_PROXY_NAME` |
| `APINIZER_PROXY_PATH` | Gateway'deki relative path | `YOUR_PROXY_RELATIVE_PATH` |
| `API_SPEC_URL` | OpenAPI specification URL'i | `YOUR_BACKEND_URL/openapi.json` |

### Apinizer API Endpoints

Bu pipeline'da kullanılan Apinizer API endpoint'leri:

| İşlem | Endpoint |
| - | - |
| Proxy Kontrolü | `GET /apiops/projects/{project}/apiProxies/{proxyName}/` |
| Proxy Güncelleme | `PUT /apiops/projects/{project}/apiProxies/url/` |
| Proxy Oluşturma | `POST /apiops/projects/{project}/apiProxies/url/` |
| Environment Deploy | `POST /apiops/projects/{project}/apiProxies/{proxyName}/environments/{env}/` |

<Info>
  Apinizer Management API hakkında detaylı bilgi için [API Genel Bakış](/api-reference/getting-started/overview) dokümanını inceleyebilirsiniz.
</Info>

## Kendi Pipeline'ınızı Uyarlamak

Bu örnek senaryo, Kubernetes üzerinde çalışan bir API için tasarlanmıştır. Kendi altyapınıza göre uyarlamak için:

<Steps>
  <Step title="Deployment Mekanizması">
    Kubernetes yerine farklı bir orchestrator veya doğrudan VM deployment kullanıyorsanız, `K8s Deploy` stage'ini kendi deployment metodunuza göre değiştirin.
  </Step>

  <Step title="Health Check">
    API'nizin farklı bir health check mekanizması varsa, `API_HEALTH_ENDPOINT` değişkenini ilgili endpoint ile güncelleyin.
  </Step>

  <Step title="OpenAPI Spec">
    API'nizin OpenAPI specification'ının erişilebilir bir URL'de olduğundan emin olun. Bu URL Apinizer tarafından erişilebilir olmalıdır.
  </Step>

  <Step title="Environment">
    Apinizer'da kullanmak istediğiniz environment'ı (`dev`, `test`, `prod` vb.) `APINIZER_ENVIRONMENT` değişkeninde belirtin.
  </Step>

  <Step title="Security">
    Credential'larınızı Jenkins Credentials Manager üzerinden yönetmeniz, pipeline güvenliği açısından daha uygun bir yaklaşım olacaktır.
  </Step>
</Steps>

## Sonuç

Bu kılavuz, GitHub Actions, Jenkins ve Apinizer'ı kullanarak tam otomatik bir CI/CD pipeline'ının nasıl kurulacağını göstermiştir. Her kod değişikliği otomatik olarak build edilir ve Apinizer'a deploy edilir. Bu yaklaşım, manuel işlemleri minimize ederek deployment sürecinizi hızlandırır ve hata olasılığını azaltır.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.