Skip to content

Commit

Permalink
feat: add action code
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed Nov 10, 2019
1 parent 7e321af commit 581a2e9
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules/
2 changes: 2 additions & 0 deletions .npmrc
@@ -0,0 +1,2 @@
save-exact=true
package-lock=true
9 changes: 9 additions & 0 deletions .prettierrc.json
@@ -0,0 +1,9 @@
{
"printWidth": 60,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": true
}
15 changes: 15 additions & 0 deletions action.yml
@@ -0,0 +1,15 @@
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/metadata-syntax-for-github-actions
name: 'Cypress'
description: 'GitHub Action for running Cypress end-to-end tests'
author: 'Gleb Bahmutov'
inputs:
record:
description: 'Sends test results to Cypress Dashboard'
required: false
default: false
runs:
using: 'node12'
main: 'index.js'
branding:
color: 'green'
icon: 'check-square'
138 changes: 138 additions & 0 deletions index.js
@@ -0,0 +1,138 @@
// @ts-check
const core = require('@actions/core')
const exec = require('@actions/exec')
const hasha = require('hasha')
const { restoreCache, saveCache } = require('cache/lib/index')

const packageLockHash = hasha.fromFileSync('./package-lock.json')
const platformAndArch = `${process.platform}-${process.arch}`

const NPM_CACHE = (() => {
const o = {
inputPath: '~/.npm',
restoreKeys: `npm-${platformAndArch}-`
}
o.primaryKey = o.restoreKeys + packageLockHash
return o
})()

const CYPRESS_BINARY_CACHE = (() => {
const o = {
inputPath: '~/.cache/Cypress',
restoreKeys: `cypress-${platformAndArch}-`
}
o.primaryKey = o.restoreKeys + packageLockHash
return o
})()

const restoreCachedNpm = () => {
console.log('trying to restore cached NPM modules')
return restoreCache(
NPM_CACHE.inputPath,
NPM_CACHE.primaryKey,
NPM_CACHE.restoreKeys
)
}

const saveCachedNpm = () => {
console.log('saving NPM modules')
return saveCache(NPM_CACHE.inputPath, NPM_CACHE.primaryKey)
}

const restoreCachedCypressBinary = () => {
console.log('trying to restore cached Cypress binary')
return restoreCache(
CYPRESS_BINARY_CACHE.inputPath,
CYPRESS_BINARY_CACHE.primaryKey,
CYPRESS_BINARY_CACHE.restoreKeys
)
}

const saveCachedCypressBinary = () => {
console.log('saving Cypress binary')
return saveCache(
CYPRESS_BINARY_CACHE.inputPath,
CYPRESS_BINARY_CACHE.primaryKey
)
}

const install = () => {
console.log('installing NPM dependencies')
// prevent lots of progress messages during install
core.exportVariable('CI', '1')
return exec.exec('npm ci')
}

const verifyCypressBinary = () => {
console.log('Verifying Cypress')
return exec.exec('npx cypress verify')
}

/**
* Grabs a boolean GitHub Action parameter input and casts it.
* @param {string} name - parameter name
* @param {boolean} defaultValue - default value to use if the parameter was not specified
* @returns {boolean} converted input argument or default value
*/
const getInputBool = (name, defaultValue = false) => {
const param = core.getInput(name)
if (param === 'true' || param === '1') {
return true
}
if (param === 'false' || param === '0') {
return false
}

return defaultValue
}

const runTests = () => {
const runTests = getInputBool('runTests', true)
if (!runTests) {
console.log('Skipping running tests: runTests parameter is false')
return
}

console.log('Running Cypress tests')

const record = getInputBool('record')
const parallel = getInputBool('parallel')

let cmd = 'npx cypress run'
if (record) {
cmd += ' --record'
}
if (parallel) {
// on GitHub Actions we can use workflow name and SHA commit to tie multiple jobs together
const parallelId = `${process.env.GITHUB_WORKFLOW} - ${
process.env.GITHUB_SHA
}`
cmd += ` --parallel --ci-build-id "${parallelId}"`
}
const group = core.getInput('group')
if (group) {
cmd += ` --group "${group}"`
}
console.log('Cypress test command: %s', cmd)

core.exportVariable('TERM', 'xterm')
return exec.exec(cmd)
}

Promise.all([restoreCachedNpm(), restoreCachedCypressBinary()])
.then(([npmCacheHit, cypressCacheHit]) => {
console.log('npm cache hit', npmCacheHit)
console.log('cypress cache hit', cypressCacheHit)

if (!npmCacheHit || !cypressCacheHit) {
return install()
.then(verifyCypressBinary)
.then(saveCachedNpm)
.then(saveCachedCypressBinary)
}
})
.then(runTests)
.catch(error => {
console.log(error)
core.setFailed(error.message)
})
89 changes: 89 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 19 additions & 2 deletions package.json
Expand Up @@ -4,18 +4,35 @@
"description": "GitHub Action for running Cypress end-to-end tests",
"private": false,
"main": "index.js",
"files": [
"index.js",
"action.yml"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cypress-io/github-action.git"
},
"keywords": [],
"keywords": [
"actions",
"cypress-io"
],
"author": "Gleb Bahmutov <gleb@cypress.io>",
"license": "MIT",
"bugs": {
"url": "https://github.com/cypress-io/github-action/issues"
},
"homepage": "https://github.com/cypress-io/github-action#readme"
"homepage": "https://github.com/cypress-io/github-action#readme",
"dependencies": {
"@actions/core": "1.2.0",
"@actions/exec": "1.0.1",
"cache": "github:cypress-io/github-actions-cache#8bec6cc",
"hasha": "5.1.0"
},
"devDependencies": {
"prettier": "1.19.1",
"@types/node": "^12.0.4"
}
}

0 comments on commit 581a2e9

Please sign in to comment.