Skip to content
This repository has been archived by the owner on May 29, 2023. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alecghica committed Jun 22, 2022
0 parents commit 7e0d92c
Show file tree
Hide file tree
Showing 16 changed files with 874 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cypress
locales/*.json
node_modules
omelette
npm-cache
docker-compose.yml
Dockerfile
Jenkinsfile
src/addons
.git
.env
*.log
28 changes: 28 additions & 0 deletions Dockerfile.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM node:16-slim

COPY . /opt/frontend/
WORKDIR /opt/frontend/

# Update apt packages
RUN runDeps="openssl ca-certificates patch gosu git tmux locales-all" \
&& apt-get update \
&& apt-get install -y --no-install-recommends $runDeps \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& npm install -g mrs-developer \
&& cp jsconfig.json.prod jsconfig.json \
&& mkdir -p /opt/frontend/src/addons \
&& rm -rf /opt/frontend/src/addons/* \
&& find /opt/frontend -not -user node -exec chown node {} \+

USER node
RUN cd /opt/frontend \
&& RAZZLE_API_PATH=VOLTO_API_PATH RAZZLE_INTERNAL_API_PATH=VOLTO_INTERNAL_API_PATH yarn \
&& RAZZLE_API_PATH=VOLTO_API_PATH RAZZLE_INTERNAL_API_PATH=VOLTO_INTERNAL_API_PATH yarn build \
&& rm -rf /home/node/.cache
USER root

EXPOSE 3000 3001 4000 4001

ENTRYPOINT ["/opt/frontend/entrypoint.sh"]
CMD ["yarn", "start:prod"]
255 changes: 255 additions & 0 deletions Jenkinsfile.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
pipeline {
environment {
RANCHER_STACKID = ""
RANCHER_ENVID = ""
GIT_NAME = "<%= name %>"
registry = "eeacms/<%= name %>"
template = "templates/<%= name %>"
dockerImage = ''
tagName = ''
SONARQUBE_TAG = '<%= name %>.eionet.europa.eu'
}

agent any

stages {
stage('Integration tests') {
parallel {
stage('Run Cypress: @eeacms/volto-*') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
not { branch 'master' }
not { changelog '.*^Automated release [0-9\\.]+$' }
not { buildingTag() }
}
}
steps {
node(label: 'docker') {
script {
try {
sh '''docker pull eeacms/plone-backend; docker run -d --rm --name="$BUILD_TAG-plone-eeacms" -e SITE="Plone" eeacms/plone-backend'''
sh '''docker pull eeacms/volto-project-ci; docker run -i --name="$BUILD_TAG-cypress-eeacms" --link $BUILD_TAG-plone-eeacms:plone -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" eeacms/volto-project-ci --config-file cypress.eeacms.json'''
} finally {
try {
sh '''rm -rf cypress-reports cypress-results'''
sh '''mkdir -p cypress-reports cypress-results'''
sh '''docker cp $BUILD_TAG-cypress-eeacms:/opt/frontend/my-volto-project/cypress/videos cypress-reports/'''
sh '''docker cp $BUILD_TAG-cypress-eeacms:/opt/frontend/my-volto-project/cypress/reports cypress-results/'''
sh '''touch empty_file; for ok_test in $(grep -E 'file=.*failures="0"' $(grep 'testsuites .*failures="0"' $(find cypress-results -name *.xml) empty_file | awk -F: '{print $1}') empty_file | sed 's/.* file="\\(.*\\)" time.*/\\1/' | sed 's#^node_modules/volto-slate/##g' | sed 's#^node_modules/@eeacms/##g'); do rm -f cypress-reports/videos/$ok_test.mp4; rm -f cypress-reports/$ok_test.mp4; done'''
archiveArtifacts artifacts: 'cypress-reports/**/*.mp4', fingerprint: true, allowEmptyArchive: true
}
finally {
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
junit testResults: 'cypress-results/**/*.xml', allowEmptyResults: true
}
sh script: "docker stop $BUILD_TAG-plone-eeacms", returnStatus: true
sh script: "docker rm -v $BUILD_TAG-plone-eeacms", returnStatus: true
sh script: "docker rm -v $BUILD_TAG-cypress-eeacms", returnStatus: true
}
}
}
}
}
}

