.vsts-ci.yml 14.6 KB
Newer Older
1
2
3
trigger:
  branches:
    include:
4
    - master
5
6
7
  tags:
    include:
    - v*
8
9
pr:
- master
10
- release/*
11
variables:
12
  AZURE: 'true'
13
  PYTHON_VERSION: '3.11'
14
  CMAKE_BUILD_PARALLEL_LEVEL: 4
15
  CONDA_ENV: test-env
16
17
18
19
  runCodesignValidationInjection: false
  skipComponentGovernanceDetection: true
  DOTNET_CLI_TELEMETRY_OPTOUT: true
  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
20
resources:
21
22
23
24
25
26
  # The __work/ directory, where Azure DevOps writes the source files, needs to be read-write because
  # LightGBM's CI jobs write files in the source directory.
  #
  # For all the containers included here, all other directories that Azure mounts in are mounted as read-only
  # to minimize the risk of side effects from one run affecting future runs.
  # ref: https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/resources-containers-container
27
  containers:
28
  - container: linux-artifact-builder
29
    image: lightgbm/vsts-agent:manylinux_2_28_x86_64
30
31
32
33
34
    mountReadOnly:
      work: false
      externals: true
      tools: true
      tasks: true
35
  - container: ubuntu-latest
36
    image: 'ubuntu:22.04'
37
    options: "--name ci-container -v /usr/bin/docker:/tmp/docker:ro"
38
39
40
41
42
    mountReadOnly:
      work: false
      externals: true
      tools: true
      tasks: true
43
  - container: rbase
44
    image: wch1/r-debug
45
46
47
48
49
    mountReadOnly:
      work: false
      externals: true
      tools: true
      tasks: true
50
jobs:
Guolin Ke's avatar
Guolin Ke committed
51
###########################################
52
- job: Linux
Guolin Ke's avatar
Guolin Ke committed
53
###########################################
54
  variables:
55
    COMPILER: gcc
56
    SETUP_CONDA: 'false'
57
58
    OS_NAME: 'linux'
    PRODUCES_ARTIFACTS: 'true'
59
  pool: mariner-20240410-0
60
  container: linux-artifact-builder
61
  strategy:
Guolin Ke's avatar
Guolin Ke committed
62
63
64
    matrix:
      regular:
        TASK: regular
65
        PYTHON_VERSION: '3.9'
Guolin Ke's avatar
Guolin Ke committed
66
67
      sdist:
        TASK: sdist
68
        PYTHON_VERSION: '3.7'
Guolin Ke's avatar
Guolin Ke committed
69
70
      bdist:
        TASK: bdist
71
        PYTHON_VERSION: '3.8'
72
73
74
75
76
      inference:
        TASK: if-else
      mpi_source:
        TASK: mpi
        METHOD: source
77
        PYTHON_VERSION: '3.8'
78
79
      gpu_source:
        TASK: gpu
Guolin Ke's avatar
Guolin Ke committed
80
        METHOD: source
81
82
      swig:
        TASK: swig
Guolin Ke's avatar
Guolin Ke committed
83
  steps:
84
  - script: |
85
      echo "##vso[task.setvariable variable=BUILD_DIRECTORY]$BUILD_SOURCESDIRECTORY"
86
      echo "##vso[task.prependpath]/usr/lib64/openmpi/bin"
Nikita Titov's avatar
Nikita Titov committed
87
      echo "##vso[task.prependpath]$CONDA/bin"
88
    displayName: 'Set variables'
89
90
91
  - script: |
      git clean -d -f -x
    displayName: 'Clean source directory'
92
93
94
  - script: |
      echo '$(Build.SourceVersion)' > '$(Build.ArtifactStagingDirectory)/commit.txt'
    displayName: 'Add commit hash to artifacts archive'
95
  - task: Bash@3
96
    displayName: Setup
97
98
99
100
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/setup.sh
      targetType: filePath
  - task: Bash@3
101
    displayName: Test
102
103
104
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/test.sh
      targetType: filePath
Nikita Titov's avatar
Nikita Titov committed
105
  - task: PublishBuildArtifacts@1
106
    condition: and(succeeded(), in(variables['TASK'], 'regular', 'sdist', 'bdist', 'swig'), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
Nikita Titov's avatar
Nikita Titov committed
107
108
109
110
    inputs:
      pathtoPublish: '$(Build.ArtifactStagingDirectory)'
      artifactName: PackageAssets
      artifactType: container
Guolin Ke's avatar
Guolin Ke committed
111
###########################################
112
113
114
- job: Linux_latest
###########################################
  variables:
115
    COMPILER: clang-17
116
    DEBIAN_FRONTEND: 'noninteractive'
117
    IN_UBUNTU_BASE_CONTAINER: 'true'
118
119
    OS_NAME: 'linux'
    SETUP_CONDA: 'true'
120
  pool: mariner-20240410-0
121
122
123
124
125
126
127
128
129
  container: ubuntu-latest
  strategy:
    matrix:
      regular:
        TASK: regular
      sdist:
        TASK: sdist
      bdist:
        TASK: bdist
130
        PYTHON_VERSION: '3.9'
131
132
133
134
135
136
137
138
      inference:
        TASK: if-else
      mpi_source:
        TASK: mpi
        METHOD: source
      mpi_pip:
        TASK: mpi
        METHOD: pip
139
        PYTHON_VERSION: '3.10'
140
141
142
      mpi_wheel:
        TASK: mpi
        METHOD: wheel
143
        PYTHON_VERSION: '3.8'
144
145
146
      gpu_source:
        TASK: gpu
        METHOD: source
147
        PYTHON_VERSION: '3.10'
148
149
150
      gpu_pip:
        TASK: gpu
        METHOD: pip
151
        PYTHON_VERSION: '3.9'
152
153
154
      gpu_wheel:
        TASK: gpu
        METHOD: wheel
155
        PYTHON_VERSION: '3.8'
156
157
158
      cpp_tests:
        TASK: cpp-tests
        METHOD: with-sanitizers
159
160
161
  steps:
  - script: |
      echo "##vso[task.setvariable variable=BUILD_DIRECTORY]$BUILD_SOURCESDIRECTORY"
162
      CONDA=$HOME/miniforge
163
164
165
166
167
168
169
170
      echo "##vso[task.setvariable variable=CONDA]$CONDA"
      echo "##vso[task.prependpath]$CONDA/bin"
    displayName: 'Set variables'
  # https://github.com/microsoft/azure-pipelines-agent/issues/2043#issuecomment-687983301
  - script: |
      /tmp/docker exec -t -u 0 ci-container \
      sh -c "apt-get update && apt-get -o Dpkg::Options::="--force-confold" -y install sudo"
    displayName: 'Install sudo'
171
172
173
174
175
176
  - script: |
      sudo apt-get update
      sudo apt-get install -y --no-install-recommends git
      git clean -d -f -x
    displayName: 'Clean source directory'
  - task: Bash@3
177
    displayName: Setup
178
179
180
181
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/setup.sh
      targetType: 'filePath'
  - task: Bash@3
182
    displayName: Test
183
184
185
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/test.sh
      targetType: 'filePath'
186
###########################################
187
188
189
190
191
192
193
- job: QEMU_multiarch
###########################################
  variables:
    COMPILER: gcc
    OS_NAME: 'linux'
    PRODUCES_ARTIFACTS: 'true'
  pool:
194
    vmImage: ubuntu-22.04
195
  timeoutInMinutes: 180
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  strategy:
    matrix:
      bdist:
        TASK: bdist
        ARCH: aarch64
  steps:
  - script: |
      sudo apt-get update
      sudo apt-get install --no-install-recommends -y \
        binfmt-support \
        qemu \
        qemu-user \
        qemu-user-static
    displayName: 'Install QEMU'
  - script: |
      docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
    displayName: 'Enable Docker multi-architecture support'
213
214
215
  - script: |
      git clean -d -f -x
    displayName: 'Clean source directory'
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  - script: |
      export ROOT_DOCKER_FOLDER=/LightGBM
      cat > docker.env <<EOF
      AZURE=$AZURE
      OS_NAME=$OS_NAME
      COMPILER=$COMPILER
      TASK=$TASK
      METHOD=$METHOD
      CONDA_ENV=$CONDA_ENV
      PYTHON_VERSION=$PYTHON_VERSION
      BUILD_DIRECTORY=$ROOT_DOCKER_FOLDER
      PRODUCES_ARTIFACTS=$PRODUCES_ARTIFACTS
      BUILD_ARTIFACTSTAGINGDIRECTORY=$BUILD_ARTIFACTSTAGINGDIRECTORY
      EOF
      cat > docker-script.sh <<EOF
231
      export CONDA=\$HOME/miniforge
232
233
      export PATH=\$CONDA/bin:/opt/rh/llvm-toolset-7.0/root/usr/bin:\$PATH
      export LD_LIBRARY_PATH=/opt/rh/llvm-toolset-7.0/root/usr/lib64:\$LD_LIBRARY_PATH
234
235
      $ROOT_DOCKER_FOLDER/.ci/setup.sh || exit 1
      $ROOT_DOCKER_FOLDER/.ci/test.sh || exit 1
236
      EOF
237
      IMAGE_URI="lightgbm/vsts-agent:manylinux2014_aarch64"
238
239
      docker pull "${IMAGE_URI}" || exit 1
      PLATFORM=$(docker inspect --format='{{.Os}}/{{.Architecture}}' "${IMAGE_URI}") || exit 1
240
      echo "detected image platform: ${PLATFORM}"
241
      docker run \
242
        --platform "${PLATFORM}" \
243
244
245
246
        --rm \
        --env-file docker.env \
        -v "$(Build.SourcesDirectory)":"$ROOT_DOCKER_FOLDER" \
        -v "$(Build.ArtifactStagingDirectory)":"$(Build.ArtifactStagingDirectory)" \
247
        "${IMAGE_URI}" \
248
249
250
251
252
253
254
255
256
        /bin/bash $ROOT_DOCKER_FOLDER/docker-script.sh
    displayName: 'Setup and run tests'
  - task: PublishBuildArtifacts@1
    condition: and(succeeded(), in(variables['TASK'], 'bdist'), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
    inputs:
      pathtoPublish: '$(Build.ArtifactStagingDirectory)'
      artifactName: PackageAssets
      artifactType: container
###########################################
257
- job: macOS
Guolin Ke's avatar
Guolin Ke committed
258
###########################################
259
  variables:
260
    COMPILER: clang
261
262
    OS_NAME: 'macos'
    PRODUCES_ARTIFACTS: 'true'
263
  pool:
264
    vmImage: 'macOS-11'
265
  strategy:
Guolin Ke's avatar
Guolin Ke committed
266
267
268
    matrix:
      regular:
        TASK: regular
269
        PYTHON_VERSION: '3.10'
Guolin Ke's avatar
Guolin Ke committed
270
271
      sdist:
        TASK: sdist
272
        PYTHON_VERSION: '3.9'
Guolin Ke's avatar
Guolin Ke committed
273
274
      bdist:
        TASK: bdist
275
276
      swig:
        TASK: swig
277
278
      cpp_tests:
        TASK: cpp-tests
279
280
        METHOD: with-sanitizers
        SANITIZERS: "address;undefined"
Guolin Ke's avatar
Guolin Ke committed
281
  steps:
282
  - script: |
283
      echo "##vso[task.setvariable variable=BUILD_DIRECTORY]$BUILD_SOURCESDIRECTORY"
284
      CONDA=$AGENT_HOMEDIRECTORY/miniforge
Nikita Titov's avatar
Nikita Titov committed
285
286
      echo "##vso[task.setvariable variable=CONDA]$CONDA"
      echo "##vso[task.prependpath]$CONDA/bin"
287
      echo "##vso[task.setvariable variable=JAVA_HOME]$JAVA_HOME_8_X64"
288
    displayName: 'Set variables'
289
290
291
292
  - script: |
      git clean -d -f -x
    displayName: 'Clean source directory'
  - task: Bash@3
293
    displayName: Setup
294
295
296
297
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/setup.sh
      targetType: filePath
  - task: Bash@3
298
    displayName: Test
299
300
301
    inputs:
      filePath: $(Build.SourcesDirectory)/.ci/test.sh
      targetType: filePath
Guolin Ke's avatar
Guolin Ke committed
302
  - task: PublishBuildArtifacts@1
303
    condition: and(succeeded(), in(variables['TASK'], 'regular', 'bdist', 'swig'), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
Guolin Ke's avatar
Guolin Ke committed
304
    inputs:
305
      pathtoPublish: '$(Build.ArtifactStagingDirectory)'
Guolin Ke's avatar
Guolin Ke committed
306
307
308
      artifactName: PackageAssets
      artifactType: container
###########################################
309
- job: Windows
Guolin Ke's avatar
Guolin Ke committed
310
###########################################
311
  pool:
312
    vmImage: 'windows-2019'
313
  strategy:
Guolin Ke's avatar
Guolin Ke committed
314
315
316
    matrix:
      regular:
        TASK: regular
317
        PYTHON_VERSION: '3.10'
Guolin Ke's avatar
Guolin Ke committed
318
319
      sdist:
        TASK: sdist
320
        PYTHON_VERSION: '3.9'
Guolin Ke's avatar
Guolin Ke committed
321
322
      bdist:
        TASK: bdist
323
324
      swig:
        TASK: swig
325
326
      cpp_tests:
        TASK: cpp-tests
Guolin Ke's avatar
Guolin Ke committed
327
  steps:
328
329
330
  - powershell: |
      Write-Host "##vso[task.prependpath]$env:CONDA\Scripts"
    displayName: 'Set Variables'
331
332
333
  - script: |
      git clean -d -f -x
    displayName: 'Clean source directory'
334
335
  - script: |
      cmd /c "powershell -ExecutionPolicy Bypass -File %BUILD_SOURCESDIRECTORY%/.ci/install_opencl.ps1"
336
    condition: eq(variables['TASK'], 'bdist')
337
    displayName: 'Install OpenCL'
Nikita Titov's avatar
Nikita Titov committed
338
  - script: |
339
340
      cmd /c "conda config --remove channels defaults"
      cmd /c "conda config --add channels nodefaults"
341
342
      cmd /c "conda config --add channels conda-forge"
      cmd /c "conda config --set channel_priority strict"
343
344
      cmd /c "conda init powershell"
      cmd /c "powershell -ExecutionPolicy Bypass -File %BUILD_SOURCESDIRECTORY%/.ci/test_windows.ps1"
345
    displayName: Test
Guolin Ke's avatar
Guolin Ke committed
346
  - task: PublishBuildArtifacts@1
347
    condition: and(succeeded(), in(variables['TASK'], 'regular', 'bdist', 'swig'), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
Guolin Ke's avatar
Guolin Ke committed
348
    inputs:
349
      pathtoPublish: '$(Build.ArtifactStagingDirectory)'
Guolin Ke's avatar
Guolin Ke committed
350
351
      artifactName: PackageAssets
      artifactType: container
352
353
354
355
356
###########################################
- job: R_artifact
###########################################
  condition: not(startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
  pool:
357
    vmImage: 'ubuntu-22.04'
358
359
  container: rbase
  steps:
360
361
362
  - script: |
      git clean -d -f -x
    displayName: 'Clean source directory'
363
364
  - script: |
      LGB_VER=$(head -n 1 VERSION.txt | sed "s/rc/-/g")
365
366
367
      R_LIB_PATH=~/Rlib
      export R_LIBS=${R_LIB_PATH}
      mkdir -p ${R_LIB_PATH}
368
369
      RDscript -e "install.packages(c('R6', 'data.table', 'jsonlite', 'knitr', 'markdown', 'Matrix', 'RhpcBLASctl'),  lib = '${R_LIB_PATH}', dependencies = c('Depends', 'Imports', 'LinkingTo'), repos = 'https://cran.rstudio.com', Ncpus = parallel::detectCores())" || exit 1
      sh build-cran-package.sh --r-executable=RD || exit 1
370
371
372
373
374
375
376
377
      mv lightgbm_${LGB_VER}.tar.gz $(Build.ArtifactStagingDirectory)/lightgbm-${LGB_VER}-r-cran.tar.gz
    displayName: 'Build CRAN R-package'
  - task: PublishBuildArtifacts@1
    condition: succeeded()
    inputs:
      pathtoPublish: $(Build.ArtifactStagingDirectory)
      artifactName: R-package
      artifactType: container
Guolin Ke's avatar
Guolin Ke committed
378

379
###########################################
380
- job: Package
381
###########################################
Guolin Ke's avatar
Guolin Ke committed
382
383
  dependsOn:
  - Linux
384
  - Linux_latest
385
  - QEMU_multiarch
386
  - macOS
Guolin Ke's avatar
Guolin Ke committed
387
  - Windows
388
  - R_artifact
389
  condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
390
  pool:
391
    vmImage: 'ubuntu-22.04'
Guolin Ke's avatar
Guolin Ke committed
392
  steps:
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  # Create archives with complete source code included (with git submodules)
  - task: ArchiveFiles@2
    displayName: Create zip archive
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
    inputs:
      rootFolderOrFile: $(Build.SourcesDirectory)
      includeRootFolder: false
      archiveType: zip
      archiveFile: '$(Build.ArtifactStagingDirectory)/archives/LightGBM-complete_source_code_zip.zip'
      replaceExistingArchive: true
  - task: ArchiveFiles@2
    displayName: Create tar.gz archive
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
    inputs:
      rootFolderOrFile: $(Build.SourcesDirectory)
      includeRootFolder: false
      archiveType: tar
      tarCompression: gz
      archiveFile: '$(Build.ArtifactStagingDirectory)/archives/LightGBM-complete_source_code_tar_gz.tar.gz'
      replaceExistingArchive: true
Guolin Ke's avatar
Guolin Ke committed
413
414
415
416
417
418
  # Download all agent packages from all previous phases
  - task: DownloadBuildArtifacts@0
    displayName: Download package assets
    inputs:
      artifactName: PackageAssets
      downloadPath: $(Build.SourcesDirectory)/binaries
419
420
421
422
423
424
  - task: DownloadBuildArtifacts@0
    displayName: Download R-package
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
    inputs:
      artifactName: R-package
      downloadPath: $(Build.SourcesDirectory)/R
Guolin Ke's avatar
Guolin Ke committed
425
  - script: |
426
      python "$(Build.SourcesDirectory)/.nuget/create_nuget.py" "$(Build.SourcesDirectory)/binaries/PackageAssets"
427
428
429
430
431
    displayName: 'Create NuGet configuration files'
  - task: NuGetCommand@2
    inputs:
      command: pack
      packagesToPack: '$(Build.SourcesDirectory)/.nuget/*.nuspec'
432
      packDestination: '$(Build.ArtifactStagingDirectory)/nuget'
Guolin Ke's avatar
Guolin Ke committed
433
434
  - task: PublishBuildArtifacts@1
    inputs:
435
      pathtoPublish: '$(Build.ArtifactStagingDirectory)/nuget'
436
      artifactName: NuGet
Guolin Ke's avatar
Guolin Ke committed
437
      artifactType: container
438
439
440
441
442
443
444
445
446
447
448
449
  - task: GitHubRelease@0
    displayName: 'Create GitHub Release'
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
    inputs:
      gitHubConnection: guolinke
      repositoryName: '$(Build.Repository.Name)'
      action: 'create'
      target: '$(Build.SourceVersion)'
      tagSource: 'auto'
      title: '$(Build.SourceBranchName)'
      assets: |
        $(Build.SourcesDirectory)/binaries/PackageAssets/*
450
        $(Build.SourcesDirectory)/R/R-package/*
451
452
        $(Build.ArtifactStagingDirectory)/nuget/*.nupkg
        $(Build.ArtifactStagingDirectory)/archives/*
453
454
455
      assetUploadMode: 'delete'
      isDraft: true
      isPreRelease: false
Guolin Ke's avatar
Guolin Ke committed
456
      addChangeLog: false