Add linting steps and improve testing steps

This commit is contained in:
Asher 2020-02-04 15:00:44 -06:00
parent b29346ecdf
commit b30aefcfb1
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A
7 changed files with 175 additions and 87 deletions

View File

@ -6,22 +6,30 @@ platform:
arch: amd64 arch: amd64
steps: steps:
- name: submodules
image: alpine/git
commands:
- git submodule update --init
- name: cache:restore - name: cache:restore
image: codercom/nbin:centos
commands:
- yum install -y libxkbfile-devel libsecret-devel
- . /opt/rh/devtoolset-6/enable
- ./scripts/cacher.sh
- name: lint
image: node:12 image: node:12
commands: commands:
- ./scripts/cacher.sh - yarn lint
- name: test
image: codercom/nbin:centos
commands:
- yum install -y openssl
- yarn test
- name: build - name: build
image: codercom/nbin:centos image: codercom/nbin:centos
commands: commands:
- yum install -y libxkbfile-devel libsecret-devel - yum install -y libxkbfile-devel libsecret-devel
- . /opt/rh/devtoolset-6/enable - . /opt/rh/devtoolset-6/enable
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12 image: node:12
@ -40,10 +48,10 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12 image: codercom/nbin:centos
commands: commands:
- yarn test - yarn test:build
- name: publish:github - name: publish:github
image: plugins/github-release image: plugins/github-release
@ -90,21 +98,28 @@ platform:
arch: amd64 arch: amd64
steps: steps:
- name: submodules
image: alpine/git
commands:
- git submodule update --init
- name: cache:restore - name: cache:restore
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python
- ./scripts/cacher.sh - ./scripts/cacher.sh
- name: lint
image: node:12-alpine
commands:
- yarn lint
- name: test
image: node:12-alpine
commands:
- apk add openssl
- yarn test
- name: build - name: build
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python - apk add libxkbfile-dev libsecret-dev build-base git bash python
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12-alpine image: node:12-alpine
@ -123,10 +138,10 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12-alpine image: node:12-alpine
commands: commands:
- yarn test - yarn test:build
- name: publish:github - name: publish:github
image: plugins/github-release image: plugins/github-release
@ -159,22 +174,27 @@ platform:
arch: arm64 arch: arm64
steps: steps:
- name: submodules
image: alpine
commands:
- apk add git
- git submodule update --init
- name: cache:restore - name: cache:restore
image: node:12 image: node:12
commands: commands:
- apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev
- ./scripts/cacher.sh - ./scripts/cacher.sh
- name: lint
image: node:12
commands:
- yarn lint
- name: test
image: node:12
commands:
- yarn test
- name: build - name: build
image: node:12 image: node:12
commands: commands:
- apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev - apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12 image: node:12
@ -193,10 +213,10 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12 image: node:12
commands: commands:
- yarn test - yarn test:build
- name: publish:github - name: publish:github
image: plugins/github-release image: plugins/github-release
@ -243,22 +263,28 @@ platform:
arch: arm64 arch: arm64
steps: steps:
- name: submodules
image: alpine
commands:
- apk add git
- git submodule update --init
- name: cache:restore - name: cache:restore
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python
- ./scripts/cacher.sh - ./scripts/cacher.sh
- name: lint
image: node:12-alpine
commands:
- yarn lint
- name: test
image: node:12-alpine
commands:
- apk add openssl
- yarn test
- name: build - name: build
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python - apk add libxkbfile-dev libsecret-dev build-base git bash python
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12-alpine image: node:12-alpine
@ -277,10 +303,10 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12-alpine image: node:12-alpine
commands: commands:
- yarn test - yarn test:build
- name: publish:github - name: publish:github
image: plugins/github-release image: plugins/github-release
@ -313,22 +339,27 @@ platform:
arch: arm arch: arm
steps: steps:
- name: submodules
image: alpine
commands:
- apk add git
- git submodule update --init
- name: cache:restore - name: cache:restore
image: node:12 image: node:12
commands: commands:
- apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev
- ./scripts/cacher.sh - ./scripts/cacher.sh
- name: lint
image: node:12
commands:
- yarn lint
- name: test
image: node:12
commands:
- yarn test
- name: build - name: build
image: node:12 image: node:12
commands: commands:
- apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev - apt update && apt install -y build-essential git libsecret-1-dev libx11-dev libxkbfile-dev
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12 image: node:12
@ -347,11 +378,11 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12 image: node:12
failure: ignore failure: ignore
commands: commands:
- yarn test - yarn test:build
# - name: publish:github # - name: publish:github
# image: plugins/github-release # image: plugins/github-release
@ -388,22 +419,28 @@ platform:
arch: arm arch: arm
steps: steps:
- name: submodules
image: alpine
commands:
- apk add git
- git submodule update --init
- name: cache:restore - name: cache:restore
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python
- ./scripts/cacher.sh - ./scripts/cacher.sh
- name: lint
image: node:12-alpine
commands:
- yarn lint
- name: test
image: node:12-alpine
commands:
- apk add openssl
- yarn test
- name: build - name: build
image: node:12-alpine image: node:12-alpine
commands: commands:
- apk add libxkbfile-dev libsecret-dev build-base git bash python - apk add libxkbfile-dev libsecret-dev build-base git bash python
- timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing so we can preserve cache for the next run' - timeout 50m ./scripts/ci.bash || echo 'Timed out or failed; continuing to preserve cache for the next run'
- name: cache:package - name: cache:package
image: node:12-alpine image: node:12-alpine
@ -422,11 +459,11 @@ steps:
when: when:
event: push event: push
- name: test - name: test:build
image: node:12-alpine image: node:12-alpine
failure: ignore failure: ignore
commands: commands:
- yarn test - yarn test:build
# - name: publish:github # - name: publish:github
# image: plugins/github-release # image: plugins/github-release

