Azure DevOps’ta Farklı Organizasyonlar Arasında Build Artifacts Paylaşımı (Org-1 → Org-2)

🔹 Giriş

Bazen farklı Azure DevOps organizasyonları arasında build çıktısı (artifacts) paylaşmanız gerekir.
Örneğin:

  • Org-1: Projeyi build eder ve paketler
  • Org-2: Bu paketi kendi ortamına indirip deploy eder

Bu senaryoda en güvenli ve yönetilebilir yöntemlerden biri, Azure Artifacts Universal Packages kullanmak ve erişimi Service Connection + PAT ile sağlamak.

Bu yazıda, Org-1’in nasıl build + artifacts publish işlemini yapacağını, Org-2’nin ise Service Connection ile bu artifacts indirip deploy edeceğini adım adım yazdım.


1️⃣ Org-1: Build ve Artifacts Publish Süreci

Org-1’deki görev:

  1. Projeyi build etmek
  2. Build çıktısını paketlemek
  3. Universal Package olarak kendi feed’ine publish etmek

1.1 Feed Oluşturma

  1. Azure DevOps → Artifacts sekmesine git
  2. + Create Feed
  3. Feed adını belirle (ör. SharedPackages)
  4. Visibility: Organization (isteğe göre Specific people olabilir)
  5. Kaydet

1.2 Build Pipeline (YAML)

azure-pipelines.yml dosyası:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  PackageVersion: '1.0.$(Build.BuildId)'

steps:
# 1. Build
- task: DotNetCoreCLI@2
  displayName: 'Build Project'
  inputs:
    command: build
    projects: '**/*.csproj'
    arguments: '--configuration Release'

# 2. Çıktıları topla
- task: CopyFiles@2
  displayName: 'Copy Outputs'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)/src/MyProject/bin/Release/net8.0'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

# 3. Universal Package Publish
- task: UniversalPackages@0
  displayName: 'Publish to Org-1 Feed'
  inputs:
    command: publish
    publishDirectory: '$(Build.ArtifactStagingDirectory)'
    vstsFeedPublish: 'MyProject/SharedPackages'
    vstsFeedPackagePublish: 'my-package'
    packagePublishDescription: 'Build $(Build.BuildNumber)'
    versionOption: custom
    versionPublish: '$(PackageVersion)'

🔹 Önemli:

  • vstsFeedPublish{ProjectName}/{FeedName} formatında
  • vstsFeedPackagePublish → küçük harf ve tire kullan
  • PackageVersion benzersiz olmalı
  • Publish için Feed yetki verilmesi lazım

2️⃣ Org-2: Service Connection ile Artifacts İndirme

Org-2’deki görev:

  • Org-1’deki feed’e Service Connection ile bağlanmak
  • PAT ile sadece “read” izni vermek

2.1 PAT (Personal Access Token) Oluşturma (Org-1’de)

  1. Org-1 → User Settings → Personal Access Tokens
  2. + New Token
  3. Scope: Packaging (Read)
  4. Süre: Minimum gerekli süre
  5. Token’ı kopyala (tek sefer gösterilir!)

2.2 Service Connection Oluşturma (Org-2’de)

  1. Project SettingsService connectionsNew service connection
  2. Azure Repos/Team Foundation Server seç
  3. Org-1 feed URL’sini gir (örn. https://dev.azure.com/{Org1Name})
  4. PAT’i kullanıcı adı yerine boş, şifre alanına yapıştır
  5. Bağlantıyı test et ve kaydet

2.3 Org-2 Pipeline ile Paket İndirme

pool:
  vmImage: 'ubuntu-latest'

steps:
# Universal Package Download
- task: UniversalPackages@0 # Azure DevOps Universal Packages task’ı
  inputs:
    command: 'download' # İşlem türü: download (indirme)
    downloadDirectory: '$(Build.ArtifactStagingDirectory)'  # İndirilen dosyaların kaydedileceği yer
    feedsToUse: 'external'  # Harici (başka organizasyondaki) feed kullanılacak
    externalFeedCredentials: 'org-1'  # Org-1’de tanımlı Service Connection adı (PAT içerir)
    feedDownloadExternal: 'Org1Project/SharedPackages'  # Hedef feed yolu: "Project/Feed" formatında
    packageDownloadExternal: 'my-package'  # İndirilecek paket adı
    versionDownloadExternal: '1.3.0' # Paket versiyonu


# Deploy adımları
- script: |
    echo "Deploy işlemi başlatılıyor..."
    ls -la $(Build.ArtifactStagingDirectory)
  displayName: 'List Downloaded Files'

3️⃣ Güvenlik Notları

  • PAT mutlaka read-only olmalı
  • Feed’in visibility’sini public yapma (gerekirse “Project scoped” kullan)
  • Org-1’deki build pipeline hiçbir şekilde Org-2’ye özel credential tutmaz
  • Org-2’de Service Connection sadece bu proje için yetkilendirilmeli

🎯 Sonuç

Bu yöntemle:

  • Org-1 → Build + Publish
  • Org-2 → Service Connection + Download
  • Her iki organizasyon bağımsız pipeline çalıştırır
  • Güvenli, izole ve yönetilebilir bir süreç oluşur

Bunlar da hoşunuza gidebilir...