Merge branch 'develop' of https://github.com/cypress-io/cypress into agg23/ESLintUpgrade

This commit is contained in:
Adam Gastineau
2021-03-18 11:38:56 -07:00
13 changed files with 47 additions and 382 deletions
+1 -45
View File
@@ -478,8 +478,6 @@ Please refer to each packages' `README.md` which documents how to run tests. It
If you're curious how we manage all of these tests in CI check out our [`circle.yml`](circle.yml) file found in the root `cypress` directory.
Each of the independent packages (in the [`/npm`](./npm) folder) have a `ciJobs` field in their `package.json`. This field corresponds to the CI jobs for that package and is used when determining what tests must pass before the package can be released.
#### Docker
Sometimes tests pass locally, but fail in CI. Our CI environment is dockerized. In order to run the image used in CI locally:
@@ -546,49 +544,7 @@ All updates to `master` are automatically merged into `develop`, so `develop` al
### Independent Packages CI Workflow
Independent packages are automatically released when code is merged into `master`. In order to make these automatic releases work smoothly, independent packages have a couple of special configuration options in their `package.json`.
##### `ciJobs`
List of Circle CI jobs that directly test the current package. These tests must pass before the package can be released.
In addition, these tests will run when a PR is created that changes this package. All tests will run on `develop` and `master`, regardless of what packages were changed.
Note: CI jobs should be unique to a package. Any jobs that are not listed within a `ciJobs` field are considered to be part of the binary and will only run when the binary is changed.
This option takes an array of CI job names.
Example
```json
{
"ciJobs": [
"npm-react",
"npm-react-axe",
"npm-react-next"
]
}
```
##### `ciDependents`
List of local independent (npm) packages that are dependent on the current package. The tests specified in these packages' `ciJobs` must pass before the current package will be released.
When the current package is changed in a PR, it will consider these packages to be changed as well and run CI accordingly.
This option takes an array of package names.
Example
```json
{
"ciDependents": [
"@cypress/react",
"@cypress/vue",
"@cypress/webpack-preprocessor"
]
}
```
You can read more about our CI design decisions in [#8730](https://github.com/cypress-io/cypress/pull/8730#issue-496593325)
Independent packages are automatically released when code is merged into `master` and the entire build passes.
### Pull Requests
+35 -58
View File
@@ -128,7 +128,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
environment:
CYPRESS_KONFIG_ENV: production
@@ -170,7 +169,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: |
cmd=$([[ <<parameters.percy>> == 'true' ]] && echo 'yarn percy exec --') || true
@@ -198,7 +196,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: |
cmd=$([[ <<parameters.percy>> == 'true' ]] && echo 'yarn percy exec --') || true
@@ -228,7 +225,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: yarn workspace @packages/server test ./test/e2e/$(( $CIRCLE_NODE_INDEX ))_*spec* --browser <<parameters.browser>>
- verify-mocha-results
@@ -279,7 +275,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: "Cloning test project: <<parameters.repo>>"
command: |
@@ -328,7 +323,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure the binary and NPM package files are present
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -464,7 +458,6 @@ commands:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure the binary and NPM package files are present
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -576,14 +569,6 @@ commands:
- run:
name: "Waiting on Circle CI jobs: <<parameters.job-names>>"
command: node ./scripts/wait-on-circle-jobs.js --job-names="<<parameters.job-names>>"
check-conditional-ci:
description: Halt CI if the package that this job corresponds to is unchanged
steps:
- run:
name: Check if job should run
command: node scripts/check-conditional-ci.js
build-binary:
steps:
- run:
@@ -797,15 +782,6 @@ jobs:
command: node cli/bin/cypress info --dev
- store-npm-logs
list-changed-packages:
<<: *defaults
steps:
- attach_workspace:
at: ~/
- run:
name: List changed packages
command: node scripts/changed-packages.js
# a special job that keeps polling Circle and when all
# individual jobs are finished, it closes the Percy build
percy-finalize:
@@ -845,7 +821,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run: mkdir -p cli/visual-snapshots
- run:
command: node cli/bin/cypress info --dev | yarn --silent term-to-html | node scripts/sanitize --type cli-info > cli/visual-snapshots/cypress-info.html
@@ -870,7 +845,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure mocha runs
- run: yarn test-mocha
# test binary build code
@@ -918,7 +892,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run: yarn test-unit --scope @packages/server
- verify-mocha-results:
expectedResultCount: 1
@@ -932,7 +905,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run: yarn test-unit --scope @packages/server-ct
- verify-mocha-results:
expectedResultCount: 1
@@ -946,7 +918,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run: yarn test-integration --scope @packages/server
- verify-mocha-results:
expectedResultCount: 1
@@ -959,7 +930,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: yarn workspace @packages/server test-performance
- verify-mocha-results:
@@ -1048,7 +1018,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: yarn build-prod
working_directory: packages/desktop-gui
@@ -1074,7 +1043,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
# builds JS and CSS, and we need the app CSS
# to correctly apply component styles
@@ -1108,7 +1076,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: yarn build-for-tests
working_directory: packages/reporter
@@ -1133,7 +1100,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: yarn build-for-tests
working_directory: packages/ui-components
@@ -1155,7 +1121,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
command: node index.js
working_directory: packages/launcher
@@ -1165,7 +1130,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Build
command: yarn workspace @cypress/webpack-preprocessor build
@@ -1204,7 +1168,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Run tests
command: yarn workspace @cypress/webpack-dev-server test
@@ -1213,7 +1176,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Run tests
command: yarn workspace @cypress/vite-dev-server test
@@ -1223,7 +1185,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Run tests
command: yarn workspace @cypress/rollup-dev-server test
@@ -1233,7 +1194,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Run tests
command: yarn workspace @cypress/webpack-batteries-included-preprocessor test
@@ -1243,7 +1203,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Build
command: yarn workspace @cypress/vue build
@@ -1258,7 +1217,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Build
command: yarn workspace @cypress/design-system build
@@ -1275,7 +1233,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- restore_cache:
name: Restore yarn cache
key: v{{ .Environment.CACHE_VERSION }}-{{ arch }}-npm-react-babel-cache
@@ -1308,7 +1265,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run:
name: Run tests
command: yarn workspace @cypress/eslint-plugin-dev test
@@ -1319,7 +1275,7 @@ jobs:
- attach_workspace:
at: ~/
- run:
name: Release packages
name: Release packages after all jobs pass
command: yarn npm-release
create-build-artifacts:
@@ -1328,7 +1284,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- build-binary
- build-npm-package
- run:
@@ -1412,7 +1367,6 @@ jobs:
# needs uploaded NPM and test binary
- attach_workspace:
at: ~/
- check-conditional-ci
- run: ls -la
# make sure JSON files with uploaded urls are present
- run: ls -la binary-url.json npm-package-url.json
@@ -1449,7 +1403,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure we have cypress.zip received
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -1489,7 +1442,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure we have cypress.zip received
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -1531,7 +1483,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure we have cypress.zip received
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -1575,7 +1526,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure we have cypress.zip received
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -1619,7 +1569,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# make sure we have cypress.zip received
- run: ls -l
- run: ls -l cypress.zip cypress.tgz
@@ -1652,7 +1601,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
- run: ls -l
# make sure we have the binary and NPM package
- run: ls -l cypress.zip cypress.tgz
@@ -1783,7 +1731,6 @@ jobs:
steps:
- attach_workspace:
at: ~/
- check-conditional-ci
# the user should be "node"
- run: whoami
- run: pwd
@@ -1831,10 +1778,6 @@ linux-workflow: &linux-workflow
jobs:
- build
- lint:
name: Linux lint
requires:
- build
- list-changed-packages:
requires:
- build
- percy-finalize:
@@ -1940,9 +1883,43 @@ linux-workflow: &linux-workflow
- npm-eslint-plugin-dev:
requires:
- build
# This release definition must be updated with any new jobs
# Any attempts to automate this are welcome
# If CircleCI provided an "after all" hook, then this wouldn't be necessary
- npm-release:
requires:
- build
- npm-eslint-plugin-dev
- npm-create-cypress-tests
- npm-react
- npm-vue
- npm-design-system
- npm-webpack-batteries-included-preprocessor
- npm-webpack-preprocessor
- npm-rollup-dev-server
- npm-vite-dev-server
- npm-webpack-dev-server
- run-launcher
- ui-components-integration-tests
- reporter-integration-tests
- lint
- percy-finalize
- desktop-gui-component-tests
- desktop-gui-integration-tests-2x
- runner-ct-integration-tests-chrome
- runner-integration-tests-firefox
- runner-integration-tests-chrome
- driver-integration-tests-firefox
- driver-integration-tests-chrome
- server-e2e-tests-non-root
- server-e2e-tests-firefox
- server-e2e-tests-electron
- server-e2e-tests-chrome
- server-performance-tests
- server-integration-tests
- server-unit-tests
- unit-tests
- cli-visual-tests
# various testing scenarios, like building full binary
# and testing it on a real project
-3
View File
@@ -83,9 +83,6 @@
"publishConfig": {
"access": "restricted"
},
"ciJobs": [
"npm-design-system"
],
"standard": {
"globals": [
"Cypress",
-3
View File
@@ -53,8 +53,5 @@
"cypress",
"eslint",
"eslintplugin"
],
"ciJobs": [
"npm-eslint-plugin-dev"
]
}
-3
View File
@@ -156,9 +156,6 @@
"publishConfig": {
"access": "restricted"
},
"ciJobs": [
"npm-react"
],
"standard": {
"globals": [
"Cypress",
+1 -4
View File
@@ -35,8 +35,5 @@
"bugs": "https://github.com/cypress-io/cypress/issues/new?template=1-bug-report.md",
"publishConfig": {
"access": "public"
},
"ciJobs": [
"npm-vite-dev-server"
]
}
}
+1 -4
View File
@@ -85,8 +85,5 @@
"publishConfig": {
"access": "public",
"registry": "http://registry.npmjs.org/"
},
"ciJobs": [
"npm-vue"
]
}
}
@@ -65,8 +65,5 @@
],
"publishConfig": {
"access": "public"
},
"ciJobs": [
"npm-webpack-batteries-included-preprocessor"
]
}
}
+1 -8
View File
@@ -42,12 +42,5 @@
"bugs": "https://github.com/cypress-io/cypress/issues/new?template=1-bug-report.md",
"publishConfig": {
"access": "public"
},
"ciDependents": [
"@cypress/react",
"@cypress/vue"
],
"ciJobs": [
"npm-webpack-dev-server"
]
}
}
-6
View File
@@ -88,11 +88,5 @@
"cypress-plugin",
"cypress-preprocessor",
"webpack"
],
"ciDependents": [
"@cypress/react"
],
"ciJobs": [
"npm-webpack-preprocessor"
]
}
-143
View File
@@ -1,143 +0,0 @@
/* eslint-disable no-console */
const execa = require('execa')
const fs = require('fs')
const path = require('path')
// lists all packages that have changed from develop
// and all packages that depend on those
// some files that are intimately related to the binary exist outside of lerna packages
// so we want to make sure they're considered to be part of the binary
const containsBinaryOutsideLerna = (changedFiles) => {
const binaryFiles = [
'.node-version',
'circle.yml',
'electron-builder.json',
'package.json',
'yarn.lock',
]
return !!changedFiles.find((f) => f.includes('scripts/') || binaryFiles.includes(f))
}
// merges `cypress` and all binary packages prefixed with `@packages/`
// into a single `cypress` output
const convertPackagesToBinary = (packages) => {
let output = [...packages]
let includeBinary = false
output = output.filter((name) => {
const packageInBinary = name === 'cypress' || name.includes('@packages')
includeBinary = includeBinary || packageInBinary
return !packageInBinary
})
if (includeBinary) {
output.unshift('cypress')
}
return output
}
const getLernaPackages = async () => {
const { stdout } = await execa('npx', ['lerna', 'la', '--json'])
return JSON.parse(stdout)
}
// gets all files that have changed since the current branch diverged from some base branch
const getChangedFiles = async (base = 'origin/develop', output = false) => {
const { stdout: diff } = await execa('git', ['merge-base', base, 'HEAD'])
const { stdout: filesChanged } = await execa('git', ['diff', '--name-only', diff])
if (output) {
console.log(`Comparing against ${diff}`)
console.log(`Found the following changed files:`)
console.log(filesChanged)
}
return filesChanged.split('\n')
}
const getChangedPackages = async (base = 'origin/develop', output = false) => {
const { stdout: root } = await execa('git', ['rev-parse', '--show-toplevel'])
const packages = await getLernaPackages()
const files = await getChangedFiles(base, output)
// checks if a lerna package is changed
const isChanged = ({ location }) => {
const dir = path.relative(root, location)
return !!files.find((f) => f.includes(dir))
}
let changed = packages.filter(isChanged).map((p) => p.name)
changed = convertPackagesToBinary(changed)
if (!changed.includes('cypress') && containsBinaryOutsideLerna(files)) {
changed.unshift('cypress')
}
if (output) {
console.log()
console.log(`The following packages were changed:`)
console.log(changed.join('\n'))
}
return changed
}
// finds dependents as defined in the `ciDependents` field
// within the package.json of the package - see CONTRIBUTING.md for docs
const getPackageDependents = async (name) => {
const packages = await getLernaPackages()
const pack = packages.find((p) => p.name === name)
if (!pack) {
throw new Error('Could not find that package!')
}
const packageJson = JSON.parse(fs.readFileSync(path.join(pack.location, 'package.json')))
return packageJson['ciDependents'] || []
}
// gets all of the changed packages and their corresponding dependents
const getChangedPackagesAndDependents = async (base = 'origin/develop', output = false) => {
const changedPackages = await getChangedPackages(base, output)
const dependents = {}
for (const pack of changedPackages) {
dependents[pack] = await getPackageDependents(pack)
}
if (output) {
console.log()
console.log(`Changed packages and their dependents:`)
for (const pack in dependents) {
console.log(`${pack}: ${dependents[pack].join(', ') || 'none'}`)
}
}
return dependents
}
// execute main function if called from command line
if (require.main === module) {
const argv = require('minimist')(process.argv.slice(2))
const base = argv._[0]
getChangedPackagesAndDependents(base, true)
}
module.exports = {
getLernaPackages,
getChangedPackages,
getPackageDependents,
getChangedPackagesAndDependents,
}
-68
View File
@@ -1,68 +0,0 @@
/* eslint-disable no-console */
const { execSync } = require('child_process')
const { getCurrentBranch, readPackageJson } = require('./utils')
const { getChangedPackagesAndDependents, getLernaPackages } = require('./changed-packages')
const skipTests = () => {
execSync('circleci-agent step halt')
}
const main = async (ciJob) => {
if (!ciJob) {
console.log(`Could not get current CI job`)
process.exit(1)
}
const currentBranch = await getCurrentBranch()
if (currentBranch === 'develop' || currentBranch === 'master') {
console.log(`Currently on ${currentBranch} - all tests run`)
return
}
const packages = await getLernaPackages()
const changed = await getChangedPackagesAndDependents()
const packageInfo = packages
.filter((pack) => !pack.private && !pack.name.includes('@packages'))
.find((p) => {
const packageJson = readPackageJson(p)
return packageJson.ciJobs && packageJson.ciJobs.includes(ciJob)
})
// default to binary if we don't find an independent package
const pack = packageInfo ? packageInfo.name : 'cypress'
console.log(`Found package ${pack} that corresponds to current job ${ciJob}.`)
if (Object.keys(changed).includes(pack)) {
console.log(`${pack} was directly changed, so tests run.`)
return
}
const dependenciesChanged = []
for (const c in changed) {
if (changed[c].includes(pack)) {
dependenciesChanged.push(c)
}
}
if (dependenciesChanged.length) {
console.log(`${pack} is listed as a dependant of ${dependenciesChanged.join(', ')}, so tests run.`)
return
}
console.log(`${pack} is unchanged and not dependent on any changed packages, so tests do not run.`)
return skipTests()
}
main(process.env.CIRCLE_JOB).catch(() => {
process.exit(1)
})
+7 -33
View File
@@ -8,9 +8,7 @@ const fs = require('fs')
const path = require('path')
const semverSortNewestFirst = require('semver/functions/rcompare')
const { getCurrentBranch, getPackagePath, readPackageJson, minutes, independentTagRegex } = require('./utils')
const { getLernaPackages, getPackageDependents } = require('./changed-packages')
const { waitForJobToPass } = require('./wait-on-circle-jobs')
const { getCurrentBranch, getPackagePath, readPackageJson, independentTagRegex } = require('./utils')
const error = (message) => {
if (require.main === module) {
@@ -136,34 +134,6 @@ const injectVersions = (packagesToRelease, versions, packages) => {
}
}
// we want to wait on all tests to pass for the packages that we want to release
// even if they aren't related to a specific package
// since releasing some but not all could break the package numbers we injected
// failing/passing all also ensures that stuff doesn't get out of sync if the job is rerun
const waitOnTests = async (names, packageInfo) => {
const packages = names.concat(...await Promise.all(names.map(getPackageDependents)))
const jobs = [...new Set([].concat(...packages.map((name) => {
const pkg = packageInfo.find((p) => p.name === name)
return readPackageJson(pkg).ciJobs || []
})))]
console.log(`\nWaiting on the following CI jobs: ${jobs.join(', ')}`)
return Promise.all(jobs.map((job) => {
return waitForJobToPass(job)
.timeout(minutes(60))
.then(() => {
console.log(`${job} passed`)
}).catch(() => {
error(`${job} failed - cannot release`)
})
})).then(() => {
console.log(`\nAll CI jobs passed`)
})
}
const releasePackages = async (packages) => {
console.log(`\nReleasing packages`)
@@ -181,6 +151,12 @@ const releasePackages = async (packages) => {
console.log(`\nAll packages released successfully`)
}
const getLernaPackages = async () => {
const { stdout } = await execa('npx', ['lerna', 'la', '--json'])
return JSON.parse(stdout)
}
// goes through the release process for all of our independent npm projects
const main = async () => {
// in case no NPM_TOKEN is provided (running a simulation locally),
@@ -215,8 +191,6 @@ const main = async () => {
return console.log(`Release process cannot be run on a PR`)
}
await waitOnTests(packagesToRelease, packages)
await releasePackages(packagesToRelease)
console.log(`\n\nRelease process completed successfully!`)