Merge pull request #557 from docwho2/dependabot/submodules/ChimeSMALi… #743
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CDK and SAM Deployment | |
on: | |
push: | |
branches: [ "main" ] | |
tags-ignore: | |
- sandbox* | |
paths-ignore: | |
- '**.png' | |
- '**.md' | |
- '**.sh' | |
- '**dependabot.yml' | |
permissions: | |
id-token: write # This is required for requesting the JWT | |
contents: read # This is required for actions/checkout | |
concurrency: deploy | |
env: | |
# https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository | |
# Create secrets in the repository and they will be pushed to Parameter store, these are required | |
# If you don't set an API key for square, you can still use ChatGPT by itself | |
SQUARE_API_KEY: ${{ secrets.SQUARE_API_KEY || 'DISABLED' }} | |
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'NEED_TO_SET_THIS' }} | |
FB_PAGE_ACCESS_TOKEN: ${{ secrets.FB_PAGE_ACCESS_TOKEN || 'DISABLED' }} | |
FB_PAGE_ID: ${{ vars.FB_PAGE_ID || 'DISABLED' }} | |
# https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository | |
# Create repository variables to override any/all of the below from the defaults | |
# | |
CDK_STACK_NAME: ${{ vars.CDK_STACK_NAME || 'chatgpt-square-ivr-cdk' }} | |
STACK_NAME: ${{ vars.STACK_NAME || 'chatgpt-square-ivr' }} | |
# The E164 Number to be used when transferring to main number | |
TRANSFER_NUMBER: ${{ vars.TRANSFER_NUMBER || '+18004444444' }} | |
# Set to PRODUCTION if you have a real Sqaure Buisness or Leave it as SANDBOX if you just have a dev account | |
SQUARE_ENVIRONMENT: ${{ vars.SQUARE_ENVIRONMENT || 'SANDBOX' }} | |
# You can have many locations in Square, need to set to the location you want to query inventory or employees against (required for functions to work) | |
SQUARE_LOCATION_ID: ${{ vars.SQUARE_LOCATION_ID || 'DISABLED' }} | |
# https://platform.openai.com/docs/models/overview (requres model with function calling) | |
OPENAI_MODEL: ${{ vars.OPENAI_MODEL || 'gpt-3.5-turbo-1106' }} | |
# Polly voices to use https://docs.aws.amazon.com/polly/latest/dg/ntts-voices-main.html | |
VOICE_ID_EN: ${{ vars.VOICE_ID_EN || 'Joanna' }} | |
VOICE_ID_ES: ${{ vars.VOICE_ID_ES || 'Lupe' }} | |
VOICE_ID_DE: ${{ vars.VOICE_ID_DE || 'Vicki' }} | |
jobs: | |
# First we must create all the Chime resources like Voice Connectors, SIP Media Application, SIP Rules, etc. | |
cdk-deploy: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- name: Setup AWS Credentials | |
id: aws-creds | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: us-east-1 | |
# The full role ARN if you are using OIDC | |
# https://github.com/aws-actions/configure-aws-credentials#oidc | |
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
# Set up the below secrets if you are not using OIDC and want to use regular keys (best practive is to use just role above with OIDC provider) | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
mask-aws-account-id: true | |
- name: Add AWS_ACCOUNT_ID to Environment | |
run: echo "AWS_ACCOUNT_ID=${{ steps.aws-creds.outputs.aws-account-id }}" >> $GITHUB_ENV | |
- name: Set up JDK 21 | |
uses: actions/setup-java@v4 | |
with: | |
java-version: '21' | |
distribution: 'corretto' | |
cache: maven | |
- name: Install AWS CDK | |
run: | | |
# Install latest version of AWS CDK | |
npm install -g aws-cdk | |
echo "Node Version: $(node -v)" | |
echo "CDK Version: $(cdk version)" | |
- name: Ensure CDK is bootstraped | |
run: | | |
cdk bootstrap --ci=true -c accountId=${AWS_ACCOUNT_ID} aws://${AWS_ACCOUNT_ID}/us-east-1 | |
cdk bootstrap --ci=true -c accountId=${AWS_ACCOUNT_ID} aws://${AWS_ACCOUNT_ID}/us-west-2 | |
- name: Deploy Stack with CDK | |
working-directory: ./ChimeCDKProvision | |
run: | | |
# Deploy to both regions in parallel | |
cdk deploy -c accountId=${AWS_ACCOUNT_ID} -c stackName=${CDK_STACK_NAME} -c regionEast=us-east-1 -c regionWest=us-west-2 --concurrency=4 --all --require-approval=never --ci=true | |
env: | |
# SIP PBX like Asterisk with public static IP, this will configure VC to allow calls from this and send calls to it (use IP, not a hostname actually) | |
PBX_HOSTNAME: ${{ vars.PBX_HOSTNAME }} | |
# If you have an existing Phone number provisioned and want to point it to the SMA's that are created | |
CHIME_PHONE_NUMBER: ${{ vars.CHIME_PHONE_NUMBER }} | |
# Configure a VC, this is implied if either of the above is set, however it show be set to TRUE if you want a VC and are not setting Phone or PBX | |
VOICE_CONNECTOR: ${{ vars.VOICE_CONNECTOR }} | |
# Twilio Create SIP trunk pointing to Voice Connector | |
TWILIO_ACCOUNT_SID: ${{ secrets.TWILIO_ACCOUNT_SID }} | |
TWILIO_AUTH_TOKEN: ${{ secrets.TWILIO_AUTH_TOKEN }} | |
TWILIO_PHONE_NUMBER_SID: ${{ secrets.TWILIO_PHONE_NUMBER_SID }} | |
# Now deploy the app into 2 regions at the same time via SAM with matrix job | |
sam-deploy: | |
strategy: | |
matrix: | |
region: [ us-east-1, us-west-2 ] | |
runs-on: ubuntu-latest | |
environment: ${{ matrix.region }} | |
needs: [cdk-deploy] | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- name: Setup AWS Credentials | |
id: aws-creds | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
aws-region: ${{ matrix.region }} | |
# The full role ARN if you are using OIDC | |
# https://github.com/aws-actions/configure-aws-credentials#oidc | |
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
# Set up the below secrets if you are not using OIDC and want to use regular keys (best practive is to use just role above with OIDC provider) | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
mask-aws-account-id: true | |
- name: Add AWS_ACCOUNT_ID to Environment | |
run: echo "AWS_ACCOUNT_ID=${{ steps.aws-creds.outputs.aws-account-id }}" >> $GITHUB_ENV | |
- name: Set up JDK 21 | |
uses: actions/setup-java@v4 | |
with: | |
java-version: '21' | |
distribution: 'corretto' | |
cache: maven | |
- name: Install ChimeSMALibrary Parent POM | |
working-directory: ./ChimeSMALibrary | |
run: mvn -N install --no-transfer-progress | |
- name: Build/Install Needed Libraries | |
# Exclude modules that SAM builds so it can use SAM cache and speed deploys | |
run: > | |
mvn -B install -DskipTests | |
--no-transfer-progress --quiet | |
--projects '!ChimeSMA,!ChatGPT,!ChimeCDKProvision,!ChimeSMALibrary/PollyPromptCreation' | |
- name: Setup AWS SAM | |
uses: aws-actions/setup-sam@v2 | |
with: | |
use-installer: true | |
- name: Push Square API Key to Parameter store | |
run: > | |
aws ssm put-parameter | |
--name /${STACK_NAME}/SQUARE_API_KEY | |
--description "Square API Key used for stack ${STACK_NAME}" | |
--type String | |
--value ${SQUARE_API_KEY} | |
--overwrite | |
- name: Push OpenAI API Key to Parameter store | |
run: > | |
aws ssm put-parameter | |
--name /${STACK_NAME}/OPENAI_API_KEY | |
--description "OpenAI API Key used for stack ${STACK_NAME}" | |
--type String | |
--value ${OPENAI_API_KEY} | |
--overwrite | |
- name: Push Facebook Access Token to Parameter store | |
run: > | |
aws ssm put-parameter | |
--name /${STACK_NAME}/FB_PAGE_ACCESS_TOKEN | |
--description "Facebook Access token used for stack ${STACK_NAME}" | |
--type String | |
--value ${FB_PAGE_ACCESS_TOKEN} | |
--overwrite | |
- name: Cache SAM Build files | |
uses: actions/cache@v4 | |
with: | |
path: .aws-sam | |
key: ${{ runner.os }}-sam | |
- name: SAM Build | |
run: sam build | |
- name: Does Stack Exist | |
id: stack-exists | |
continue-on-error: true | |
run: aws cloudformation describe-stacks --stack-name ${STACK_NAME} > /dev/null | |
- name: Delete PromptCreator Custom resource Logs if stack doesn't exist | |
if: steps.stack-exists.outcome == 'failure' | |
continue-on-error: true | |
run: | | |
aws logs delete-log-group --log-group-name "/aws/lambda/${STACK_NAME}-PromptCreator" | |
- name: Delete PromptCopier Custom resource Logs if stack doesn't exist | |
if: steps.stack-exists.outcome == 'failure' | |
continue-on-error: true | |
run: | | |
aws logs delete-log-group --log-group-name "/aws/lambda/${STACK_NAME}-PromptCopier" | |
- name: SAM Deploy | |
run: > | |
sam deploy --no-fail-on-empty-changeset --no-confirm-changeset | |
--region ${{ matrix.region }} | |
--stack-name ${STACK_NAME} | |
--parameter-overrides | |
SQUAREAPIKEY=/${STACK_NAME}/SQUARE_API_KEY | |
OPENAIAPIKEY=/${STACK_NAME}/OPENAI_API_KEY | |
FBPAGEACCESSTOKEN=/${STACK_NAME}/FB_PAGE_ACCESS_TOKEN | |
FBPAGEID=${FB_PAGE_ID} | |
SMAID=/${CDK_STACK_NAME}/SMA_ID | |
VOICECONNECTORARN=/${CDK_STACK_NAME}/VC_ARN | |
SQUAREENVIRONMENT=${SQUARE_ENVIRONMENT} | |
SQUARELOCATIONID=${SQUARE_LOCATION_ID} | |
TRANSFERNUMBER=${TRANSFER_NUMBER} | |
OPENAIMODEL=${OPENAI_MODEL} | |
VOICEIDEN=${VOICE_ID_EN} | |
VOICEIDES=${VOICE_ID_ES} | |
VOICEIDDE=${VOICE_ID_DE} | |
- name: Update SMA Endpoint | |
run: | | |
# The SMA ID is was pushed to param store by the CDK stack | |
SMA_ID=$(aws ssm get-parameter --name /${CDK_STACK_NAME}/SMA_ID --query Parameter.Value --output text) | |
# Chime for some reason loses reference to lambda, so always set to dummay and then back to what it should be | |
TARGET_ENDPOINT=arn:aws:lambda:${{ matrix.region }}:${AWS_ACCOUNT_ID}:function:${STACK_NAME}-ChimeSMA:SNAPSTART | |
DUMMY_ENDPOINT=$(aws ssm get-parameter --name /${CDK_STACK_NAME}/LAMBDA_ARN --query Parameter.Value --output text) | |
aws chime-sdk-voice update-sip-media-application --sip-media-application-id ${SMA_ID} --endpoints LambdaArn=${DUMMY_ENDPOINT} | |
# Once and a while the second update will fail, likely because above update didn't complete immediately, so give a little time | |
sleep 5 | |
aws chime-sdk-voice update-sip-media-application --sip-media-application-id ${SMA_ID} --endpoints LambdaArn=${TARGET_ENDPOINT} | |
# Run a couple tests to make sure ChatGPT is responding and able to make Square calls | |
run-tests: | |
if: ${{ vars.RUN_TESTS }} | |
strategy: | |
matrix: | |
region: [ us-east-1, us-west-2 ] | |
runs-on: ubuntu-latest | |
environment: "${{ matrix.region }}-tests" | |
needs: [sam-deploy] | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v4 | |
- name: Execute Tests | |
uses: ./.github/actions/test | |
with: | |
region: ${{ matrix.region }} | |
stack-name: ${{ vars.STACK_NAME || 'chatgpt-square-ivr' }} | |
aws-role: ${{ secrets.AWS_ROLE_TO_ASSUME }} | |
session-id: ${{ github.run_id }}-${{ github.run_attempt }} | |