stage('Run Cypress: volto-slate') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
not { branch 'master' }
not { changelog '.*^Automated release [0-9\\.]+$' }
not { buildingTag() }
}
}
steps {
node(label: 'docker') {
script {
try {
sh '''docker pull eeacms/plone-backend; docker run -d --rm --name="$BUILD_TAG-plone-slate" -e SITE="Plone" eeacms/plone-backend'''
sh '''docker pull eeacms/volto-project-ci; docker run -i --name="$BUILD_TAG-cypress-slate" --link $BUILD_TAG-plone-slate:plone -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" eeacms/volto-project-ci --config-file cypress.slate.json'''
} finally {
try {
sh '''rm -rf cypress-reports cypress-results'''
sh '''mkdir -p cypress-reports cypress-results'''
sh '''docker cp $BUILD_TAG-cypress-slate:/opt/frontend/my-volto-project/cypress/videos cypress-reports/'''
sh '''docker cp $BUILD_TAG-cypress-slate:/opt/frontend/my-volto-project/cypress/reports cypress-results/'''
sh '''touch empty_file; for ok_test in $(grep -E 'file=.*failures="0"' $(grep 'testsuites .*failures="0"' $(find cypress-results -name *.xml) empty_file | awk -F: '{print $1}') empty_file | sed 's/.* file="\\(.*\\)" time.*/\\1/' | sed 's#^node_modules/volto-slate/##g' | sed 's#^node_modules/@eeacms/##g'); do rm -f cypress-reports/videos/$ok_test.mp4; rm -f cypress-reports/$ok_test.mp4; done'''
archiveArtifacts artifacts: 'cypress-reports/**/*.mp4', fingerprint: true, allowEmptyArchive: true
}
finally {
catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') {
junit testResults: 'cypress-results/**/*.xml', allowEmptyResults: true
}
sh script: "docker stop $BUILD_TAG-plone-slate", returnStatus: true
sh script: "docker rm -v $BUILD_TAG-plone-slate", returnStatus: true
sh script: "docker rm -v $BUILD_TAG-cypress-slate", returnStatus: true
}
}
}
}
}
}

stage("Docker test build") {
when {
allOf {
not { changelog '.*^Automated release [0-9\\.]+$' }
not { environment name: 'CHANGE_ID', value: '' }
environment name: 'CHANGE_TARGET', value: 'master'
}
}
environment {
IMAGE_NAME = BUILD_TAG.toLowerCase()
}
steps {
node(label: 'docker-host') {
script {
checkout scm
try {
dockerImage = docker.build("${IMAGE_NAME}", "--no-cache .")
} finally {
sh script: "docker rmi ${IMAGE_NAME}", returnStatus: true
}
}
}
}
}


}
}


stage('Pull Request') {
when {
allOf {
not { environment name: 'CHANGE_ID', value: '' }
environment name: 'CHANGE_TARGET', value: 'master'
not { changelog '.*^Automated release [0-9\\.]+$' }
}
}
steps {
node(label: 'docker') {
script {
if ( env.CHANGE_BRANCH != "develop" && !( env.CHANGE_BRANCH.startsWith("hotfix")) ) {
error "Pipeline aborted due to PR not made from develop or hotfix branch"
}
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
sh '''docker pull eeacms/gitflow'''
sh '''docker run -i --rm --name="$BUILD_TAG-gitflow-pr" -e GIT_CHANGE_TARGET="$CHANGE_TARGET" -e GIT_CHANGE_BRANCH="$CHANGE_BRANCH" -e GIT_CHANGE_AUTHOR="$CHANGE_AUTHOR" -e GIT_CHANGE_TITLE="$CHANGE_TITLE" -e GIT_TOKEN="$GITHUB_TOKEN" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e GIT_ORG="$GIT_ORG" -e GIT_NAME="$GIT_NAME" -e LANGUAGE=javascript eeacms/gitflow'''
}
}
}
}
}


stage('Release') {
when {
allOf {
environment name: 'CHANGE_ID', value: ''
branch 'master'
}
}
steps {
node(label: 'docker') {
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
sh '''docker pull eeacms/gitflow'''
sh '''docker run -i --rm --name="$BUILD_TAG-gitflow-master" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" -e GIT_TOKEN="$GITHUB_TOKEN" -e LANGUAGE=javascript eeacms/gitflow'''
}
}
}
}

stage('Build & Push ( on tag )') {
when {
buildingTag()
}
steps{
node(label: 'docker-host') {
script {
checkout scm
if (env.BRANCH_NAME == 'master') {
tagName = 'latest'
} else {
tagName = "$BRANCH_NAME"
}
try {
dockerImage = docker.build("$registry:$tagName", "--no-cache .")
docker.withRegistry( '', 'eeajenkins' ) {
dockerImage.push()
}
} finally {
sh "docker rmi $registry:$tagName"
}
}
}
}
}

stage('Release catalog ( on tag )') {
when {
buildingTag()
}
steps{
node(label: 'docker') {
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GITHUB_TOKEN')]) {
sh '''docker pull eeacms/gitflow; docker run -i --rm --name="${BUILD_TAG}-release" -e GIT_TOKEN="${GITHUB_TOKEN}" -e RANCHER_CATALOG_PATH="${template}" -e DOCKER_IMAGEVERSION="${BRANCH_NAME}" -e DOCKER_IMAGENAME="${registry}" --entrypoint /add_rancher_catalog_entry.sh eeacms/gitflow'''
}
}
}
}