View File

@ -9,7 +9,8 @@
"patch:generate": "cd ./lib/vscode && git diff HEAD > ../../scripts/vscode.patch", "patch:generate": "cd ./lib/vscode && git diff HEAD > ../../scripts/vscode.patch",
"patch:apply": "cd ./lib/vscode && git apply ../../scripts/vscode.patch", "patch:apply": "cd ./lib/vscode && git apply ../../scripts/vscode.patch",
"test": "mocha -r ts-node/register ./test/*.test.ts", "test": "mocha -r ts-node/register ./test/*.test.ts",
"lint:js": "eslint {src,test,scripts} --ext .ts,.tsx", "test:build": "./scripts/test.sh",
"lint:js": "eslint src test scripts --ext .ts,.tsx",
"lint:css": "stylelint 'src/**/*.css'", "lint:css": "stylelint 'src/**/*.css'",
"lint": "./scripts/lint.sh", "lint": "./scripts/lint.sh",
"watch": "yarn runner watch", "watch": "yarn runner watch",

View File

@ -46,7 +46,18 @@ main() {
# The action is determined by the name of the step. # The action is determined by the name of the step.
case $DRONE_STEP_NAME in case $DRONE_STEP_NAME in
*restore*) restore "$branch" "$DRONE_REPO_BRANCH" ;; *restore*)
# Sub-modules must be pulled first since extracting the cache directories
# will prevent git from cloning into them.
git submodule update --init
restore "$branch" "$DRONE_REPO_BRANCH"
# Now make sure the pulled Node modules are up to date.
YARN_CACHE_FOLDER="$(pwd)/yarn-cache"
export YARN_CACHE_FOLDER
yarn
;;
*rebuild*|*package*) package "$branch" ;; *rebuild*|*package*) package "$branch" ;;
*) exit 1 ;; *) exit 1 ;;
esac esac

View File

