diff --git a/.github/custom-actions/npm-action/action.yml b/.github/custom-actions/npm-action/action.yml new file mode 100644 index 000000000..9198ef7d4 --- /dev/null +++ b/.github/custom-actions/npm-action/action.yml @@ -0,0 +1,18 @@ +name: 'NPM Custom Action' +description: 'Installing and Caching NPM Packages' +inputs: + path-of-folder: #id of input + description: 'the path to cache' + required: true +runs: + using: "composite" + steps: + - name: Cache NPM dependencies + uses: actions/cache@v6.1.0 + with: + path: ${{ inputs.path-of-folder }} + key: '${{ runner.os }}-node-modules-${{ hashFiles(''package-lock.json'') }}' + + - name: Install Dependencies + run: npm install + shell: bash \ No newline at end of file diff --git a/.github/workflows/reusable-workflow.yml b/.github/workflows/reusable-workflow.yml new file mode 100644 index 000000000..329751317 --- /dev/null +++ b/.github/workflows/reusable-workflow.yml @@ -0,0 +1,16 @@ +name: Testing - Reusable Workflow +on: + workflow_call: + inputs: + ingress-url: + description: Provide the Ingress URL + required: true + type: string +jobs: + integration-test: + runs-on: ubuntu-latest + steps: + - env: + URL: '${{ inputs.ingress-url }}' + run: | + curl https://$URL/live -s -k | jq -r .status | grep -i live \ No newline at end of file diff --git a/.github/workflows/reuse-deployment.yml b/.github/workflows/reuse-deployment.yml new file mode 100644 index 000000000..ec36f3feb --- /dev/null +++ b/.github/workflows/reuse-deployment.yml @@ -0,0 +1,116 @@ +name: Deployment- Reusable Workflow + +on: + workflow_call: + inputs: + mongodb-uri: + required: true + type: string + kubectl-version: + description: Provide the required Kubectl version + default: v1.26.0 + required: false + type: string + k8s-manifest-dir: + description: Directory containing Kubernetes manifests files + default: kubernetes/ + required: true + type: string + environment: + description: Provide the Deployment Environment + default: developtment + required: true + type: string + outputs: + application-url: + value: "${{ jobs.reuse-deploy.outputs.APP_INGRESS_URL }}" + secrets: + # k8s-kubeconfig: + # required: true + mongodb-password: + required: true +jobs: + reuse-deploy: + environment: + name: ${{ inputs.environment }} + # url: https://${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }} + # outputs: + # APP_INGRESS_URL: ${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }} + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Kubectl CLI + uses: Azure/setup-kubectl@v5.1.0 + with: + version: '${{ inputs.kubectl-version }}' + + - name: Install Cluster + uses: helm/kind-action@v1.14.0 + + - name: Test Pod Deployment + run: | + sleep 5 + kubectl -n kube-system get pod + set +e + REPO_OWNER_LC="${GITHUB_REPOSITORY_OWNER,,}" + kubectl run solar --image ghcr.io/${REPO_OWNER_LC}/solar-system:${{ github.sha }} \ + --env MONGO_URI=${{ env.MONGO_URI}} \ + --env MONGO_USERNAME=${{ env.MONGO_USERNAME}} \ + --env MONGO_PASSWORD=${{ env.MONGO_PASSWORD}} + set -e + echo "kubectl returned $?" + kubectl -n default get pod + sleep 10 + + # - name: Set Kubeconfig file + # uses: Azure/k8s-set-context@v5.0.1 + # with: + # method: kubeconfig + # kubeconfig: ${{ secrets.k8s-kubeconfig }} + + # - name: Fetch Kubernetes Cluster Details + # run: | + # kubectl version --short + # echo ---------------------------- + # kubectl get nodes + + # - name: Save Nginx Ingress Controller IP as a GITHUB environment variable + # run: | + # echo "INGRESS_IP=$(kubectl -n ingress-nginx get services ingress-nginx-controller -o jsonpath="{.status.loadbalancer.ingress[0]}")" >> $GITHUB_ENV + + # - name: Replace Tokens in manifest Files + # uses: cschleiden/replace-tokens@v1.4 + # with: + # tokenPrefix: '_{_' + # tokenSuffix: '_}_' + # files: '["${{ inputs.k8s-manifest-dir }}*.yaml"]' + # env: + # NAMESPACE: ${{ vars.NAMESPACE }} + # REPLICAS: ${{ vars.REPLICAS }} + # IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/solar-system:${{ github.sha }} + # # INGESS_IP: ${{ env.INGESS_IP }} + + # - name: Check Files + # run: | + # cat ${{ inputs.k8s-manifest-dir }}*.yaml + + # - name: Create MongoDB Secret + # run: | + # kubectl -n ${{ vars.NAMESPACE }} create secret generic mongo-db-creds \ + # --from-literal=MONGO_URI=${{ inputs.mongodb-uri }} \ + # --from-literal=MONGO_USERNAME=${{ vars.MONGO_USERNAME }} \ + # --from-literal=MONGO_PASSWORD=${{ secrets.mongodb-password }} \ + # --save-config \ + # --dry-run=client \ + # -o yaml | kubectl apply -f - + + # - name: Deploy To Dev Env + # run: | + # kubectl apply -f ${{ inputs.k8s-manifest-dir }} + + # - name: Set App Ingress Host URL + # id: set-ingress-host-address + # run: | + # echo "APP_INGRESS_HOST=$(kubectl -n ${{ vars.NAMESPACE }} get ingress -o jsonpath "{.items[0].spec.tls[0]}")" >> $GITHUB_OUTPUT \ No newline at end of file diff --git a/.github/workflows/script-injection-test.yml b/.github/workflows/script-injection-test.yml new file mode 100644 index 000000000..da86f149a --- /dev/null +++ b/.github/workflows/script-injection-test.yml @@ -0,0 +1,24 @@ +name: Label Issues (Script Injection) +on: + workflow_dispatch: + issues: + types: + - opened +jobs: + assign-label: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + + - name: Add a Label + env: + AWS_SECRET_ACCESS_KEY: 'im a secret' + + run: | + issue_title == "${{ github.event.issue.title }}" + if [[ "$issue_title" == *"bug"* ]]; then + echo "Issue is about a bug!" + echo "Assigning Label - BUG .... .... .... ...." + else + echo "Not a bug" + fi \ No newline at end of file diff --git a/.github/workflows/solar-system.yml b/.github/workflows/solar-system.yml index d56aa02f7..5e9bbafd2 100644 --- a/.github/workflows/solar-system.yml +++ b/.github/workflows/solar-system.yml @@ -1,33 +1,289 @@ name: Solar System Workflow -on: +on: workflow_dispatch: push: branches: - main - 'feature/*' - +env: + MONGO_URI: mongodb+srv://supercluster.d83jj.mongodb.net/superData + MONGO_USERNAME: superuser + MONGO_PASSWORD: ${{secrets.MONGO_PASSWORD}} + jobs: - unit-testing: - name: Unit Testing - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Setup NodeJS Version - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install Dependencies - run: npm install + unit-testing: + name: Unit Testing + container: + image: node:20 + services: + mongodb: + image: siddharth67/mongo-db:non-prod + options: + --name mongo + # ports: + # - 27017:27017 + env: + MONGO_URI: mongodb://mongo:27017/superData + MONGO_USERNAME: non-prod-user + MONGO_PASSWORD: non-prod-password + strategy: + matrix: + nodejs_version: [18, 20] + operation_system: [ubuntu-latest] + runs-on: ${{ matrix.operation_system }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + # - name: Setup NodeJS Version - ${{ matrix.nodejs_version }} + # uses: actions/setup-node@v4 + # with: + # node-version: ${{ matrix.nodejs_version }} + + - name: Composite Action - Cache install NPM Packages + uses: ./.github/custom-actions/npm-action + with: + path-of-folder: ~/.npm - - name: Unit Testing - run: npm test + - name: Unit Testing + run: npm test - - name: Archive Test Result - uses: actions/upload-artifact@v4 - with: - name: Mocha-Test-Result - path: test-results.xml + - name: Archive Test Result + if: always() + uses: actions/upload-artifact@v7.0.1 + with: + name: Mocha-Test-Result + path: test-results.xml + + code-coverage: + name: code-coverage + container: + image: node:18 + services: + mongodb: + image: siddharth67/mongo-db:non-prod + options: + --name mongo + env: + MONGO_URI: mongodb://mongo:27017/superData + MONGO_USERNAME: non-prod-user + MONGO_PASSWORD: non-prod-password + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + # - name: Setup NodeJS Version + # uses: actions/setup-node@v4 + # with: + # node-version: 18 + + - name: Install Dependencies + run: npm install + + - name: Run Code coverage + continue-on-error: true + run: npm run coverage + + - name: Archive Test Result + uses: actions/upload-artifact@v7.0.1 + with: + name: Code-Coverage-Result + path: coverage + retention-days: 5 + + reports-s3: + needs: + - code-coverage + - unit-testing + name: AWS S3 - Upload Reports + runs-on: ubuntu-latest + continue-on-error: true + steps: + - name: Download Mocha Test Artifact + uses: actions/download-artifact@v8.0.1 + with: + name: Mocha-Test-Result + + - name: Download Code Coverage Artifact + uses: actions/download-artifact@v8.0.1 + with: + name: Code-Coverage-Result + + - name: Merge Test Files + run: | + ls -ltr + mkdir reports-${{ github.sha }} + mv cobertura-coverage.xml reports-${{ github.sha }}/ + mv test-results.xml reports-${{ github.sha }}/ + ls -ltr reports-${{ github.sha }}/ + + - name: Upload to AWS S3 + run: echo "Uploading......." + + docker: + permissions: + packages: write + needs: [unit-testing, code-coverage] + name: containerization + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: DockeHub Login + uses: docker/login-action@v4.6.0 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: GHCR Login + uses: docker/login-action@v4.6.0 + with: + registry: ghcr.io + username: ${{ github.Repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker build for testing + uses: docker/build-push-action@v7.3.0 + with: + context: . #Dockerfile location + push: false + tags: eliorsofer123/solar-system:${{ github.sha }} + + - name: Docker Image Testing + run: | + docker images + docker run --name solar-system-app -d \ + -p 3000:3000 \ + -e MONGO_URI=$MONGO_URI \ + -e MONGO_USERNAME=$MONGO_USERNAME \ + -e MONGO_PASSWORD=$MONGO_PASSWORD \ + eliorsofer123/solar-system:${{ github.sha }} + + export IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' solar-system-app) + echo $IP + + echo Testing Image URL using wget + wget -q -O - 127.0.0.1:3000/live | grep live + + - name: Container Registry Push + uses: docker/build-push-action@v7.3.0 + with: + context: . #Dockerfile location + push: true + tags: | + ${{ vars.DOCKERHUB_USERNAME }}/solar-system:${{ github.sha }} + ghcr.io/${{ github.Repository_owner }}/solar-system:${{ github.sha }} + + dev-deploy: + if: contains(github.ref, 'feature/') + name: dev-deploy + needs: docker + uses: ./.github/workflows/reuse-deployment.yml + secrets: + # k8s-kubeconfig: ${{ secrets.KUBECONFIG }} + mongodb-password: ${{ secrets.MONGO_PASSWORD }} + with: + mongodb-uri: ${{ vars.MONGO_URI }} + environment: development + k8s-manifest-dir: kubernetes/development/ + + # dev-integration-testing: + # if: contains(github.ref, 'feature/') + # name: Dev integration-testing + # needs: dev-deploy + # runs-on: ubuntu-latest + # steps: + # - name: Test URL Output using Curl and JQ + # env: + # URL: ${{ needs.dev-deploy.outputs.application-url }} + # run: | + # echo URL: ${{ env.APP_INGRESS_HOST }} + # echo "---------------------------------" + # curl https://${{ env.OUTPUT }}/live -s -k | jq -r .status | grep -i live + + prod-deploy: + if: github.ref == 'refs/heads/main' + name: prod-deploy + needs: docker + environment: + name: production + # url: https://${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }} + # outputs: + # APP_INGRESS_URL: ${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }} + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Kubectl CLI + uses: Azure/setup-kubectl@v5.1.0 + with: + version: '1.26.0' + + # - name: Set Kubeconfig file + # uses: Azure/k8s-set-context@v5.0.1 + # with: + # method: kubeconfig + # kubeconfig: ${{ secrets.KUBECONFIG }} + + # - name: Fetch Kubernetes Cluster Details + # run: | + # kubectl version --short + # echo ---------------------------- + # kubectl get nodes + + # - name: Save Nginx Ingress Controller IP as a GITHUB environment variable + # run: | + # echo "INGRESS_IP=$(kubectl -n ingress-nginx get services ingress-nginx-controller -o jsonpath="{.status.loadbalancer.ingress[0]}")" >> $GITHUB_ENV + + # - name: Replace Tokens in manifest Files + # uses: cschleiden/replace-tokens@v1.4 + # with: + # tokenPrefix: '_{_' + # tokenSuffix: '_}_' + # files: '["kubernetes/production/*.yaml"]' + # env: + # NAMESPACE: ${{ vars.NAMESPACE }} + # REPLICAS: ${{ vars.REPLICAS }} + # IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/solar-system:${{ github.sha }} + # # INGESS_IP: ${{ env.INGESS_IP }} + + # - name: Check Files + # run: | + # cat kubernetes/production/*.yaml + + # - name: Create MongoDB Secret + # run: | + # kubectl -n ${{ vars.NAMESPACE }} create secret generic mongo-db-creds \ + # --from-literal=MONGO_URI=${{ env.MONGO_URI }} \ + # --from-literal=MONGO_USERNAME=${{ vars.MONGO_USERNAME }} \ + # --from-literal=MONGO_PASSWORD=${{ secrets.MONGO_PASSWORD }} \ + # --save-config \ + # --dry-run=client \ + # -o yaml | kubectl apply -f - + + # - name: Deploy To Prod Env + # run: | + # kubectl apply -f kubernetes/production + + # - name: Set App Ingress Host URL + # id: set-ingress-host-address + # run: | + # echo "APP_INGRESS_HOST=$(kubectl -n ${{ vars.NAMESPACE }} get ingress -o jsonpath "{.items[0].spec.tls[0]}")" >> GITHUB_OUTPUT + + # prod-integration-testing: + # if: github.ref == 'refs/heads/main' + # name: Prod integration-testing + # needs: prod-deploy + # runs-on: ubuntu-latest + # steps: + # - name: Test URL Output using Curl and JQ + # env: + # URL: ${{ needs.prod-deploy.outputs.APP_INGRESS_URL }} + # run: | + # echo URL: ${{ env.APP_INGRESS_HOST }} + # echo "---------------------------------" + # curl https://${{ env.OUTPUT }}/live -s -k | jq -r .status | grep -i live