Skip to content

update deploy process #6

update deploy process

update deploy process #6

Workflow file for this run

name: Deploy

Check failure on line 1 in .github/workflows/deploy.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/deploy.yml

Invalid workflow file

(Line: 13, Col: 14): Unrecognized named-value: 'github'. Located at position 1 within expression: github.event.inputs.environment
on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'staging'
type: choice
options:
- staging
- ${{ github.event.inputs.environment }}
env:
AWS_REGION: us-east-1
PROJECT_NAME: mindsdb
# # AWS credentials
# AWS_GIT_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
# AWS_GIT_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# AWS_REGION: us-east-1
# # For clonning private composer dependencies
# COMPOSER_AUTH: '{"github-oauth": { "github.com": "${{ secrets.GIT_COMPOSER_AUTH }}" } }'
# # Kubernetes
# PROJECT_NAME: mindsdb
# KUBE_EKS_CLUSTER: programmatic-ad-prod-cluster
# #
# CONTAINER_REPOSITORY_URI: "124082513016.dkr.ecr.us-east-1.amazonaws.com/mindsdb"
# ENVIRONMENT: prod
jobs:
deploy:
# if: github.ref == 'refs/heads/main'
name: Deploy to ${{ github.event.inputs.environment }}
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.environment }}
# Custom environment variables
# reference: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idenv
env:
# Variables need be change on each environment
ENVIRONMENT: ${{ github.event.inputs.environment }}
KUBE_EKS_CLUSTER: programmatic-ad-prod-cluster
K8S_NAMESPACE: mindsdb
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set Python version
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- 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: ${{ secrets.AWS_REGION }}
mask-aws-account-id: "true"
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: "true"
# references:
# https://docs.github.com/en/actions/learn-github-actions/environment-variables#passing-values-between-steps-and-jobs-in-a-workflow
# https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context
- name: Generate new APP_VERSION and publish release
id: generate_app_version
run: |
APP_VERSION="$(date +'%Y-%m-%d_%H%M%S')"
APP_LATEST_IMAGE_VERSION="${APP_VERSION}"
MIGRATION_JOB_NAME=$(echo $APP_LATEST_IMAGE_VERSION | sed s/_/-/g)
echo "MIGRATION_JOB_NAME=${MIGRATION_JOB_NAME}" >> $GITHUB_ENV
echo "APP_VERSION=${APP_VERSION}" >> $GITHUB_ENV
echo "APP_LATEST_IMAGE_VERSION=${APP_LATEST_IMAGE_VERSION}" >> $GITHUB_ENV
echo GIT_LAST_COMMIT_MESSAGE=\"$(git log -n 1 --format=%s)\" >> $GITHUB_ENV
env:
TZ: America/Sao_Paulo
- name: Log in K8S
run: |
aws eks update-kubeconfig --region ${{ secrets.AWS_REGION }} --name ${{ env.KUBE_EKS_CLUSTER }}
#|
#| Update secret APP_VERSION
#|
- name: "[${{ env.ENVIRONMENT }}] mindsdb: update Secret 'APP_VERSION'"
env:
K8S_NAMESPACE: mindsdb
run: |
kubectl patch secret -n mindsdb mindsdb-all -p="{\"data\":{\"APP_VERSION\":\"$(echo -n $APP_VERSION | base64)\"}}"
# #|
# #| Build main image
# #|
- name: Build and push - mindsdb base
uses: docker/build-push-action@v6
with:
target: web-base
context: .
file: var/docker/Dockerfile
push: true
build-args: |
APP_VERSION=${{ env.APP_VERSION }}
GH_AUTH=${{ secrets.GIT_COMPOSER_AUTH }}
tags: |
${{ env.CONTAINER_REPOSITORY_URI }}:web-prod-${{ env.APP_LATEST_IMAGE_VERSION }}
${{ env.CONTAINER_REPOSITORY_URI }}:web-prod-latest
cache-from: type=gha
cache-to: type=gha,mode=max
# Trivy vulnerability scanner — FS (IaC + dependências) em tabela
- name: Trivy FS (table)
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
scan-ref: .
ignore-unfixed: true
severity: CRITICAL,HIGH
format: table
output: trivy-fs.table.txt
exit-code: 0 # opcional: não falha o job; remova se quiser falhar em vulnerabilidade
# Trivy vulnerability scanner — Repo (SBOM/deps) em tabela
- name: Trivy Repo (table)
uses: aquasecurity/trivy-action@master
with:
scan-type: repo
scan-ref: .
ignore-unfixed: true
severity: CRITICAL,HIGH
format: table
output: trivy-repo.table.txt
exit-code: 0
# Trivy vulnerability scanner — FS em JSON (para parsing/CI)
- name: Trivy FS (json)
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
scan-ref: .
ignore-unfixed: true
severity: CRITICAL,HIGH
format: json
output: trivy-fs.json
exit-code: 0
# Trivy vulnerability scanner
- name: Verificar vulnerabilidades na imagem Docker
uses: aquasecurity/trivy-action@0.28.0
with:
scan-type: 'image'
image-ref: '${{ env.CONTAINER_REPOSITORY_URI }}:web-${{ env.ENVIRONMENT }}-${{ env.APP_LATEST_IMAGE_VERSION }}'
format: 'table'
exit-code: '0' # Não falhará se encontrar vulnerabilidades
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
output: trivy-image.table.txt
# Escrever um relatório no Job Summary com os relatórios em tabela
- name: Montar Job Summary
if: always()
run: |
{
echo "## Trivy — Sumário"
echo ""
echo "### FS (table)"
echo '```'
sed -n '1,200p' trivy-fs.table.txt
echo '```'
echo ""
echo "### Repo (table)"
echo '```'
sed -n '1,200p' trivy-repo.table.txt
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
# Upload de TODOS os relatórios gerados
- name: Upload dos Relatórios Trivy
if: always()
uses: actions/upload-artifact@v4
with:
name: trivy-reports
path: |
trivy-fs.table.txt
trivy-repo.table.txt
trivy-fs.json
trivy-image.table.txt
retention-days: 1
#| Create release
- run: npm install axios
- uses: actions/github-script@v6
name: "Create release"
with:
script: |
const script = require('./.github/workflows/create_release.js')
await script({github, context})
env:
# https://app.shortcut.com/talentify/story/40035
SHORTCUT_API_TOKEN: ${{ secrets.SHORTCUT_API_TOKEN }}
#|
#| Namespace: web / migrations
#|
- name: "[prod] migrations: update and run migrations job"
env:
K8S_NAMESPACE: mindsdb
run: |
sed -i 's/MIGRATION_JOB_NAME/${{ env.MIGRATION_JOB_NAME }}/g' ./var/kubernetes/${{ env.ENVIRONMENT }}/web/migrations.yaml
sed -i 's/WEB_TAG_TEMPLATE/web-prod-${{ env.APP_LATEST_IMAGE_VERSION }}/g' ./var/kubernetes/${{ env.ENVIRONMENT }}/web/migrations.yaml
kubectl apply -f ./var/kubernetes/${{ env.ENVIRONMENT }}/web/migrations.yaml -n ${{ env.K8S_NAMESPACE }}
sleep 5
# kubectl wait --for=condition=complete --timeout=3600s job/mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }} -n ${{ env.K8S_NAMESPACE }}
# please, note that the k8s job also has a timeout defined by "ttlSecondsAfterFinished"
- name: Wait for Job migrations complete
id: wait-migrations
if: ${{ always() }}
run: |
while true; do
STATUS=$(kubectl get job mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }} -n ${{ env.K8S_NAMESPACE }} -o jsonpath='{.status.conditions[?(@.type=="Complete")].status}')
if [ "$STATUS" == "True" ]; then
echo "Job succeeded"
break
fi
STATUS=$(kubectl get job mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }} -n ${{ env.K8S_NAMESPACE }} -o jsonpath='{.status.conditions[?(@.type=="Failed")].status}')
if [ "$STATUS" == "True" ]; then
echo "Job failed"
break
fi
echo "Waiting for job to complete..."
sleep 2
done
- name: Get migrations Pod Names
if: ${{ always() }}
id: get-pod-names
run: |
POD_NAMES=$(kubectl get pods -n ${{ env.K8S_NAMESPACE }} -l job-name=mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }} -o jsonpath='{.items[*].metadata.name}')
echo "POD_NAMES=${POD_NAMES}" >> $GITHUB_ENV
- name: Save Migrations Logs
if: ${{ always() }}
id: check-status
run: |
STATUS=$(kubectl get job mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }} -n ${{ env.K8S_NAMESPACE }} -o jsonpath='{.status.conditions[?(@.type=="Complete")].status}')
PODS=(${{ env.POD_NAMES }})
for POD in "${PODS[@]}"; do
echo "========== log pod: $POD =============" >> "mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}.txt"
kubectl logs pod/$POD -n ${{ env.K8S_NAMESPACE }} >> "mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}.txt"
echo "==========================================" >> "mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}.txt"
done
if [ "$STATUS" != "True" ]; then
echo "Job failed"
exit 1
fi
echo "Job succeeded"
- name: Show Migrations Logs
if: ${{ always() }}
run: |
cat mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}.txt
- name: Upload Migrations Logs Artifact
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}
path: mindsdb-migrations-${{ env.MIGRATION_JOB_NAME }}.txt
retention-days: 1
#|
#| Namespace: cronjob
#|
# ## Nesse método estou dando apply em todo o diretório /cronjob logo se adicionar um arquivo novo ele será adicionado no próximo deploy
# - name: "[${{ env.ENVIRONMENT }}] cronjob: update configurations for cronjobs"
# id: deployment
# env:
# K8S_NAMESPACE: mindsdb
# run: |
# FILES=$(cd var/kubernetes/${{ env.ENVIRONMENT }}/cronjob && ls *.yaml)
# for pod_name in $FILES; do
# echo "Updating CronJob $pod_name"
# sed -i 's/WEB_TAG_TEMPLATE/web-${{ env.ENVIRONMENT }}-${{ env.APP_LATEST_IMAGE_VERSION }}/g' ./var/kubernetes/${{ env.ENVIRONMENT }}/cronjob/$pod_name
# kubectl apply -f ./var/kubernetes/${{ env.ENVIRONMENT }}/cronjob/$pod_name -n ${{ env.K8S_NAMESPACE }}
# done
#|
#| Deploy web
#|
- name: "[${{ env.ENVIRONMENT }}] web: update image for workload 'mindsdb-web', container 'mindsdb-web'."
id: deployment
env:
K8S_NAMESPACE: mindsdb
run: |
sed -i 's/WEB_TAG_TEMPLATE/web-${{ env.ENVIRONMENT }}-${{ env.APP_LATEST_IMAGE_VERSION }}/g' ./var/kubernetes/${{ env.ENVIRONMENT }}/web/deployment.yaml
kubectl config use-context arn:aws:eks:us-east-1:124082513016:cluster/${{ env.KUBE_EKS_CLUSTER }}
kubectl apply -f ./var/kubernetes/${{ env.ENVIRONMENT }}/web/deployment.yaml -n ${{ env.K8S_NAMESPACE }}
- uses: actions/checkout@v4
- name: Create Sentry release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ env.PROJECT_NAME }}
with:
environment: prod
version: ${{ env.APP_VERSION }}
- name: Status
id: status
if: ${{ always() }}
env:
BLOCK_FAILURE: ff2500
BLOCK_SUCCESS: 2b8a3e
run: |
if [[ "${{ steps.deployment.outcome }}" != 'success' ]]; then
echo ${{ steps.deployment.outcome }}
echo "flag=${{ steps.deployment.outcome }} :red_circle:" >> $GITHUB_OUTPUT
echo "block=${{ env.BLOCK_FAILURE }}" >> $GITHUB_OUTPUT
else
echo ${{ steps.deployment.outcome }}
echo "flag=${{ steps.deployment.outcome }} :large_green_circle:" >> $GITHUB_OUTPUT
echo "block=${{ env.BLOCK_SUCCESS }}" >> $GITHUB_OUTPUT
fi
#|
#| Notify
#|
# reference: https://github.com/slackapi/slack-github-action#technique-3-slack-incoming-webhook
# Create your app or use mine: https://api.slack.com/apps/A037R2Q23RQ
# Copy the "Webhook URL" and then add it in GitHub secret called "SLACK_WEBHOOK_URL".
- name: Notify about the new deployment
id: slack
if: ${{ always() }}
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
# For posting a rich message using Block Kit
payload: |
{
"attachments": [
{
"color": "${{ steps.status.outputs.block }}",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Deploy - ${{ env.PROJECT_NAME }} - env: ${{ env.ENVIRONMENT }} - Created by: ${{ github.actor }}",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Status:* ${{ steps.status.outputs.flag }} - *Version:* <${{ env.RELEASE_URL }}|${{ env.APP_VERSION }}> - *Branch:* <${{ github.server_url }}/${{ github.repository }}/tree/${{ github.ref_name }}|${{ github.ref_name }}>"
}
}
]
}
]
}
env:
RELEASE_URL: ${{ github.server_url }}/${{ github.repository }}/releases/tag/v${{ env.APP_VERSION }}