Skip to content

Add action to sync app in ArgoCD #57

Add action to sync app in ArgoCD

Add action to sync app in ArgoCD #57

Workflow file for this run

name: CI CD Pipeline
on:
push:
branches:
- main
- master
jobs:
sonarqube:
name: Sonarqube Analysis
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: 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
METRIC_NAME: "new_coverage"
- name: "πŸ“Šβ˜οΈ Fetch Reliability Rating Metric"
id: fetch-reliability-rating
run: |
# Fetching data from SonarQube
response=$(curl --location --location-trusted --max-redirs 10 --silent --fail --show-error --user ${{ secrets.SONARQUBE_TOKEN }}: "${{ secrets.SONAR_HOST_URL }}/api/measures/component?component=OpsVerseIO_hello-world-api-dotnet_0b6ec67c-a096-486a-b4aa-16d972f93a22&metricKeys=reliability_rating")
# Extracting reliability ratings
reliability_score=$(echo $response | jq -r '.component.measures[] | select(.metric=="reliability_rating") | .value')
best_reliability_score=$(echo $response | jq -r '.component.measures[] | select(.metric=="security_rating") | .bestValue')
# Setting the scores as outputs
echo "::set-output name=reliability::$reliability_score"
echo "::set-output name=best_reliability::$best_reliability_score"
# Print the Reliability rating score/metric
echo "Reliability Score: ${{ steps.fetch-reliability-rating.outputs.reliability }}"
echo "Best/Allowed Reliability Score: ${{ steps.fetch-reliability-rating.outputs.best_reliability_score }}"
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONARQUBE_PROJECT_KEY: ${{ secrets.SONARQUBE_PROJECT_KEY }}
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
- name: "πŸ“ŠπŸ” Fetch Security Rating Metric"
id: fetch-security-rating
run: |
# Fetching data from SonarQube
response=$(curl --location --location-trusted --max-redirs 10 --silent --fail --show-error --user ${{ secrets.SONARQUBE_TOKEN }}: "${{ secrets.SONAR_HOST_URL }}/api/measures/component?component=OpsVerseIO_hello-world-api-dotnet_0b6ec67c-a096-486a-b4aa-16d972f93a22&metricKeys=security_rating")
# Extracting security ratings
security_score=$(echo $response | jq -r '.component.measures[] | select(.metric=="security_rating") | .value')
best_security_score=$(echo $response | jq -r '.component.measures[] | select(.metric=="security_rating") | .bestValue')
# Setting the scores as outputs
echo "::set-output name=security::$security_score"
echo "::set-output name=best_security::$best_security_score"
# Print the Security rating score/metric
echo "Security Score: ${{ steps.fetch-security-rating.outputs.security }}"
echo "Best/Allowed Security Score: ${{ steps.fetch-security-rating.outputs.best_security_score }}"
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONARQUBE_PROJECT_KEY: ${{ secrets.SONARQUBE_PROJECT_KEY }}
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
- name: "Print Security Rating"
run: |
echo "Security Score: ${{ steps.fetch-security-rating.outputs.security }}"
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 }}
reliability_score: ${{ steps.fetch-reliability-rating.outputs.reliability }}
best_reliability_score: ${{ steps.fetch-reliability-rating.outputs.best_reliability_score }}
security_score: ${{ steps.fetch-security-rating.outputs.security }}
best_security_score: ${{ steps.fetch-reliability-rating.outputs.best_security_score }}
opa-reliability-gate:
name: "🚧 Reliability gate"
runs-on: ubuntu-latest
needs:
- sonarqube
steps:
- name: "⏳ Validate Reliability score using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "http://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
# opaServerInput: '{"input": { "status": "${{needs.sonarqube.outputs.reliability_score}}", "metric": "unit-test"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.reliability_score}}", "metricName": "reliability_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa-security-gate:
name: "🚧 Security gate"
runs-on: ubuntu-latest
needs:
- sonarqube
steps:
- name: "⏳ Validate Security score using OPA"
uses: OpsVerseIO/[email protected]
with:
opaServerUrl: "http://opa-opsverse.int.devopsnow.io"
opaServerAuthToken: ${{ secrets.OPA_SERVER_AUTH_TOKEN }}
# opaServerInput: '{"input": { "status": "${{needs.sonarqube.outputs.security_score}}", "metric": "unit-test"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.security_score}}", "metricName": "security_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa:
name: "🚧 Unit tests gate"
runs-on: ubuntu-latest
needs:
- sonarqube
steps:
- name: "Print Output"
run: |
echo ${{needs.sonarqube.outputs.sonarcloud_output}}
echo ${{needs.sonarqube.outputs.sonar_quality_gate_project_status}}
- 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.sonarqube.outputs.sonarcloud_output}}", "metric": "unit-test"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.security_score}}", "metricName": "security_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa-code-coverage:
name: "🚧 Code coverage gate"
runs-on: ubuntu-latest
needs:
- sonarqube
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": "code-coverage"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.security_score}}", "metricName": "security_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
opa-sonarqube:
name: "🚧 Static code analysis gate"
runs-on: ubuntu-latest
needs:
- sonarqube
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"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.security_score}}", "metricName": "security_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
build:
name: "πŸ“¦ Build docker image and push to Amazon ECR"
runs-on: ubuntu-latest
env:
APP_NAME: hello-world-api-dotnet
needs:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
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: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
- name: "πŸ”’ Login to Amazon ECR πŸ”“"
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: "πŸ“¦πŸ“‚ Build, tag, and push docker image to Amazon ECR"
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: "hello-world-api-dotnet"
IMAGE_TAG: ${{ env.SHORT_SHA }}
run: |
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
update-image-stage:
name: "πŸ“ Update STAGE image tag"
runs-on: ubuntu-latest
needs:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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 DEV manifest file"
uses: OpsVerseIO/[email protected]
with:
repository: "OpsVerseIO/deployment-manifests"
valueFile: 'hello-world-api-dotnet/helm/stage/values.yaml'
propertyPath: 'helloworldapidotnet.image.tag'
value: '${{ env.SHORT_SHA }}'
branch: main
createPR: false
message: '[STAGE] Update Image tag of hello-world-api-dotnet'
token: ${{ secrets.GH_PAT }}
workDir: main
masterBranchName: main
targetBranch: main
force: true
updateFile: true
release-stage:
name: "πŸš€ Deploy to STAGE (ArgoCD Sync)"
runs-on: ubuntu-latest
needs:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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 }}
disableTlsVerification: "true"
- 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:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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"}}'
opaServerInput: '{"input": { "metricValue": "${{needs.sonarqube.outputs.reliability_score}}", "metricName": "reliability_rating"}}'
opaServerPackageName: "example/include"
skipTlsValidation: true
update-image-prod:
name: "πŸ“ Update prod image tag"
runs-on: ubuntu-latest
needs:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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/deployment-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"
valueFile: 'hello-world-api-dotnet/helm/prod/values.yaml'
propertyPath: 'helloworldapidotnet.image.tag'
value: '${{ env.SHORT_SHA }}'
branch: main
createPR: false
message: '[PROD] Update Image tag of hello-world-api-dotnet'
token: ${{ secrets.GH_PAT }}
workDir: main
masterBranchName: main
targetBranch: main
force: true
updateFile: true
release-prod:
environment:
name: production
name: "πŸš€ Deploy to PROD (ArgoCD Sync)"
needs:
- sonarqube
- opa-reliability-gate
- opa-security-gate
- opa
- opa-code-coverage
- opa-sonarqube
- 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 }}
disableTlsVerification: "true"
- 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"