Copy test runner binaries before releasing new version (#4082)

* adding S3 sdk

* test binary folder

* linting

* before searching for binary

* linting

* grab folders in the given S3 prefix

* grab folders in the given S3 prefix

* find the last build

* found last builds for commit

* refactoring

* add tests for upload dir name

* create destination zip filename

* copying S3 files

* move s3 helpers into own object, prepare for testing

* add realistic test

* linting

* chore: add documentation to DEPLOY.md file
This commit is contained in:
Gleb Bahmutov
2019-05-01 10:14:25 -04:00
committed by GitHub
parent da23a9760a
commit ebaa7a375c
16 changed files with 756 additions and 23 deletions
+158
View File
@@ -0,0 +1,158 @@
const snapshot = require('snap-shot-it')
const la = require('lazy-ass')
const is = require('check-more-types')
const uploadUtils = require('../../binary/util/upload')
/* eslint-env mocha */
/* global sinon */
describe('move-binaries', () => {
const moveBinaries = require('../../binary/move-binaries')
context('parseBuildPath', () => {
const parseBuildPath = moveBinaries.parseBuildPath
it('parses into SHA and build', () => {
const path =
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/'
const parsed = parseBuildPath(path)
la(is.commitId(parsed.commit), 'missing commit', parsed)
la(is.positive(parsed.build), 'missing build', parsed)
snapshot({
path,
parsed,
})
})
})
context('findBuildByCommit', () => {
const findBuildByCommit = moveBinaries.findBuildByCommit
const sha = '47e98fa1d0b18867a74da91a719d0f1ae73fcbc7'
it('is a function', () => {
la(is.fn(findBuildByCommit))
})
it('finds single matching path', () => {
const paths = [
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
]
const found = findBuildByCommit(sha, paths)
la(found === paths[0], 'expected to find the only path', found)
})
it('finds single matching path among several', () => {
const paths = [
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
// these are not matching
'beta/binary/3.3.0/darwin-x64/circle-develop-ffff8fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
'beta/binary/3.3.0/darwin-x64/circle-develop-aaaa8fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
]
const found = findBuildByCommit(sha, paths)
la(found === paths[0], 'expected to find the only path', found)
})
it('finds last matching build', () => {
const paths = [
// matching, but not the last one
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-50/',
// this is both matching and is the latest build (100)
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-100/',
// these are not matching
'beta/binary/3.3.0/darwin-x64/circle-develop-ffff8fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
'beta/binary/3.3.0/darwin-x64/circle-develop-aaaa8fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
// this one is matching, but not the latest one
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-2/',
]
const found = findBuildByCommit(sha, paths)
la(found === paths[1], 'expected to find the only path', found)
})
})
context('moveBinaries', () => {
const move = moveBinaries.moveBinaries
it('is a function', () => {
la(is.fn(move))
})
it('finds and copies latest build for each platform', () => {
// realistic end-to-end test
// stubs S3 method calls
// and lets our "moveBinaries" function collect builds
// find latest build for each platform (for the same commit)
// then call S3 to copy the desktop zip file to the final destination folder
const sha = '455046b928c861d4457b2ec5426a51de1fda74fd'
const version = '3.3.0'
// limit ourselves to single platform
sinon.stub(uploadUtils, 'getValidPlatformArchs').returns(['darwin-x64'])
// Mac builds for several commits in the beta folder
// below is the latest build matching the commit
const latestMacBuild =
'beta/binary/3.3.0/darwin-x64/circle-develop-455046b928c861d4457b2ec5426a51de1fda74fd-102457/'
const darwinBuilds = [
'beta/binary/3.3.0/darwin-x64/circle-develop-167934f0e45a07f03f6b1c5ddd6d8f201b5bb708-102287/',
'beta/binary/3.3.0/darwin-x64/circle-develop-455046b928c861d4457b2ec5426a51de1fda74fd-102212/',
'beta/binary/3.3.0/darwin-x64/circle-develop-47e98fa1d0b18867a74da91a719d0f1ae73fcbc7-101843/',
latestMacBuild,
'beta/binary/3.3.0/darwin-x64/circle-develop-5015cbbe876687deca571c221dfbc90715ad6d00-101982/',
'beta/binary/3.3.0/darwin-x64/circle-develop-9372bc3f67a6a83bd5ec8a69d7350f5a9b52ddf9-102246/',
'beta/binary/3.3.0/darwin-x64/circle-develop-455046b928c861d4457b2ec5426a51de1fda74fd-102359/',
'beta/binary/3.3.0/darwin-x64/circle-develop-ec36bf013224942f6198bf831d62af64b9b16cf5-102729/',
'beta/binary/3.3.0/darwin-x64/circle-issue-3996-6d539513e709ddd5aad866f6bf653280db6622cd-98450/',
]
// fake AWS config
const aws = {
bucket: 'cdn.cypress.io',
folder: 'desktop', // destination for test runner downloads
}
sinon.stub(uploadUtils, 'getS3Credentials').returns(aws)
// fake S3 api
const s3 = {}
sinon.stub(moveBinaries.s3helpers, 'makeS3').returns(s3)
sinon
.stub(moveBinaries.s3helpers, 'listS3Objects')
.withArgs('beta/binary/3.3.0/darwin-x64', aws.bucket)
.resolves(darwinBuilds)
sinon
.stub(moveBinaries.s3helpers, 'verifyZipFileExists')
.withArgs(`${latestMacBuild}cypress.zip`, aws.bucket)
.resolves()
// our method will ask user to confirm copying
sinon.stub(moveBinaries.prompts, 'shouldCopy').resolves()
sinon
.stub(moveBinaries.s3helpers, 'copyS3')
.withArgs(
`${latestMacBuild}cypress.zip`,
'desktop/3.3.0/darwin-x64/cypress.zip',
aws.bucket
)
.resolves()
// first two arguments are sliced anyway
const nodeName = null
const scriptName = null
const args = [nodeName, scriptName, '--sha', sha, '--version', version]
return move(args).then((result) => {
la(is.object(result), 'expected a result', result)
snapshot('collected builds and copied desktop', result)
})
})
})
})
+38
View File
@@ -1,6 +1,11 @@
require('../../spec-helper')
const snapshot = require('snap-shot-it')
const la = require('lazy-ass')
const os = require('os')
/* eslint-env mocha */
/* global sinon */
describe('upload', () => {
const upload = require('../../binary/upload')
@@ -13,4 +18,37 @@ describe('upload', () => {
snapshot('test runner manifest', manifest)
})
})
context('getUploadeVersionFolder', () => {
it('returns folder', () => {
const aws = {
folder: 'desktop',
}
const folder = upload.getUploadeVersionFolder(aws, '3.3.0')
la(folder === 'desktop/3.3.0', 'wrong desktop folder', folder)
})
})
context('getUploadDirName', () => {
it('returns folder with platform', () => {
const aws = {
folder: 'desktop',
}
sinon.stub(upload, 'getAwsObj').returns(aws)
sinon.stub(os, 'arch').returns('x64')
const folder = upload.getUploadDirName({
platform: 'darwin',
version: '3.3.0',
})
la(
folder === 'desktop/3.3.0/darwin-x64/',
'wrong upload desktop folder',
folder
)
})
})
})
@@ -1,22 +1,61 @@
const snapshot = require('snap-shot-it')
/* eslint-env mocha */
describe('getCDN', () => {
context('binary', () => {
const { getCDN } = require('../../binary/upload-unique-binary')
describe('upload-unique-binary', () => {
describe('getUploadDirName', () => {
const { getUploadDirName } = require('../../binary/upload-unique-binary')
it('returns CDN s3 path', () => {
it('returns folder for given version', () => {
const options = {
platform: 'darwin-x64',
filename: 'cypress.zip',
platformArch: 'darwin-x64',
version: '3.3.0',
// ci name + commit sha + build number
hash: 'ci-name-e154a40f3f76abd39a1d85c0ebc0ff9565015706-123',
}
snapshot({
snapshot('upload binary folder', {
input: options,
result: getCDN(options),
result: getUploadDirName(options),
})
})
})
describe('getUploadDirForPlatform', () => {
const {
getUploadDirForPlatform,
} = require('../../binary/upload-unique-binary')
it('returns folder for given version and platform', () => {
const options = {
platformArch: 'darwin-x64',
version: '3.3.0',
}
const result = getUploadDirForPlatform(options, options.platformArch)
snapshot('upload binary folder for platform', {
input: options,
result,
})
})
})
describe('getCDN', () => {
context('binary', () => {
const { getCDN } = require('../../binary/upload-unique-binary')
it('returns CDN s3 path', () => {
const options = {
platform: 'darwin-x64',
filename: 'cypress.zip',
version: '3.3.0',
// ci name + commit sha + build number
hash: 'ci-name-e154a40f3f76abd39a1d85c0ebc0ff9565015706-123',
}
snapshot('getCDN for binary', {
input: options,
result: getCDN(options),
})
})
})
})
@@ -0,0 +1,21 @@
const snapshot = require('snap-shot-it')
// I named this file util-upload-spec
// to avoid snapshots being saved into same file
// since "snap-shot-it" v8.x saves all snapshots into single folder
/* eslint-env mocha */
describe('upload util', () => {
const upload = require('../../../binary/util/upload')
context('isValidPlatformArch', () => {
const { isValidPlatformArch } = upload
it('checks given strings', () => {
const valid = upload.validPlatformArchs
const invalid = ['darwin', 'win32', 'windows', 'linux', 'linux64']
snapshot(isValidPlatformArch, ...valid, ...invalid)
})
})
})