@ -3,6 +3,7 @@
set -euo pipefail set -euo pipefail
# This script assumes that yarn has already ran.
function main() { function main() {
cd "$(dirname "${0}")/.." cd "$(dirname "${0}")/.."
@ -21,10 +22,6 @@ function main() {
export PACKAGE="true" export PACKAGE="true"
fi fi
if [[ -z ${SKIP_YARN:-} ]] ; then
yarn
fi
yarn build yarn build
yarn binary yarn binary
if [[ -n ${PACKAGE:-} ]] ; then if [[ -n ${PACKAGE:-} ]] ; then

19
scripts/test.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env sh
# test.sh -- Simple build test.
set -eu
main() {
cd "$(dirname "$0")/.."
# The main goal here is to ensure that the build fully completed and the
# result looks usable.
version=$(node ./build/out/node/entry.js --version --json)
echo "Got '$version' for the version"
case $version in
"{ codeServer":*) exit 0 ;;
*) exit 1 ;;
esac
}
main "$@"

View File

@ -49,7 +49,7 @@ const main = async (args: Args = {}): Promise<void> => {
new VscodeHttpProvider([], { base: "/vscode-embed", auth, password }) new VscodeHttpProvider([], { base: "/vscode-embed", auth, password })
) )
ipcMain.onDispose(() => httpServer.dispose()) ipcMain().onDispose(() => httpServer.dispose())
const serverAddress = await httpServer.listen() const serverAddress = await httpServer.listen()
logger.info(`Server listening on ${serverAddress}`) logger.info(`Server listening on ${serverAddress}`)
@ -84,4 +84,18 @@ const main = async (args: Args = {}): Promise<void> => {
} }
} }
wrap(main) // TODO: Implement CLI parser.
if (process.argv.includes("--version")) {
const version = require("../../package.json").version
if (process.argv.includes("--json")) {
console.log({
codeServer: version,
vscode: require("../../lib/vscode/package.json").version,
})
} else {
console.log(version)
}
process.exit(0)
} else {
wrap(main)
}

View File

