server: pass CI group id with API call to create run (#396)

* server: pass CI parallel id with API call to create run

* rename parallel-id to group-id

* pass --group to use --group-id or infer groupId from environment

* test group with groupId

* fix integration spec
This commit is contained in:
Gleb Bahmutov
2017-08-31 14:24:37 -04:00
committed by Brian Mann
parent df5280d0ac
commit a7c398ce8b
8 changed files with 131 additions and 33 deletions

View File

@@ -0,0 +1,57 @@
exports['lib/modes/record .generateProjectBuildId calls api.createRun with args 1'] = [
{
"projectId": "id-123",
"recordKey": "key-123",
"commitSha": "sha-123",
"commitBranch": "master",
"commitAuthorName": "brian",
"commitAuthorEmail": "brian@cypress.io",
"commitMessage": "such hax",
"remoteOrigin": "https://github.com/foo/bar.git",
"ciParams": {
"foo": "bar"
},
"ciProvider": "circle",
"ciBuildNumber": "build-123",
"groupId": null
}
]
exports['lib/modes/record .generateProjectBuildId passes groupId 1'] = [
{
"projectId": "id-123",
"recordKey": "key-123",
"commitSha": "sha-123",
"commitBranch": "master",
"commitAuthorName": "brian",
"commitAuthorEmail": "brian@cypress.io",
"commitMessage": "such hax",
"remoteOrigin": "https://github.com/foo/bar.git",
"ciParams": {
"foo": "bar"
},
"ciProvider": "circle",
"ciBuildNumber": "build-123",
"groupId": "gr123"
}
]
exports['lib/modes/record .generateProjectBuildId figures out groupId from CI environment variables 1'] = [
{
"projectId": "id-123",
"recordKey": "key-123",
"commitSha": "sha-123",
"commitBranch": "master",
"commitAuthorName": "brian",
"commitAuthorEmail": "brian@cypress.io",
"commitMessage": "such hax",
"remoteOrigin": "https://github.com/foo/bar.git",
"ciParams": {
"foo": "bar"
},
"ciProvider": "circle",
"ciBuildNumber": "build-123",
"groupId": "ci-group-123"
}
]

View File

@@ -89,6 +89,20 @@ module.exports = {
.catch(errors.StatusCodeError, formatResponseBody)
createRun: (options = {}) ->
body = _.pick(options, [
"projectId"
"recordKey"
"commitSha"
"commitBranch"
"commitAuthorName"
"commitAuthorEmail"
"commitMessage"
"remoteOrigin"
"ciParams"
"ciProvider"
"ciBuildNumber",
"groupId"
])
rp.post({
url: Routes.runs()
json: true
@@ -96,19 +110,7 @@ module.exports = {
headers: {
"x-route-version": "2"
}
body: _.pick(options, [
"projectId"
"recordKey"
"commitSha"
"commitBranch"
"commitAuthorName"
"commitAuthorEmail"
"commitMessage"
"remoteOrigin"
"ciParams"
"ciProvider"
"ciBuildNumber"
])
body: body
})
.promise()
.get("buildId")

View File

@@ -29,7 +29,7 @@ module.exports = {
repo.getBranch()
generateProjectBuildId: (projectId, projectPath, projectName, recordKey) ->
generateProjectBuildId: (projectId, projectPath, projectName, recordKey, group, groupId) ->
if not recordKey
errors.throw("RECORD_KEY_MISSING")
@@ -44,6 +44,11 @@ module.exports = {
message: repo.getMessage()
})
.then (git) ->
# only send groupId if group option is true
if group
groupId ?= ciProvider.groupId()
else
groupId = null
api.createRun({
projectId: projectId
recordKey: recordKey
@@ -56,6 +61,7 @@ module.exports = {
ciParams: ciProvider.params()
ciProvider: ciProvider.name()
ciBuildNumber: ciProvider.buildNum()
groupId: groupId
})
.catch (err) ->
switch err.statusCode
@@ -218,7 +224,7 @@ module.exports = {
.then (cfg) =>
{projectName} = cfg
@generateProjectBuildId(projectId, projectPath, projectName, options.key)
@generateProjectBuildId(projectId, projectPath, projectName, options.key, options.group, options.groupId)
.then (buildId) =>
## bail if we dont have a buildId
return if not buildId

View File

@@ -5,7 +5,7 @@ coerce = require("./coerce")
config = require("../config")
cwd = require("../cwd")
whitelist = "appPath execPath apiKey smokeTest getKey generateKey cliVersion runProject project spec ci record updating ping key logs clearLogs returnPkg version mode autoOpen removeIds showHeadlessGui config exitWithCode hosts browser headless outputPath".split(" ")
whitelist = "appPath execPath apiKey smokeTest getKey generateKey cliVersion runProject project spec ci record updating ping key logs clearLogs returnPkg version mode autoOpen removeIds showHeadlessGui config exitWithCode hosts browser headless outputPath group groupId".split(" ")
whitelist = whitelist.concat(config.getConfigKeys())
parseNestedValues = (vals) ->
@@ -48,9 +48,10 @@ module.exports = {
"env": "environmentVariables"
"headless": "isTextTerminal"
"show-headless-gui":"showHeadlessGui"
"exit-with-code": "exitWithCode"
"exit-with-code": "exitWithCode"
"reporter-options": "reporterOptions"
"output-path": "outputPath"
"output-path": "outputPath"
"group-id": "groupId"
}
})

View File

@@ -37,6 +37,11 @@ buildNums = (provider) -> {
travis: process.env.TRAVIS_BUILD_NUMBER
}[provider]
groupIds = (provider) -> {
# for CircleCI v2 use workflow id to group builds
circle: process.env.CIRCLE_WORKFLOW_ID
}[provider]
params = (provider) -> {
appveyor: {
accountName: process.env.APPVEYOR_ACCOUNT_NAME
@@ -122,4 +127,7 @@ module.exports = {
buildNum: ->
buildNums(getProviderName()) ? null
groupId: ->
groupIds(getProviderName()) ? null
}

View File

@@ -767,7 +767,7 @@ describe "lib/cypress", ->
beforeEach ->
@setup = =>
@createRun = @sandbox.stub(api, "createRun").withArgs({
createRunArgs = {
projectId: @projectId
recordKey: "token-123"
commitSha: "sha-123"
@@ -779,7 +779,9 @@ describe "lib/cypress", ->
ciProvider: "travis"
ciBuildNumber: "987"
ciParams: null
})
groupId: null
}
@createRun = @sandbox.stub(api, "createRun").withArgs(createRunArgs)
@upload = @sandbox.stub(record, "upload").resolves()
@sandbox.stub(stdout, "capture").returns({

View File

@@ -17,6 +17,22 @@ describe "lib/util/ci_provider", ->
## restore the env
process.env = JSON.parse(@env)
context "grou-id", ->
describe "circle", ->
beforeEach ->
process.env.CIRCLECI = true
process.env.CIRCLE_BUILD_URL = "circle build url"
process.env.CIRCLE_BUILD_NUM = "4"
it "grabs workflow id as group id", ->
id = "1234-group-id"
process.env.CIRCLE_WORKFLOW_ID = id
expect(ciProvider.groupId()).to.equal(id)
it "no group id without workflow id", ->
expect(ciProvider.groupId()).to.be.null
it "returns 'unknown' when not found", ->
process.env = {}

View File

@@ -11,6 +11,7 @@ record = require("#{root}../lib/modes/record")
headless = require("#{root}../lib/modes/headless")
git = require("#{root}../lib/util/git")
ciProvider = require("#{root}../lib/util/ci_provider")
snapshot = require("snap-shot-it")
describe "lib/modes/record", ->
beforeEach ->
@@ -70,19 +71,24 @@ describe "lib/modes/record", ->
api.createRun.resolves()
record.generateProjectBuildId("id-123", "/_test-output/path/to/project", "project", "key-123").then ->
expect(api.createRun).to.be.calledWith({
projectId: "id-123"
recordKey: "key-123"
commitSha: "sha-123"
commitBranch: "master"
commitAuthorName: "brian"
commitAuthorEmail: "brian@cypress.io"
commitMessage: "such hax"
remoteOrigin: "https://github.com/foo/bar.git"
ciProvider: "circle"
ciBuildNumber: "build-123"
ciParams: {foo: "bar"}
})
snapshot(api.createRun.firstCall.args)
it "passes groupId", ->
api.createRun.resolves()
group = true
groupId = "gr123"
record.generateProjectBuildId("id-123", "/_test-output/path/to/project", "project", "key-123", group, groupId).then ->
snapshot(api.createRun.firstCall.args)
it "figures out groupId from CI environment variables", ->
@sandbox.stub(ciProvider, "groupId").returns("ci-group-123")
api.createRun.resolves()
group = true
record.generateProjectBuildId("id-123", "/_test-output/path/to/project", "project", "key-123", group).then ->
snapshot(api.createRun.firstCall.args)
it "handles status code errors of 401", ->
err = new Error