Browse Source

Add release build to VSTS

John Kleinschmidt 6 years ago
parent
commit
475a1e30d9
2 changed files with 163 additions and 2 deletions
  1. 81 2
      script/ci-release-build.js
  2. 82 0
      vsts.yml

+ 81 - 2
script/ci-release-build.js

@@ -1,6 +1,7 @@
 const assert = require('assert')
 const request = require('request')
 const buildAppVeyorURL = 'https://windows-ci.electronjs.org/api/builds'
+const vstsURL = 'https://github.visualstudio.com/electron/_apis/build'
 
 const circleCIJobs = [
   'electron-linux-arm',
@@ -10,6 +11,11 @@ const circleCIJobs = [
   'electron-linux-x64'
 ]
 
+const vstsJobs = [
+  'electron-release-mas-x64',
+  'electron-release-osx-x64'
+]
+
 async function makeRequest (requestOptions, parseResponse) {
   return new Promise((resolve, reject) => {
     request(requestOptions, (err, res, body) => {
@@ -62,7 +68,7 @@ async function circleCIcall (buildUrl, targetBranch, job, options) {
   }, true).catch(err => {
     console.log('Error calling CircleCI:', err)
   })
-  console.log(`Check ${circleResponse.build_url} for status. (${job})`)
+  console.log(`CircleCI release build request for ${job} successful.  Check ${circleResponse.build_url} for status.`)
 }
 
 async function buildAppVeyor (targetBranch, options) {
@@ -113,6 +119,70 @@ function buildCircleCI (targetBranch, options) {
   }
 }
 
+async function buildVSTS (targetBranch, options) {
+  if (options.job) {
+    assert(vstsJobs.includes(options.job), `Unknown CI job name: ${options.job}.`)
+  }
+  console.log(`Triggering VSTS to run build on branch: ${targetBranch} with release flag.`)
+  assert(process.env.VSTS_TOKEN, 'VSTS_TOKEN not found in environment')
+  let environmentVariables = {}
+
+  if (!options.ghRelease) {
+    environmentVariables.UPLOAD_TO_S3 = 1
+  }
+
+  if (options.automaticRelease) {
+    environmentVariables.AUTO_RELEASE = 'true'
+  }
+
+  let requestOpts = {
+    url: `${vstsURL}/definitions?api-version=4.1`,
+    auth: {
+      user: '',
+      password: process.env.VSTS_TOKEN
+    },
+    headers: {
+      'Content-Type': 'application/json'
+    }
+  }
+  let vstsResponse = await makeRequest(requestOpts, true).catch(err => {
+    console.log('Error calling VSTS to get build definitions:', err)
+  })
+  let buildsToRun = []
+  if (options.job) {
+    buildsToRun = vstsResponse.value.filter(build => build.name === options.job)
+  } else {
+    buildsToRun = vstsResponse.value.filter(build => vstsJobs.includes(build.name))
+  }
+  buildsToRun.forEach((build) => callVSTSBuild(build, targetBranch, environmentVariables))
+}
+
+async function callVSTSBuild (build, targetBranch, environmentVariables) {
+  let buildBody = {
+    definition: build,
+    sourceBranch: targetBranch
+  }
+  if (Object.keys(environmentVariables).length !== 0) {
+    buildBody.parameters = JSON.stringify(environmentVariables)
+  }
+  let requestOpts = {
+    url: `${vstsURL}/builds?api-version=4.1`,
+    auth: {
+      user: '',
+      password: process.env.VSTS_TOKEN
+    },
+    headers: {
+      'Content-Type': 'application/json'
+    },
+    body: JSON.stringify(buildBody),
+    method: 'POST'
+  }
+  let vstsResponse = await makeRequest(requestOpts, true).catch(err => {
+    console.log(`Error calling VSTS for job ${build.name}`, err)
+  })
+  console.log(`VSTS release build request for ${build.name} successful. Check ${vstsResponse._links.web.href} for status.`)
+}
+
 function runRelease (targetBranch, options) {
   if (options.ci) {
     switch (options.ci) {
@@ -124,10 +194,19 @@ function runRelease (targetBranch, options) {
         buildAppVeyor(targetBranch, options)
         break
       }
+      case 'VSTS': {
+        buildVSTS(targetBranch, options)
+        break
+      }
+      default: {
+        console.log(`Error! Unknown CI: ${options.ci}.`)
+        process.exit(1)
+      }
     }
   } else {
     buildCircleCI(targetBranch, options)
     buildAppVeyor(targetBranch, options)
+    buildVSTS(targetBranch, options)
   }
 }
 
@@ -140,7 +219,7 @@ if (require.main === module) {
   const targetBranch = args._[0]
   if (args._.length < 1) {
     console.log(`Trigger CI to build release builds of electron.
-    Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor] [--ghRelease] [--automaticRelease] TARGET_BRANCH
+    Usage: ci-release-build.js [--job=CI_JOB_NAME] [--ci=CircleCI|AppVeyor|VSTS] [--ghRelease] [--automaticRelease] TARGET_BRANCH
     `)
     process.exit(0)
   }

+ 82 - 0
vsts.yml

@@ -0,0 +1,82 @@
+resources:
+- repo: self
+steps:
+- bash: |
+    if [ "$ELECTRON_RELEASE" == "1" ]; then
+      echo 'Bootstrapping Electron for release build'
+      script/bootstrap.py --target_arch=$TARGET_ARCH
+    else
+      echo 'Bootstrapping Electron for debug build'
+      script/bootstrap.py --target_arch=$TARGET_ARCH --dev
+    fi
+  name: Bootstrap
+
+- bash: |
+    npm run lint
+  name: Lint
+  condition: and(succeeded(), ne(variables['ELECTRON_RELEASE'], '1'))
+
+- bash: |
+    if [ "$ELECTRON_RELEASE" == "1" ]; then
+      echo 'Building Electron for release'
+      script/build.py -c R
+    else
+      echo 'Building Electron for debug'
+      script/build.py -c D
+    fi
+  name: Build
+
+- bash: |
+    echo 'Creating Electron release distribution'
+    script/create-dist.py
+  name: Create_distribution
+  condition: and(succeeded(), eq(variables['ELECTRON_RELEASE'], '1'))
+
+- bash: |
+    if [ "$UPLOAD_TO_S3" != "1" ]; then
+      echo 'Uploading Electron release distribution to github releases'
+      ELECTRON_S3_BUCKET="$(s3_bucket)" ELECTRON_S3_ACCESS_KEY="$(s3_access_key)" ELECTRON_S3_SECRET_KEY="$(s3_secret_key)" ELECTRON_GITHUB_TOKEN="$(github_token)" script/upload.py
+    else
+      echo 'Uploading Electron release distribution to s3'
+      ELECTRON_S3_BUCKET="$(s3_bucket)" ELECTRON_S3_ACCESS_KEY="$(s3_access_key)" ELECTRON_S3_SECRET_KEY="$(s3_secret_key)" ELECTRON_GITHUB_TOKEN="$(github_token)" script/upload.py --upload_to_s3
+    fi
+  name: Upload_distribution
+  condition: and(succeeded(), eq(variables['ELECTRON_RELEASE'], '1'))
+
+- bash: |
+    echo 'Testing Electron build'
+    mkdir junit
+    export MOCHA_FILE="junit/test-results.xml"
+    export MOCHA_REPORTER="mocha-junit-reporter"
+    if [ "$ELECTRON_RELEASE" == "1" ]; then
+      script/test.py --ci --rebuild_native_modules -c R
+    else
+      script/test.py --ci --rebuild_native_modules
+    fi
+  name: Test
+
+- bash: |
+    echo 'Verifying ffmpeg on build'
+    if [ "$ELECTRON_RELEASE" == "1" ]; then
+      script/verify-ffmpeg.py -R
+    else
+      script/verify-ffmpeg.py
+    fi
+  name: Verify_FFmpeg
+
+- task: PublishTestResults@2
+  displayName: Publish Test Results
+  inputs:
+    testResultsFiles: 'test-results.xml'
+    searchFolder: junit
+  condition: and(always(), ne(variables['ELECTRON_RELEASE'], '1'))
+
+- task: kasunkodagoda.slack-notification.slack-notification-task.SlackNotification@3
+  displayName: Post Slack Notification
+  inputs:
+    SlackApiToken: '$(slack_token)'
+    Channel: '#bot-nightly-releases'
+    Message: '$(Build.DefinitionName)-$(Build.BuildNumber) finished with a $(Agent.JobStatus) status.'
+  condition: and(always(), eq(variables['Build.Reason'], 'Schedule'))
+
+- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3