diff --git a/.github/workflows/test.workflow.yml b/.github/workflows/test.workflow.yml new file mode 100644 index 0000000..420e71f --- /dev/null +++ b/.github/workflows/test.workflow.yml @@ -0,0 +1,24 @@ +name: Node.js CI + +on: [pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run build --if-present + - run: npm test + env: + CI: true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 927082e..52b51e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,11 @@ -# ================================ -# Create image to build project FROM node:12-alpine as builder -WORKDIR /ota-admin-portal -COPY . . -COPY .env.template ./.env - -# Install the dependencies +COPY package*.json ./ RUN npm install - -# Build the project +COPY . . +COPY .env.template .env RUN npm run build -# ================================ -# Create image to serve react app -FROM nginx:latest +FROM nginx:alpine -#!/bin/sh - -COPY ./nginx.conf /etc/nginx/nginx.conf - -## Remove default nginx index page -RUN rm -rf /usr/share/nginx/html/* - -# Copy from the stahg 1 -COPY --from=builder /ota-admin-portal/build /usr/share/nginx/html - -EXPOSE 80 443 8080 - -ENTRYPOINT ["nginx", "-g", "daemon off;"] \ No newline at end of file +COPY --from=builder build /usr/share/nginx/html diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..f597a6d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,81 @@ +@Library('fisker') _ + +pipeline { + agent none + options { + ansiColor('xterm') + } + environment { + PROJECT = getProject() + ENV = getEnv() + } + stages { + stage('Build') { + when { + beforeAgent true + allOf { + not { + changeRequest() + } + anyOf { + branch 'development' + branch 'main' + } + } + } + agent { + kubernetes { + cloud 'dev' + inheritFrom 'fisker' + } + } + steps { + slack("Build Started - ${env.JOB_NAME} (${env.BUILD_URL})", 'info', '#team-eng-compute-jenkins') + slack(getChanges(), 'info', '#team-eng-compute-jenkins') + container('awscli') { + ecr() + } + container('kaniko') { + buildImage() + } + } + post { + failure { + slack("${env.JOB_NAME} build failed!", 'error', '#team-eng-compute-jenkins') + } + } + } + stage('Deploy') { + when { + beforeAgent true + allOf { + not { + changeRequest() + } + anyOf { + branch 'development' + branch 'main' + } + } + } + agent { + kubernetes { + cloud getEnv() + inheritFrom 'fisker' + } + } + steps { + slack("Deploying ${PROJECT} to ${ENV}... :partydeploy: ", 'info', '#team-eng-compute-jenkins') + container('helm') { + deploy(getEnv()) + } + slack("Successfully deployed ${PROJECT} to ${ENV}! :tada: ", 'info', '#team-eng-compute-jenkins') + } + post { + failure { + slack("${PROJECT} deploy to ${ENV} failed!", 'error', '#team-eng-compute-jenkins') + } + } + } + } +} \ No newline at end of file diff --git a/k8s/Chart.yaml b/k8s/Chart.yaml new file mode 100644 index 0000000..6a1b177 --- /dev/null +++ b/k8s/Chart.yaml @@ -0,0 +1,2 @@ +name: ota-admin-portal +version: 1.0.0 \ No newline at end of file diff --git a/k8s/templates/deployment.yaml b/k8s/templates/deployment.yaml new file mode 100644 index 0000000..d807e32 --- /dev/null +++ b/k8s/templates/deployment.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Chart.Name }} + labels: + app: {{ .Chart.Name }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: {{ .Chart.Name }} + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + + template: + metadata: + labels: + app: {{ .Chart.Name }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.registry }}/{{ .Values.image.name }}:{{ .Values.image.tag}}" + resources: + requests: + cpu: {{ .Values.resources.requests.cpu }} + memory: {{ .Values.resources.requests.memory }} + limits: + cpu: {{ .Values.resources.limits.cpu }} + memory: {{ .Values.resources.limits.memory }} + env: + # non-secret env vars + {{- range $name, $value := $.Values.env }} + {{- if not (empty $value) }} + - name: {{ $name | quote }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + # Params for env vars populated from k8s secrets + {{- range $.Values.secrets }} + - name: {{ . }} + valueFrom: + secretKeyRef: + name: {{ $.Chart.Name }} + key: {{ . }} + {{- end }} \ No newline at end of file diff --git a/k8s/templates/ingress.yaml b/k8s/templates/ingress.yaml new file mode 100644 index 0000000..b1a92d8 --- /dev/null +++ b/k8s/templates/ingress.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: nginx + labels: + app: {{ .Chart.Name }} + name: {{ .Chart.Name }} +spec: + rules: + - host: {{ .Values.ingress.hostname }} + http: + paths: + - backend: + serviceName: {{ .Chart.Name }} + servicePort: 80 + path: / + tls: + - hosts: + - {{ .Values.ingress.hostname }} + secretName: fiskerdps-cert \ No newline at end of file diff --git a/k8s/templates/service.yaml b/k8s/templates/service.yaml new file mode 100644 index 0000000..4f9a2bd --- /dev/null +++ b/k8s/templates/service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }} +spec: + selector: + app: {{ .Chart.Name }} + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: ClusterIP \ No newline at end of file diff --git a/k8s/values-dev.yaml b/k8s/values-dev.yaml new file mode 100644 index 0000000..1e69f1c --- /dev/null +++ b/k8s/values-dev.yaml @@ -0,0 +1,12 @@ +ingress: + hostname: dev-ota-admin.fiskerdps.com + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + +replicas: 1 \ No newline at end of file diff --git a/k8s/values-prd.yaml b/k8s/values-prd.yaml new file mode 100644 index 0000000..139cf6c --- /dev/null +++ b/k8s/values-prd.yaml @@ -0,0 +1,12 @@ +ingress: + hostname: ota-admin.fiskerdps.com + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 250m + memory: 256Mi + +replicas: 1 \ No newline at end of file