Skip to content

Merge pull request #9 from OpsVerseIO/dependabot/pip/dot-github/workf… #198

Merge pull request #9 from OpsVerseIO/dependabot/pip/dot-github/workf…

Merge pull request #9 from OpsVerseIO/dependabot/pip/dot-github/workf… #198

name: CI CD Pipeline
on:
push:
branches:
- main
- master
jobs:
lint:
name: "πŸ•΅πŸ»β€β™‚οΈ Lint"
runs-on: ubuntu-latest
steps:
- name: "☁️ checkout the repository"
uses: actions/checkout@v2
- name: "πŸ”§ setup node.js"
uses: actions/setup-node@v3
with:
node-version: 18
- name: "πŸ“¦ install dependencies"
run: npm install
- name: "πŸ”§ lint code"
run: npm run lint
test:
name: "🚨 Run unit test cases"
runs-on: ubuntu-latest
steps:
- name: "☁️ checkout the repository"
uses: actions/checkout@v2
- name: "πŸ”§ setup node.js"
uses: actions/setup-node@v3
with:
node-version: 18
- name: "πŸ“¦ install dependencies"
run: npm install
- name: "πŸ” run all unit test cases"
run: npm t
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
# - name: SonarCloud Scan
# uses: SonarSource/sonarcloud-github-action@master
# env:
# GITHUB_TOKEN: ${{ secrets.GH_PAT }} # Needed to get PR information, if any
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- name: SonarQube Quality Gate check
id: sonarqube-quality-gate-check
uses: opsverseio/[email protected]
# Force to fail step after specific time.
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SET_SONAR_PROJECT_STATUS: true
outputs:
sonarcloud_output: ${{ steps.sonarqube-quality-gate-check.outputs.quality-gate-status }}
sonar_quality_gate_project_status: ${{ steps.sonarqube-quality-gate-check.outputs.quality_gate_project_status }}
opa:
name: "🚧 Unit tests gate"
runs-on: ubuntu-latest
needs:
- lint
- test
- sonarcloud
steps:
- name: "Print Output"
run: |
echo ${{needs.sonarcloud.outputs.sonarcloud_output}}
echo ${{needs.sonarcloud.outputs.sonar_quality_gate_project_status}}
- name: "⏳ Parse SonarQube Output"
uses: jannekem/run-python-script-action@v1
with:
script: |
import os
import json
dict = json.loads(${{needs.sonarcloud.outputs.sonar_quality_gate_project_status}})
print(dict)
# print("Starting OPA Policy Enforcement Check:")
# opa_endpoint = "20.237.56.131"
# policy_name = "policies/codecoverage.rego"
# rule_name = "allow"
# client = OpaClient(host=opa_endpoint)
# exit_on_fail = os.environ.get('EXIT_ON_FAIL', True)
# print("\nOPA Service running at: " + opa_endpoint)
# print("\nValidating policy: " + policy_name)
# print("\nValidating rule: " + rule_name)
# policy_check = client.check_permission(input_data=json.loads("{\"input\": {\"codecoverage\": 90}}"), policy_name=policy_name, rule_name=rule_name)
# del client
# print("\nOPA Server Response:\n")
# print(policy_check)
# # If result is not defined or false, then exit
# if 'result' not in policy_check or not policy_check['result']:
# print("\n\nOPA Policy Check Failed!")
# if exit_on_fail:
# print("\nExiting on policy check failure")
# exit(1)
# print("\nEnd OPA Policy Check")
- name: "⏳ Validate quality using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "http://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
opaServerInput: '{"input": { "status": "${{needs.sonarcloud.outputs.sonarcloud_output}}", "metric": "unit-test"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa-code-coverage:
name: "🚧 Code coverage gate"
runs-on: ubuntu-latest
needs:
- lint
- test
- sonarcloud
steps:
- name: "⏳ Validate quality using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "http://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
opaServerInput: '{"input": { "status": "PASSED", "metric": "code-coverage"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa-sonarqube:
name: "🚧 Static code analysis gate"
runs-on: ubuntu-latest
needs:
- lint
- test
- sonarcloud
steps:
- name: "⏳ Validate quality using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "http://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
opaServerInput: '{"input": { "status": "${{needs.sonarcloud.outputs.sonarcloud_output}}", "metric": "static-code-analysis"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
visualize:
name: "πŸ“Š Visualize the repository"
runs-on: ubuntu-latest
needs:
- lint
- test
- sonarcloud
- opa
- opa-sonarqube
- opa-code-coverage
steps:
- name: "πŸ“©πŸ“¨ Visualize the repository"
run: |
echo "πŸ“Š Visualize the repository"
- name: "☁️ Checkout repository"
uses: actions/checkout@v4
- name: "πŸ“Š Repository visualizer"
uses: githubocto/[email protected]
with:
excluded_paths: "node_modules,.github"
# output_file: "src/diagram.svg"
# should_push: false
# root_path: "/"
- name: "πŸ“Š Visualiser artifacts"
uses: actions/upload-artifact@v2
with:
name: diagram
path: public/diagram.svg
build:
name: "πŸ“¦ Build docker image"
runs-on: ubuntu-latest
env:
APP_NAME: node-js-server
needs:
- lint
- test
- sonarcloud
- opa
- visualize
timeout-minutes: 10
steps:
- name: "πŸ”§ Add dynamic envs"
run: |
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV
echo "SHA= ${GITHUB_SHA}"
echo "SHORT SHA= ${SHORT_SHA}"
- name: "☁️ checkout repository"
uses: actions/checkout@v2
- name: "πŸ”’ Authenticate to artifactory (Harbor) πŸ”“"
uses: docker/login-action@v1
with:
registry: registry.devopsnow.io
username: ${{ secrets.DEVOPSNOW_DOCKER_INTERNAL_ROBOT_USER }}
password: ${{ secrets.DEVOPSNOW_DOCKER_INTERNAL_ROBOT_PASS }}
- name: "πŸ“¦ Build the image"
uses: docker/build-push-action@v2
with:
context: .
tags: "registry.devopsnow.io/internal/node-js-server:${{ env.SHORT_SHA }}"
- name: "πŸ“‚ Push the image to artifactory"
run: docker push "registry.devopsnow.io/internal/node-js-server:${{ env.SHORT_SHA }}"
update-image-stage:
name: "πŸ“ Update STAGE image tag"
runs-on: ubuntu-latest
needs:
- lint
- test
- opa
- visualize
- build
timeout-minutes: 10
steps:
- name: "πŸ”§ Add dynamic envs"
id: "image-tag"
run: |
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV
echo "SHA= ${GITHUB_SHA}"
echo "SHORT SHA= ${SHORT_SHA}"
echo "::set-output name=version::$SHORT_SHA"
- name: Checkout Target Repository
uses: actions/checkout@v3
with:
repository: "OpsVerseIO/node-js-server-manifests"
path: main
token: ${{ secrets.GH_PAT }}
- name: "πŸ“ Update Image tag Version in the DEV manifest file"
uses: OpsVerseIO/[email protected]
with:
repository: "OpsVerseIO/deployment-manifests"
valueFile: 'node-js-server/helm/stage/node-js-server/values.yaml'
propertyPath: 'nodejssever.image.tag'
value: '${{ env.SHORT_SHA }}'
branch: main
createPR: false
message: '[DEV] Update Image tag of node-js-server'
token: ${{ secrets.GH_PAT }}
workDir: main
masterBranchName: main
targetBranch: main
force: true
updateFile: true
update-image-stage-k8s-manifest:
name: "πŸ“ Update stage image tag"
runs-on: ubuntu-latest
needs:
- lint
- test
- opa
- visualize
- build
timeout-minutes: 10
steps:
- name: "πŸ”§ Add dynamic envs"
id: "image-tag"
run: |
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV
echo "SHA= ${GITHUB_SHA}"
echo "SHORT SHA= ${SHORT_SHA}"
echo "::set-output name=version::$SHORT_SHA"
- name: Checkout Target Repository
uses: actions/checkout@v3
with:
repository: "OpsVerseIO/deployment-manifests"
path: main
token: ${{ secrets.GH_PAT }}
- name: "πŸ“ Update Image tag Version in the STAGE manifest file"
uses: OpsVerseIO/[email protected]
with:
repository: "OpsVerseIO/node-js-server-manifests"
valueFile: 'node-js-server/stage/deployment.yaml'
propertyPath: 'spec.template.spec.containers[0].image'
value: 'registry.devopsnow.io/internal/node-js-server:${{ env.SHORT_SHA }}'
branch: main
createPR: false
message: '[STAGE] Update Image tag of node-js-server'
token: ${{ secrets.GH_PAT }}
workDir: main
masterBranchName: main
targetBranch: main
force: true
updateFile: true
release-stage:
name: "⏳ ArgoCD Sync Stage"
runs-on: ubuntu-latest
needs:
- lint
- test
- opa
- visualize
- build
- update-image-stage
timeout-minutes: 10
steps:
- name: "πŸ”§ Trigger ArgoCD Sync/Deployment in STAGE"
uses: OpsVerseIO/[email protected]
with:
address: ${{ secrets.ARGOCD_SERVER }}
token: ${{ secrets.ARGOCD_TOKEN }}
action: sync
appName: ${{ secrets.ARGOCD_PROD_APP_NAME }}
- name: "πŸš€ Deploy to STAGE"
run: |
echo "⏳ Deploying the application to STAGE"
echo "πŸš€βœ…πŸ’š Successfully synced STAGE ArgoCD and deployed the application to STAGE"
integration-test:
name: "🚨 Run integration test suite"
needs:
- lint
- test
- opa
- visualize
- build
- release-stage
runs-on: ubuntu-latest
steps:
- name: "πŸ“©πŸ“¨ Message from Open Policy Agent (OPA) Server"
run: |
echo "Running integration test suite"
echo "βŒ› Connecting to STAGE application at: https://staging-server.opsverse.io"
echo "βœ…πŸ’š Integration tests passed"
integration-test-opa:
name: "🚧 Integration tests gate"
needs:
- lint
- test
- opa
- visualize
- build
- release-stage
- integration-test
runs-on: ubuntu-latest
steps:
- name: "⏳ Validate quality using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "https://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
opaServerInput: '{"input": { "status": "${{needs.sonarcloud.outputs.sonarcloud_output}}", "metric": "static-code-analysis"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
update-image-prod:
name: "πŸ“ Update prod image tag"
runs-on: ubuntu-latest
needs:
- lint
- test
- opa
- visualize
- build
- release-stage
- integration-test
- integration-test-opa
timeout-minutes: 10
steps:
- name: "πŸ”§ Add dynamic envs"
id: "image-tag"
run: |
echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV
echo "SHA= ${GITHUB_SHA}"
echo "SHORT SHA= ${SHORT_SHA}"
echo "::set-output name=version::$SHORT_SHA"
- name: Checkout Target Repository
uses: actions/checkout@v3
with:
repository: "OpsVerseIO/node-js-server-manifests"
path: main
token: ${{ secrets.GH_PAT }}
- name: "πŸ“ Update Image tag Version in the PROD manifest file"
uses: OpsVerseIO/[email protected]
with:
repository: "OpsVerseIO/deployment-manifests"
# Uncomment this if you want to use vanilla K8S manifests
# valueFile: 'node-js-server/prod/node-js-server/values.yaml'
# Uncomment this if you want to use Helm
valueFile: 'node-js-server/helm/prod/node-js-server/values.yaml'
# Uncomment this if you want to use Helm
propertyPath: 'nodejssever.image.tag'
# Uncomment this if you want to use vanilla K8S manifests
# propertyPath: 'spec.template.spec.containers[0].image'
value: 'registry.devopsnow.io/internal/node-js-server:${{ env.SHORT_SHA }}'
branch: main
createPR: false
message: '[PROD] Update Image tag of node-js-server'
token: ${{ secrets.GH_PAT }}
workDir: main
masterBranchName: main
targetBranch: main
force: true
updateFile: true
release-prod:
environment:
name: production
name: "πŸš€ Deploy to PROD"
needs:
- lint
- test
- opa
- visualize
- build
- release-stage
- integration-test
- integration-test-opa
- update-image-prod
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: "πŸ”§ Trigger ArgoCD Sync/Deployment in PROD"
uses: OpsVerseIO/[email protected]
with:
address: ${{ secrets.ARGOCD_SERVER }}
token: ${{ secrets.ARGOCD_TOKEN }}
action: sync
appName: ${{ secrets.ARGOCD_PROD_APP_NAME }}
- name: "πŸš€ Deploy to PROD ENV"
run: |
echo "⏳ Deploying the application to PROD"
echo "πŸš€βœ…πŸ’š Successfully synced PROD ArgoCD and deployed the application to PROD"
cleanup:
name: "♻️ Cleanup actions"
needs:
- release-stage
- release-prod
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: "♻️ remove build artifacts"
run: |
echo "♻️ Cleaning up the build artifacts"
echo "β™»οΈβœ… Successfully cleaned up the build artifacts"