action config
parent
f6641c0f41
commit
52f42d12fc
@ -1,93 +0,0 @@
|
||||
name: Run Pytest
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- api/**
|
||||
- docker/**
|
||||
- .github/workflows/api-tests.yml
|
||||
|
||||
concurrency:
|
||||
group: api-tests-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: API Tests
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup UV and Python
|
||||
uses: ./.github/actions/setup-uv
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
uv-lockfile: api/uv.lock
|
||||
|
||||
- name: Check UV lockfile
|
||||
run: uv lock --project api --check
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --project api --dev
|
||||
|
||||
- name: Run Unit tests
|
||||
run: |
|
||||
uv run --project api bash dev/pytest/pytest_unit_tests.sh
|
||||
# Extract coverage percentage and create a summary
|
||||
TOTAL_COVERAGE=$(python -c 'import json; print(json.load(open("coverage.json"))["totals"]["percent_covered_display"])')
|
||||
|
||||
# Create a detailed coverage summary
|
||||
echo "### Test Coverage Summary :test_tube:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Total Coverage: ${TOTAL_COVERAGE}%" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
uv run --project api coverage report >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Run dify config tests
|
||||
run: uv run --project api dev/pytest/pytest_config_tests.py
|
||||
|
||||
- name: MyPy Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: api/.mypy_cache
|
||||
key: mypy-${{ matrix.python-version }}-${{ runner.os }}-${{ hashFiles('api/uv.lock') }}
|
||||
|
||||
- name: Run MyPy Checks
|
||||
run: dev/mypy-check
|
||||
|
||||
- name: Set up dotenvs
|
||||
run: |
|
||||
cp docker/.env.example docker/.env
|
||||
cp docker/middleware.env.example docker/middleware.env
|
||||
|
||||
- name: Expose Service Ports
|
||||
run: sh .github/workflows/expose_service_ports.sh
|
||||
|
||||
- name: Set up Sandbox
|
||||
uses: hoverkraft-tech/compose-action@v2.0.2
|
||||
with:
|
||||
compose-file: |
|
||||
docker/docker-compose.middleware.yaml
|
||||
services: |
|
||||
sandbox
|
||||
ssrf_proxy
|
||||
|
||||
- name: Run Workflow
|
||||
run: uv run --project api bash dev/pytest/pytest_workflow.sh
|
||||
|
||||
- name: Run Tool
|
||||
run: uv run --project api bash dev/pytest/pytest_tools.sh
|
||||
@ -1,149 +0,0 @@
|
||||
name: Build and Push API & Web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "deploy/dev"
|
||||
- "deploy/enterprise"
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
concurrency:
|
||||
group: build-push-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
DIFY_WEB_IMAGE_NAME: ${{ vars.DIFY_WEB_IMAGE_NAME || 'langgenius/dify-web' }}
|
||||
DIFY_API_IMAGE_NAME: ${{ vars.DIFY_API_IMAGE_NAME || 'langgenius/dify-api' }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.platform == 'linux/arm64' && 'arm64_runner' || 'ubuntu-latest' }}
|
||||
if: github.repository == 'langgenius/dify'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- service_name: "build-api-amd64"
|
||||
image_name_env: "DIFY_API_IMAGE_NAME"
|
||||
context: "api"
|
||||
platform: linux/amd64
|
||||
- service_name: "build-api-arm64"
|
||||
image_name_env: "DIFY_API_IMAGE_NAME"
|
||||
context: "api"
|
||||
platform: linux/arm64
|
||||
- service_name: "build-web-amd64"
|
||||
image_name_env: "DIFY_WEB_IMAGE_NAME"
|
||||
context: "web"
|
||||
platform: linux/amd64
|
||||
- service_name: "build-web-arm64"
|
||||
image_name_env: "DIFY_WEB_IMAGE_NAME"
|
||||
context: "web"
|
||||
platform: linux/arm64
|
||||
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USER }}
|
||||
password: ${{ env.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env[matrix.image_name_env] }}
|
||||
|
||||
- name: Build Docker image
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: "{{defaultContext}}:${{ matrix.context }}"
|
||||
platforms: ${{ matrix.platform }}
|
||||
build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env[matrix.image_name_env] }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=gha,scope=${{ matrix.service_name }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.service_name }}
|
||||
|
||||
- name: Export digest
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
sanitized_digest=${DIGEST#sha256:}
|
||||
touch "/tmp/digests/${sanitized_digest}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: digests-${{ matrix.context }}-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
create-manifest:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'langgenius/dify'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- service_name: "merge-api-images"
|
||||
image_name_env: "DIFY_API_IMAGE_NAME"
|
||||
context: "api"
|
||||
- service_name: "merge-web-images"
|
||||
image_name_env: "DIFY_WEB_IMAGE_NAME"
|
||||
context: "web"
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-${{ matrix.context }}-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ env.DOCKERHUB_USER }}
|
||||
password: ${{ env.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env[matrix.image_name_env] }}
|
||||
tags: |
|
||||
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && !contains(github.ref, '-') }}
|
||||
type=ref,event=branch
|
||||
type=sha,enable=true,priority=100,prefix=,suffix=,format=long
|
||||
type=raw,value=${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
env:
|
||||
IMAGE_NAME: ${{ env[matrix.image_name_env] }}
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf "$IMAGE_NAME@sha256:%s " *)
|
||||
|
||||
- name: Inspect image
|
||||
env:
|
||||
IMAGE_NAME: ${{ env[matrix.image_name_env] }}
|
||||
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
|
||||
run: |
|
||||
docker buildx imagetools inspect "$IMAGE_NAME:$IMAGE_VERSION"
|
||||
@ -1,57 +0,0 @@
|
||||
name: DB Migration Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- plugins/beta
|
||||
paths:
|
||||
- api/migrations/**
|
||||
- .github/workflows/db-migration-test.yml
|
||||
|
||||
concurrency:
|
||||
group: db-migration-test-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
db-migration-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup UV and Python
|
||||
uses: ./.github/actions/setup-uv
|
||||
with:
|
||||
uv-lockfile: api/uv.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --project api
|
||||
|
||||
- name: Prepare middleware env
|
||||
run: |
|
||||
cd docker
|
||||
cp middleware.env.example middleware.env
|
||||
|
||||
- name: Set up Middlewares
|
||||
uses: hoverkraft-tech/compose-action@v2.0.2
|
||||
with:
|
||||
compose-file: |
|
||||
docker/docker-compose.middleware.yaml
|
||||
services: |
|
||||
db
|
||||
redis
|
||||
|
||||
- name: Prepare configs
|
||||
run: |
|
||||
cd api
|
||||
cp .env.example .env
|
||||
|
||||
- name: Run DB Migration
|
||||
env:
|
||||
DEBUG: true
|
||||
run: uv run --directory api flask upgrade-db
|
||||
@ -1,24 +0,0 @@
|
||||
name: Deploy Dev
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build and Push API & Web"]
|
||||
branches:
|
||||
- "deploy/dev"
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.workflow_run.conclusion == 'success'
|
||||
steps:
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{ secrets.SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
script: |
|
||||
${{ vars.SSH_SCRIPT || secrets.SSH_SCRIPT }}
|
||||
@ -1,29 +0,0 @@
|
||||
name: Deploy Enterprise
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build and Push API & Web"]
|
||||
branches:
|
||||
- "deploy/enterprise"
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_branch == 'deploy/enterprise'
|
||||
|
||||
steps:
|
||||
- name: Deploy to server
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{ secrets.ENTERPRISE_SSH_HOST }}
|
||||
username: ${{ secrets.ENTERPRISE_SSH_USER }}
|
||||
password: ${{ secrets.ENTERPRISE_SSH_PASSWORD }}
|
||||
script: |
|
||||
${{ vars.ENTERPRISE_SSH_SCRIPT || secrets.ENTERPRISE_SSH_SCRIPT }}
|
||||
@ -0,0 +1,142 @@
|
||||
name: Reusable deployment job
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
APPLICATION_NAME:
|
||||
default: 'oneapi'
|
||||
type: string
|
||||
AWS_REGION:
|
||||
default: 'us-east-2'
|
||||
type: string
|
||||
DEPLOYMENT_ENV:
|
||||
required: true
|
||||
type: string
|
||||
ECR_REPOSITORY:
|
||||
required: true
|
||||
type: string
|
||||
ECS_CLUSTER:
|
||||
required: true
|
||||
type: string
|
||||
SECURITY_GROUP_IDS_SSM:
|
||||
required: true
|
||||
type: string
|
||||
SUBNET_IDS_SSM:
|
||||
required: true
|
||||
type: string
|
||||
VPC_ID_SSM:
|
||||
required: true
|
||||
type: string
|
||||
SNS_TO_LARK_LAMBDA_ARN:
|
||||
required: true
|
||||
type: string
|
||||
CERERTIFICATE_US_EAST_2_ARN:
|
||||
required: true
|
||||
type: string
|
||||
ECS_EXECUTION_ROLE_ARN:
|
||||
required: true
|
||||
type: string
|
||||
DOCKER_IMAGE_NAME:
|
||||
required: true
|
||||
type: string
|
||||
MODE:
|
||||
required: true
|
||||
type: string
|
||||
APP_PORT:
|
||||
required: true
|
||||
type: number
|
||||
HEALTH_CHECK:
|
||||
required: true
|
||||
type: string
|
||||
TEMPLATE:
|
||||
required: true
|
||||
type: string
|
||||
DOCKERFILEDIR:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID:
|
||||
required: true
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY:
|
||||
required: true
|
||||
ED25519_CI_KEY:
|
||||
required: true
|
||||
PAT:
|
||||
required: true
|
||||
env:
|
||||
ECS_CONTAINER_ENV_FILE_S3_PATH: ${{ inputs.DEPLOYMENT_ENV }}-dify-ai/.env
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to ${{ inputs.DEPLOYMENT_ENV }}
|
||||
runs-on: ubuntu-latest
|
||||
concurrency: deployment-${{ inputs.APPLICATION_NAME }}-${{ inputs.DEPLOYMENT_ENV }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Fetch and checkout branch
|
||||
run: |
|
||||
BRANCH=${{ inputs.DEPLOYMENT_ENV }}
|
||||
echo "Target branch: $BRANCH"
|
||||
git fetch origin $BRANCH
|
||||
git checkout $BRANCH
|
||||
git reset --hard origin/$BRANCH
|
||||
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ inputs.AWS_REGION }}
|
||||
|
||||
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v1
|
||||
|
||||
- name: Set SHORT_SHA
|
||||
id: set_short_sha
|
||||
run: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >>$GITHUB_ENV
|
||||
- name: Set IMAGE_TAG
|
||||
id: set_image_tag
|
||||
run: echo "IMAGE_TAG=${{ inputs.APPLICATION_NAME }}-$SHORT_SHA" >> $GITHUB_ENV
|
||||
- name: Set GIT_BRANCH
|
||||
id: set_git_branch
|
||||
run: echo "GIT_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build, tag, and push image to Amazon ECR
|
||||
id: build-image
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
|
||||
run: |
|
||||
cd ${{ inputs.DOCKERFILEDIR }}
|
||||
docker build --build-arg GIT_BRANCH=$GIT_BRANCH --build-arg GIT_PAT_TOKEN=${{ secrets.PAT }} -t $ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG .
|
||||
docker push $ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG
|
||||
echo "::set-output name=image::$ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG"
|
||||
|
||||
- name: Deploy CloudFormation
|
||||
uses: aws-actions/aws-cloudformation-github-deploy@v1
|
||||
with:
|
||||
name: ${{ inputs.APPLICATION_NAME }}-${{ inputs.DEPLOYMENT_ENV }}
|
||||
template: aws/${{ inputs.TEMPLATE }}
|
||||
no-fail-on-empty-changeset: "1"
|
||||
parameter-overrides: >-
|
||||
CertificateArn=${{ inputs.CERERTIFICATE_US_EAST_2_ARN }},
|
||||
ExecutionRoleArn=${{ inputs.ECS_EXECUTION_ROLE_ARN }},
|
||||
ECSClusterName=${{ inputs.ECS_CLUSTER }},
|
||||
ApplicationName=${{ inputs.APPLICATION_NAME }},
|
||||
EnvName=${{ inputs.DEPLOYMENT_ENV }},
|
||||
SecurityGroupIDs=${{ inputs.SECURITY_GROUP_IDS_SSM }},
|
||||
SubnetIDs=${{ inputs.SUBNET_IDS_SSM }},
|
||||
VpcID=${{ inputs.VPC_ID_SSM }},
|
||||
DockerImageUrl=${{ steps.build-image.outputs.image }},
|
||||
EnvironmentFileUrl=arn:aws:s3:::${{ env.ECS_CONTAINER_ENV_FILE_S3_PATH }},
|
||||
SnsToLarkLambda=${{ inputs.SNS_TO_LARK_LAMBDA_ARN }},
|
||||
AppPort=${{ inputs.APP_PORT }},
|
||||
Mode=${{ inputs.MODE }},
|
||||
DockerImageName=${{ inputs.DOCKER_IMAGE_NAME }},
|
||||
HealthCheck=${{ inputs.HEALTH_CHECK }}
|
||||
@ -1,48 +0,0 @@
|
||||
name: Build docker image
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- api/Dockerfile
|
||||
- web/Dockerfile
|
||||
|
||||
concurrency:
|
||||
group: docker-build-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- service_name: "api-amd64"
|
||||
platform: linux/amd64
|
||||
context: "api"
|
||||
- service_name: "api-arm64"
|
||||
platform: linux/arm64
|
||||
context: "api"
|
||||
- service_name: "web-amd64"
|
||||
platform: linux/amd64
|
||||
context: "web"
|
||||
- service_name: "web-arm64"
|
||||
platform: linux/arm64
|
||||
context: "web"
|
||||
steps:
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker Image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: false
|
||||
context: "{{defaultContext}}:${{ matrix.context }}"
|
||||
file: "${{ matrix.file }}"
|
||||
platforms: ${{ matrix.platform }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
yq eval '.services.weaviate.ports += ["8080:8080"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.qdrant.ports += ["6333:6333"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.chroma.ports += ["8000:8000"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services["milvus-standalone"].ports += ["19530:19530"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.pgvector.ports += ["5433:5432"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services["pgvecto-rs"].ports += ["5431:5432"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services["elasticsearch"].ports += ["9200:9200"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.couchbase-server.ports += ["8091-8096:8091-8096"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.couchbase-server.ports += ["11210:11210"]' -i docker/docker-compose.yaml
|
||||
yq eval '.services.tidb.ports += ["4000:4000"]' -i docker/tidb/docker-compose.yaml
|
||||
yq eval '.services.opengauss.ports += ["6600:6600"]' -i docker/docker-compose.yaml
|
||||
|
||||
echo "Ports exposed for sandbox, weaviate, tidb, qdrant, chroma, milvus, pgvector, pgvecto-rs, elasticsearch, couchbase, opengauss"
|
||||
@ -0,0 +1,36 @@
|
||||
|
||||
name: Api Prod Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
if: contains('carloschen6688,yvan-65535', github.actor)
|
||||
uses: ./.github/workflows/prod-deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-api
|
||||
DEPLOYMENT_ENV: prod
|
||||
ECR_REPOSITORY: ai-dify-api
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /prod/security-groups
|
||||
SUBNET_IDS_SSM: /prod/subnet-ids
|
||||
VPC_ID_SSM: /prod/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /prod/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /prod/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /prod/ecs-execution-role
|
||||
APP_PORT: 5001
|
||||
MODE: api
|
||||
DOCKER_IMAGE_NAME: dify-api
|
||||
HEALTH_CHECK: /console/api/ping
|
||||
TEMPLATE: cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: api
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_PROD }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_PROD }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
|
||||
@ -0,0 +1,134 @@
|
||||
name: Reusable deployment job
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
APPLICATION_NAME:
|
||||
default: 'oneapi'
|
||||
type: string
|
||||
AWS_REGION:
|
||||
default: 'us-east-2'
|
||||
type: string
|
||||
DEPLOYMENT_ENV:
|
||||
required: true
|
||||
type: string
|
||||
ECR_REPOSITORY:
|
||||
required: true
|
||||
type: string
|
||||
ECS_CLUSTER:
|
||||
required: true
|
||||
type: string
|
||||
SECURITY_GROUP_IDS_SSM:
|
||||
required: true
|
||||
type: string
|
||||
SUBNET_IDS_SSM:
|
||||
required: true
|
||||
type: string
|
||||
VPC_ID_SSM:
|
||||
required: true
|
||||
type: string
|
||||
SNS_TO_LARK_LAMBDA_ARN:
|
||||
required: true
|
||||
type: string
|
||||
CERERTIFICATE_US_EAST_2_ARN:
|
||||
required: true
|
||||
type: string
|
||||
ECS_EXECUTION_ROLE_ARN:
|
||||
required: true
|
||||
type: string
|
||||
DOCKER_IMAGE_NAME:
|
||||
required: true
|
||||
type: string
|
||||
MODE:
|
||||
required: true
|
||||
type: string
|
||||
APP_PORT:
|
||||
required: true
|
||||
type: number
|
||||
HEALTH_CHECK:
|
||||
required: true
|
||||
type: string
|
||||
TEMPLATE:
|
||||
required: true
|
||||
type: string
|
||||
DOCKERFILEDIR:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID:
|
||||
required: true
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY:
|
||||
required: true
|
||||
ED25519_CI_KEY:
|
||||
required: true
|
||||
PAT:
|
||||
required: true
|
||||
env:
|
||||
ECS_CONTAINER_ENV_FILE_S3_PATH: ${{ inputs.DEPLOYMENT_ENV }}-dify-ai/.env
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to ${{ inputs.DEPLOYMENT_ENV }}
|
||||
runs-on: ubuntu-latest
|
||||
concurrency: deployment-${{ inputs.APPLICATION_NAME }}-${{ inputs.DEPLOYMENT_ENV }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ inputs.AWS_REGION }}
|
||||
|
||||
|
||||
- name: Login to Amazon ECR
|
||||
id: login-ecr
|
||||
uses: aws-actions/amazon-ecr-login@v1
|
||||
|
||||
- name: Set SHORT_SHA
|
||||
id: set_short_sha
|
||||
run: echo "SHORT_SHA=$(git rev-parse --short HEAD)" >>$GITHUB_ENV
|
||||
- name: Set IMAGE_TAG
|
||||
id: set_image_tag
|
||||
run: echo "IMAGE_TAG=${{ inputs.APPLICATION_NAME }}-$SHORT_SHA" >> $GITHUB_ENV
|
||||
- name: Set GIT_BRANCH
|
||||
id: set_git_branch
|
||||
run: echo "GIT_BRANCH=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build, tag, and push image to Amazon ECR
|
||||
id: build-image
|
||||
env:
|
||||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
|
||||
|
||||
run: |
|
||||
cd ${{ inputs.DOCKERFILEDIR }}
|
||||
docker build --build-arg GIT_BRANCH=$GIT_BRANCH --build-arg GIT_PAT_TOKEN=${{ secrets.PAT }} -t $ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG .
|
||||
docker push $ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG
|
||||
echo "::set-output name=image::$ECR_REGISTRY/${{ inputs.ECR_REPOSITORY }}:$IMAGE_TAG"
|
||||
|
||||
- name: Deploy CloudFormation
|
||||
uses: aws-actions/aws-cloudformation-github-deploy@v1
|
||||
with:
|
||||
name: ${{ inputs.APPLICATION_NAME }}-${{ inputs.DEPLOYMENT_ENV }}
|
||||
template: aws/${{ inputs.TEMPLATE }}
|
||||
no-fail-on-empty-changeset: "1"
|
||||
parameter-overrides: >-
|
||||
CertificateArn=${{ inputs.CERERTIFICATE_US_EAST_2_ARN }},
|
||||
ExecutionRoleArn=${{ inputs.ECS_EXECUTION_ROLE_ARN }},
|
||||
ECSClusterName=${{ inputs.ECS_CLUSTER }},
|
||||
ApplicationName=${{ inputs.APPLICATION_NAME }},
|
||||
EnvName=${{ inputs.DEPLOYMENT_ENV }},
|
||||
SecurityGroupIDs=${{ inputs.SECURITY_GROUP_IDS_SSM }},
|
||||
SubnetIDs=${{ inputs.SUBNET_IDS_SSM }},
|
||||
VpcID=${{ inputs.VPC_ID_SSM }},
|
||||
DockerImageUrl=${{ steps.build-image.outputs.image }},
|
||||
EnvironmentFileUrl=arn:aws:s3:::${{ env.ECS_CONTAINER_ENV_FILE_S3_PATH }},
|
||||
SnsToLarkLambda=${{ inputs.SNS_TO_LARK_LAMBDA_ARN }},
|
||||
AppPort=${{ inputs.APP_PORT }},
|
||||
Mode=${{ inputs.MODE }},
|
||||
DockerImageName=${{ inputs.DOCKER_IMAGE_NAME }},
|
||||
HealthCheck=${{ inputs.HEALTH_CHECK }}
|
||||
@ -0,0 +1,34 @@
|
||||
name: Web Prod Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
if: contains('carloschen6688,yvan-65535', github.actor)
|
||||
uses: ./.github/workflows/prod-deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-web
|
||||
DEPLOYMENT_ENV: prod
|
||||
ECR_REPOSITORY: ai-dify-web
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /prod/security-groups
|
||||
SUBNET_IDS_SSM: /prod/subnet-ids
|
||||
VPC_ID_SSM: /prod/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /prod/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /prod/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /prod/ecs-execution-role
|
||||
APP_PORT: 3000
|
||||
MODE: web
|
||||
DOCKER_IMAGE_NAME: dify-web
|
||||
HEALTH_CHECK: /apps
|
||||
TEMPLATE: cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: web
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_PROD }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_PROD }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
name: Worker Prod Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
if: contains('carloschen6688,yvan-65535', github.actor)
|
||||
uses: ./.github/workflows/prod-deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-worker
|
||||
DEPLOYMENT_ENV: prod
|
||||
ECR_REPOSITORY: ai-dify-worker
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /prod/security-groups
|
||||
SUBNET_IDS_SSM: /prod/subnet-ids
|
||||
VPC_ID_SSM: /prod/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /prod/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /prod/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /prod/ecs-execution-role
|
||||
APP_PORT: 5001
|
||||
MODE: worker
|
||||
DOCKER_IMAGE_NAME: dify-api
|
||||
HEALTH_CHECK: /health
|
||||
TEMPLATE: worker-cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: api
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_PROD }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_PROD }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
name: Api Staging Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types: [deploy-staging]
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
uses: ./.github/workflows/deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-api
|
||||
DEPLOYMENT_ENV: staging
|
||||
ECR_REPOSITORY: ai-dify-api
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /staging/security-groups
|
||||
SUBNET_IDS_SSM: /staging/subnet-ids
|
||||
VPC_ID_SSM: /staging/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /staging/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /staging/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /staging/ecs-execution-role
|
||||
APP_PORT: 5001
|
||||
MODE: api
|
||||
DOCKER_IMAGE_NAME: dify-api
|
||||
HEALTH_CHECK: /console/api/ping
|
||||
TEMPLATE: cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: api
|
||||
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_STAGING }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_STAGING }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
name: Web Staging Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
uses: ./.github/workflows/deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-web
|
||||
DEPLOYMENT_ENV: staging
|
||||
ECR_REPOSITORY: ai-dify-web
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /staging/security-groups
|
||||
SUBNET_IDS_SSM: /staging/subnet-ids
|
||||
VPC_ID_SSM: /staging/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /staging/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /staging/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /staging/ecs-execution-role
|
||||
APP_PORT: 3000
|
||||
MODE: web
|
||||
DOCKER_IMAGE_NAME: dify-web
|
||||
HEALTH_CHECK: /apps
|
||||
TEMPLATE: cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: web
|
||||
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_STAGING }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_STAGING }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
name: Worker Staging Deployment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-deployment-in-local-repo:
|
||||
uses: ./.github/workflows/deploy.yml
|
||||
with:
|
||||
APPLICATION_NAME: dify-worker
|
||||
DEPLOYMENT_ENV: staging
|
||||
ECR_REPOSITORY: ai-dify-worker
|
||||
ECS_CLUSTER: ai-dify
|
||||
SECURITY_GROUP_IDS_SSM: /staging/security-groups
|
||||
SUBNET_IDS_SSM: /staging/subnet-ids
|
||||
VPC_ID_SSM: /staging/vpc-id
|
||||
SNS_TO_LARK_LAMBDA_ARN: /staging/lambda/sns-to-lark
|
||||
CERERTIFICATE_US_EAST_2_ARN: /staging/certificate
|
||||
ECS_EXECUTION_ROLE_ARN: /staging/ecs-execution-role
|
||||
APP_PORT: 5001
|
||||
MODE: worker
|
||||
DOCKER_IMAGE_NAME: dify-api
|
||||
HEALTH_CHECK: /health
|
||||
TEMPLATE: worker-cloudformation-ecs-service-template.yml
|
||||
DOCKERFILEDIR: api
|
||||
|
||||
|
||||
secrets:
|
||||
DEPLOYMENT_AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOYMENT_AWS_ACCESS_KEY_ID_STAGING }}
|
||||
DEPLOYMENT_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOYMENT_AWS_SECRET_ACCESS_KEY_STAGING }}
|
||||
ED25519_CI_KEY: ${{ secrets.ED25519_CI_KEY }}
|
||||
PAT: ${{ secrets.PAT }}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
days-before-issue-stale: 15
|
||||
days-before-issue-close: 3
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: "Close due to it's no longer active, if you have any questions, you can reopen it."
|
||||
stale-pr-message: "Close due to it's no longer active, if you have any questions, you can reopen it."
|
||||
stale-issue-label: 'no-issue-activity'
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
any-of-labels: 'duplicate,question,invalid,wontfix,no-issue-activity,no-pr-activity,enhancement,cant-reproduce,help-wanted'
|
||||
@ -1,183 +0,0 @@
|
||||
name: Style check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: style-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
checks: write
|
||||
statuses: write
|
||||
contents: read
|
||||
|
||||
|
||||
jobs:
|
||||
python-style:
|
||||
name: Python Style
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
with:
|
||||
files: |
|
||||
api/**
|
||||
.github/workflows/style.yml
|
||||
|
||||
- name: Setup UV and Python
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: ./.github/actions/setup-uv
|
||||
with:
|
||||
uv-lockfile: api/uv.lock
|
||||
enable-cache: false
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: uv sync --project api --dev
|
||||
|
||||
- name: Ruff check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
uv run --directory api ruff --version
|
||||
uv run --directory api ruff check --diff ./
|
||||
uv run --directory api ruff format --check --diff ./
|
||||
|
||||
- name: Dotenv check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: uv run --project api dotenv-linter ./api/.env.example ./web/.env.example
|
||||
|
||||
- name: Lint hints
|
||||
if: failure()
|
||||
run: echo "Please run 'dev/reformat' to fix the fixable linting errors."
|
||||
|
||||
web-style:
|
||||
name: Web Style
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
with:
|
||||
files: web/**
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v4
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
cache-dependency-path: ./web/package.json
|
||||
|
||||
- name: Web dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Web style check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm run lint
|
||||
|
||||
docker-compose-template:
|
||||
name: Docker Compose Template
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
with:
|
||||
files: |
|
||||
docker/generate_docker_compose
|
||||
docker/.env.example
|
||||
docker/docker-compose-template.yaml
|
||||
docker/docker-compose.yaml
|
||||
|
||||
- name: Generate Docker Compose
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cd docker
|
||||
./generate_docker_compose
|
||||
|
||||
- name: Check for changes
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: git diff --exit-code
|
||||
|
||||
superlinter:
|
||||
name: SuperLinter
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
with:
|
||||
files: |
|
||||
**.sh
|
||||
**.yaml
|
||||
**.yml
|
||||
**Dockerfile
|
||||
dev/**
|
||||
|
||||
- name: Super-linter
|
||||
uses: super-linter/super-linter/slim@v7
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
env:
|
||||
BASH_SEVERITY: warning
|
||||
DEFAULT_BRANCH: main
|
||||
FILTER_REGEX_INCLUDE: pnpm-lock.yaml
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
IGNORE_GENERATED_FILES: true
|
||||
IGNORE_GITIGNORED_FILES: true
|
||||
VALIDATE_BASH: true
|
||||
VALIDATE_BASH_EXEC: true
|
||||
# FIXME: temporarily disabled until api-docker.yaml's run script is fixed for shellcheck
|
||||
# VALIDATE_GITHUB_ACTIONS: true
|
||||
VALIDATE_DOCKERFILE_HADOLINT: true
|
||||
VALIDATE_XML: true
|
||||
VALIDATE_YAML: true
|
||||
|
||||
- name: EditorConfig checks
|
||||
uses: super-linter/super-linter/slim@v7
|
||||
env:
|
||||
DEFAULT_BRANCH: main
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
IGNORE_GENERATED_FILES: true
|
||||
IGNORE_GITIGNORED_FILES: true
|
||||
# EditorConfig validation
|
||||
VALIDATE_EDITORCONFIG: true
|
||||
EDITORCONFIG_FILE_NAME: editorconfig-checker.json
|
||||
@ -1,43 +0,0 @@
|
||||
name: Run Unit Test For SDKs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- sdks/**
|
||||
|
||||
concurrency:
|
||||
group: sdk-tests-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: unit test for Node.js SDK
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16, 18, 20, 22]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: sdks/nodejs-client
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: ''
|
||||
cache-dependency-path: 'pnpm-lock.yaml'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Test
|
||||
run: pnpm test
|
||||
@ -1,63 +0,0 @@
|
||||
name: Check i18n Files and Create PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
check-and-update:
|
||||
if: github.event.pull_request.merged == true
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: web
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2 # last 2 commits
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check for file changes in i18n/en-US
|
||||
id: check_files
|
||||
run: |
|
||||
recent_commit_sha=$(git rev-parse HEAD)
|
||||
second_recent_commit_sha=$(git rev-parse HEAD~1)
|
||||
changed_files=$(git diff --name-only $recent_commit_sha $second_recent_commit_sha -- 'i18n/en-US/*.ts')
|
||||
echo "Changed files: $changed_files"
|
||||
if [ -n "$changed_files" ]; then
|
||||
echo "FILES_CHANGED=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "FILES_CHANGED=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Set up Node.js
|
||||
if: env.FILES_CHANGED == 'true'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
cache: pnpm
|
||||
cache-dependency-path: ./web/package.json
|
||||
|
||||
- name: Install dependencies
|
||||
if: env.FILES_CHANGED == 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Run npm script
|
||||
if: env.FILES_CHANGED == 'true'
|
||||
run: pnpm run auto-gen-i18n
|
||||
|
||||
- name: Create Pull Request
|
||||
if: env.FILES_CHANGED == 'true'
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
commit-message: Update i18n files based on en-US changes
|
||||
title: 'chore: translate i18n files'
|
||||
body: This PR was automatically created to update i18n files based on changes in en-US locale.
|
||||
branch: chore/automated-i18n-updates
|
||||
@ -1,83 +0,0 @@
|
||||
name: Run VDB Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- api/core/rag/datasource/**
|
||||
- docker/**
|
||||
- .github/workflows/vdb-tests.yml
|
||||
- api/uv.lock
|
||||
- api/pyproject.toml
|
||||
|
||||
concurrency:
|
||||
group: vdb-tests-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: VDB Tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.11"
|
||||
- "3.12"
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup UV and Python
|
||||
uses: ./.github/actions/setup-uv
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
uv-lockfile: api/uv.lock
|
||||
|
||||
- name: Check UV lockfile
|
||||
run: uv lock --project api --check
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --project api --dev
|
||||
|
||||
- name: Set up dotenvs
|
||||
run: |
|
||||
cp docker/.env.example docker/.env
|
||||
cp docker/middleware.env.example docker/middleware.env
|
||||
|
||||
- name: Expose Service Ports
|
||||
run: sh .github/workflows/expose_service_ports.sh
|
||||
|
||||
- name: Set up Vector Store (TiDB)
|
||||
uses: hoverkraft-tech/compose-action@v2.0.2
|
||||
with:
|
||||
compose-file: docker/tidb/docker-compose.yaml
|
||||
services: |
|
||||
tidb
|
||||
tiflash
|
||||
|
||||
- name: Set up Vector Stores (Weaviate, Qdrant, PGVector, Milvus, PgVecto-RS, Chroma, MyScale, ElasticSearch, Couchbase)
|
||||
uses: hoverkraft-tech/compose-action@v2.0.2
|
||||
with:
|
||||
compose-file: |
|
||||
docker/docker-compose.yaml
|
||||
services: |
|
||||
weaviate
|
||||
qdrant
|
||||
couchbase-server
|
||||
etcd
|
||||
minio
|
||||
milvus-standalone
|
||||
pgvecto-rs
|
||||
pgvector
|
||||
chroma
|
||||
elasticsearch
|
||||
|
||||
- name: Check TiDB Ready
|
||||
run: uv run --project api python api/tests/integration_tests/vdb/tidb_vector/check_tiflash_ready.py
|
||||
|
||||
- name: Test Vector Stores
|
||||
run: uv run --project api bash dev/pytest/pytest_vdb.sh
|
||||
@ -1,55 +0,0 @@
|
||||
name: Web Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- web/**
|
||||
|
||||
concurrency:
|
||||
group: web-tests-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Web Tests
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v45
|
||||
with:
|
||||
files: web/**
|
||||
|
||||
- name: Install pnpm
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
cache-dependency-path: ./web/package.json
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Run tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm test
|
||||
@ -0,0 +1,347 @@
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: The template used to create an ECS Service.
|
||||
Parameters:
|
||||
CertificateArn:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::CertificateManager::Certificate::ARN>
|
||||
ExecutionRoleArn:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::IAM::Role::ARN>
|
||||
ECSClusterName:
|
||||
Type: String
|
||||
ApplicationName:
|
||||
Type: String
|
||||
EnvName:
|
||||
Type: String
|
||||
SecurityGroupIDs:
|
||||
Type: AWS::SSM::Parameter::Value<List<AWS::EC2::SecurityGroup::Id>>
|
||||
SubnetIDs:
|
||||
Type: AWS::SSM::Parameter::Value<List<AWS::EC2::Subnet::Id>>
|
||||
VpcID:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::EC2::VPC::Id>
|
||||
DockerImageUrl:
|
||||
Type: String
|
||||
EnvironmentFileUrl:
|
||||
Type: String
|
||||
Description: The s3 url that contains the list of ecs container environment variables
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
TaskCpuSetting:
|
||||
Type: Number
|
||||
Default: 2048
|
||||
TaskMemorySetting:
|
||||
Type: Number
|
||||
Default: 4096
|
||||
AppPort:
|
||||
Type: Number
|
||||
Default: 3000
|
||||
SnsToLarkLambda:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::Lambda::ARN>
|
||||
RedisPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/REDIS_PASSWORD
|
||||
PgPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/PG_PASS
|
||||
OpenserchPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/ES_PASS
|
||||
S3SecretsKey:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/S3_KEY
|
||||
Mode:
|
||||
Type: String
|
||||
HealthCheck:
|
||||
Type: String
|
||||
DockerImageName:
|
||||
Type: String
|
||||
EnvironmentFileUrl:
|
||||
Type: String
|
||||
CeleryBrokerUrl:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/REDIS_URL
|
||||
CeleryWorkerAmount:
|
||||
Type: Number
|
||||
Default: 5
|
||||
SqlalchemyPoolSize:
|
||||
Type: Number
|
||||
Default: 50
|
||||
ServerWorkerConnections:
|
||||
Type: Number
|
||||
Default: 1000
|
||||
SqlalchemyPoolRecycle:
|
||||
Type: Number
|
||||
Default: 1200
|
||||
ServerWorkerAmount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
Lang:
|
||||
Type: String
|
||||
Default: US.UTF-8
|
||||
LcAll:
|
||||
Type: String
|
||||
Default: US.UTF-8
|
||||
Resources:
|
||||
ECSService:
|
||||
Type: 'AWS::ECS::Service'
|
||||
Properties:
|
||||
Cluster: !Ref ECSClusterName
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${ApplicationName}-${EnvName}
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
EnableExecuteCommand: true
|
||||
LoadBalancers:
|
||||
- ContainerName: !Sub ${ApplicationName}-${EnvName}
|
||||
ContainerPort: !Ref AppPort
|
||||
TargetGroupArn: !Ref TargetGroup
|
||||
HealthCheckGracePeriodSeconds: '60'
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups: !Ref SecurityGroupIDs
|
||||
Subnets: !Ref SubnetIDs
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
DependsOn: Listener
|
||||
LoadBalancer:
|
||||
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
|
||||
Properties:
|
||||
Name: !Sub ${ApplicationName}-${EnvName}-alb
|
||||
SecurityGroups: !Ref SecurityGroupIDs
|
||||
Subnets: !Ref SubnetIDs
|
||||
Type: application
|
||||
Scheme: internal
|
||||
TargetGroup:
|
||||
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
|
||||
Properties:
|
||||
VpcId: !Ref VpcID
|
||||
Protocol: HTTP
|
||||
Port: '443'
|
||||
HealthCheckPath: !Ref HealthCheck
|
||||
TargetType: ip
|
||||
Listener:
|
||||
Type: 'AWS::ElasticLoadBalancingV2::Listener'
|
||||
Properties:
|
||||
DefaultActions:
|
||||
- TargetGroupArn: !Ref TargetGroup
|
||||
Type: forward
|
||||
LoadBalancerArn: !Ref LoadBalancer
|
||||
Port: '80'
|
||||
Protocol: HTTP
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${ApplicationName}-${EnvName}
|
||||
Cpu: !Ref TaskCpuSetting
|
||||
Memory: !Ref TaskMemorySetting
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
ExecutionRoleArn: !Ref ExecutionRoleArn
|
||||
TaskRoleArn: !Ref ExecutionRoleArn
|
||||
ContainerDefinitions:
|
||||
- Name: !Sub ${ApplicationName}-${EnvName}
|
||||
Image: !Ref DockerImageUrl
|
||||
Environment:
|
||||
- Name: REDIS_PASSWORD
|
||||
Value: !Ref RedisPass
|
||||
- Name: DB_PASSWORD
|
||||
Value: !Ref PgPass
|
||||
- Name: OPENSEARCH_PASSWORD
|
||||
Value: !Ref OpenserchPass
|
||||
- Name: S3_SECRET_KEY
|
||||
Value: !Ref S3SecretsKey
|
||||
- Name: MODE
|
||||
Value: !Ref Mode
|
||||
- Name: CELERY_BROKER_URL
|
||||
Value: !Ref CeleryBrokerUrl
|
||||
- Name: CELERY_WORKER_AMOUNT
|
||||
Value: !Ref CeleryWorkerAmount
|
||||
- Name: SQLALCHEMY_POOL_SIZE
|
||||
Value: !Ref SqlalchemyPoolSize
|
||||
- Name: SERVER_WORKER_AMOUNT
|
||||
Value: !Ref ServerWorkerAmount
|
||||
- Name: SQLALCHEMY_POOL_RECYCLE
|
||||
Value: !Ref SqlalchemyPoolRecycle
|
||||
- Name: SERVER_WORKER_CONNECTIONS
|
||||
Value: !Ref ServerWorkerConnections
|
||||
- Name: LANG
|
||||
Value: !Ref Lang
|
||||
- Name: LC_ALL
|
||||
Value: !Ref LcAll
|
||||
|
||||
EnvironmentFiles:
|
||||
- Type: s3
|
||||
Value: !Ref EnvironmentFileUrl
|
||||
PortMappings:
|
||||
- ContainerPort: !Ref AppPort
|
||||
HostPort: !Ref AppPort
|
||||
LogConfiguration:
|
||||
LogDriver: "awslogs"
|
||||
Options:
|
||||
awslogs-create-group: true
|
||||
awslogs-group: !Sub ${ApplicationName}-${EnvName}
|
||||
awslogs-region: !Ref "AWS::Region"
|
||||
awslogs-stream-prefix: ecs
|
||||
|
||||
TooManyHttpCodeElb5XXCountAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "TooMany_HTTPCode_ELB_5XX_Count_Alarm-${EnvName}-${ApplicationName}"
|
||||
AlarmDescription: !Sub "TooMany_HTTPCode_ELB_5XX_Count_Alarm of ${ApplicationName} in environment ${EnvName}"
|
||||
Namespace: AWS/ApplicationELB
|
||||
MetricName: HTTPCode_ELB_5XX_Count
|
||||
Dimensions:
|
||||
- Name: LoadBalancer
|
||||
Value: !GetAtt LoadBalancer.LoadBalancerFullName
|
||||
Statistic: Sum
|
||||
Period: 600
|
||||
EvaluationPeriods: 1
|
||||
Threshold: 1
|
||||
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||
TreatMissingData: notBreaching
|
||||
AlarmActions:
|
||||
- !Ref LarkTopic
|
||||
OKActions:
|
||||
- !Ref LarkTopic
|
||||
|
||||
TargetResponseTimeTooSlowAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "TargetResponseTime-too-slow-${EnvName}-${ApplicationName}"
|
||||
AlarmDescription: !Sub "TargetResponseTime is too slow for ${ApplicationName} in environment ${EnvName}"
|
||||
Namespace: AWS/ApplicationELB
|
||||
MetricName: TargetResponseTime
|
||||
Dimensions:
|
||||
- Name: LoadBalancer
|
||||
Value: !GetAtt LoadBalancer.LoadBalancerFullName
|
||||
Statistic: Maximum
|
||||
Period: 600
|
||||
EvaluationPeriods: 2
|
||||
Threshold: 20
|
||||
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||
TreatMissingData: notBreaching
|
||||
AlarmActions:
|
||||
- !Ref LarkTopic
|
||||
OKActions:
|
||||
- !Ref LarkTopic
|
||||
|
||||
HealthyHostCountTooLowAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "HealthyHostCountTooLow-alarm-${EnvName}-${ApplicationName}"
|
||||
AlarmDescription: !Sub "The HealthyHostCount is too low for ${ApplicationName} in environment ${EnvName}"
|
||||
Namespace: AWS/ApplicationELB
|
||||
MetricName: HealthyHostCount
|
||||
Dimensions:
|
||||
- Name: LoadBalancer
|
||||
Value: !GetAtt LoadBalancer.LoadBalancerFullName
|
||||
- Name: TargetGroup
|
||||
Value: !GetAtt TargetGroup.TargetGroupFullName
|
||||
Statistic: Minimum
|
||||
Period: 180
|
||||
EvaluationPeriods: 1
|
||||
Threshold: !Ref TaskDesiredCount
|
||||
ComparisonOperator: LessThanThreshold
|
||||
TreatMissingData: breaching
|
||||
AlarmActions:
|
||||
- !Ref LarkTopic
|
||||
OKActions:
|
||||
- !Ref LarkTopic
|
||||
|
||||
LarkTopic:
|
||||
Type: AWS::SNS::Topic
|
||||
Properties:
|
||||
TopicName: !Sub ${ApplicationName}-${EnvName}
|
||||
Subscription:
|
||||
- Endpoint: !Ref SnsToLarkLambda
|
||||
Protocol: "LAMBDA"
|
||||
|
||||
|
||||
# ASG setting begin
|
||||
AutoScalingRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service:
|
||||
- ecs-tasks.amazonaws.com
|
||||
Action:
|
||||
- 'sts:AssumeRole'
|
||||
Path: '/'
|
||||
Policies:
|
||||
- PolicyName: allow-ecs-cw-scaling
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- ecs:DescribeServices
|
||||
- ecs:UpdateService
|
||||
- cloudwatch:DeleteAlarms
|
||||
- cloudwatch:DescribeAlarms
|
||||
- cloudwatch:PutMetricAlarm
|
||||
Resource: '*'
|
||||
AutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
Properties:
|
||||
MinCapacity: !Ref TaskDesiredCount
|
||||
MaxCapacity: 50
|
||||
ResourceId: !Join ["/", [service, !Ref ECSClusterName, !GetAtt ECSService.Name]]
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
ServiceNamespace: ecs
|
||||
RoleARN: !GetAtt AutoScalingRole.Arn
|
||||
AutoScalingPolicyForCPU:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: ecs-cpu-utilization-ScalingPolicy
|
||||
PolicyType: TargetTrackingScaling
|
||||
ScalingTargetId: !Ref AutoScalingTarget
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageCPUUtilization
|
||||
ScaleInCooldown: 300
|
||||
ScaleOutCooldown: 120
|
||||
TargetValue: 70.0
|
||||
AutoScalingPolicyForMemory:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: ecs-memory-utilization-ScalingPolicy
|
||||
PolicyType: TargetTrackingScaling
|
||||
ScalingTargetId: !Ref AutoScalingTarget
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageMemoryUtilization
|
||||
ScaleInCooldown: 300
|
||||
ScaleOutCooldown: 120
|
||||
TargetValue: 75.0
|
||||
# ASG setting end
|
||||
|
||||
Outputs:
|
||||
ClusterName:
|
||||
Description: The cluster used to create the service.
|
||||
Value: !Ref ECSClusterName
|
||||
ECSService:
|
||||
Description: The created service.
|
||||
Value: !Ref ECSService
|
||||
LoadBalancer:
|
||||
Description: The created load balancer.
|
||||
Value: !Ref LoadBalancer
|
||||
Listener:
|
||||
Description: The created listener.
|
||||
Value: !Ref Listener
|
||||
TargetGroup:
|
||||
Description: The created target group.
|
||||
Value: !Ref TargetGroup
|
||||
LarkTopic:
|
||||
Description: The created Lark Topic.
|
||||
Value: !Ref LarkTopic
|
||||
@ -0,0 +1,204 @@
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: The template used to create an ECS Service without Load Balancer.
|
||||
Parameters:
|
||||
CertificateArn:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::CertificateManager::Certificate::ARN>
|
||||
ExecutionRoleArn:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::IAM::Role::ARN>
|
||||
ECSClusterName:
|
||||
Type: String
|
||||
ApplicationName:
|
||||
Type: String
|
||||
EnvName:
|
||||
Type: String
|
||||
SecurityGroupIDs:
|
||||
Type: AWS::SSM::Parameter::Value<List<AWS::EC2::SecurityGroup::Id>>
|
||||
SubnetIDs:
|
||||
Type: AWS::SSM::Parameter::Value<List<AWS::EC2::Subnet::Id>>
|
||||
VpcID:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::EC2::VPC::Id>
|
||||
DockerImageUrl:
|
||||
Type: String
|
||||
EnvironmentFileUrl:
|
||||
Type: String
|
||||
Description: The s3 url that contains the list of ecs container environment variables
|
||||
TaskDesiredCount:
|
||||
Type: Number
|
||||
Default: 1
|
||||
TaskCpuSetting:
|
||||
Type: Number
|
||||
Default: 1024
|
||||
TaskMemorySetting:
|
||||
Type: Number
|
||||
Default: 4096
|
||||
AppPort:
|
||||
Type: Number
|
||||
Default: 3000
|
||||
SnsToLarkLambda:
|
||||
Type: AWS::SSM::Parameter::Value<AWS::Lambda::ARN>
|
||||
RedisPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/REDIS_PASSWORD
|
||||
PgPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/PG_PASS
|
||||
OpenserchPass:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/ES_PASS
|
||||
S3SecretsKey:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/S3_KEY
|
||||
Mode:
|
||||
Type: String
|
||||
HealthCheck:
|
||||
Type: String
|
||||
DockerImageName:
|
||||
Type: String
|
||||
CeleryBrokerUrl:
|
||||
Type: AWS::SSM::Parameter::Value<String>
|
||||
Default: /ai-dify/REDIS_URL
|
||||
Resources:
|
||||
ECSService:
|
||||
Type: 'AWS::ECS::Service'
|
||||
Properties:
|
||||
Cluster: !Ref ECSClusterName
|
||||
CapacityProviderStrategy:
|
||||
- CapacityProvider: FARGATE
|
||||
Base: 0
|
||||
Weight: 1
|
||||
TaskDefinition: !Ref TaskDefinition
|
||||
ServiceName: !Sub ${ApplicationName}-${EnvName}
|
||||
DesiredCount: !Ref TaskDesiredCount
|
||||
EnableExecuteCommand: true
|
||||
NetworkConfiguration:
|
||||
AwsvpcConfiguration:
|
||||
AssignPublicIp: ENABLED
|
||||
SecurityGroups: !Ref SecurityGroupIDs
|
||||
Subnets: !Ref SubnetIDs
|
||||
DeploymentConfiguration:
|
||||
MaximumPercent: 200
|
||||
MinimumHealthyPercent: 100
|
||||
DeploymentController:
|
||||
Type: ECS
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
Properties:
|
||||
Family: !Sub ${ApplicationName}-${EnvName}
|
||||
Cpu: !Ref TaskCpuSetting
|
||||
Memory: !Ref TaskMemorySetting
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
- FARGATE
|
||||
ExecutionRoleArn: !Ref ExecutionRoleArn
|
||||
TaskRoleArn: !Ref ExecutionRoleArn
|
||||
ContainerDefinitions:
|
||||
- Name: !Sub ${ApplicationName}-${EnvName}
|
||||
Image: !Ref DockerImageUrl
|
||||
Environment:
|
||||
- Name: REDIS_PASSWORD
|
||||
Value: !Ref RedisPass
|
||||
- Name: DB_PASSWORD
|
||||
Value: !Ref PgPass
|
||||
- Name: OPENSEARCH_PASSWORD
|
||||
Value: !Ref OpenserchPass
|
||||
- Name: S3_SECRET_KEY
|
||||
Value: !Ref S3SecretsKey
|
||||
- Name: MODE
|
||||
Value: !Ref Mode
|
||||
- Name: CELERY_BROKER_URL
|
||||
Value: !Ref CeleryBrokerUrl
|
||||
EnvironmentFiles:
|
||||
- Type: s3
|
||||
Value: !Ref EnvironmentFileUrl
|
||||
PortMappings:
|
||||
- ContainerPort: !Ref AppPort
|
||||
HostPort: !Ref AppPort
|
||||
LogConfiguration:
|
||||
LogDriver: "awslogs"
|
||||
Options:
|
||||
awslogs-create-group: true
|
||||
awslogs-group: !Sub ${ApplicationName}-${EnvName}
|
||||
awslogs-region: !Ref "AWS::Region"
|
||||
awslogs-stream-prefix: ecs
|
||||
|
||||
LarkTopic:
|
||||
Type: AWS::SNS::Topic
|
||||
Properties:
|
||||
TopicName: !Sub ${ApplicationName}-${EnvName}
|
||||
Subscription:
|
||||
- Endpoint: !Ref SnsToLarkLambda
|
||||
Protocol: "LAMBDA"
|
||||
|
||||
# ASG setting begin
|
||||
AutoScalingRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service:
|
||||
- ecs-tasks.amazonaws.com
|
||||
Action:
|
||||
- 'sts:AssumeRole'
|
||||
Path: '/'
|
||||
Policies:
|
||||
- PolicyName: allow-ecs-cw-scaling
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- ecs:DescribeServices
|
||||
- ecs:UpdateService
|
||||
- cloudwatch:DeleteAlarms
|
||||
- cloudwatch:DescribeAlarms
|
||||
- cloudwatch:PutMetricAlarm
|
||||
Resource: '*'
|
||||
AutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
Properties:
|
||||
MinCapacity: !Ref TaskDesiredCount
|
||||
MaxCapacity: 10
|
||||
ResourceId: !Join ["/", [service, !Ref ECSClusterName, !GetAtt ECSService.Name]]
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
ServiceNamespace: ecs
|
||||
RoleARN: !GetAtt AutoScalingRole.Arn
|
||||
AutoScalingPolicyForCPU:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: ecs-cpu-utilization-ScalingPolicy
|
||||
PolicyType: TargetTrackingScaling
|
||||
ScalingTargetId: !Ref AutoScalingTarget
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageCPUUtilization
|
||||
ScaleInCooldown: 300
|
||||
ScaleOutCooldown: 120
|
||||
TargetValue: 70.0
|
||||
AutoScalingPolicyForMemory:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: ecs-memory-utilization-ScalingPolicy
|
||||
PolicyType: TargetTrackingScaling
|
||||
ScalingTargetId: !Ref AutoScalingTarget
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
PredefinedMetricSpecification:
|
||||
PredefinedMetricType: ECSServiceAverageMemoryUtilization
|
||||
ScaleInCooldown: 300
|
||||
ScaleOutCooldown: 120
|
||||
TargetValue: 75.0
|
||||
# ASG setting end
|
||||
|
||||
Outputs:
|
||||
ClusterName:
|
||||
Description: The cluster used to create the service.
|
||||
Value: !Ref ECSClusterName
|
||||
ECSService:
|
||||
Description: The created service.
|
||||
Value: !Ref ECSService
|
||||
LarkTopic:
|
||||
Description: The created Lark Topic.
|
||||
Value: !Ref LarkTopic
|
||||
Loading…
Reference in New Issue