Skip to content

Commit

Permalink
[APM-CI] Pipeline for OpBeans Node (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
v1v authored Jun 10, 2019
1 parent 4eb7abd commit bedd92b
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 0 deletions.
128 changes: 128 additions & 0 deletions .ci/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env groovy
@Library('apm@current') _

pipeline {
agent { label 'linux && immutable' }
environment {
BASE_DIR = 'src/github.com/elastic/opbeans-node'
NOTIFY_TO = credentials('notify-to')
JOB_GCS_BUCKET = credentials('gcs-bucket')
JOB_GCS_CREDENTIALS = 'apm-ci-gcs-plugin'
DOCKERHUB_SECRET = 'secret/apm-team/ci/elastic-observability-dockerhub'
PIPELINE_LOG_LEVEL = 'INFO'
}
options {
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20', daysToKeepStr: '30'))
timestamps()
ansiColor('xterm')
disableResume()
durabilityHint('PERFORMANCE_OPTIMIZED')
rateLimitBuilds(throttle: [count: 60, durationName: 'hour', userBoost: true])
quietPeriod(10)
}
parameters {
booleanParam(name: 'Run_As_Master_Branch', defaultValue: false, description: 'Allow to run any steps on a PR, some steps normally only run on master branch.')
}
triggers {
issueCommentTrigger('(?i).*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
}
stages {
stage('Initializing'){
agent { label 'linux && immutable' }
options { skipDefaultCheckout() }
environment {
PATH = "${env.PATH}:${env.WORKSPACE}/bin"
HOME = "${env.WORKSPACE}"
}
stages {
/**
Checkout the code and stash it, to use it on other stages.
*/
stage('Checkout') {
steps {
deleteDir()
gitCheckout(basedir: "${BASE_DIR}")
stash allowEmpty: true, name: 'source', useDefaultExcludes: false
}
}
/**
Build the project from code..
*/
stage('Build') {
steps {
deleteDir()
unstash 'source'
dir("${BASE_DIR}"){
sh 'make build'
}
}
}
/**
Execute unit tests.
*/
stage('Test') {
steps {
deleteDir()
unstash 'source'
dir("${BASE_DIR}"){
sh "make test"
}
}
post {
always {
junit(allowEmptyResults: true,
keepLongStdio: true,
testResults: "${BASE_DIR}/**/junit-*.xml")
}
}
}
stage('Release') {
input {
message 'Should we release a new version?'
ok 'Yes, we should.'
parameters {
string(name: 'VERSION', defaultValue: 'latest', description: 'What tag?')
}
}
when {
beforeInput true
beforeAgent true
allOf {
anyOf {
branch 'master'
branch "\\d+\\.\\d+"
branch "v\\d?"
tag "v\\d+\\.\\d+\\.\\d+*"
expression { return params.Run_As_Master_Branch }
}
}
}
steps {
deleteDir()
unstash 'source'
dir("${BASE_DIR}"){
dockerLogin(secret: "${DOCKERHUB_SECRET}", registry: 'docker.io')
sh "VERSION=${VERSION} make publish"
}
}
}
}
}
}
post {
success {
echoColor(text: '[SUCCESS]', colorfg: 'green', colorbg: 'default')
}
aborted {
echoColor(text: '[ABORTED]', colorfg: 'magenta', colorbg: 'default')
}
failure {
echoColor(text: '[FAILURE]', colorfg: 'red', colorbg: 'default')
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: "${NOTIFY_TO}", sendToIndividuals: false])
}
unstable {
echoColor(text: '[UNSTABLE]', colorfg: 'yellow', colorbg: 'default')
}
}
}
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
Dockerfile
client
Makefile
tests
bats
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.env*
node_modules
client

# For the BATS testing
bats/
target/
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "tests/test_helper/bats-support"]
path = tests/test_helper/bats-support
url = https://github.com/ztombol/bats-support
[submodule "tests/test_helper/bats-assert"]
path = tests/test_helper/bats-assert
url = https://github.com/ztombol/bats-assert
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
PORT ?= 3000
VERSION ?= latest
LTS_ALPINE ?= 12-alpine

.DEFAULT_GOAL := help

help: ## Display this help text
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

all: build test

build: ## Build docker image
@docker build --file Dockerfile --tag=opbeans/opbeans-node:${VERSION} .

bats: ## Install bats in the project itself
@git clone https://github.com/sstephenson/bats.git

prepare-test: bats ## Prepare the bats dependencies
@docker pull node:${LTS_ALPINE}
@mkdir -p target
@git submodule sync
@git submodule update --init --recursive

test: prepare-test ## Run the tests
@echo "Tests are in progress, please be patient"
@PORT=${PORT} bats/bin/bats --tap tests | tee target/results.tap
@docker run --rm -v "${PWD}":/usr/src/app -w /usr/src/app node:${LTS_ALPINE} \
sh -c "npm install tap-xunit -g && cat target/results.tap | tap-xunit --package='co.elastic.opbeans' > target/junit-results.xml"

publish: build ## Publish docker image
@docker push opbeans/opbeans-node:${VERSION}

