Diğer CI sistemleri

TestDetta, .NET ve git çalıştıran her CI'da çalışır. GitHub Actions dışında iki komut ve bir klasör işi görür.

<maps> sıradan bir klasördür. Onu CI'ınızın pipeline'lar arasında dosya tutabildiği herhangi bir yerde saklayın:

TestDetta'nın kendisi haritalar için hiçbir zaman ağı kullanmaz.

Her kurulumun ihtiyaç duydukları

Kurulum

dotnet tool install --global <package>

Paket adı lansmanda belirlenecek. O zamana kadar TestDetta'yı kaynaktan dotnet build src/TestDetta.Cli -c Release -o testdetta-bin ile derleyin ve aşağıda td geçen her yerde dotnet testdetta-bin/TestDetta.Cli.dll çağırın.

GitLab CI

variables:
  GIT_DEPTH: "0"                    # full history
  TESTDETTA_MAPS: /srv/testdetta-maps/$CI_PROJECT_PATH   # a disk the runners share; or sync with object storage

record-coverage:
  stage: test
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - td record --maps-dir "$TESTDETTA_MAPS"

affected-tests:
  stage: test
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - git fetch --no-tags origin "+refs/heads/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME:refs/remotes/origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
    - td test --base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --maps-dir "$TESTDETTA_MAPS" --summary-file testdetta-summary.md
  artifacts:
    when: always
    paths: [testdetta-summary.md]

TESTDETTA_LICENSE değişkenini Settings → CI/CD → Variables altında, gerektiği gibi masked ve protected olarak tanımlayın. TestDetta açık projeleri CI_PROJECT_VISIBILITY üzerinden algılar.

Jenkins

Bildirimsel (declarative) bir multibranch pipeline:

pipeline {
  agent any
  environment {
    TESTDETTA_LICENSE = credentials('testdetta-license')          // a "secret text" credential
    TESTDETTA_MAPS = "/srv/testdetta-maps/${env.JOB_NAME.split('/')[0]}"
  }
  options { skipDefaultCheckout() }
  stages {
    stage('Checkout') {
      steps {
        checkout scmGit(branches: scm.branches, userRemoteConfigs: scm.userRemoteConfigs,
                        extensions: [cloneOption(shallow: false, depth: 0, noTags: true, reference: '')])
      }
    }
    stage('Record coverage') {
      when { branch 'main' }
      steps { sh 'td record --maps-dir "$TESTDETTA_MAPS"' }
    }
    stage('Affected tests') {
      when { changeRequest() }
      steps {
        sh 'git fetch --no-tags origin "+refs/heads/$CHANGE_TARGET:refs/remotes/origin/$CHANGE_TARGET"'
        sh 'td test --base "origin/$CHANGE_TARGET" --maps-dir "$TESTDETTA_MAPS"'
      }
    }
  }
}

Jenkins çoğu zaman remote URL'sinde kimlik bilgileriyle clone yapar. TestDetta bunları lisans kapsamını eşleştirmeden önce çıkarır ve hiçbir zaman loglamaz. Remote, lisansın kapsadığı depoyu adlandırmıyorsa (örneğin yerel bir mirror), TESTDETTA_LICENSE_SCOPE ayarlayın, örneğin git.acme.corp/scm/pay/app.

Azure DevOps Pipelines

trigger: [main]
pr: [main]

steps:
  - checkout: self
    fetchDepth: 0
  - script: td record --maps-dir "$(TESTDETTA_MAPS)"
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    env:
      TESTDETTA_LICENSE: $(TestDettaLicense)          # a secret pipeline variable
  - script: |
      target="${SYSTEM_PULLREQUEST_TARGETBRANCH#refs/heads/}"
      git fetch --no-tags origin "+refs/heads/$target:refs/remotes/origin/$target"
      td test --base "origin/$target" --maps-dir "$(TESTDETTA_MAPS)" --summary-file "$(Agent.TempDirectory)/testdetta.md"
      echo "##vso[task.uploadsummary]$(Agent.TempDirectory)/testdetta.md"
    condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
    env:
      TESTDETTA_LICENSE: $(TestDettaLicense)

TESTDETTA_MAPS, self-hosted agent'larda bir paylaşıma işaret eder. Microsoft-hosted agent'larda onu Azure Blob depolamayla senkronize edin (bkz. Nesne depolama).

Bitbucket Pipelines

clone:
  depth: full

pipelines:
  branches:
    main:
      - step:
          script:
            - td record --maps-dir maps
            - ./sync-maps.sh upload maps        # see "Object storage"
  pull-requests:
    '**':
      - step:
          script:
            - git fetch --no-tags origin "+refs/heads/$BITBUCKET_PR_DESTINATION_BRANCH:refs/remotes/origin/$BITBUCKET_PR_DESTINATION_BRANCH"
            - ./sync-maps.sh download maps "origin/$BITBUCKET_PR_DESTINATION_BRANCH"
            - td test --base "origin/$BITBUCKET_PR_DESTINATION_BRANCH" --maps-dir maps

TESTDETTA_LICENSE değişkenini secured bir depo değişkeni olarak tanımlayın.

Paylaşılan disk yerine nesne depolama

Barındırılan (hosted) runner'larda paylaşılan bir disk yoktur. Kayıttan sonra yeni klasörü yükleyin. Test etmeden önce yalnızca kullanılabilecek klasörleri indirin: merge base ve ondan önceki en fazla 50 first-parent commit. Onları en yeniden başlayarak indirin ve mevcut olan ilkinde durun. S3 için bir örnek; cp ve ls komutları olan her araç aynı şekilde çalışır:

#!/usr/bin/env bash
# sync-maps.sh upload <maps>          | after td record on the default branch
# sync-maps.sh download <maps> <base> | before td test on a pull request
set -euo pipefail
remote="s3://my-bucket/testdetta-maps/my-repository"
case "$1" in
  upload)
    aws s3 cp --recursive "$2/$(git rev-parse HEAD)" "$remote/$(git rev-parse HEAD)" ;;
  download)
    for sha in $(git rev-list --first-parent -n 51 "$(git merge-base "$3" HEAD)"); do
      if aws s3 ls "$remote/$sha/" > /dev/null 2>&1; then
        aws s3 cp --recursive "$remote/$sha" "$2/$sha"
        break
      fi
    done ;;
esac

Harita olmadığında

Kurulumdan sonraki ilk pull request'ler ya da çok geride kalanlar, erişilebilir mesafede bir harita bulamaz. TestDetta bu durumda yalnızca isimlere göre seçer; bu güvenlidir ama daha fazlasını seçer ve bunu logunda belirtir. td record varsayılan branch'te çalıştıktan sonra seçim isabetli hale gelir.