mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
Versioned & Local Deps for E2E Preview Envs (#933)
* initial * update deploy * test * fix * fix artifact sharing * fix workflow * push stuff * dynamic trigger e2e * add permissions * trigger * trigger * trigger * test ci * update dir * add dockerize.sh * with shared artifacts * with artifact upload * test variant * debug * test again * try-at-once * one more try * add dockerfiles * test * add turbo build * progress * fix build * progress * version * test with follow up action * progress * progress * update * update * update * with provenance false * multiple deployments * fix issuez * update * update * fix * more envs * deploy two * oopdate * better yaml * unleash * update infra * fix + comment * cleanup * update deprecated Checkout version * remove commented code * WITH_LOCAL_DEPS arg for python * update * iteration * change to poetry * with deploy * update * iteration * with pnpm * with Pr number * test matrix * update workflow * with app installation for ui * consolidate dockerfiles * more changes * with monorepo install * fix dockerfile path * with linking * with deploy step * rewire * fix type errors * fix * fix typo * lots of good stuff * with all demos * better stuff * array * remove temp matrix in deploy * better table * update workflow name
This commit is contained in:
@@ -15,7 +15,3 @@ docs
|
||||
**/.husky
|
||||
|
||||
**/node_modules
|
||||
**/.next
|
||||
|
||||
!examples/**/node_modules
|
||||
!examples/**/.next
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Preview Environments (Deploy)
|
||||
name: Preview Environments
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -12,60 +12,26 @@ concurrency:
|
||||
jobs:
|
||||
build_images:
|
||||
runs-on: ubuntu-latest
|
||||
name: Dockerize
|
||||
name: Build Images
|
||||
strategy:
|
||||
matrix:
|
||||
app:
|
||||
- { name: 'coagents-research-canvas-ui', path: 'examples/coagents-research-canvas/ui', dockerfile: 'Dockerfile.ui', type: 'node' }
|
||||
- { name: 'coagents-research-canvas-agent', path: 'examples/coagents-research-canvas/agent', dockerfile: 'Dockerfile.agent', type: 'poetry' }
|
||||
- { name: 'coagents-ai-researcher-ui', path: 'examples/coagents-ai-researcher/ui', dockerfile: 'Dockerfile.ui', type: 'node' }
|
||||
- { name: 'coagents-ai-researcher-agent', path: 'examples/coagents-ai-researcher/agent', dockerfile: 'Dockerfile.agent', type: 'poetry' }
|
||||
- { name: 'coagents-qa-native-ui', path: 'examples/coagents-qa-native/ui', dockerfile: 'Dockerfile.ui', type: 'node' }
|
||||
- { name: 'coagents-qa-native-agent', path: 'examples/coagents-qa-native/agent', dockerfile: 'Dockerfile.agent', type: 'poetry' }
|
||||
- { name: 'coagents-qa-text-ui', path: 'examples/coagents-qa-text/ui', dockerfile: 'Dockerfile.ui', type: 'node' }
|
||||
- { name: 'coagents-qa-text-agent', path: 'examples/coagents-qa-text/agent', dockerfile: 'Dockerfile.agent', type: 'poetry' }
|
||||
- { project: "coagents-research-canvas", type: "agent", deps: "remote-deps" }
|
||||
- { project: "coagents-research-canvas", type: "agent", deps: "local-deps" }
|
||||
- { project: "coagents-research-canvas", type: "ui" }
|
||||
- { project: "coagents-ai-researcher", type: "agent", deps: "remote-deps" }
|
||||
- { project: "coagents-ai-researcher", type: "agent", deps: "local-deps" }
|
||||
- { project: "coagents-ai-researcher", type: "ui" }
|
||||
- { project: "coagents-qa-text", type: "agent", deps: "remote-deps" }
|
||||
- { project: "coagents-qa-text", type: "agent", deps: "local-deps" }
|
||||
- { project: "coagents-qa-text", type: "ui" }
|
||||
- { project: "coagents-qa-native", type: "agent", deps: "remote-deps" }
|
||||
- { project: "coagents-qa-native", type: "agent", deps: "local-deps" }
|
||||
- { project: "coagents-qa-native", type: "ui" }
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: dopplerhq/secrets-fetch-action@v1.2.0
|
||||
id: doppler
|
||||
with:
|
||||
doppler-token: ${{ secrets.DOPPLER_TOKEN }}
|
||||
doppler-project: copilotkit-previews
|
||||
doppler-config: prd
|
||||
|
||||
- name: (Node) Setup pnpm
|
||||
if: matrix.app.type == 'node'
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: "9.5"
|
||||
|
||||
- name: (Node) Use Node.js 21
|
||||
if: matrix.app.type == 'node'
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 21.x
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
|
||||
- name: (Node) Install dependencies
|
||||
if: matrix.app.type == 'node'
|
||||
working-directory: ./CopilotKit
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: (Node) Install app
|
||||
if: matrix.app.type == 'node'
|
||||
working-directory: ${{ matrix.app.path }}
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: (Node) Build app
|
||||
if: matrix.app.type == 'node'
|
||||
working-directory: ${{ matrix.app.path }}
|
||||
run: pnpm run build
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ steps.doppler.outputs.OPENAI_API_KEY }}
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
@@ -86,12 +52,83 @@ jobs:
|
||||
run: |
|
||||
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 058264219587.dkr.ecr.us-east-1.amazonaws.com
|
||||
|
||||
- name: Build Image
|
||||
- name: (UI) Setup pnpm
|
||||
if: matrix.app.type == 'ui'
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: "9.5"
|
||||
|
||||
- name: (UI) Use Node.js 21
|
||||
if: matrix.app.type == 'ui'
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 21.x
|
||||
cache: 'pnpm'
|
||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||
|
||||
- name: (UI) Install dependencies
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: ./CopilotKit
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: (UI) Install app dependencies
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: examples/${{ matrix.app.project }}/${{ matrix.app.type }}
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: (UI, Local Deps) Install monorepo
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: ./CopilotKit
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: (UI, Local Deps) Build @copilotkit packages
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: ./CopilotKit
|
||||
run: pnpx turbo run build
|
||||
|
||||
- name: (UI, Local Deps) Link @copilotkit packages
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: ./examples/${{ matrix.app.project }}/${{ matrix.app.type }}
|
||||
run: |
|
||||
docker buildx build -t 058264219587.dkr.ecr.us-east-1.amazonaws.com/coagents:${{ matrix.app.name }}-${{ github.run_id }} --build-arg APP_DIR=${{ matrix.app.path }} --secret id=OPENAI_API_KEY . -f ./examples/${{ matrix.app.dockerfile }} --platform=linux/amd64 --provenance=false --push
|
||||
for package in $(ls -d ../../../CopilotKit/packages/*); do
|
||||
pnpm link $package
|
||||
done
|
||||
|
||||
- name: (UI) Build app
|
||||
if: matrix.app.type == 'ui'
|
||||
working-directory: examples/${{ matrix.app.project }}/${{ matrix.app.type }}
|
||||
run: pnpm run build
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ steps.doppler.outputs.OPENAI_API_KEY }}
|
||||
|
||||
- name: (UI) Build Image
|
||||
if: matrix.app.type == 'ui'
|
||||
run: |
|
||||
docker buildx build \
|
||||
-t 058264219587.dkr.ecr.us-east-1.amazonaws.com/coagents:${{ matrix.app.project }}-ui-${{ github.run_id }} \
|
||||
--build-arg APP_DIR=examples/${{ matrix.app.project }}/${{ matrix.app.type }} \
|
||||
-f ./examples/Dockerfile.${{ matrix.app.type }} \
|
||||
--platform=linux/amd64 \
|
||||
--provenance=false \
|
||||
--push \
|
||||
.
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
|
||||
- name: (Agent) Build Image
|
||||
if: matrix.app.type == 'agent'
|
||||
run: |
|
||||
docker buildx build \
|
||||
-t 058264219587.dkr.ecr.us-east-1.amazonaws.com/coagents:${{ matrix.app.project }}-agent-${{ matrix.app.deps }}-${{ github.run_id }} \
|
||||
--build-arg APP_DIR=examples/${{ matrix.app.project }}/${{ matrix.app.type }} \
|
||||
-f ./examples/Dockerfile.${{ matrix.app.type }} \
|
||||
--build-arg WITH_LOCAL_DEPS=${{ matrix.app.deps == 'local-deps' }} \
|
||||
--platform=linux/amd64 \
|
||||
--provenance=false \
|
||||
--push \
|
||||
.
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
OPENAI_API_KEY: ${{ steps.doppler.outputs.OPENAI_API_KEY }}
|
||||
|
||||
cdk_deploy:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -138,8 +175,8 @@ jobs:
|
||||
run: cdk deploy --profile default --all --require-approval never --outputs-file=cdk_outputs.json --concurrency 10
|
||||
env:
|
||||
UNIQUE_ENV_ID: 'PR${{ github.event.number }}'
|
||||
OPENAI_API_KEY: ${{ steps.doppler.outputs.OPENAI_API_KEY }}
|
||||
GITHUB_RUN_ID: "${{ github.run_id }}"
|
||||
GITHUB_ACTIONS_RUN_ID: "${{ github.run_id }}"
|
||||
GITHUB_PR_NUMBER: "${{ github.event.number }}"
|
||||
|
||||
- name: Generate table from outputs
|
||||
id: generate-table
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Preview Environments (Destroy)
|
||||
name: Destroy Preview Environments
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
FROM public.ecr.aws/docker/library/python:3.12.0-slim-bullseye
|
||||
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
|
||||
ARG APP_DIR
|
||||
ARG WITH_LOCAL_DEPS
|
||||
|
||||
ENV POETRY_VIRTUALENVS_CREATE=false
|
||||
|
||||
@@ -14,8 +15,8 @@ COPY ${APP_DIR}/pyproject.toml ${APP_DIR}/poetry.lock ./
|
||||
# Copy SDK and install dependencies in a single layer
|
||||
COPY sdk-python/ /opt/sdk-python
|
||||
WORKDIR /asset
|
||||
RUN poetry install --no-interaction --no-ansi && \
|
||||
poetry add /opt/sdk-python
|
||||
RUN poetry install --no-interaction --no-ansi
|
||||
RUN if [ "$WITH_LOCAL_DEPS" = "true" ]; then poetry add /opt/sdk-python; fi
|
||||
|
||||
# Copy application code last
|
||||
COPY ${APP_DIR}/ ./
|
||||
|
||||
@@ -12,13 +12,14 @@ ARG APP_DIR
|
||||
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the built artifacts from the builder stage
|
||||
# COPY --from=builder-monorepo /app/${APP_DIR}/.next/standalone ./
|
||||
# COPY --from=builder-monorepo /app/${APP_DIR}/.next/static ./.next/static
|
||||
COPY ${APP_DIR}/package.json ${APP_DIR}/pnpm-lock.yaml ./
|
||||
RUN pnpm i --frozen-lockfile
|
||||
|
||||
# Copy the built artifacts from the builder stage
|
||||
COPY ${APP_DIR}/.next/standalone ./
|
||||
COPY ${APP_DIR}/.next/static ./.next/static
|
||||
|
||||
|
||||
# Set the environment variables (if needed)
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 3000
|
||||
|
||||
+119
-139
@@ -1,171 +1,151 @@
|
||||
#!/usr/bin/env node
|
||||
import "source-map-support/register";
|
||||
import * as cdk from "aws-cdk-lib";
|
||||
import { requireEnv } from "../lib/utils";
|
||||
import { PreviewProjectStack } from "../lib/demo-project-stack";
|
||||
import { createAgentProjectStack, createUIProjectStack } from "../lib/utils";
|
||||
|
||||
// app
|
||||
const app = new cdk.App();
|
||||
const uniqueEnvironmentId = requireEnv("UNIQUE_ENV_ID");
|
||||
const githubRunId = requireEnv("GITHUB_RUN_ID")
|
||||
|
||||
/**
|
||||
* CoAgents Research Canvas Demo
|
||||
/*
|
||||
* Research Canvas
|
||||
*/
|
||||
|
||||
const researchCanvasAgent = new PreviewProjectStack(app, `CoAgentsResearchCanvasDemoAgent`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents Research Canvas - Agent",
|
||||
demoDir: "examples/coagents-research-canvas/agent",
|
||||
ecrImageTag: `coagents-research-canvas-agent-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.agent",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY", "TAVILY_API_KEY"],
|
||||
port: "8000",
|
||||
includeInPRComment: false,
|
||||
outputEnvVariable: "COAGENTS_RESEARCH_CANVAS_AGENT_ENDPOINT_URL",
|
||||
// Remote Dependencies
|
||||
const agentWithRemoteDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-research-canvas",
|
||||
description: "CoAgents Research Canvas (Agent) - Remote Depenencies",
|
||||
dependencies: "Remote"
|
||||
});
|
||||
|
||||
const researchCanvasUI = new PreviewProjectStack(app, `CoAgentsResearchCanvasDemoUI`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents Research Canvas - UI",
|
||||
demoDir: "examples/coagents-research-canvas/ui",
|
||||
ecrImageTag: `coagents-research-canvas-ui-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.ui",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY"],
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
environmentVariables: {
|
||||
REMOTE_ACTION_URL: `${researchCanvasAgent.fnUrl}/copilotkit`,
|
||||
},
|
||||
port: "3000",
|
||||
includeInPRComment: true,
|
||||
outputEnvVariable: "COAGENTS_RESEARCH_CANVAS_UI_ENDPOINT_URL"
|
||||
const uiWithRemoteDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-research-canvas",
|
||||
description: "CoAgents Research Canvas (UI) - Remote Depenencies",
|
||||
dependencies: "Remote",
|
||||
agentProject: agentWithRemoteDeps
|
||||
});
|
||||
|
||||
/**
|
||||
// Local Dependencies
|
||||
const agentWithLocalDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-research-canvas",
|
||||
description: "CoAgents Research Canvas (Agent) - Local Depenencies",
|
||||
dependencies: "Local"
|
||||
});
|
||||
|
||||
const uiWithLocalDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-research-canvas",
|
||||
description: "CoAgents Research Canvas (UI) - Local Depenencies",
|
||||
dependencies: "Local",
|
||||
agentProject: agentWithLocalDeps
|
||||
});
|
||||
|
||||
/*
|
||||
* CoAgents Perplexity Demo
|
||||
*/
|
||||
|
||||
const perplexityAgent = new PreviewProjectStack(app, `CoAgentsPerplexityDemoAgent`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents Perplexity Clone - Agent",
|
||||
demoDir: "examples/coagents-ai-researcher/agent",
|
||||
ecrImageTag: `coagents-research-canvas-agent-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.agent",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY", "TAVILY_API_KEY"],
|
||||
port: "8000",
|
||||
includeInPRComment: false,
|
||||
outputEnvVariable: "COAGENTS_PERPLEXITY_AGENT_ENDPOINT_URL",
|
||||
// Remote Dependencies
|
||||
const perplexityAgentWithRemoteDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-ai-researcher",
|
||||
description: "CoAgents Perplexity Clone (Agent) - Remote Dependencies",
|
||||
dependencies: "Remote"
|
||||
});
|
||||
|
||||
const perplexityUI = new PreviewProjectStack(app, `CoAgentsPerplexityDemoUI`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents Perplexity Clone - UI",
|
||||
demoDir: "examples/coagents-ai-researcher/ui",
|
||||
ecrImageTag: `coagents-ai-researcher-ui-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.ui",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY"],
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
environmentVariables: {
|
||||
// REMOTE_ACTION_URL: `${perplexityAgent.fnUrl}/copilotkit`,
|
||||
},
|
||||
port: "3000",
|
||||
includeInPRComment: true,
|
||||
outputEnvVariable: "COAGENTS_PERPLEXITY_UI_ENDPOINT_URL",
|
||||
const perplexityUIWithRemoteDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-ai-researcher",
|
||||
description: "CoAgents Perplexity Clone (UI) - Remote Dependencies",
|
||||
dependencies: "Remote",
|
||||
agentProject: perplexityAgentWithRemoteDeps
|
||||
});
|
||||
|
||||
/**
|
||||
// Local Dependencies
|
||||
const perplexityAgentWithLocalDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-ai-researcher",
|
||||
description: "CoAgents Perplexity Clone (Agent) - Local Dependencies",
|
||||
dependencies: "Local"
|
||||
});
|
||||
|
||||
const perplexityUIWithLocalDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-ai-researcher",
|
||||
description: "CoAgents Perplexity Clone (UI) - Local Dependencies",
|
||||
dependencies: "Local",
|
||||
agentProject: perplexityAgentWithLocalDeps
|
||||
});
|
||||
|
||||
/*
|
||||
* CoAgents QA Text Demo
|
||||
*/
|
||||
|
||||
const qaTextAgent = new PreviewProjectStack(app, `CoAgentsQATextDemoAgent`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents QA Text - Agent",
|
||||
demoDir: "examples/coagents-ai-researcher/agent",
|
||||
ecrImageTag: `coagents-ai-researcher-agent-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.agent",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY", "TAVILY_API_KEY"],
|
||||
port: "8000",
|
||||
includeInPRComment: false,
|
||||
outputEnvVariable: "COAGENTS_QA_TEXT_AGENT_ENDPOINT_URL",
|
||||
// Remote Dependencies
|
||||
const qaTextAgentWithRemoteDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-text",
|
||||
description: "CoAgents QA Text (Agent) - Remote Dependencies",
|
||||
dependencies: "Remote"
|
||||
});
|
||||
|
||||
const qaTextUI = new PreviewProjectStack(app, `CoAgentsQATextDemoUI`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents QA Text - UI",
|
||||
demoDir: "examples/coagents-qa-text/ui",
|
||||
ecrImageTag: `coagents-qa-text-ui-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.ui",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY"],
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
environmentVariables: {
|
||||
// REMOTE_ACTION_URL: `${qaTextAgent.fnUrl}/copilotkit`,
|
||||
},
|
||||
port: "3000",
|
||||
includeInPRComment: true,
|
||||
outputEnvVariable: "COAGENTS_QA_TEXT_UI_ENDPOINT_URL",
|
||||
const qaTextUIWithRemoteDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-text",
|
||||
description: "CoAgents QA Text (UI) - Remote Dependencies",
|
||||
dependencies: "Remote",
|
||||
agentProject: qaTextAgentWithRemoteDeps
|
||||
});
|
||||
|
||||
/**
|
||||
// Local Dependencies
|
||||
const qaTextAgentWithLocalDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-text",
|
||||
description: "CoAgents QA Text (Agent) - Local Dependencies",
|
||||
dependencies: "Local"
|
||||
});
|
||||
|
||||
const qaTextUIWithLocalDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-text",
|
||||
description: "CoAgents QA Text (UI) - Local Dependencies",
|
||||
dependencies: "Local",
|
||||
agentProject: qaTextAgentWithLocalDeps
|
||||
});
|
||||
|
||||
/*
|
||||
* CoAgents QA Native Demo
|
||||
*/
|
||||
|
||||
const qaNativeAgent = new PreviewProjectStack(app, `CoAgentsQANativetDemoAgent`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents QA Native - Agent",
|
||||
demoDir: "examples/coagents-ai-researcher/agent",
|
||||
ecrImageTag: `coagents-qa-native-agent-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.agent",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY", "TAVILY_API_KEY"],
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
port: "8000",
|
||||
includeInPRComment: false,
|
||||
outputEnvVariable: "COAGENTS_QA_NATIVE_AGENT_ENDPOINT_URL",
|
||||
// Remote Dependencies
|
||||
const qaNativeAgentWithRemoteDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-native",
|
||||
description: "CoAgents QA Native (Agent) - Remote Dependencies",
|
||||
dependencies: "Remote"
|
||||
});
|
||||
|
||||
const qaNativeAUI = new PreviewProjectStack(app, `CoAgentsQANativeDemoUI`, {
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
projectName: "CoAgents QA Native - UI",
|
||||
demoDir: "examples/coagents-qa-native/ui",
|
||||
ecrImageTag: `coagents-qa-native-ui-${githubRunId}`,
|
||||
overrideDockerWorkdir: "./",
|
||||
overrideDockerfile: "examples/Dockerfile.ui",
|
||||
uniqueEnvironmentId,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY"],
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
environmentVariables: {
|
||||
// REMOTE_ACTION_URL: `${qaNativeAgent.fnUrl}/copilotkit`,
|
||||
},
|
||||
port: "3000",
|
||||
includeInPRComment: true,
|
||||
outputEnvVariable: "COAGENTS_QA_NATIVE_UI_ENDPOINT_URL",
|
||||
});
|
||||
const qaNativeUIWithRemoteDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-native",
|
||||
description: "CoAgents QA Native (UI) - Remote Dependencies",
|
||||
dependencies: "Remote",
|
||||
agentProject: qaNativeAgentWithRemoteDeps
|
||||
});
|
||||
|
||||
// Local Dependencies
|
||||
const qaNativeAgentWithLocalDeps = createAgentProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-native",
|
||||
description: "CoAgents QA Native (Agent) - Local Dependencies",
|
||||
dependencies: "Local"
|
||||
});
|
||||
|
||||
const qaNativeUIWithLocalDeps = createUIProjectStack({
|
||||
app,
|
||||
project: "coagents-qa-native",
|
||||
description: "CoAgents QA Native (UI) - Local Dependencies",
|
||||
dependencies: "Local",
|
||||
agentProject: qaNativeAgentWithLocalDeps
|
||||
});
|
||||
|
||||
+49
-19
@@ -15,15 +15,45 @@ function generateTable() {
|
||||
|
||||
console.log(json);
|
||||
|
||||
|
||||
|
||||
// const rows = [{
|
||||
// "Name": "test",
|
||||
// "Preview (Local Dependencies)": "url"
|
||||
// "Preview (Remote Dependencies)": "url",
|
||||
// }]
|
||||
|
||||
// Group entries by ProjectName
|
||||
const projectGroups = Object.values(json).reduce((acc, entry) => {
|
||||
if (!acc[entry.ProjectName]) {
|
||||
acc[entry.ProjectName] = {
|
||||
name: entry.ProjectName,
|
||||
remote: '',
|
||||
local: ''
|
||||
};
|
||||
}
|
||||
|
||||
// Add URLs based on dependency type
|
||||
if (entry.Dependencies === 'Remote') {
|
||||
acc[entry.ProjectName].remote = `[Preview](${entry.FunctionUrl})`;
|
||||
} else if (entry.Dependencies === 'Local') {
|
||||
acc[entry.ProjectName].local = `[Preview](${entry.FunctionUrl})`;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Convert grouped data to rows array
|
||||
const rows = Object.values(projectGroups).map(project => ({
|
||||
"Name": project.name,
|
||||
"Preview (Local Dependencies)": project.local,
|
||||
"Preview (Remote Dependencies)": project.remote
|
||||
}));
|
||||
|
||||
structure.push({
|
||||
table: {
|
||||
headers: ["Name", "URL"],
|
||||
rows: Object.entries(json)
|
||||
.filter(([key, value]) => value.IncludeInComment === "true")
|
||||
.map(([key, value]) => ({
|
||||
Name: value.ProjectName,
|
||||
URL: `[Link](${value.FunctionUrl})`,
|
||||
})),
|
||||
headers: ["Name", "Preview (Local Dependencies)", "Preview (Remote Dependencies)"],
|
||||
rows,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -32,19 +62,19 @@ function generateTable() {
|
||||
fs.writeFileSync(path.resolve(__dirname, "./preview-comment.md"), md);
|
||||
}
|
||||
|
||||
function generateProcessedOutputForTests() {
|
||||
let output = "";
|
||||
const json = JSON.parse(file);
|
||||
// function generateProcessedOutputForTests() {
|
||||
// let output = "";
|
||||
// const json = JSON.parse(file);
|
||||
|
||||
Object.entries(json)
|
||||
.filter(([key, value]) => !!value.OutputEnvVariable)
|
||||
.forEach(([key, value]) => {
|
||||
const envVariableName = value.OutputEnvVariable;
|
||||
output += `${envVariableName}="${value.FunctionUrl.replace(/\/$/, '')}"\n`;
|
||||
});
|
||||
// Object.entries(json)
|
||||
// .filter(([key, value]) => !!value.OutputEnvVariable)
|
||||
// .forEach(([key, value]) => {
|
||||
// const envVariableName = value.OutputEnvVariable;
|
||||
// output += `${envVariableName}="${value.FunctionUrl.replace(/\/$/, '')}"\n`;
|
||||
// });
|
||||
|
||||
fs.writeFileSync(path.resolve(__dirname, "./.env.test"), output);
|
||||
}
|
||||
// fs.writeFileSync(path.resolve(__dirname, "./.env.test"), output);
|
||||
// }
|
||||
|
||||
generateTable();
|
||||
generateProcessedOutputForTests();
|
||||
// generateProcessedOutputForTests();
|
||||
|
||||
@@ -8,18 +8,15 @@ import * as logs from "aws-cdk-lib/aws-logs"; // Add this import
|
||||
import * as events from "aws-cdk-lib/aws-events";
|
||||
import * as targets from "aws-cdk-lib/aws-events-targets";
|
||||
import * as ecr from "aws-cdk-lib/aws-ecr";
|
||||
import { requireEnv } from "./utils";
|
||||
|
||||
interface ProjectStackProps extends cdk.StackProps {
|
||||
export interface ProjectStackProps extends cdk.StackProps {
|
||||
/**
|
||||
* Path to the directory of the demo to deploy, relative to the root of the repository.
|
||||
*/
|
||||
projectName: string;
|
||||
projectDescription: string;
|
||||
demoDir: string;
|
||||
uniqueEnvironmentId: string;
|
||||
/**
|
||||
* Path to the workdir, relative to the root of the repository. By default, this will be the `demoDir`.
|
||||
*/
|
||||
overrideDockerWorkdir?: string;
|
||||
/**
|
||||
* Path to the Dockerfile to use, relative to the root of the repository. By default, this will be `${demoDir}/Dockerfile`.
|
||||
*/
|
||||
@@ -30,19 +27,23 @@ interface ProjectStackProps extends cdk.StackProps {
|
||||
environmentVariablesFromSecrets?: string[];
|
||||
buildSecrets?: string[];
|
||||
buildArgs?: Record<string, string>;
|
||||
port: number | string;
|
||||
port: string;
|
||||
timeout?: number;
|
||||
memorySize?: number;
|
||||
includeInPRComment?: boolean;
|
||||
outputEnvVariable?: string;
|
||||
ecrImageTag: string;
|
||||
overrideBuildProps?: Partial<cdk.aws_ecr_assets.DockerImageAssetProps>;
|
||||
imageTag: string;
|
||||
outputs?: Record<string, string>;
|
||||
}
|
||||
|
||||
export class PreviewProjectStack extends cdk.Stack {
|
||||
fnUrl: string;
|
||||
|
||||
constructor(scope: Construct, id: string, props: ProjectStackProps) {
|
||||
const processedId = `${id}${props.uniqueEnvironmentId}`;
|
||||
const uniqueEnvironmentId = requireEnv("UNIQUE_ENV_ID");
|
||||
const processedId = `${id}${uniqueEnvironmentId}`;
|
||||
|
||||
super(scope, processedId, props);
|
||||
|
||||
const secrets = secretsmanager.Secret.fromSecretNameV2(
|
||||
@@ -87,35 +88,7 @@ export class PreviewProjectStack extends cdk.Stack {
|
||||
Object.assign(buildArgs, props.buildArgs);
|
||||
}
|
||||
|
||||
const dockerWorkdir = props.overrideDockerWorkdir ?
|
||||
path.resolve(__dirname, "../../", props.overrideDockerWorkdir) :
|
||||
path.resolve(__dirname, "../../", props.demoDir)
|
||||
|
||||
// const fn = new lambda.Function(this, `Function`, {
|
||||
// logGroup: logGroup,
|
||||
// runtime: lambda.Runtime.FROM_IMAGE,
|
||||
// architecture: lambda.Architecture.X86_64,
|
||||
// handler: lambda.Handler.FROM_IMAGE,
|
||||
// environment: {
|
||||
// ...environmentVariables,
|
||||
// PORT: props.port.toString(),
|
||||
// AWS_LWA_INVOKE_MODE: "RESPONSE_STREAM",
|
||||
// },
|
||||
// code: lambda.Code.fromAssetImage(dockerWorkdir, {
|
||||
// platform: ecr_assets.Platform.LINUX_AMD64,
|
||||
// buildSecrets,
|
||||
// buildArgs,
|
||||
// file: props.overrideDockerfile ? props.overrideDockerfile : "Dockerfile",
|
||||
// }),
|
||||
// timeout: cdk.Duration.seconds(props.timeout ?? 300),
|
||||
// memorySize: props.memorySize ?? 1024,
|
||||
// });
|
||||
|
||||
const ecrRepo = ecr.Repository.fromRepositoryName(
|
||||
this,
|
||||
"ExamplesRepo",
|
||||
"coagents"
|
||||
);
|
||||
const ecrRepository = ecr.Repository.fromRepositoryName(this, "ECRRepo", "coagents");
|
||||
|
||||
const fn = new lambda.Function(this, `Function`, {
|
||||
logGroup: logGroup,
|
||||
@@ -127,8 +100,8 @@ export class PreviewProjectStack extends cdk.Stack {
|
||||
PORT: props.port.toString(),
|
||||
AWS_LWA_INVOKE_MODE: "RESPONSE_STREAM",
|
||||
},
|
||||
code: lambda.Code.fromEcrImage(ecrRepo, {
|
||||
tagOrDigest: props.ecrImageTag
|
||||
code: lambda.Code.fromEcrImage(ecrRepository, {
|
||||
tagOrDigest: props.imageTag
|
||||
}),
|
||||
timeout: cdk.Duration.seconds(props.timeout ?? 300),
|
||||
memorySize: props.memorySize ?? 1024,
|
||||
@@ -136,7 +109,7 @@ export class PreviewProjectStack extends cdk.Stack {
|
||||
|
||||
|
||||
const eventRule = new events.Rule(this, 'LambdaWarmUpSchedule', {
|
||||
schedule: events.Schedule.rate(cdk.Duration.minutes(5)),
|
||||
schedule: events.Schedule.rate(cdk.Duration.minutes(1)),
|
||||
});
|
||||
|
||||
eventRule.addTarget(new targets.LambdaFunction(fn));
|
||||
@@ -176,18 +149,24 @@ export class PreviewProjectStack extends cdk.Stack {
|
||||
value: props.projectName,
|
||||
});
|
||||
|
||||
new cdk.CfnOutput(this, "UniqueEnvironmentId", {
|
||||
value: `${props.uniqueEnvironmentId}`,
|
||||
new cdk.CfnOutput(this, "ProjectDescription", {
|
||||
value: props.projectDescription,
|
||||
});
|
||||
|
||||
if (props.outputEnvVariable) {
|
||||
new cdk.CfnOutput(this, "OutputEnvVariable", {
|
||||
value: props.outputEnvVariable,
|
||||
});
|
||||
new cdk.CfnOutput(this, "UniqueEnvironmentId", {
|
||||
value: `${uniqueEnvironmentId}`,
|
||||
});
|
||||
|
||||
if (props.outputs) {
|
||||
for (const [key, value] of Object.entries(props.outputs)) {
|
||||
new cdk.CfnOutput(this, key, {
|
||||
value: value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add tag for PR number to all resources
|
||||
cdk.Tags.of(this).add("env-id", props.uniqueEnvironmentId);
|
||||
cdk.Tags.of(this).add("env-id", uniqueEnvironmentId);
|
||||
cdk.Tags.of(this).add("preview-env", "true");
|
||||
}
|
||||
}
|
||||
|
||||
+104
-1
@@ -1,7 +1,110 @@
|
||||
import { App } from "aws-cdk-lib";
|
||||
import { PreviewProjectStack } from "./demo-project-stack";
|
||||
|
||||
export function requireEnv(name: string): string {
|
||||
const value = process.env[name];
|
||||
if (!value) {
|
||||
throw new Error(`Required environment variable ${name} is missing`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
export function toCdkStackName(input: string) {
|
||||
return input
|
||||
.split("-") // Split the string by hyphens
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1)) // Capitalize each word
|
||||
.join(""); // Join the words back together
|
||||
}
|
||||
|
||||
export function createAgentProjectStack({
|
||||
app,
|
||||
project,
|
||||
description,
|
||||
dependencies,
|
||||
}: {
|
||||
app: App;
|
||||
project: string;
|
||||
description: string;
|
||||
dependencies: "Remote" | "Local";
|
||||
}) {
|
||||
const cdkStackName =
|
||||
toCdkStackName(project) + "Agent" + dependencies + "Deps";
|
||||
const dockerfile =
|
||||
dependencies === "Remote"
|
||||
? `examples/Dockerfile.agent-remote-deps`
|
||||
: `examples/Dockerfile.agent-local-deps`;
|
||||
const GITHUB_ACTIONS_RUN_ID = requireEnv("GITHUB_ACTIONS_RUN_ID");
|
||||
|
||||
const outputs: Record<string,string> = {
|
||||
Dependencies: dependencies,
|
||||
};
|
||||
|
||||
if (process.env.GITHUB_PR_NUMBER) {
|
||||
outputs["PRNumber"] = process.env.GITHUB_PR_NUMBER;
|
||||
}
|
||||
|
||||
return new PreviewProjectStack(app, cdkStackName, {
|
||||
projectName: project,
|
||||
projectDescription: description,
|
||||
demoDir: `examples/${project}/agent`,
|
||||
overrideDockerfile: dockerfile,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY", "TAVILY_API_KEY"],
|
||||
port: "8000",
|
||||
includeInPRComment: false,
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
imageTag: `${project}-agent-${
|
||||
dependencies === "Remote" ? "remote-deps" : "local-deps"
|
||||
}-${GITHUB_ACTIONS_RUN_ID}`,
|
||||
outputs
|
||||
});
|
||||
}
|
||||
|
||||
export function createUIProjectStack({
|
||||
app,
|
||||
project,
|
||||
description,
|
||||
dependencies,
|
||||
agentProject,
|
||||
}: {
|
||||
app: App;
|
||||
project: string;
|
||||
description: string;
|
||||
dependencies: "Remote" | "Local";
|
||||
agentProject: PreviewProjectStack;
|
||||
}) {
|
||||
const cdkStackName = toCdkStackName(project) + "UI" + dependencies + "Deps";
|
||||
const dockerfile =
|
||||
dependencies === "Remote"
|
||||
? `examples/Dockerfile.ui-remote-deps`
|
||||
: `examples/Dockerfile.ui-local-deps`;
|
||||
const GITHUB_ACTIONS_RUN_ID = requireEnv("GITHUB_ACTIONS_RUN_ID");
|
||||
|
||||
const outputs: Record<string,string> = {
|
||||
Dependencies: dependencies,
|
||||
};
|
||||
|
||||
if (process.env.GITHUB_PR_NUMBER) {
|
||||
outputs["PRNumber"] = process.env.GITHUB_PR_NUMBER;
|
||||
}
|
||||
|
||||
return new PreviewProjectStack(app, cdkStackName, {
|
||||
projectName: project,
|
||||
projectDescription: `${description} (Dependencies: ${dependencies})`,
|
||||
demoDir: `examples/${project}/ui`,
|
||||
overrideDockerfile: dockerfile,
|
||||
environmentVariablesFromSecrets: ["OPENAI_API_KEY"],
|
||||
environmentVariables: {
|
||||
REMOTE_ACTION_URL: `${agentProject.fnUrl}/copilotkit`,
|
||||
},
|
||||
buildSecrets: ["OPENAI_API_KEY"],
|
||||
port: "3000",
|
||||
includeInPRComment: true,
|
||||
env: {
|
||||
account: process.env.CDK_DEFAULT_ACCOUNT,
|
||||
},
|
||||
imageTag: `${project}-ui-${GITHUB_ACTIONS_RUN_ID}`,
|
||||
outputs,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user