diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..6efbb96e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.git +dist +docs +node_modules diff --git a/ci/Dockerfile b/ci/Dockerfile new file mode 100644 index 00000000..01068c5c --- /dev/null +++ b/ci/Dockerfile @@ -0,0 +1,63 @@ +FROM node:10-alpine AS builder +LABEL maintainer="p.nyari@gentics.com" +ARG BUILD_USER="jenkins" +# Installs latest Chromium package +RUN echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories \ + && echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories \ + && apk add --no-cache \ + chromium@edge \ + harfbuzz@edge \ + nss@edge \ + freetype@edge \ + ttf-freefont@edge \ + git \ + && rm -rf /var/cache/* \ + && mkdir /var/cache/apk +ENV CHROME_BIN /usr/bin/chromium-browser +ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true +RUN adduser -D -u 10000 -h /ci ${BUILD_USER} +RUN chown ${BUILD_USER}: /ci -R +USER ${BUILD_USER} +WORKDIR /ci +LABEL stage=builder + +# Setup dependencies +FROM builder as dependencies +COPY package.json package-lock.json ./ +RUN npm set progress=false \ + && npm config set depth 0 +RUN npm ci +COPY --chown=10000 . . +ARG CACHEBUST=1 +RUN echo "Rebuild from here (unique number: $CACHEBUST)" +LABEL stage=buildenv + +# Run unit tests +FROM dependencies AS test +ARG linting=false +ARG testing=false +RUN [ "$linting" != true ] || npm run lint +RUN [ "$testing" != true ] || npm run test -- --watch=false --browsers=ChromeHeadlessCI --reporters=junit +LABEL stage=test + +# Build application +FROM dependencies AS build +RUN npm run build -- --progress=false +LABEL stage=build + +# Release to NPM +FROM dependencies AS release +ARG releaseProjectName='gentics-ui-core' +ARG release=false +ARG releaseNext=false +ARG releaseVersion='' +RUN sh ci/release.sh +LABEL stage=release + +# Publish Docs on Github Pages +FROM dependencies AS docs +ARG GIT_BRANCH='' +ARG publishDocs=false +ARG docsVersion='' +RUN sh ci/publishDocs.sh +LABEL stage=docs \ No newline at end of file diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile new file mode 100644 index 00000000..9bd7b61e --- /dev/null +++ b/ci/Jenkinsfile @@ -0,0 +1,139 @@ +// The GIT repository for this pipeline lib is defined in the global Jenkins setting +@Library('jenkins-pipeline-library') +import com.gentics.* + +// Make the helpers aware of this jobs environment +JobContext.set(this) + +pipeline { + agent { + kubernetes { + label env.BUILD_TAG + defaultContainer 'build' + yaml """ +apiVersion: v1 +kind: Pod +spec: + nodeSelector: + jenkins_worker: true + volumes: + - name: cache + hostPath: + path: /opt/kubernetes/cache + containers: + - name: build + image: docker:18 + imagePullPolicy: Always + command: + - cat + tty: true + resources: + requests: + cpu: 2 + memory: 4Gi + env: + - name: DOCKER_HOST + value: tcp://127.0.0.1:2375 + volumeMounts: + - mountPath: /root/.npm/_cacache + name: cache + subPath: npm/_cacache + - name: docker + image: docker:18-dind + imagePullPolicy: Always + args: + - '--storage-driver=overlay2' + securityContext: + privileged: true + tty: true + imagePullSecrets: + - name: docker-jenkinsbuilds-apa-it +""" + } + } + + environment { + VERSION_CONSTRAINT = /^((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/ + } + + options { + gitLabConnection('git.gentics.com') + gitlabBuilds(builds: ['Jenkins build']) + timestamps() + timeout(time: 1, unit: 'HOURS') + ansiColor('xterm') + } + + parameters { + booleanParam(name: 'linting', defaultValue: false, description: 'Whether to run linting') + booleanParam(name: 'testing', defaultValue: true, description: 'Whether to run unit tests') + string(name: 'releaseVersion', defaultValue: '', description: 'Version must comply with semver, a tag will be created, cannot be the same as in package.json') + booleanParam(name: 'release', defaultValue: false, description: "Whether to run the release steps") + booleanParam(name: 'releaseNext', defaultValue: false, description: "Whether release as an upcoming version") + booleanParam(name: 'publishDocs', defaultValue: false, description: 'Build docs app and uploads to Github Pages') + string(name: 'docsVersion', defaultValue: '', description: 'If empty, its auto-detected, otherwise version of the maintenance documentation') + } + + stages { + stage('Clone Github Pages') { + when { + beforeAgent true + expression { + return params.publishDocs + } + } + + steps { + dir('docs') { + git branch: 'gh-pages', + credentialsId: 'git', + url: env.GIT_URL + } + } + } + + stage('Docker build') { + when { + beforeAgent true + expression { + isValidVersion = params.releaseVersion.trim() =~ env.VERSION_CONSTRAINT || params.releaseVersion == '' + return isValidVersion + } + } + + steps { + sh """docker build -f ci/Dockerfile \ + --build-arg linting=${params.linting} \ + --build-arg testing=${params.testing} \ + --build-arg release=${params.release} \ + --build-arg releaseNext=${params.releaseNext} \ + --build-arg releaseVersion=${params.releaseVersion} \ + --build-arg publishDocs=${params.publishDocs} \ + --build-arg docsVersion=${params.docsVersion} \ + --build-arg GIT_BRANCH=${env.GIT_BRANCH} \ + --build-arg CACHEBUST=\$(date +%s) \ + . + """ + } + } + + stage('Publish Docs to Github Pages') { + when { + expression { + return params.publishDocs + } + } + + steps { + echo "Now it should publish..." + } + } + } + + post { + always { + //updateGitlabCommitCurrentBuildStatus name: 'Jenkins build' + notifyMattermostUsers() + } + } +} diff --git a/ci/publishDocs.sh b/ci/publishDocs.sh new file mode 100644 index 00000000..85912fbc --- /dev/null +++ b/ci/publishDocs.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# This should be before set -o errexit! +MAINTPREFIX="maintenance-v[0-9][\.x0-9]+" +isMaintenanceBranch=$(echo "$GIT_BRANCH" | grep -Eq "$MAINTPREFIX"; echo $?) + +set -o errexit +set -o nounset + + +if [ "$publishDocs" == true ] +then + PARAMS="" + + if [ -z "$docsVersion" ] && [ ! -z "$GIT_BRANCH" ] && [ $isMaintenanceBranch -eq 0 ] + then + docsVersion=$(echo "$GIT_BRANCH" | cut -d '-' -f 2) + fi + + if [ ! -z "$docsVersion" ] + then + PARAMS="$PARAMS --docsVersion=${docsVersion}" + fi + + echo "Will publishes docs part... (PARAMS: $PARAMS)" +fi \ No newline at end of file diff --git a/ci/release.sh b/ci/release.sh new file mode 100644 index 00000000..312f0422 --- /dev/null +++ b/ci/release.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -o errexit +set -o nounset +WORKDIR="$PWD" + +if [ "$release" == true ] +then + if [ ! -z "$releaseVersion" ] + then + cd "/ci/projects/$releaseProjectName/" + npm version "$releaseVersion" + cd "$WORKDIR" + fi + + npm run build -- "$releaseProjectName" + + if [ "$releaseNext" == true ] + then + npm publish --dry-run --tag next "/ci/dist/$releaseProjectName" + else + npm publish --dry-run "/ci/dist/$releaseProjectName" + fi +fi diff --git a/package-lock.json b/package-lock.json index 657a3c8a..56227070 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4392,7 +4392,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4413,12 +4414,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4433,17 +4436,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4560,7 +4566,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4572,6 +4579,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4586,6 +4594,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4593,12 +4602,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4617,6 +4628,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4697,7 +4709,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4709,6 +4722,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4794,7 +4808,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4830,6 +4845,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4849,6 +4865,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4892,12 +4909,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/projects/docs/karma.conf.js b/projects/docs/karma.conf.js index c57e8065..dddfaa1f 100644 --- a/projects/docs/karma.conf.js +++ b/projects/docs/karma.conf.js @@ -20,6 +20,17 @@ module.exports = function (config) { reports: ['html', 'lcovonly', 'text-summary'], fixWebpackSourcePaths: true }, + customLaunchers: { + ChromeHeadlessCI: { + base: 'Chrome', + flags: [ + '--headless', + '--disable-gpu', + '--no-sandbox', + '--remote-debugging-port=9222' + ], + } + }, reporters: ['progress', 'kjhtml'], port: 9876, colors: true, diff --git a/projects/gentics-ui-core/karma.conf.js b/projects/gentics-ui-core/karma.conf.js index 4c5f8d03..682c0a14 100644 --- a/projects/gentics-ui-core/karma.conf.js +++ b/projects/gentics-ui-core/karma.conf.js @@ -20,6 +20,17 @@ module.exports = function (config) { reports: ['html', 'lcovonly'], fixWebpackSourcePaths: true }, + customLaunchers: { + ChromeHeadlessCI: { + base: 'Chrome', + flags: [ + '--headless', + '--disable-gpu', + '--no-sandbox', + '--remote-debugging-port=9222' + ], + } + }, reporters: ['progress', 'kjhtml'], port: 9876, colors: true,