diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..c1ab2eb2 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,271 @@ +pipeline { + + agent none + + stages { + + stage('worker-build') { + agent { + docker { + image 'maven:3.9.8-sapmachine-21' + args '-v $HOME/.m2:/root/.m2' + } + + } + when { + changeset '**/worker/**' + } + steps { + echo 'Compiling worker app..' + dir(path: 'worker') { + sh 'mvn compile' + } + + } + } + + stage('worker test') { + agent { + docker { + image 'maven:3.9.8-sapmachine-21' + args '-v $HOME/.m2:/root/.m2' + } + + } + when { + changeset '**/worker/**' + } + steps { + echo 'Running Unit Tets on worker app.' + dir(path: 'worker') { + sh 'mvn clean test' + } + + } + } + + stage('worker-package') { + agent { + docker { + image 'maven:3.9.8-sapmachine-21' + args '-v $HOME/.m2:/root/.m2' + } + + } + when { + branch 'master' + changeset '**/worker/**' + } + steps { + echo 'Packaging worker app' + dir(path: 'worker') { + sh 'mvn package -DskipTests' + archiveArtifacts(artifacts: '**/target/*.jar', fingerprint: true) + } + + } + } + + stage('worker-docker-package') { + agent any + when { + changeset '**/worker/**' + branch 'master' + } + steps { + echo 'Packaging worker app with docker' + script { + docker.withRegistry('https://index.docker.io/v1/', 'dockerlogin') { + def workerImage = docker.build("xxxxx/worker:v${env.BUILD_ID}", './worker') + workerImage.push() + workerImage.push("${env.BRANCH_NAME}") + workerImage.push('latest') + } + } + + } + } + + stage('result-build') { + agent { + docker { + image 'node:22.4.0-alpine' + } + + } + when { + changeset '**/result/**' + } + steps { + echo 'Compiling result app..' + dir(path: 'result') { + sh 'npm install' + } + + } + } + + stage('result-test') { + agent { + docker { + image 'node:22.4.0-alpine' + } + + } + when { + changeset '**/result/**' + } + steps { + echo 'Running Unit Tests on result app..' + dir(path: 'result') { + sh 'npm install' + sh 'npm test' + } + + } + } + + stage('result-docker-package') { + agent any + when { + changeset '**/result/**' + branch 'master' + } + steps { + echo 'Packaging result app with docker' + script { + docker.withRegistry('https://index.docker.io/v1/', 'dockerlogin') { + def resultImage = docker.build("xxxxx/result:v${env.BUILD_ID}", './result') + resultImage.push() + resultImage.push("${env.BRANCH_NAME}") + resultImage.push('latest') + } + } + } + } + + stage('vote-build') { + agent { + docker { + image 'python:2.7.16-slim' + args '--user root' + } + + } + when { + changeset '**/vote/**' + } + steps { + echo 'Compiling vote app.' + dir(path: 'vote') { + sh 'pip install -r requirements.txt' + } + + } + } + + stage('vote-test') { + agent { + docker { + image 'python:2.7.16-slim' + args '--user root' + } + + } + when { + changeset '**/vote/**' + } + steps { + echo 'Running Unit Tests on vote app.' + dir(path: 'vote') { + sh 'pip install -r requirements.txt' + sh 'nosetests -v' + } + + } + } + + stage('vote integration'){ + agent any + when{ + changeset "**/vote/**" + branch 'master' + } + steps{ + echo 'Running Integration Tests on vote app' + dir('vote'){ + sh 'sh integration_test.sh' + } + } +} + + + stage('vote-docker-package') { + agent any + steps { + echo 'Packaging vote app with docker' + script { + docker.withRegistry('https://index.docker.io/v1/', 'dockerlogin') { + // ./vote is the path to the Dockerfile that Jenkins will find from the Github repo + def voteImage = docker.build("xxxxx/vote:${env.GIT_COMMIT}", "./vote") + voteImage.push() + voteImage.push("${env.BRANCH_NAME}") + voteImage.push("latest") + } + } + + } + } + + stage('Sonarqube') { + agent any + when{ + branch 'master' + } + // tools { + // jdk "JDK11" // the name you have given the JDK installation in Global Tool Configuration + // } + + environment{ + sonarpath = tool 'SonarScanner' + } + + steps { + echo 'Running Sonarqube Analysis..' + withSonarQubeEnv('sonar-instavote') { + sh "${sonarpath}/bin/sonar-scanner -Dproject.settings=sonar-project.properties -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.HEARTBEAT_CHECK_INTERVAL=86400" + } + } + } + + + stage("Quality Gate") { + steps { + timeout(time: 1, unit: 'HOURS') { + // Parameter indicates whether to set pipeline to UNSTABLE if Quality Gate fails + // true = set pipeline to UNSTABLE, false = don't + waitForQualityGate abortPipeline: true + } + } + } + + stage('deploy to dev') { + agent any + when { + branch 'master' + } + steps { + echo 'Deploy instavote app with docker compose' + sh 'docker-compose up -d' + } + } + + } + + post { + always { + echo 'Building mono pipeline for voting app is completed.' + } + } +} + diff --git a/README.md b/README.md index b8ad8a94..cc59bb39 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Example Voting App +Voting App ========= Getting started @@ -58,3 +58,12 @@ Note ---- The voting application only accepts one vote per client. It does not register votes if a vote has already been submitted from a client. + + +Note: +Example Voting App +========= +This is a sample voting app + +Testing the commits +==== diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..745349a6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,52 @@ +volumes: + db-data: + +networks: + instavote: + driver: bridge + +services: + vote: + image: jmmoralesc/vote:latest + ports: + - 5000:80 + depends_on: + - redis + networks: + - instavote + + redis: + image: redis:alpine + networks: + - instavote + + db: + image: postgres:15-alpine + environment: + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "postgres" + volumes: + - "db-data:/var/lib/postgresql/data" + - "./healthchecks:/healthchecks" + healthcheck: + test: /healthchecks/postgres.sh + interval: "5s" + networks: + - instavote + + result: + image: jmmoralesc/result:latest + ports: + - 5001:4000 + depends_on: + - db + networks: + - instavote + + worker: + image: jmmoralesc/worker:latest + depends_on: + - redis + - db + networks: + - instavote diff --git a/sonar-project.properties b/sonar-project.properties index dcd32fdc..a1a87f9b 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ # Uncomment and update Org matching your configurations on Sonarcloud -sonar.organization=your-org -sonar.projectKey=your-org_example-voting-app -sonar.projectName=Instavote AIO +sonar.organization=jmmoralesc +sonar.projectKey=jmmoralesc_LFS261-example-voting-app +sonar.projectName=Instavote AIO LFS261examplevotingapp sonar.projectVersion=1.0 # Comma-separated paths to directories with sources (required) sonar.sources=worker diff --git a/test.jmc b/test.jmc new file mode 100644 index 00000000..9f4b6d8b --- /dev/null +++ b/test.jmc @@ -0,0 +1 @@ +This is a test file diff --git a/vote/Dockerfile b/vote/Dockerfile index 9e812ca9..4cdac813 100644 --- a/vote/Dockerfile +++ b/vote/Dockerfile @@ -2,29 +2,20 @@ FROM python:3.11-slim AS base # Add curl for healthcheck -RUN apt-get update && \ - apt-get install -y --no-install-recommends curl && \ - rm -rf /var/lib/apt/lists/* +#RUN apt-get update && \ +# apt-get install -y --no-install-recommends curl && \ +# rm -rf /var/lib/apt/lists/* # Set the application directory -WORKDIR /usr/local/app +WORKDIR /app # Install our requirements.txt -COPY requirements.txt ./requirements.txt -RUN pip install --no-cache-dir -r requirements.txt +#COPY requirements.txt ./requirements.txt +ADD requirements.txt /app/requirements.txt +RUN pip install -r requirements.txt -# Define a stage specifically for development, where it'll watch for -# filesystem changes -FROM base AS dev -RUN pip install watchdog -ENV FLASK_ENV=development -CMD ["python", "app.py"] - -# Define the final stage that will bundle the application for production -FROM base AS final - -# Copy our code from the current folder to the working directory inside the container -COPY . . +#Copy our code from the current folder to /app inside the container +ADD . /app # Make port 80 available for links and/or publish EXPOSE 80 diff --git a/vote/Dockerfile.old b/vote/Dockerfile.old new file mode 100644 index 00000000..9e812ca9 --- /dev/null +++ b/vote/Dockerfile.old @@ -0,0 +1,33 @@ +# Define a base stage that uses the official python runtime base image +FROM python:3.11-slim AS base + +# Add curl for healthcheck +RUN apt-get update && \ + apt-get install -y --no-install-recommends curl && \ + rm -rf /var/lib/apt/lists/* + +# Set the application directory +WORKDIR /usr/local/app + +# Install our requirements.txt +COPY requirements.txt ./requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# Define a stage specifically for development, where it'll watch for +# filesystem changes +FROM base AS dev +RUN pip install watchdog +ENV FLASK_ENV=development +CMD ["python", "app.py"] + +# Define the final stage that will bundle the application for production +FROM base AS final + +# Copy our code from the current folder to the working directory inside the container +COPY . . + +# Make port 80 available for links and/or publish +EXPOSE 80 + +# Define our command to be run when launching the container +CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--log-file", "-", "--access-logfile", "-", "--workers", "4", "--keep-alive", "0"] diff --git a/vote/Jenkinsfile b/vote/Jenkinsfile index cf328100..3abdf052 100644 --- a/vote/Jenkinsfile +++ b/vote/Jenkinsfile @@ -31,22 +31,20 @@ pipeline { dir('vote'){ sh "pip install -r requirements.txt" - sh 'nosetests -v' - - + sh 'nosetests -v' } } } - stage('docker-package'){ - agent any - + + stage('vote-docker-package'){ + agent any steps{ echo 'Packaging wvoteorker app with docker' script{ docker.withRegistry('https://index.docker.io/v1/', 'dockerlogin') { // ./vote is the path to the Dockerfile that Jenkins will find from the Github repo - def voteImage = docker.build("okapetanios/vote:v${env.BUILD_ID}", "./vote") + def voteImage = docker.build("jmmoralesc/vote:v${env.BUILD_ID}", "./vote") voteImage.push() voteImage.push("${env.BRANCH_NAME}") voteImage.push("latest") @@ -54,7 +52,6 @@ pipeline { } } } - } post { always{ diff --git a/webhook2.test b/webhook2.test new file mode 100644 index 00000000..654de816 --- /dev/null +++ b/webhook2.test @@ -0,0 +1 @@ +this is a second webhook test diff --git a/worker/Jenkinsfile b/worker/Jenkinsfile old mode 100644 new mode 100755 index b66016b2..6897f7e1 --- a/worker/Jenkinsfile +++ b/worker/Jenkinsfile @@ -1,41 +1,80 @@ -pipeline { - agent{ - docker{ - image 'maven:3.9.8-sapmachine-21' - args '-v $HOME/.m2:/root/.m2' - } - } - stages{ - stage('build'){ - steps{ - echo 'building worker app' - dir('worker'){ - sh 'mvn compile' - } - } - } - stage('test'){ - steps{ - echo 'running unit tests on worker app' - dir('worker'){ - sh 'mvn clean test' - } - } - } - stage('package'){ - steps{ - echo 'packaging worker app into a jarfile' - dir('worker'){ - sh 'mvn package -DskipTests' - archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true - } - } - } - } - post{ - always{ - echo 'the job is complete' - - } - } +pipeline { + agent none + + stages { + stage("build") { + when { + changeset "**/worker/**" + } + agent { + docker { + image 'maven:3.6.1-jdk-8-slim' + args '-v $HOME/.m2:/root/.m2' + } + } + steps { + echo 'Compiling worker app..' + dir('worker') { + sh 'mvn compile' + } + } + } + stage("test") { + when { + changeset "**/worker/**" + } + agent { + docker { + image 'maven:3.6.1-jdk-8-slim'args '-v $HOME/.m2:/root/.m2' + } + } + steps { + echo 'Running Unit Tests on worker app..' + dir('worker') { + sh 'mvn clean test' + } + } + } + stage("package") { + when { + branch 'master'changeset "**/worker/**" + } + agent { + docker { + image 'maven:3.6.1-jdk-8-slim' + args '-v $HOME/.m2:/root/.m2' + } + } + steps { + echo 'Packaging worker app' + dir('worker') { + sh 'mvn package -DskipTests' + archiveArtifacts artifacts: '**/target/*.jar',fingerprint: true + } + } + } + stage('docker-package') { + agent any + when { + changeset "**/worker/**" + branch 'master' + } + steps { + echo 'Packaging worker app with docker' + script { + docker.withRegistry('https://index.docker.io/v1/','dockerlogin') { + def workerImage = docker.build("xxxxx/worker:v${env.BUILD_ID}", "./worker") + workerImage.push() + workerImage.push("${env.BRANCH_NAME}") + workerImage.push("latest") + } + } + } + } + + post { + always { + echo 'Building multibranch pipeline for worker is completed..' + } + } } diff --git a/worker/Jenkinsfile.abc b/worker/Jenkinsfile.abc new file mode 100644 index 00000000..b66016b2 --- /dev/null +++ b/worker/Jenkinsfile.abc @@ -0,0 +1,41 @@ +pipeline { + agent{ + docker{ + image 'maven:3.9.8-sapmachine-21' + args '-v $HOME/.m2:/root/.m2' + } + } + stages{ + stage('build'){ + steps{ + echo 'building worker app' + dir('worker'){ + sh 'mvn compile' + } + } + } + stage('test'){ + steps{ + echo 'running unit tests on worker app' + dir('worker'){ + sh 'mvn clean test' + } + } + } + stage('package'){ + steps{ + echo 'packaging worker app into a jarfile' + dir('worker'){ + sh 'mvn package -DskipTests' + archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true + } + } + } + } + post{ + always{ + echo 'the job is complete' + + } + } +} diff --git a/worker/Jenkinsfile.jmc b/worker/Jenkinsfile.jmc new file mode 100644 index 00000000..b66016b2 --- /dev/null +++ b/worker/Jenkinsfile.jmc @@ -0,0 +1,41 @@ +pipeline { + agent{ + docker{ + image 'maven:3.9.8-sapmachine-21' + args '-v $HOME/.m2:/root/.m2' + } + } + stages{ + stage('build'){ + steps{ + echo 'building worker app' + dir('worker'){ + sh 'mvn compile' + } + } + } + stage('test'){ + steps{ + echo 'running unit tests on worker app' + dir('worker'){ + sh 'mvn clean test' + } + } + } + stage('package'){ + steps{ + echo 'packaging worker app into a jarfile' + dir('worker'){ + sh 'mvn package -DskipTests' + archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true + } + } + } + } + post{ + always{ + echo 'the job is complete' + + } + } +} diff --git a/worker/jmc2.test b/worker/jmc2.test new file mode 100644 index 00000000..493021b1 --- /dev/null +++ b/worker/jmc2.test @@ -0,0 +1 @@ +this is a test file diff --git a/worker/pom.xml b/worker/pom.xml index 15e1b5b5..c1f27f2c 100644 --- a/worker/pom.xml +++ b/worker/pom.xml @@ -103,3 +103,4 @@ +