Skip to content

nolanpro send deploy EKS 🚀 #118

nolanpro send deploy EKS 🚀

nolanpro send deploy EKS 🚀 #118

Workflow file for this run

name: deploy-k8s
run-name: ${{ github.actor }} send deploy EKS 🚀
on:
pull_request:
types: [opened, reopened, synchronize, edited, closed]
#schedule:
# - cron: '30 2 * * *' # run daily
workflow_dispatch:
inputs:
delete:
description: 'CI Instance ID to delete. If present, all other jobs will be skipped.'
required: false
default: 'false'
workflow_call:
env:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
AWS_URL: ${{ secrets.AWS_URL }}
pull_req_id: ${{github.event.pull_request.number}}
DATE: $(date -d '-1 day' '+%Y-%m-%d'|sed 's/-//g')
CURRENT_DATE: $(date '+%Y-%m-%d %H:%M:%S'|sed 's/-//g')
CI_PACKAGE_BRANCH: ${{ github.event.pull_request.head.ref || github.event.ref || 'develop' }}
CI_PROJECT: ${{github.event.pull_request.head.repo.name || github.event.repository.name || 'processmaker' }}
CI_PR_BODY: ${{ github.event_name == 'schedule' && 'No ci tags needed here' || github.event.pull_request.body }}
IMAGE_TAG: $(echo "$CI_PROJECT-$CI_PACKAGE_BRANCH" | sed "s;/;-;g" | sed "s/refs-heads-//g")
DEPLOY: ${{ secrets.DEPLOY }}
GH_USER: ${{ secrets.GH_USER }}
GH_EMAIL: ${{ secrets.GH_EMAIL }}
DOM_EKS: ${{ secrets.DOM_EKS }}
GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }}
BUILD_BASE: ${{ (contains(github.event.pull_request.body, 'ci:build-base') || github.event_name == 'schedule') && '1' || '0' }}
MULTITENANCY: ${{ (contains(github.event.pull_request.body, 'ci:multitenancy')) && 'true' || 'false' }}
BASE_IMAGE: ${{ secrets.REGISTRY_HOST }}/processmaker/processmaker:base
CUSTOMER_LICENSES_PAT: ${{ secrets.CUSTOMER_LICENSES_PAT }}
# K8S_BRANCH: ${{ contains(github.event.pull_request.body, 'ci:next') && 'next' || 'release-2024-fall' }}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
imageEKS:
name: build-docker-image-EKS
if: github.event.action != 'closed' && inputs.delete == 'false'
runs-on: ${{ vars.RUNNER }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: processmaker/.github
- name: Common
uses: ./.github/actions/common
with:
token: ${{ secrets.GIT_TOKEN }}
- name: Set image name
run: |
echo "IMAGE=${{ secrets.REGISTRY_HOST }}/processmaker/enterprise:$RESOLVED_IMAGE_TAG" >> $GITHUB_ENV
- name: Generate image EKS
if: ${{ !contains(github.event.pull_request.body, 'ci:skip-build') }}
run: |
cd pm4-k8s-distribution/images
export CI_RELEASE_BRANCH=$RELEASE_BRANCH
branch=$(echo "${{ env.CI_PACKAGE_BRANCH }}" | sed 's/refs-heads-//g') tag=${{env.IMAGE_TAG}} bash build.k8s-cicd.sh
echo "VERSION=${{ env.IMAGE_TAG }}" >> $GITHUB_ENV
- name: List Images
run: |
docker images
# - name: Run Trivy vulnerability scanner
# uses: aquasecurity/trivy-action@master
# with:
# image-ref: processmaker/enterprise:${{ env.VERSION }}
# format: 'table'
# exit-code: '0'
# ignore-unfixed: false
# vuln-type: 'os,library'
# scanners: 'vuln,secret'
# severity: 'MEDIUM,HIGH,CRITICAL'
# env:
# TRIVY_TIMEOUT: 30m
- name: Login to Harbor
uses: docker/login-action@v2
with:
registry: ${{ secrets.REGISTRY_HOST }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Push Enterprise Image to Harbor
if: ${{ !contains(github.event.pull_request.body, 'ci:skip-build') }}
run: |
docker tag processmaker/enterprise:${{env.IMAGE_TAG}} ${{ secrets.REGISTRY_HOST }}/processmaker/enterprise:${{env.IMAGE_TAG}}
docker push ${{ secrets.REGISTRY_HOST }}/processmaker/enterprise:${{env.IMAGE_TAG}}
deployEKS:
name: deploy-EKS
if: contains(github.event.pull_request.body, 'ci:deploy')
needs: imageEKS
runs-on: ${{ vars.RUNNER }}
steps:
- name: Checkout .github repo
uses: actions/checkout@v4
with:
repository: processmaker/.github
ref: multitenancy
- name: Common
uses: ./.github/actions/common
with:
token: ${{ secrets.GIT_TOKEN }}
- name: Install pm4-tools
run: |
cd pm4-k8s-distribution/images/pm4-tools
composer install --no-interaction
cd ..
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Set up kubectl
run: |
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
echo ${{ secrets.AWS_ACCESS_KEY_ID }} | md5sum
- name: Authenticate with Amazon EKS
run: aws eks update-kubeconfig --region us-east-1 --name pm4-eng
- name: Deploy instance EKS
env:
IMAGE_TAG: ${{ env.IMAGE_TAG }}
CURRENT_DATE: ${{ env.CURRENT_DATE }}
HELM_REPO: ${{ secrets.HELM_REPO }}
HELM_USERNAME: ${{ secrets.HELM_USERNAME }}
HELM_PASSWORD: ${{ secrets.HELM_PASSWORD }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPEN_AI_SECRET: ${{ secrets.OPENAI_API_KEY }}
ANALYTICS_AWS_ACCESS_KEY: ${{ secrets.ANALYTICS_AWS_ACCESS_KEY }}
ANALYTICS_AWS_SECRET_KEY: ${{ secrets.ANALYTICS_AWS_SECRET_KEY }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
REGISTRY_HOST: ${{ secrets.REGISTRY_HOST }}
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
TWILIO_SID: ${{ secrets.TWILIO_SID }}
TWILIO_TOKEN: ${{ secrets.TWILIO_TOKEN }}
versionHelm: ${{ env.versionHelm }}
DOM_EKS: ${{ env.DOM_EKS }}
KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}
KEYCLOAK_PASSWORD: ${{ secrets.KEYCLOAK_PASSWORD }}
CUSTOMER_LICENSES_PAT: ${{ secrets.CUSTOMER_LICENSES_PAT }}
RDS_ADMIN_USERNAME: ${{ secrets.RDS_ADMIN_USERNAME }}
RDS_ADMIN_PASSWORD: ${{ secrets.RDS_ADMIN_PASSWORD }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
instance=$(echo -n ${{env.IMAGE_TAG}} | md5sum | head -c 10)
echo "INSTANCE: $instance"
echo "IMAGE_TAG: $IMAGE_TAG"
sed -i "s#{{INSTANCE}}#$instance#g" .github/scripts/deploy-instance.sh
sed -i "s#{{INSTANCE}}#$instance#g" .github/templates/instance.yaml
sed -i "s#{{INSTANCE}}#$instance#g" .github/templates/db.yaml
sed -i "s#{{IMAGE_TAG}}#$IMAGE_TAG#g" .github/templates/instance.yaml
sed -i "s#{{KEYCLOAK_CLIENT_SECRET}}#$KEYCLOAK_CLIENT_SECRET#g" .github/templates/instance.yaml
sed -i "s#{{KEYCLOAK_PASSWORD}}#$KEYCLOAK_PASSWORD#g" .github/templates/instance.yaml
sed -i "s#{{CUSTOMER_LICENSES_PAT}}#$CUSTOMER_LICENSES_PAT#g" .github/templates/instance.yaml
sed -i "s#{{MYSQL_USER}}#$RDS_ADMIN_USERNAME#g" .github/templates/instance.yaml
sed -i "s#{{MYSQL_PASSWORD}}#$RDS_ADMIN_PASSWORD#g" .github/templates/instance.yaml
sed -i "s#{{MULTITENANCY}}#$MULTITENANCY#g" .github/templates/instance.yaml
sed -i "s#{{MYSQL_USERNAME}}#$RDS_ADMIN_USERNAME#g" .github/templates/db.yaml
sed -i "s#{{MYSQL_PASSWORD}}#$RDS_ADMIN_PASSWORD#g" .github/templates/db.yaml
echo "=== Checking instance.yaml after replacements ==="
cat .github/templates/instance.yaml
echo "=== Checking db.yaml after replacements ==="
cat .github/templates/db.yaml
chmod +x .github/scripts/deploy-instance.sh
bash .github/scripts/deploy-instance.sh
if [ "$MULTITENANCY" = "true" ]; then
export INSTANCE_URL="https://tenant-1.ci-$instance.engk8s.processmaker.net"
else
export INSTANCE_URL="https://ci-$instance.engk8s.processmaker.net"
fi
echo "Instance URL: $INSTANCE_URL"
bash .github/scripts/gh_comment.sh "$CI_PROJECT" "$pull_req_id"
runAPITest:
name: Run API Tests
needs: [deployEKS]
if: contains(github.event.pull_request.body, 'ci:api-test')
runs-on: ${{ vars.RUNNER }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: processmaker/.github
- name: Common
uses: ./.github/actions/common
with:
token: ${{ secrets.GIT_TOKEN }}
- name: Install pm4-tools
run: |
echo "versionHelm=$(grep "version:" "pm4-k8s-distribution/charts/enterprise/Chart.yaml" | awk '{print $2}' | sed 's/\"//g')" >> $GITHUB_ENV
cd pm4-k8s-distribution/images/pm4-tools
composer install --no-interaction
cd ..
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID1 }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY1 }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Set up kubectl
run: |
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
- name: Authenticate with Amazon EKS
run: aws eks update-kubeconfig --region us-east-1 --name pm4-eng
- name: Run the API tests
run: |
INSTANCE=$(echo -n ${{env.IMAGE_TAG}} | md5sum | head -c 10)
namespace="ci-$INSTANCE-ns-pm4"
pr_body=$(jq -r .pull_request.body < "$GITHUB_EVENT_PATH" | base64)
kubectl get pods --namespace=$namespace
pod_names=$(kubectl get pods --namespace=$namespace --field-selector=status.phase=Running -o jsonpath="{.items[*].metadata.name}" | tr ' ' '\n' | grep -E '(-processmaker-scheduler-)')
for pod in $pod_names; do
code='
has_processmaker=$(ls /opt | grep processmaker)
has_sudo=$(ls /usr/bin | grep sudo)
has_php=$(ls /usr/bin | grep php)
if [ ! -z "$has_processmaker" ] && [ ! -z "$has_sudo" ] && [ ! -z "$has_php" ]; then
echo $pr_body | base64 -d > /tmp/pr_body
cd /opt/processmaker
docker system prune -af
sudo -u nginx php artisan package-api-testing:run --body="$pr_body"
else
exit 1
fi'
kubectl exec -n $namespace $pod -- /bin/sh -c "pr_body='${pr_body}';${code}" | tee /tmp/comment.md && break || true
done
# Send the content of /tmp/comment.md as a PR comment
MESSAGE=$(cat /tmp/comment.md)
GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY=${{ github.repository }}
PR_NUMBER=$(jq -r .number < "$GITHUB_EVENT_PATH")
if [ -z "$PR_NUMBER" ]; then
echo "The PR number is not available. Make sure this script is executed in a context of Pull Request."
exit 1
fi
URL="https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments"
json_payload=$(jq -n --arg message "$MESSAGE" '{"body": $message}')
curl -s \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
-d "$json_payload" \
"${URL}"
deleteEKS:
name: Delete Instance
if: github.event.action == 'closed' || inputs.delete != 'false'
runs-on: self-hosted
steps:
- name: Delete instance EKS
run: |
# If inputs.delete does not equal 'false', set the IMAGE_TAG to the value of inputs.delete
if [ "${{ inputs.delete }}" != "false" ]; then
IMAGE_TAG=${{ inputs.delete }}
else
IMAGE_TAG=${{ env.IMAGE_TAG }}
fi
INSTANCE=$(echo -n $IMAGE_TAG | md5sum | head -c 10)
if kubectl get namespace/ci-$INSTANCE-ns-pm4 ; then
echo "Deleting Instace :: ci-$INSTANCE"
helm delete ci-$INSTANCE
kubectl delete namespace ci-$INSTANCE-ns-pm4
#Drop database
deploy_db="pm4_ci-${INSTANCE}%"
deploy_ai="\`pm4_ci-$INSTANCE_ai\`"
# check that that string length of $deploy_db is 12 or more as a safety check. If its less than 12, exit now
if [ ${#deploy_db} -lt 12 ]; then
exit 1
fi
# Drop the main database including any tenant databases
mysql -u${{ secrets.USER_MYSQL_ENG }} -p${{ secrets.PASS_MYSQL_ENG }} -h ${{ secrets.RDS_ENG }} -N -e "SHOW DATABASES LIKE '${deploy_db}'" | xargs -I{} mysql -u${{ secrets.USER_MYSQL_ENG }} -p${{ secrets.PASS_MYSQL_ENG }} -h ${{ secrets.RDS_ENG }} -e "DROP DATABASE IF EXISTS \`{}\`;"
mysql -u${{ secrets.USER_MYSQL_ENG }} -p${{ secrets.PASS_MYSQL_ENG }} -e "DROP DATABASE IF EXISTS $deploy_ai" -h ${{ secrets.RDS_ENG }}
mysql -u${{ secrets.USER_MYSQL_ENG }} -p${{ secrets.PASS_MYSQL_ENG }} -e "DROP USER IF EXISTS 'user_ci-$INSTANCE'@'%'" -h ${{ secrets.RDS_ENG }}
mysql -u${{ secrets.USER_MYSQL_ENG }} -p${{ secrets.PASS_MYSQL_ENG }} -e "DROP USER IF EXISTS 'user_ci-$INSTANCE_ai'@'%'" -h ${{ secrets.RDS_ENG }}
#Drop image Harbor
curl -X DELETE -u ${{ secrets.REGISTRY_USERNAME }}:${{ secrets.REGISTRY_PASSWORD }} "https://${{ secrets.REGISTRY_HOST }}/api/v2.0/projects/processmaker/repositories/enterprise/artifacts/${IMAGE_TAG}"
echo "The instance [https://ci-$INSTANCE.engk8s.processmaker.net] was deleted!!"
else
echo "The pull request does not have an instance on K8s [https://ci-$INSTANCE.engk8s.processmaker.net] not found!!"
fi
runPhpUnit:
name: run-phpunit
if: github.event.action != 'closed' && inputs.delete == 'false'
needs: imageEKS
runs-on: ${{ vars.RUNNER }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: processmaker/.github
- name: Common
uses: ./.github/actions/common
with:
token: ${{ secrets.GIT_TOKEN }}
- name: Export Params
run: |
echo "IMAGE=${{ secrets.REGISTRY_HOST }}/processmaker/enterprise:${{env.IMAGE_TAG}}" >> $GITHUB_ENV
# - uses: actions/checkout@v2
# with:
# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
# - name: Clone repo K8S
# run: |
# echo "IMAGE: ${{ env.IMAGE }}"
# git clone --depth 1 -b "$K8S_BRANCH" "https://[email protected]/ProcessMaker/pm4-k8s-distribution.git" pm4-k8s-distribution
- name: Login to Harbor
uses: docker/login-action@v2
with:
registry: ${{ secrets.REGISTRY_HOST }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: PHPUnits
run: |
cd pm4-k8s-distribution/images/pm4-tools
docker pull $IMAGE
docker compose down -v
docker compose build phpunit
docker compose run phpunit
CONTAINER_ID=$(sudo docker ps -a | grep phpunit | awk '{print $1}')
echo "Copying coverage report from PHP Unit Container: $CONTAINER_ID"
sudo docker cp $CONTAINER_ID:/opt/processmaker/coverage.xml coverage.xml
- name: Archive code coverage
uses: actions/upload-artifact@v4
with:
name: code-coverage
path: ./pm4-k8s-distribution/images/pm4-tools/coverage.xml
- name: SonarQube Coverage Report
uses: sonarsource/sonarqube-scan-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
with:
args: >
-Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }}
-Dsonar.sources=.
-Dsonar.tests=.
-Dsonar.test.inclusions=**/*Test.php
-Dsonar.php.coverage.reportPaths=./pm4-k8s-distribution/images/pm4-tools/coverage.xml