stage('Upgrade demo ( on tag )') {
when {
buildingTag()
}
steps {
node(label: 'docker') {
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'Rancher_dev_token', usernameVariable: 'RANCHER_ACCESS', passwordVariable: 'RANCHER_SECRET'],string(credentialsId: 'Rancher_dev_url', variable: 'RANCHER_URL')]) {
sh '''wget -O rancher_upgrade.sh https://github.com/raw/eea/eea.docker.gitflow/master/src/rancher_upgrade.sh'''
sh '''chmod 755 rancher_upgrade.sh'''
sh '''./rancher_upgrade.sh'''
}
}
}
}

stage('Update SonarQube Tags') {
when {
not {
environment name: 'SONARQUBE_TAG', value: ''
}
buildingTag()
}
steps{
node(label: 'docker') {
withSonarQubeEnv('Sonarqube') {
withCredentials([string(credentialsId: 'eea-jenkins-token', variable: 'GIT_TOKEN')]) {
sh '''docker pull eeacms/gitflow'''
sh '''docker run -i --rm --name="${BUILD_TAG}-sonar" -e GIT_NAME=${GIT_NAME} -e GIT_TOKEN="${GIT_TOKEN}" -e SONARQUBE_TAG=${SONARQUBE_TAG} -e SONARQUBE_TOKEN=${SONAR_AUTH_TOKEN} -e SONAR_HOST_URL=${SONAR_HOST_URL} eeacms/gitflow /update_sonarqube_tags.sh'''
}
}
}
}
}
}



post {
changed {
script {
def url = "${env.BUILD_URL}/display/redirect"
def status = currentBuild.currentResult
def subject = "${status}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
def details = """<h1>${env.JOB_NAME} - Build #${env.BUILD_NUMBER} - ${status}</h1>
<p>Check console output at <a href="${url}">${env.JOB_BASE_NAME} - #${env.BUILD_NUMBER}</a></p>
"""
emailext (subject: '$DEFAULT_SUBJECT', to: '$DEFAULT_RECIPIENTS', body: details)
}
}
}
}
82 changes: 82 additions & 0 deletions README.md.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# <%= name %>

[![Release](https://img.shields.io/github/v/release/eea/<%= name %>?sort=semver)](https://github.com/eea/<%= name %>/releases)
[![Pipeline](https://ci.eionet.europa.eu/buildStatus/icon?job=volto%2F<%= name %>%2Fmaster&subject=master)](https://ci.eionet.europa.eu/view/Github/job/volto/job/<%= name %>/job/master/lastBuild/display/redirect)
[![Pipeline](https://ci.eionet.europa.eu/buildStatus/icon?job=volto%2F<%= name %>%2Fdevelop&subject=develop)](https://ci.eionet.europa.eu/view/Github/job/volto/job/<%= name %>/job/develop/lastBuild/display/redirect)
[![Release pipeline](https://ci.eionet.europa.eu/buildStatus/icon?job=volto%2F<%= name %>%2F0.0.0&build=last&subject=release%20v0.0.0%20pipeline)](https://ci.eionet.europa.eu/view/Github/job/volto/job/<%= name %>/job/0.0.0/lastBuild/display/redirect/)


## Documentation

A training on how to create your own website using Volto is available as part of the Plone training at [https://training.plone.org/5/volto/index.html](https://training.plone.org/5/volto/index.html).


## Getting started

1. Install `nvm`

touch ~/.bash_profile
curl -o- https://github.com/raw/creationix/nvm/v0.34.0/install.sh | bash

source ~/.bash_profile
nvm version

1. Install latest `NodeJS 16.x`:

nvm install 16
nvm use 16
node -v
v16.16.2

1. Install `yarn`

curl -o- -L https://yarnpkg.com/install.sh | bash
yarn -v

1. Clone:

git clone https://github.com/eea/<%= name %>.git
cd <%= name %>

1. Install

yarn build

1. Start backend

docker-compose up -d
docker-compose logs -f

1. Start frontend

yarn start:prod

1. See application at http://localhost:3000

## Automated @eeacms dependencies upgrades

All the addon dependencies that are located in the dependencies section of `package.json` file that belong to @eeacms and have a `MAJOR.MINOR.PATCH` version are automatically upgraded on the release of a new version of the addon. This upgrade is done directly on the `develop` branch.

Exceptions from automated upgrades ( see https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies for dependency configuration examples ) :
* All github or local paths
* Any version intervals ( `^version` or `>version` or `MAJOR.MINOR.x` etc )

## Release

See [release](https://github.com/eea/ims-frontend/tree/master/RELEASE.md)

## Production

We use [Docker](https://www.docker.com/), [Rancher](https://rancher.com/) and [Jenkins](https://jenkins.io/) to deploy this application in production.

### Deploy

* Within `Rancher > Catalog > EEA`

### Upgrade

* Within your Rancher environment click on the `Upgrade available` yellow button next to your stack.

* Confirm the upgrade

* Or roll-back if something went wrong and abort the upgrade procedure.
Loading

0 comments on commit 7e0d92c

Please sign in to comment.