clean: ## Clean autogenerated files/folders
@rm -rf bats
@rm -rf target
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Build Status](https://apm-ci.elastic.co/job/apm-agent-nodejs/job/opbeans-node-mbp/job/master/badge/icon)](https://apm-ci.elastic.co/job/apm-agent-nodejs/job/opbeans-node-mbp/job/master/)

# Opbeans for Node.js

The Opbeans inventory management system is a demo app created and
Expand Down Expand Up @@ -89,6 +91,26 @@ opbeans-frontend, just run:
npm run client-update
```

## Testing locally

The simplest way to test this demo is by running:

```bash
make test
```

Tests are written using [bats](https://github.com/sstephenson/bats) under the tests dir

## Publishing to dockerhub locally

Publish the docker image with

```bash
VERSION=1.2.3 make publish
```

NOTE: VERSION refers to the tag for the docker image which will be published in the registry

## Demo notes

### Trigger error
Expand Down
145 changes: 145 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
version: "2.1"
services:
opbeans-node:
build: .
image: opbeans/opbeans-node:latest
ports:
- "127.0.0.1:${OPBEANS_NODE_PORT:-8000}:3000"
container_name: opbeans-node
logging:
driver: 'json-file'
options:
max-size: '2m'
max-file: '5'
environment:
- ELASTIC_APM_SERVER_URL=${ELASTIC_APM_SERVER_URL:-http://apm-server:8200}
- ELASTIC_APM_JS_BASE_SERVER_URL=${ELASTIC_APM_JS_BASE_SERVER_URL:-http://localhost:8200}
- PGHOST=postgres
- PGUSER=postgres
- PGPASSWORD=hunter2
- PGDATABASE=opbeans
- REDIS_URL=redis://redis:6379
depends_on:
redis:
condition: service_healthy
elasticsearch:
condition: service_healthy
apm-server:
condition: service_healthy
postgres:
condition: service_started

apm-server:
image: docker.elastic.co/apm/apm-server:${STACK_VERSION:-6.5.1}
ports:
- "127.0.0.1:${APM_SERVER_PORT:-8200}:8200"
- "127.0.0.1:${APM_SERVER_MONITOR_PORT:-6060}:6060"
command: >
apm-server -e
-E apm-server.frontend.enabled=true
-E apm-server.frontend.rate_limit=100000
-E apm-server.host=0.0.0.0:8200
-E apm-server.read_timeout=1m
-E apm-server.shutdown_timeout=2m
-E apm-server.write_timeout=1m
-E setup.kibana.host=kibana:5601
-E setup.template.settings.index.number_of_replicas=0
-E xpack.monitoring.elasticsearch=true
-E output.elasticsearch.enabled=${APM_SERVER_ELASTICSEARCH_OUTPUT_ENABLED:-true}
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- SETGID
- SETUID
logging:
driver: 'json-file'
options:
max-size: '2m'
max-file: '5'
depends_on:
elasticsearch:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "--write-out", "'HTTP %{http_code}'", "--silent", "--output", "/dev/null", "http://apm-server:8200/healthcheck"]
retries: 10
interval: 10s

elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION:-6.5.1}
environment:
- cluster.name=docker-cluster
- xpack.security.enabled=false
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
- "path.data=/usr/share/elasticsearch/data/${STACK_VERSION:-6.5.1}"
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: 5g
logging:
driver: 'json-file'
options:
max-size: '2m'
max-file: '5'
ports:
- "127.0.0.1:${ELASTICSEARCH_PORT:-9200}:9200"
healthcheck:
test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -vq '\"status\":\"red\"'"]
retries: 10
interval: 20s
volumes:
- esdata:/usr/share/elasticsearch/data

kibana:
image: docker.elastic.co/kibana/kibana:${STACK_VERSION:-6.5.1}
environment:
SERVER_NAME: kibana.example.org
ELASTICSEARCH_URL: http://elasticsearch:9200
ports:
- "127.0.0.1:${KIBANA_PORT:-5601}:5601"
logging:
driver: 'json-file'
options:
max-size: '2m'
max-file: '5'
healthcheck:
test: ["CMD", "curl", "--write-out", "'HTTP %{http_code}'", "--silent", "--output", "/dev/null", "http://kibana:5601/"]
retries: 10
interval: 10s
depends_on:
elasticsearch:
condition: service_healthy

redis:
image: redis:4
ports:
- "127.0.0.1:6379:6379"
logging:
driver: 'json-file'
options:
max-size: '2m'
max-file: '5'
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s

postgres:
image: postgres:latest
environment:
- POSTGRES_PASSWORD=hunter2
- POSTGRES_DB=opbeans
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "127.0.0.1:5432:5432"

volumes:
esdata:
driver: local
opbeansdb:
driver: local
pgdata:
driver: local
1 change: 1 addition & 0 deletions tests/test_helper/bats-assert
Submodule bats-assert added at 9f88b4
1 change: 1 addition & 0 deletions tests/test_helper/bats-support
Submodule bats-support added at 004e70
7 changes: 7 additions & 0 deletions tests/test_helpers.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bats

# check dependencies
(
type docker &>/dev/null || ( echo "docker is not available"; exit 1 )
type curl &>/dev/null || ( echo "curl is not available"; exit 1 )
)>&2
Loading

0 comments on commit bedd92b

Please sign in to comment.