@ -21,14 +21,6 @@ export class ProcessError extends Error {
} }
} }
/**
* Ensure we control when the process exits.
*/
const exit = process.exit
process.exit = function(code?: number) {
logger.warn(`process.exit() was prevented: ${code || "unknown code"}.`)
} as (code?: number) => never
/** /**
* Allows the wrapper and inner processes to communicate. * Allows the wrapper and inner processes to communicate.
*/ */
@ -37,19 +29,26 @@ export class IpcMain {
public readonly onMessage = this._onMessage.event public readonly onMessage = this._onMessage.event
private readonly _onDispose = new Emitter<NodeJS.Signals | undefined>() private readonly _onDispose = new Emitter<NodeJS.Signals | undefined>()
public readonly onDispose = this._onDispose.event public readonly onDispose = this._onDispose.event
public readonly exit: (code?: number) => never
public constructor(public readonly parentPid?: number) { public constructor(public readonly parentPid?: number) {
process.on("SIGINT", () => this._onDispose.emit("SIGINT")) process.on("SIGINT", () => this._onDispose.emit("SIGINT"))
process.on("SIGTERM", () => this._onDispose.emit("SIGTERM")) process.on("SIGTERM", () => this._onDispose.emit("SIGTERM"))
process.on("exit", () => this._onDispose.emit(undefined)) process.on("exit", () => this._onDispose.emit(undefined))
// Ensure we control when the process exits.
this.exit = process.exit
process.exit = function(code?: number) {
logger.warn(`process.exit() was prevented: ${code || "unknown code"}.`)
} as (code?: number) => never
this.onDispose((signal) => { this.onDispose((signal) => {
// Remove listeners to avoid possibly triggering disposal again. // Remove listeners to avoid possibly triggering disposal again.
process.removeAllListeners() process.removeAllListeners()
// Let any other handlers run first then exit. // Let any other handlers run first then exit.
logger.debug(`${parentPid ? "inner process" : "wrapper"} ${process.pid} disposing`, field("code", signal)) logger.debug(`${parentPid ? "inner process" : "wrapper"} ${process.pid} disposing`, field("code", signal))
setTimeout(() => exit(0), 0) setTimeout(() => this.exit(0), 0)
}) })
// Kill the inner process if the parent dies. This is for the case where the // Kill the inner process if the parent dies. This is for the case where the
@ -117,9 +116,17 @@ export class IpcMain {
} }
} }
export const ipcMain = new IpcMain( let _ipcMain: IpcMain
typeof process.env.CODE_SERVER_PARENT_PID !== "undefined" ? parseInt(process.env.CODE_SERVER_PARENT_PID) : undefined export const ipcMain = (): IpcMain => {
) if (!_ipcMain) {
_ipcMain = new IpcMain(
typeof process.env.CODE_SERVER_PARENT_PID !== "undefined"
? parseInt(process.env.CODE_SERVER_PARENT_PID)
: undefined
)
}
return _ipcMain
}
export interface WrapperOptions { export interface WrapperOptions {
maxMemory?: number maxMemory?: number
@ -135,14 +142,14 @@ export class WrapperProcess {
private started?: Promise<void> private started?: Promise<void>
public constructor(private currentVersion: string, private readonly options?: WrapperOptions) { public constructor(private currentVersion: string, private readonly options?: WrapperOptions) {
ipcMain.onDispose(() => { ipcMain().onDispose(() => {
if (this.process) { if (this.process) {
this.process.removeAllListeners() this.process.removeAllListeners()
this.process.kill() this.process.kill()
} }
}) })
ipcMain.onMessage(async (message) => { ipcMain().onMessage(async (message) => {
switch (message.type) { switch (message.type) {
case "relaunch": case "relaunch":
logger.info(`Relaunching: ${this.currentVersion} -> ${message.version}`) logger.info(`Relaunching: ${this.currentVersion} -> ${message.version}`)
@ -156,7 +163,7 @@ export class WrapperProcess {
await this.start() await this.start()
} catch (error) { } catch (error) {
logger.error(error.message) logger.error(error.message)
exit(typeof error.code === "number" ? error.code : 1) ipcMain().exit(typeof error.code === "number" ? error.code : 1)
} }
break break
default: default:
@ -170,10 +177,12 @@ export class WrapperProcess {
if (!this.started) { if (!this.started) {
const child = this.spawn() const child = this.spawn()
logger.debug(`spawned inner process ${child.pid}`) logger.debug(`spawned inner process ${child.pid}`)
this.started = ipcMain.handshake(child).then(() => { this.started = ipcMain()
.handshake(child)
.then(() => {
child.once("exit", (code) => { child.once("exit", (code) => {
logger.debug(`inner process ${child.pid} exited unexpectedly`) logger.debug(`inner process ${child.pid} exited unexpectedly`)
exit(code || 0) ipcMain().exit(code || 0)
}) })
}) })
this.process = child this.process = child
@ -201,23 +210,23 @@ export class WrapperProcess {
// // It's possible that the pipe has closed (for example if you run code-server // // It's possible that the pipe has closed (for example if you run code-server
// // --version | head -1). Assume that means we're done. // // --version | head -1). Assume that means we're done.
if (!process.stdout.isTTY) { if (!process.stdout.isTTY) {
process.stdout.on("error", () => exit()) process.stdout.on("error", () => ipcMain().exit())
} }
export const wrap = (fn: () => Promise<void>): void => { export const wrap = (fn: () => Promise<void>): void => {
if (ipcMain.parentPid) { if (ipcMain().parentPid) {
ipcMain ipcMain()
.handshake() .handshake()
.then(() => fn()) .then(() => fn())
.catch((error: ProcessError): void => { .catch((error: ProcessError): void => {
logger.error(error.message) logger.error(error.message)
exit(typeof error.code === "number" ? error.code : 1) ipcMain().exit(typeof error.code === "number" ? error.code : 1)
}) })
} else { } else {
const wrapper = new WrapperProcess(require("../../package.json").version) const wrapper = new WrapperProcess(require("../../package.json").version)
wrapper.start().catch((error) => { wrapper.start().catch((error) => {
logger.error(error.message) logger.error(error.message)
exit(typeof error.code === "number" ? error.code : 1) ipcMain().exit(typeof error.code === "number" ? error.code : 1)
}) })
} }
} }