chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:34:48 +08:00
commit 77bb5bf71f
3762 changed files with 353249 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Botpress V12
url: https://github.com/botpress/v12
about: If you're experiencing issues when using the on premise version of Botpress, please report the issue on the v12 repo.
- name: Botpress Cloud
url: https://discord.gg/botpress
about: To get assistance as fast as possible, please reach us on our Discord server.
+25
View File
@@ -0,0 +1,25 @@
name: Botpress Cloud
description: File a bug report or feature request for Botpress Cloud
body:
- type: markdown
attributes:
value: "Thank you for taking the time to fill out this issue report.\n\nKeep in mind that you will get a faster response time by talking to us on [our Discord Server](https://discord.gg/botpress)."
- type: checkboxes
id: dx-related-confirmation
attributes:
label: 'Make sure the issue is related to Botpress Cloud.'
description: 'When in doubt, please reach out on [our Discord Server](https://discord.gg/botpress).'
options:
- label: 'I confirm that the reported bug or feature request is not related to Botpress v12 and below (on premise version)'
required: true
- type: input
id: report-id
attributes:
label: 'Report ID'
description: 'Directly in the Studio, click on the "Report a Problem" button in the bottom left corner to create a report. You can then copy the report ID. Providing a report ID will allow us to help you faster. This information is safe to share publicly.'
placeholder: 'e.g. report_0123456789ABCDEFGHIJKLMNOPQRS'
- type: textarea
id: issue-description
attributes:
label: 'Description of the bug or feature request'
description: 'What is your bug or feature request ? Make sure to add logs, context or any information that you think might help understand and solve the issue.'
@@ -0,0 +1,33 @@
name: 'Create or Update Secret'
description: 'Creates or updates a secret in the repository'
inputs:
secret_name:
description: 'Secret name'
required: true
secret_value:
description: 'Secret value'
required: true
sync_secret_app_id:
description: 'Sync secret app id'
required: true
sync_secret_app_private_key:
description: 'Sync secret app private key'
required: true
runs:
using: 'composite'
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ inputs.sync_secret_app_id }}
private-key: ${{ inputs.sync_secret_app_private_key }}
- name: Set secret
shell: bash
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
SECRET_NAME: ${{ inputs.secret_name }}
SECRET_VALUE: ${{ inputs.secret_value }}
run: |
gh secret set "$SECRET_NAME" --body "$SECRET_VALUE"
@@ -0,0 +1,135 @@
name: Deploy Integrations
description: Deploys integrations
inputs:
environment:
type: choice
description: 'Environment to deploy to'
required: true
options:
- staging
- production
extra_filter:
type: string
description: 'Pnpm additional filters to select integrations to deploy'
required: false
default: ''
force:
type: boolean
description: 'Force re-deploying integrations'
default: false
required: false
dry_run:
type: boolean
description: 'Ask the backend to perform validation without actually deploying'
default: false
required: false
token_cloud_ops_account:
description: 'Cloud Ops account token'
required: true
cloud_ops_workspace_id:
description: 'Cloud Ops workspace id'
required: true
shopify_admin_automation_token:
description: 'Shopify app automation token for the Shopify Admin app (app-scoped, env-specific)'
required: false
default: ''
shopify_storefront_automation_token:
description: 'Shopify app automation token for the Shopify Storefront app (app-scoped, env-specific)'
required: false
default: ''
runs:
using: 'composite'
steps:
- name: Deploys Integrations
env:
INPUT_ENVIRONMENT: ${{ inputs.environment }}
INPUT_FORCE: ${{ inputs.force }}
INPUT_DRY_RUN: ${{ inputs.dry_run }}
INPUT_EXTRA_FILTER: ${{ inputs.extra_filter }}
TOKEN_CLOUD_OPS_ACCOUNT: ${{ inputs.token_cloud_ops_account }}
CLOUD_OPS_WORKSPACE_ID: ${{ inputs.cloud_ops_workspace_id }}
SHOPIFY_ADMIN_AUTOMATION_TOKEN: ${{ inputs.shopify_admin_automation_token }}
SHOPIFY_STOREFRONT_AUTOMATION_TOKEN: ${{ inputs.shopify_storefront_automation_token }}
COMMIT_URL: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}
shell: bash
run: |
if [ "$INPUT_ENVIRONMENT" = "staging" ]; then
api_url="https://api.botpress.dev"
else
api_url="https://api.botpress.cloud"
fi
# login
echo "### Logging in to $api_url ###"
pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT"
# deploy
if [ "$INPUT_FORCE" = "true" ]; then
redeploy=1
else
redeploy=0
fi
if [ "$INPUT_DRY_RUN" = "true" ]; then
dryrun="--dryRun"
is_dry_run=1
else
dryrun=""
is_dry_run=0
fi
all_filters="-F '{integrations/*}' $INPUT_EXTRA_FILTER"
list_integrations_cmd="pnpm list $all_filters --json"
integration_paths=$(eval "$list_integrations_cmd" | jq -r 'map(.path) | .[]')
for integration_path in $integration_paths; do
integration=$(basename "$integration_path")
exists=$(./.github/scripts/integration-exists.sh "$integration")
base_command="bp deploy -v -y --noBuild --visibility public --allowDeprecated $dryrun"
integration_deployed=false
if [ "$exists" -eq 0 ]; then
echo -e "\nDeploying integration: ### $integration ###\n"
pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" -c exec -- "$base_command"
integration_deployed=true
elif [ "$redeploy" -eq 1 ]; then
echo -e "\nRe-deploying integration: ### $integration ###\n"
pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" -c exec -- "$base_command"
integration_deployed=true
else
echo -e "\nSkipping integration: ### $integration ###\n"
fi
# upload sandbox scripts
integration_implements_sandbox=$(./.github/scripts/integration-implements-sandbox.sh "$integration")
if [ "$integration_implements_sandbox" = "true" ] && [ "$integration_deployed" = "true" ] && [ "$is_dry_run" -eq 0 ]; then
echo -e "\nUploading integration sandbox scripts\n"
base_upload_command="uploadSandboxScripts --apiUrl=$api_url --workspaceId=$CLOUD_OPS_WORKSPACE_ID --token=$TOKEN_CLOUD_OPS_ACCOUNT --userEmail=cloud-ops@botpress.com"
# shellcheck disable=SC2086 # base_upload_command contains multiple space-separated arguments
pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" run -- $base_upload_command
fi
# deploy shopify app manifest (config-as-code) for the current environment
manifest_file="$integration_path/shopify.app.$INPUT_ENVIRONMENT.toml"
if [ "$integration_deployed" = "true" ] && [ "$is_dry_run" -eq 0 ] && [ -f "$manifest_file" ]; then
case "$integration" in
shopify-admin) shopify_token="$SHOPIFY_ADMIN_AUTOMATION_TOKEN" ;;
shopify-storefront) shopify_token="$SHOPIFY_STOREFRONT_AUTOMATION_TOKEN" ;;
*) shopify_token="" ;;
esac
if [ -z "$shopify_token" ]; then
echo "::warning::Found $manifest_file but no Shopify automation token for $integration - skipping manifest deploy"
else
echo -e "\nDeploying Shopify app manifest ($INPUT_ENVIRONMENT): ### $integration ###\n"
shopify_deploy_command="pnpm shopify app deploy --config $INPUT_ENVIRONMENT --allow-updates --source-control-url $COMMIT_URL"
SHOPIFY_APP_AUTOMATION_TOKEN="$shopify_token" \
pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" -c exec -- "$shopify_deploy_command"
fi
fi
done
@@ -0,0 +1,78 @@
name: Deploy Interfaces
description: Deploys interfaces
inputs:
environment:
type: choice
description: 'Environment to deploy to'
required: true
options:
- staging
- production
extra_filter:
type: string
description: 'Pnpm additional filters to select interfaces to deploy'
required: false
default: ''
force:
type: boolean
description: 'Force re-deploying interfaces'
default: false
required: false
token_cloud_ops_account:
description: 'Cloud Ops account token'
required: true
cloud_ops_workspace_id:
description: 'Cloud Ops workspace id'
required: true
runs:
using: 'composite'
steps:
- name: Deploys Interfaces
shell: bash
env:
INPUT_ENVIRONMENT: ${{ inputs.environment }}
INPUT_FORCE: ${{ inputs.force }}
INPUT_EXTRA_FILTER: ${{ inputs.extra_filter }}
TOKEN_CLOUD_OPS_ACCOUNT: ${{ inputs.token_cloud_ops_account }}
CLOUD_OPS_WORKSPACE_ID: ${{ inputs.cloud_ops_workspace_id }}
run: |
if [ "$INPUT_ENVIRONMENT" = "staging" ]; then
api_url="https://api.botpress.dev"
else
api_url="https://api.botpress.cloud"
fi
# login
echo "### Logging in to $api_url ###"
pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT"
# deploy
if [ "$INPUT_FORCE" = "true" ]; then
redeploy=1
else
redeploy=0
fi
all_filters="-F '{interfaces/*}' $INPUT_EXTRA_FILTER"
list_interfaces_cmd="pnpm list $all_filters --json"
interface_paths=$(eval "$list_interfaces_cmd" | jq -r 'map(.path) | .[]')
for interface_path in $interface_paths; do
interface=$(basename "$interface_path")
exists=$(./.github/scripts/interface-exists.sh "$interface")
base_command="bp deploy -v -y --visibility public"
if [ "$exists" -eq 0 ]; then
echo -e "\nDeploying interface: ### $interface ###\n"
pnpm retry -n 2 -- pnpm -F "{interfaces/$interface}" -c exec -- "$base_command"
elif [ "$redeploy" -eq 1 ]; then
echo -e "\nRe-deploying interface: ### $interface ###\n"
pnpm retry -n 2 -- pnpm -F "{interfaces/$interface}" -c exec -- "$base_command"
else
echo -e "\nSkipping interface: ### $interface ###\n"
fi
done
+79
View File
@@ -0,0 +1,79 @@
name: Deploy Plugins
description: Deploys plugins
inputs:
environment:
type: choice
description: 'Environment to deploy to'
required: true
options:
- staging
- production
extra_filter:
type: string
description: 'Pnpm additional filters to select plugins to deploy'
required: false
default: ''
force:
type: boolean
description: 'Force re-deploying plugins'
default: false
required: false
token_cloud_ops_account:
description: 'Cloud Ops account token'
required: true
cloud_ops_workspace_id:
description: 'Cloud Ops workspace id'
required: true
runs:
using: 'composite'
steps:
- name: Deploys Plugins
shell: bash
env:
INPUT_ENVIRONMENT: ${{ inputs.environment }}
INPUT_FORCE: ${{ inputs.force }}
INPUT_EXTRA_FILTER: ${{ inputs.extra_filter }}
TOKEN_CLOUD_OPS_ACCOUNT: ${{ inputs.token_cloud_ops_account }}
CLOUD_OPS_WORKSPACE_ID: ${{ inputs.cloud_ops_workspace_id }}
run: |
if [ "$INPUT_ENVIRONMENT" = "staging" ]; then
api_url="https://api.botpress.dev"
else
api_url="https://api.botpress.cloud"
fi
# login
echo "### Logging in to $api_url ###"
pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT"
# deploy
if [ "$INPUT_FORCE" = "true" ]; then
redeploy=1
else
redeploy=0
fi
all_filters="-F '{plugins/*}' $INPUT_EXTRA_FILTER"
list_plugins_cmd="pnpm list $all_filters --json"
plugin_paths=$(eval "$list_plugins_cmd" | jq -r 'map(.path) | .[]')
for plugin_path in $plugin_paths; do
plugin=$(basename "$plugin_path")
exists=$(./.github/scripts/plugin-exists.sh "$plugin")
base_command="bp deploy -v -y --visibility public"
if [ "$exists" -eq 0 ]; then
echo -e "\nDeploying plugin: ### $plugin ###\n"
pnpm retry -n 2 -- pnpm -F "{plugins/$plugin}" -c exec -- "$base_command"
elif [ "$redeploy" -eq 1 ]; then
echo -e "\nRe-deploying plugin: ### $plugin ###\n"
pnpm retry -n 2 -- pnpm -F "{plugins/$plugin}" -c exec -- "$base_command"
else
echo -e "\nSkipping plugin: ### $plugin ###\n"
fi
done
+85
View File
@@ -0,0 +1,85 @@
name: Docker Build
description: 'Build and push a Docker image to the registry'
inputs:
repository:
description: 'The name of the repository to build'
required: true
dockerfile:
description: 'The name of the Dockerfile to build'
required: true
push:
description: 'Whether to push the image to the registry'
required: false
default: false
minify:
description: 'Whether to minify the build'
required: false
default: true
tag:
description: 'Optional Docker tag'
required: false
default: ''
depot-project:
description: 'Depot project ID (required if no depot.json; get it from depot.dev)'
required: false
default: ''
runs:
using: 'composite'
steps:
- uses: aws-actions/configure-aws-credentials@v3
with:
role-session-name: container_pusher
role-to-assume: arn:aws:iam::986677156374:role/actions/build/container_pusher
aws-region: us-east-1
- uses: aws-actions/amazon-ecr-login@v1
id: ecr
with:
mask-password: true
- uses: docker/metadata-action@v4
id: meta
with:
images: ${{ steps.ecr.outputs.registry }}/${{ inputs.repository }}
flavor: |
latest=false
tags: |
type=raw,enable=${{ inputs.tag != '' }},value=${{ inputs.tag }}
type=semver,pattern={{version}}
type=sha,enable=${{ !startsWith(github.ref, 'refs/tags') }},prefix=,format=long
- name: Set BUILD_DATE
id: meta_date
shell: bash
run: |
export TZ=America/Toronto
echo "timestamp=$(date +"%Y-%m-%d %H:%M:%S")" >> "$GITHUB_OUTPUT"
- name: Create ECR Registry
shell: bash
env:
ECR_REPOSITORY: ${{ inputs.repository }}
ECR_REGISTRY: ${{ steps.ecr.outputs.registry }}
run: |
aws --version
aws ecr create-repository --repository-name "$ECR_REPOSITORY" || true
aws ssm get-parameter --name '/cloud/container-registry/ecr-policy-document' --query 'Parameter.Value' | jq -r > repository-policy.json
aws ecr set-repository-policy --repository-name "$ECR_REPOSITORY" --policy-text file://repository-policy.json &> /dev/null
- name: Set up Depot CLI
uses: depot/setup-action@v1
- uses: depot/build-push-action@v1
with:
project: ${{ inputs.depot-project }}
build-args: |
MINIFY=${{ inputs.minify }}
DOCKER_TAG=${{ inputs.tag }}
BUILD_DATE=${{ steps.meta_date.outputs.timestamp }}
file: ${{ inputs.dockerfile }}
context: .
push: ${{ inputs.push }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
@@ -0,0 +1,53 @@
name: 'Refresh Instagram Access Tokens'
description: 'Refreshes Instagram access token, updates the integrations secrets and update the token GitHub secrets'
inputs:
token_cloud_ops_account:
description: 'Cloud Ops account token'
required: true
cloud_ops_workspace_id:
description: 'Cloud Ops workspace id'
required: true
api_url:
description: 'API URL'
required: true
current_token:
description: 'Current token'
required: true
secret_name:
description: 'Secret name'
required: true
sync_secret_app_id:
description: 'Create or update secret app id'
required: true
sync_secret_app_private_key:
description: 'Create or update secret app private key'
required: true
runs:
using: 'composite'
steps:
- name: Refresh Access Tokens
id: refresh_tokens
shell: bash
env:
BP_API_URL: ${{ inputs.api_url }}
BP_WORKSPACE_ID: ${{ inputs.cloud_ops_workspace_id }}
BP_TOKEN: ${{ inputs.token_cloud_ops_account }}
run: |
refresh_result=$(pnpm -F 'instagram' exec -- pnpm run --silent refreshTokens --json --refreshToken "${{ inputs.current_token }}")
new_token=$(echo "$refresh_result" | jq -r '.refreshedToken')
if [ -z "$new_token" ]; then
echo "❌ Error: Failed to refresh token" >&2
exit 1
fi
echo "$refresh_result" | jq -r '.message'
echo "✅ Tokens refreshed successfully"
echo "::add-mask::$new_token"
echo "new_token=$new_token" >> "$GITHUB_OUTPUT"
- uses: ./.github/actions/create-or-update-secret
with:
secret_name: ${{ inputs.secret_name }}
secret_value: ${{ steps.refresh_tokens.outputs.new_token }}
sync_secret_app_id: ${{ inputs.sync_secret_app_id }}
sync_secret_app_private_key: ${{ inputs.sync_secret_app_private_key }}
+45
View File
@@ -0,0 +1,45 @@
name: Setup
description: install dependencies and build
inputs:
extra_filters:
description: 'Turbo additional filters to select packages to build'
required: false
runs:
using: 'composite'
steps:
- uses: pnpm/action-setup@v4 # uses the version from package.json
- uses: actions/setup-node@v6
with:
node-version-file: '.tool-versions'
package-manager-cache: false
- name: Install Node Gyp Build
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
run: |
npm install -g node-gyp-build
- name: Install dependencies
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
run: pnpm i --frozen-lockfile
- name: Cache Turbo
uses: actions/cache@v5
with:
path: |
.turbo
node_modules/.cache/turbo
key: turbo-${{ runner.os }}-${{ github.workflow_ref }}
restore-keys: |
turbo-${{ runner.os }}-
- name: Build
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
env:
BP_VERBOSE: 'true'
EXTRA_FILTERS: ${{ inputs.extra_filters }}
run: |
# shellcheck disable=SC2086 # EXTRA_FILTERS contains multiple space-separated filter arguments
pnpm turbo run build $EXTRA_FILTERS
@@ -0,0 +1,26 @@
name: Update Linear Status
inputs:
linearApiKey:
required: true
teamName:
required: true
targetLabel:
required: true
runs:
using: 'composite'
steps:
- uses: actions/checkout@v4
- name: Install dependencies
shell: bash
run: pnpm install tsx -w --save-dev
- name: Update issues
shell: bash
run: npx tsx ./.github/scripts/update-linear.ts
env:
LINEAR_API_KEY: ${{inputs.linearApiKey}}
TEAM_NAME: ${{inputs.teamName}}
TARGET_LABEL: ${{inputs.targetLabel}}
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi
integration=$1
integration_path="integrations/$integration"
if ! integration_def=$(pnpm bp read --work-dir "$integration_path" --json); then
echo "Error: Failed to read integration definition for \"$integration\". Check the integration for TypeScript errors." >&2
exit 1
fi
name=$(echo "$integration_def" | jq -r ".name")
version=$(echo "$integration_def" | jq -r ".version")
exists=$(pnpm bp integrations ls --name "$name" --version-number "$version" --json | jq '[ .[] | select(.public) ] | length') # 0 if not exists
echo "$exists"
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi
integration=$1
integration_path="integrations/$integration"
if ! integration_def=$(pnpm bp read --work-dir "$integration_path" --json); then
echo "Error: Failed to read integration definition for \"$integration\". Check the integration for TypeScript errors." >&2
exit 1
fi
category=$(echo "$integration_def" | jq -r '.attributes.category // empty')
valid_categories=(
"AI Models"
"Business Operations"
"CRM & Sales"
"Communication & Channels"
"Customer Support"
"Developer Tools"
"E-commerce & Payments"
"File Management"
"Marketing & Email"
"Other"
"Project Management"
)
if [ -z "$category" ]; then
echo "Integration \"$integration\" is missing the \"category\" attribute in its definition file" >&2
echo "Valid categories are: $(printf '"%s", ' "${valid_categories[@]}" | sed 's/, $//')" >&2
exit 1
fi
for valid_category in "${valid_categories[@]}"; do
if [ "$category" = "$valid_category" ]; then
echo "Integration \"$integration\" has a valid category: \"$category\""
exit 0
fi
done
echo "Integration \"$integration\" has an invalid category: \"$category\"" >&2
echo "Valid categories are: $(printf '"%s", ' "${valid_categories[@]}" | sed 's/, $//')" >&2
exit 1
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi
integration=$1
integration_path="integrations/$integration"
has_sandbox=false
sandbox_script="$integration_path/sandboxIdentifierExtract.vrl"
if [ -f "$sandbox_script" ]; then
has_sandbox=true
fi
echo "$has_sandbox"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Error: interface name is not provided" >&2
exit 1
fi
interface=$1
interface_path="interfaces/$interface"
interface_def=$(pnpm bp read --work-dir "$interface_path" --json)
name=$(echo "$interface_def" | jq -r ".name")
version=$(echo "$interface_def" | jq -r ".version")
command="pnpm bp interfaces get \"$name@$version\" --json >/dev/null 2>&1"
exists=$(eval "$command" && echo 1 || echo 0)
echo "$exists"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Error: plugin name is not provided" >&2
exit 1
fi
plugin=$1
plugin_path="plugins/$plugin"
plugin_def=$(pnpm bp read --work-dir "$plugin_path" --json)
name=$(echo "$plugin_def" | jq -r ".name")
version=$(echo "$plugin_def" | jq -r ".version")
command="pnpm bp plugins get \"$name@$version\" --json >/dev/null 2>&1"
exists=$(eval "$command" && echo 1 || echo 0)
echo "$exists"
+93
View File
@@ -0,0 +1,93 @@
import { LinearClient, Team, WorkflowState, IssueLabel } from '@linear/sdk'
const LINEAR_API_KEY = process.env.LINEAR_API_KEY
const SOURCE_STATE_NAME = 'Staging'
const TARGET_STATE_NAME = 'Production (Done)'
const TEAM_NAME = process.env.TEAM_NAME
const TARGET_LABEL = process.env.TARGET_LABEL
if (!LINEAR_API_KEY) {
throw new Error('No LINEAR_API_KEY environment variable')
}
if (!TEAM_NAME) {
throw new Error('No TEAM_NAME environment variable')
}
if (!TARGET_LABEL) {
throw new Error('No TARGET_LABEL environment variable')
}
void updateLinearIssues()
async function getTeam(): Promise<Team> {
const client = new LinearClient({ apiKey: LINEAR_API_KEY })
const teams = await client.teams()
const targetTeam = teams.nodes.find((t) => t.name === TEAM_NAME)
if (!targetTeam) throw new Error(`Could not find team with name "${TEAM_NAME}"`)
return targetTeam
}
async function getStates(targetTeam: Team): Promise<{ sourceState: WorkflowState; targetState: WorkflowState }> {
const states = await targetTeam.states()
const sourceState = states.nodes.find((s) => s.name === SOURCE_STATE_NAME)
const targetState = states.nodes.find((s) => s.name === TARGET_STATE_NAME)
if (!sourceState) throw new Error(`Could not find workflow state ${SOURCE_STATE_NAME}`)
if (!targetState) throw new Error(`Could not find workflow state ${TARGET_STATE_NAME}`)
console.info(`Found source state: ${sourceState.name} (${sourceState.id})`)
console.info(`Found target state: ${targetState.name} (${targetState.id})`)
return { sourceState, targetState }
}
async function getTargetLabels(targetTeam: Team): Promise<IssueLabel[]> {
let labels = await targetTeam.labels()
const labelsArray = [...labels.nodes]
while (labels.pageInfo.hasNextPage) {
labels = await labels.fetchNext()
labelsArray.push(...labels.nodes)
}
const targetLabels = labelsArray.filter(
(label) => label.name === TARGET_LABEL || label.name.startsWith(TARGET_LABEL + '/')
)
if (targetLabels.length === 0) {
throw new Error(`Could not find any labels matching ${TARGET_LABEL}`)
}
console.info(`Found ${targetLabels.length} matching label(s):`)
targetLabels.forEach((label) => {
console.info(` - ${label.name} (${label.id})`)
})
return targetLabels
}
async function updateLinearIssues() {
const targetTeam = await getTeam()
const { sourceState, targetState } = await getStates(targetTeam)
const targetLabels = await getTargetLabels(targetTeam)
const targetLabelIds = targetLabels.map((label) => label.id)
const issues = await targetTeam.issues({
filter: {
labels: { some: { id: { in: targetLabelIds } } },
state: { id: { eq: sourceState.id } },
},
})
console.info(`Found ${issues.nodes.length} issue(s) in state "${SOURCE_STATE_NAME}"`)
await Promise.all(
issues.nodes.map(async (issue) => {
console.info(`Updating issue ${issue.identifier} to ${TARGET_STATE_NAME}`)
await issue.update({ stateId: targetState.id })
})
)
}
+19
View File
@@ -0,0 +1,19 @@
name: Check All
on:
pull_request:
branches:
- master
jobs:
check-all:
runs-on: ubuntu-latest
permissions:
checks: read
statuses: read
steps:
- name: Check All
uses: upsidr/merge-gatekeeper@v1
with:
timeout: 900 # 15 minutes
token: ${{ secrets.GITHUB_TOKEN }}
self: check-all
@@ -0,0 +1,46 @@
name: Check Integration Categories
on: pull_request
permissions:
id-token: write
contents: read
jobs:
check-integration-categories:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: 'integrations/**/*.{ts,md,svg,vrl}'
separator: '\n'
- name: Check integration categories
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
modified_integrations=$(echo -e "$CHANGED_FILES" | awk -F'/' '{print $2}' | sort -u)
should_fail=0
for integration in $modified_integrations; do
if [ ! -d "integrations/$integration" ]; then
continue
fi
echo "Checking $integration"
if ! ./.github/scripts/integration-has-valid-category.sh "$integration"; then
should_fail=1
fi
done
if [ "$should_fail" -ne 0 ]; then
echo "Please add a valid category attribute to your integration definition before pushing your changes."
exit 1
fi
@@ -0,0 +1,64 @@
name: Check Integration Versions
on: pull_request
permissions:
id-token: write
contents: read
jobs:
check-integration-versions:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Login to Botpress
env:
TOKEN: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
WORKSPACE_ID: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
run: pnpm bp login -y --token "$TOKEN" --workspace-id "$WORKSPACE_ID"
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: 'integrations/**/*.{ts,md,svg,vrl}'
separator: '\n'
- name: Check integration versions
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
modified_integrations=$(echo -e "$CHANGED_FILES" | awk -F'/' '{print $2}' | sort -u)
should_fail=0
SKIP_INTEGRATIONS=("chat")
for integration in $modified_integrations; do
skip=0
for skip_integration in "${SKIP_INTEGRATIONS[@]}"; do
if [ "$integration" = "$skip_integration" ]; then
echo "Skipping $integration"
skip=1
break
fi
done
if [ $skip -eq 1 ]; then
continue
fi
echo "Checking $integration"
exists=$(./.github/scripts/integration-exists.sh "$integration")
if [ "$exists" -ne 0 ]; then
echo "Integration $integration is already deployed publicly with the same version. Please update the version of your integration."
should_fail=1
fi
done
if [ "$should_fail" -ne 0 ]; then
echo "Please update the version of your integration before pushing your changes."
exit 1
fi
@@ -0,0 +1,49 @@
name: Check Plugins Versions
on: pull_request
permissions:
id-token: write
contents: read
jobs:
check-plugins-versions:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Login to Botpress
env:
TOKEN: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
WORKSPACE_ID: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
run: pnpm bp login -y --token "$TOKEN" --workspace-id "$WORKSPACE_ID"
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: 'plugins/**/*.{ts,md,svg}'
separator: '\n'
- name: Check plugin versions
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
modified_plugins=$(echo -e "$CHANGED_FILES" | awk -F'/' '{print $2}' | sort -u)
should_fail=0
for plugin in $modified_plugins; do
echo "Checking $plugin"
exists=$(./.github/scripts/plugin-exists.sh "$plugin")
if [ "$exists" -ne 0 ]; then
echo "Plugin $plugin is already deployed publicly with the same version. Please update the version of your plugin."
should_fail=1
fi
done
if [ "$should_fail" -ne 0 ]; then
echo "Please update the version of your plugin before pushing your changes."
exit 1
fi
+18
View File
@@ -0,0 +1,18 @@
name: Check Shell Scripts
on:
pull_request:
paths:
- '**/*.sh'
- .github/workflows
- .github/actions
jobs:
check-shells:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check shell scripts
uses: botpress/gh-actions/check-shells@v3
+52
View File
@@ -0,0 +1,52 @@
name: Deploy Bots
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup
env:
BUGBUSTER_GITHUB_TOKEN: ${{ secrets.BUGBUSTER_GITHUB_TOKEN }}
BUGBUSTER_GITHUB_WEBHOOK_SECRET: ${{ secrets.BUGBUSTER_GITHUB_WEBHOOK_SECRET }}
BUGBUSTER_LINEAR_API_KEY: ${{ secrets.BUGBUSTER_LINEAR_API_KEY }}
BUGBUSTER_LINEAR_WEBHOOK_SIGNING_SECRET: ${{ secrets.BUGBUSTER_LINEAR_WEBHOOK_SIGNING_SECRET }}
BUGBUSTER_TELEGRAM_BOT_TOKEN: ${{ secrets.BUGBUSTER_TELEGRAM_BOT_TOKEN }}
BUGBUSTER_SLACK_REFRESH_TOKEN: ${{ secrets.BUGBUSTER_SLACK_REFRESH_TOKEN }}
BUGBUSTER_SLACK_CLIENT_ID: ${{ secrets.BUGBUSTER_SLACK_CLIENT_ID }}
BUGBUSTER_SLACK_CLIENT_SECRET: ${{ secrets.BUGBUSTER_SLACK_CLIENT_SECRET }}
BUGBUSTER_SLACK_SIGNING_SECRET: ${{ secrets.BUGBUSTER_SLACK_SIGNING_SECRET }}
CLOG_SLACK_CLIENT_ID: ${{ secrets.CLOG_SLACK_CLIENT_ID }}
CLOG_SLACK_CLIENT_SECRET: ${{ secrets.CLOG_SLACK_CLIENT_SECRET }}
CLOG_SLACK_SIGNING_SECRET: ${{ secrets.CLOG_SLACK_SIGNING_SECRET }}
CLOG_SLACK_REFRESH_TOKEN: ${{ secrets.CLOG_SLACK_REFRESH_TOKEN }}
uses: ./.github/actions/setup
- name: Deploy Bots
env:
WORKSPACE_ID: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
TOKEN: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
api_url="https://api.botpress.cloud"
# login
echo "### Logging in to $api_url ###"
pnpm bp login -y --api-url "$api_url" --workspaceId "$WORKSPACE_ID" --token "$TOKEN"
# deploy
bots="pnpm list -F bugbuster -F clog --json"
bot_paths=$(eval "$bots" | jq -r 'map(.path) | .[]')
for bot_path in $bot_paths; do
bot_name=$(basename "$bot_path")
echo -e "\nDeploying bot: ### $bot_name ###\n"
bot_id=$(pnpm bp bots new --name "$bot_name" --json --if-not-exists | jq -r ".id")
pnpm retry -n 2 -- pnpm -F "$bot_name" -c exec -- "pnpm bp deploy -v -y --botId $bot_id"
done
@@ -0,0 +1,75 @@
name: Deploy Chat Production
on:
workflow_dispatch:
inputs:
branchOrCommit:
description: 'Branch/Commit/Tag to deploy'
required: false
type: string
default: 'master'
skipDeploy:
description: 'Skip deployment to ECS'
required: false
type: boolean
default: false
builder:
description: 'Image Builder'
required: false
type: choice
options:
- docker
- depot
default: 'depot'
permissions:
id-token: write
contents: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
deploy-chat-production:
runs-on: ubuntu-latest
steps:
- uses: botpress/gh-actions/full-service-deploy@v3.3
with:
service: chat
repository: chat-integration
dockerfile: integrations/chat/Dockerfile
context: .
builder: ${{ inputs.builder || 'depot' }}
depot-project: ${{ secrets.DEPOT_PROJECT_ID }}
role-ecs-update: botpress_infra_update
skip-ecs-update: ${{ inputs.skipDeploy }}
create-tag: true
ref: ${{ inputs.branchOrCommit || github.sha }}
environment: production
deploy-chat-lambda:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ inputs.branchOrCommit || github.sha }}
- name: Setup
uses: ./.github/actions/setup
- name: Deploy to Lambda
run: |
pnpm bp login -y --api-url "https://api.botpress.cloud" --workspaceId "${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}" --token "${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}"
pnpm -F "{integrations/chat}" -c exec -- bp deploy -v -y --noBuild --visibility public --allowDeprecated
ping-success:
needs: [deploy-chat-production, deploy-chat-lambda]
runs-on: ubuntu-latest
steps:
- run: curl -m 10 --retry 5 "${{ secrets.CHAT_DEPLOY_PRODUCTION_PING_URL }}"
ping-failure:
needs: [deploy-chat-production, deploy-chat-lambda]
if: ${{ failure() }}
runs-on: ubuntu-latest
steps:
- run: curl -m 10 --retry 5 "${{ secrets.CHAT_DEPLOY_PRODUCTION_PING_URL }}/fail"
+79
View File
@@ -0,0 +1,79 @@
name: Deploy Chat Staging
on:
push:
branches:
- master
paths:
- 'integrations/chat/**'
workflow_dispatch:
inputs:
branchOrCommit:
description: 'Branch/Commit/Tag to deploy'
required: false
type: string
default: 'master'
skipDeploy:
description: 'Skip deployment to ECS'
required: false
type: boolean
default: false
builder:
description: 'Image Builder'
required: false
type: choice
options:
- docker
- depot
default: 'depot'
permissions:
id-token: write
contents: write
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
deploy-chat-staging:
runs-on: ubuntu-latest
steps:
- uses: botpress/gh-actions/full-service-deploy@v3.3
with:
service: chat
repository: chat-integration
dockerfile: integrations/chat/Dockerfile
context: .
builder: ${{ inputs.builder || 'depot' }}
depot-project: ${{ secrets.DEPOT_PROJECT_ID }}
role-ecs-update: botpress_infra_update
skip-ecs-update: ${{ inputs.skipDeploy }}
ref: ${{ inputs.branchOrCommit || github.sha }}
environment: staging
deploy-chat-lambda:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ inputs.branchOrCommit || github.sha }}
- name: Setup
uses: ./.github/actions/setup
- name: Deploy to Lambda
run: |
pnpm bp login -y --api-url "https://api.botpress.dev" --workspaceId "${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}" --token "${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}"
pnpm -F "{integrations/chat}" -c exec -- bp deploy -v -y --noBuild --visibility public --allowDeprecated
ping-success:
needs: [deploy-chat-staging, deploy-chat-lambda]
runs-on: ubuntu-latest
steps:
- run: curl -m 10 --retry 5 "${{ secrets.CHAT_DEPLOY_STAGING_PING_URL }}"
ping-failure:
needs: [deploy-chat-staging, deploy-chat-lambda]
if: ${{ failure() }}
runs-on: ubuntu-latest
steps:
- run: curl -m 10 --retry 5 "${{ secrets.CHAT_DEPLOY_STAGING_PING_URL }}/fail"
@@ -0,0 +1,55 @@
name: Deploy Integrations Production
on:
workflow_dispatch:
inputs:
force:
description: 'Force re-deploying integrations'
type: boolean
required: false
default: false
permissions:
id-token: write
contents: read
jobs:
deploy-production:
runs-on: depot-ubuntu-22.04-8
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Deploy Interfaces
uses: ./.github/actions/deploy-interfaces
with:
environment: 'production'
force: ${{ github.event.inputs.force == 'true' }}
token_cloud_ops_account: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
- name: Deploy Integrations
uses: ./.github/actions/deploy-integrations
with:
environment: 'production'
extra_filter: "-F '!docusign' -F '!chat' -F '!grafana'"
force: ${{ github.event.inputs.force == 'true' }}
token_cloud_ops_account: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
shopify_admin_automation_token: ${{ secrets.PRODUCTION_SHOPIFY_ADMIN_AUTOMATION_TOKEN }}
shopify_storefront_automation_token: ${{ secrets.PRODUCTION_SHOPIFY_STOREFRONT_AUTOMATION_TOKEN }}
- name: Deploy Plugins
uses: ./.github/actions/deploy-plugins
with:
extra_filter: "-F '!analytics' -F '!logger' -F '!personality' -F '!synchronizer' -F '!knowledge'"
environment: 'production'
force: ${{ github.event.inputs.force == 'true' }}
token_cloud_ops_account: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
- name: Update Linear Status
uses: ./.github/actions/update-linear-status
continue-on-error: true
with:
linearApiKey: ${{secrets.LINEAR_API_KEY}}
teamName: 'SHELL (Integration)'
targetLabel: 'area/integrations'
@@ -0,0 +1,56 @@
name: Deploy Integrations Staging
on:
push:
branches:
- master
pull_request:
paths: 'integrations/**'
workflow_dispatch:
inputs:
force:
description: 'Force re-deploying integrations'
type: boolean
required: false
default: false
permissions:
id-token: write
contents: read
jobs:
deploy-staging:
runs-on: depot-ubuntu-22.04-8
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Deploy Interfaces
uses: ./.github/actions/deploy-interfaces
if: ${{ github.event_name != 'pull_request' }}
with:
environment: 'staging'
force: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force == 'true' }}
token_cloud_ops_account: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}
- name: Deploy Integrations
uses: ./.github/actions/deploy-integrations
with:
environment: 'staging'
extra_filter: "-F '!chat'"
force: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force == 'true' }}
dry_run: ${{ github.event_name == 'pull_request' }}
token_cloud_ops_account: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}
shopify_admin_automation_token: ${{ secrets.STAGING_SHOPIFY_ADMIN_AUTOMATION_TOKEN }}
shopify_storefront_automation_token: ${{ secrets.STAGING_SHOPIFY_STOREFRONT_AUTOMATION_TOKEN }}
- name: Deploy Plugins
uses: ./.github/actions/deploy-plugins
if: ${{ github.event_name != 'pull_request' }}
with:
environment: 'staging'
force: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.force == 'true' }}
token_cloud_ops_account: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}
+89
View File
@@ -0,0 +1,89 @@
name: Check Chat Integration Docker
on:
pull_request:
branches:
- master
paths:
- 'integrations/chat/**'
- 'packages/sdk/**'
permissions:
id-token: write
contents: read
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
build-and-test:
runs-on: depot-ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Depot CLI
uses: depot/setup-action@v1
- name: Build Docker image
uses: depot/build-push-action@v1
with:
project: ${{ secrets.DEPOT_PROJECT_ID }}
build-args: |
MINIFY=true
file: ./integrations/chat/Dockerfile
context: .
push: false
load: true
tags: chat-integration:test
- name: Start Docker container
run: |
docker run -d \
--name chat-test \
-p 8081:8081 \
-e SECRET_SIGNAL_URL=https://chat.botpress.dev \
chat-integration:test
- name: Wait for container to be ready
run: |
echo "Waiting for container to start..."
for i in {1..30}; do
if docker ps --filter "name=chat-test" --filter "status=running" | grep -q chat-test; then
echo "Container is running"
sleep 5
exit 0
fi
if docker ps -a --filter "name=chat-test" --filter "status=exited" | grep -q chat-test; then
echo "Container exited prematurely!"
docker logs chat-test
exit 1
fi
echo "Waiting for container... ($i/30)"
sleep 2
done
echo "Container did not start within expected time"
docker ps -a
exit 1
- name: Check health endpoint
run: |
echo "Checking /health endpoint..."
for i in {1..15}; do
if curl -f http://localhost:8081/health; then
echo "Health check passed!"
exit 0
fi
echo "Attempt $i/15 failed, retrying..."
sleep 2
done
echo "Health check failed after 15 attempts"
exit 1
- name: Show container logs on failure
if: failure()
run: docker logs chat-test
- name: Cleanup container
if: always()
run: docker rm -f chat-test || true
@@ -0,0 +1,78 @@
name: Production version matches master
on:
schedule:
- cron: '0 8 * * 1-5'
workflow_dispatch: # optional manual trigger
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Login to Botpress
env:
TOKEN: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
WORKSPACE_ID: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
run: pnpm bp login -y --token "$TOKEN" --workspace-id "$WORKSPACE_ID"
- name: Check integration versions
env:
SERVER_URL: ${{ github.server_url }}
REPO: ${{ github.repository }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WORKFLOW_SEAGULL_WEBHOOK_URL }}
run: |
SKIP_INTEGRATIONS=("chat" "docusign" "zendesk-messaging-hitl")
integrations=$(find integrations -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -n1 basename | sort -u)
should_fail=0
outdated_integrations=""
skipped_integrations=""
for integration in $integrations; do
# Check if integration should be skipped
skip=0
for skip_integration in "${SKIP_INTEGRATIONS[@]}"; do
if [ "$integration" = "$skip_integration" ]; then
echo "Skipping $integration"
skip=1
skipped_integrations="$skipped_integrations> $integration\n"
break
fi
done
if [ $skip -eq 1 ]; then
continue
fi
echo "Checking $integration"
exists=$(.github/scripts/integration-exists.sh "$integration")
if [ "$exists" -eq 0 ]; then
echo "Integration $integration is not up to date. Please deploy the latest version of your integration."
should_fail=1
outdated_integrations="$outdated_integrations> $integration\n"
fi
done
if [ $should_fail -eq 1 ]; then
message="\n\nThe following integrations are out of date:\n$outdated_integrations"
message="$message\nThe following integrations were skipped:\n$skipped_integrations"
message="$message\nPlease run the deployment for the out-of-date integrations in ${SERVER_URL}/${REPO}"
echo -e "\n\nSending curl request to Slack webhook"
echo "Response:"
curl -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"key": "prod-master-version-verification",
"text": "'"$message"'"
}'
echo -e "\nCurl request sent"
echo -e "$message"
exit 1
fi
+65
View File
@@ -0,0 +1,65 @@
name: Publish Packages
on:
workflow_dispatch: {}
push:
branches:
- master
permissions:
id-token: write
contents: read
jobs:
publish-packages:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/* -F llmz -F @bpinternal/zui'
- name: update npm
shell: bash
run: npm install -g npm@^11.5.1 # Required for OIDC login
- name: Publish Zui
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/zui'
- name: Publish Client
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/client'
- name: Publish SDK
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/sdk'
- name: Publish CLI
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/cli'
- name: Publish Chat Client
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/chat-client'
- name: Publish Cognitive Client
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/cognitive'
- name: Publish Vai
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/vai'
- name: Publish Zai
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/zai'
- name: Publish LLMz
uses: botpress/gh-actions/publish-if-not-exists@master
with:
path: './packages/llmz'
+29
View File
@@ -0,0 +1,29 @@
name: Purge Cache
on:
workflow_dispatch: {}
jobs:
purge-cache:
runs-on: ubuntu-latest
steps:
- name: Delete Cache Entries
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.ref_name }}
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache keys for branch '$BRANCH'"
cacheKeysForBranch=$(gh actions-cache list --limit 100 -R "$REPO" -B "$BRANCH" | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting cache entries..."
for cacheKey in $cacheKeysForBranch
do
echo "Deleting entry: $cacheKey"
gh actions-cache delete "$cacheKey" -R "$REPO" -B "$BRANCH" --confirm
done
echo "Done"
@@ -0,0 +1,43 @@
name: Refresh Instagram Access Tokens Production
on:
schedule:
# Run at 10:00 AM EST (15:00 UTC) on the first Tuesday of every month
- cron: '0 15 1-7 * 2'
workflow_dispatch:
jobs:
refresh-tokens:
runs-on: depot-ubuntu-22.04-8
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpresshub/instagram'
- name: Refresh Instagram Access Tokens
uses: ./.github/actions/refresh-instagram-tokens
with:
token_cloud_ops_account: ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}
api_url: https://api.botpress.cloud
current_token: ${{ secrets.PRODUCTION_INSTAGRAM_ACCESS_TOKEN }}
secret_name: PRODUCTION_INSTAGRAM_ACCESS_TOKEN
sync_secret_app_id: ${{ vars.SYNC_SECRET_APP_ID }}
sync_secret_app_private_key: ${{ secrets.SYNC_SECRET_APP_PRIVATE_KEY }}
ping-success:
runs-on: depot-ubuntu-22.04-8
needs: [refresh-tokens]
steps:
- env:
PING_URL: ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }}
run: curl -m 10 --retry 5 "$PING_URL"
ping-failure:
runs-on: depot-ubuntu-22.04-8
if: ${{ failure() }}
needs: [refresh-tokens]
steps:
- env:
PING_URL: ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }}
run: curl -m 10 --retry 5 "$PING_URL/fail"
@@ -0,0 +1,43 @@
name: Refresh Instagram Access Tokens Staging
on:
schedule:
# Run at 10:00 AM EST (15:00 UTC) on the first Tuesday of every month
- cron: '0 15 1-7 * 2'
workflow_dispatch:
jobs:
refresh-tokens:
runs-on: depot-ubuntu-22.04-8
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpresshub/instagram'
- name: Refresh Instagram Access Tokens
uses: ./.github/actions/refresh-instagram-tokens
with:
token_cloud_ops_account: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
cloud_ops_workspace_id: ${{ secrets.STAGING_CLOUD_OPS_WORKSPACE_ID }}
api_url: https://api.botpress.dev
current_token: ${{ secrets.STAGING_INSTAGRAM_ACCESS_TOKEN }}
secret_name: STAGING_INSTAGRAM_ACCESS_TOKEN
sync_secret_app_id: ${{ vars.SYNC_SECRET_APP_ID }}
sync_secret_app_private_key: ${{ secrets.SYNC_SECRET_APP_PRIVATE_KEY }}
ping-success:
runs-on: depot-ubuntu-22.04-8
needs: [refresh-tokens]
steps:
- env:
PING_URL: ${{ secrets.STAGING_INSTAGRAM_REFRESH_TOKEN_PING_URL }}
run: curl -m 10 --retry 5 "$PING_URL"
ping-failure:
runs-on: depot-ubuntu-22.04-8
if: ${{ failure() }}
needs: [refresh-tokens]
steps:
- env:
PING_URL: ${{ secrets.STAGING_INSTAGRAM_REFRESH_TOKEN_PING_URL }}
run: curl -m 10 --retry 5 "$PING_URL/fail"
+32
View File
@@ -0,0 +1,32 @@
name: Run Chat Tests
on: pull_request
permissions:
id-token: write
contents: read
jobs:
run-chat-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpresshub/chat -F @bp-bots/echo -F @botpress/chat'
- name: Install tilt
run: curl -k -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
- name: Run Tilt
env:
BP_TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
tilt ci -f ./echo.Tiltfile -- \
--skip-install \
--skip-build \
--bp-domain 'botpress.dev' \
--bp-workspace-id '95de33eb-1551-4af9-9088-e5dcb02efd09' \
--bp-token "$BP_TOKEN"
+26
View File
@@ -0,0 +1,26 @@
name: Run Checks
on: pull_request
permissions:
id-token: write
contents: read
jobs:
run-checks:
runs-on: depot-ubuntu-22.04-8
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- run: pnpm run check:dep
- run: pnpm run check:sherif
- run: pnpm run check:oxlint
- run: pnpm run check:format
- run: pnpm run check:eslint
- run: pnpm run check:bplint
- run: pnpm run check:type
- run: pnpm run test
@@ -0,0 +1,29 @@
name: Run CLI Tests Windows
on:
pull_request: {}
workflow_dispatch: {}
permissions:
id-token: write
contents: read
jobs:
run-cli-tests-windows:
runs-on: windows-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/cli'
- env:
WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
# shellcheck disable=all
pnpm run -F cli test:e2e -v --api-url https://api.botpress.dev --workspace-id $env:WORKSPACE_ID --workspace-handle clitests --token $env:TOKEN --sdk-path "$(pwd)/packages/sdk" --client-path "$(pwd)/packages/client"
shell: pwsh
+33
View File
@@ -0,0 +1,33 @@
name: Run CLI Tests
on:
pull_request: {}
workflow_dispatch: {}
permissions:
id-token: write
contents: read
jobs:
run-cli-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/cli'
- env:
WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
pnpm run -F cli test:e2e -v \
--api-url https://api.botpress.dev \
--workspace-id "$WORKSPACE_ID" \
--workspace-handle clitests \
--token "$TOKEN" \
--sdk-path "$(pwd)/packages/sdk" \
--client-path "$(pwd)/packages/client"
+23
View File
@@ -0,0 +1,23 @@
name: Run Client Tests
on: pull_request
permissions:
id-token: write
contents: read
jobs:
run-client-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/client'
- run: |
# pnpm -F client exec puppeteer browsers install chrome
pnpm -F client run test:e2e
+49
View File
@@ -0,0 +1,49 @@
name: Run Cognitive Tests
on:
pull_request:
paths:
- 'packages/cognitive/**'
- '.github/workflows/run-cognitive-tests.yml'
permissions:
id-token: write
contents: read
jobs:
run-cognitive-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/cognitive'
- name: Login
env:
BP_API_URL: 'https://api.botpress.dev'
BP_WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
BP_TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
pnpm bp login
- name: Run Cognitive Tests
id: 'run-tests'
env:
CLOUD_PAT: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
bot_id=$(pnpm bp bots new --json | jq -r ".id")
echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT"
export CLOUD_API_ENDPOINT='https://api.botpress.dev'
export CLOUD_BOT_ID="$bot_id"
pnpm -F cognitive run test:e2e
- name: Cleanup
if: ${{ always() }}
env:
BOT_ID: ${{ steps.run-tests.outputs.bot_id }}
run: |
pnpm bp bots rm "$BOT_ID"
+49
View File
@@ -0,0 +1,49 @@
name: Run LLMz Tests
on:
pull_request:
paths:
- 'packages/llmz/**'
- '.github/workflows/run-llmz-tests.yml'
permissions:
id-token: write
contents: read
jobs:
run-llmz-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F llmz'
- name: Login
env:
BP_API_URL: 'https://api.botpress.dev'
BP_WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
BP_TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
pnpm bp login
- name: Run LLMz Tests
id: 'run-tests'
env:
CLOUD_PAT: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
bot_id=$(pnpm bp bots new --json | jq -r ".id")
echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT"
export CLOUD_API_ENDPOINT='https://api.botpress.dev'
export CLOUD_BOT_ID="$bot_id"
pnpm -F llmz run test:e2e
- name: Cleanup
if: ${{ always() }}
env:
BOT_ID: ${{ steps.run-tests.outputs.bot_id }}
run: |
pnpm bp bots rm "$BOT_ID"
+49
View File
@@ -0,0 +1,49 @@
name: Run Vai Tests
on:
pull_request:
paths:
- 'packages/vai/**'
- '.github/workflows/run-vai-tests.yml'
permissions:
id-token: write
contents: read
jobs:
run-vai-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/vai'
- name: Login
env:
BP_API_URL: 'https://api.botpress.dev'
BP_WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
BP_TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
pnpm bp login
- name: Run Vai Tests
id: 'run-tests'
env:
CLOUD_PAT: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
bot_id=$(pnpm bp bots new --json | jq -r ".id")
echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT"
export CLOUD_API_ENDPOINT='https://api.botpress.dev'
export CLOUD_BOT_ID="$bot_id"
pnpm -F vai run test:e2e
- name: Cleanup
if: ${{ always() }}
env:
BOT_ID: ${{ steps.run-tests.outputs.bot_id }}
run: |
pnpm bp bots rm "$BOT_ID"
+49
View File
@@ -0,0 +1,49 @@
name: Run Zai Tests
on:
pull_request:
paths:
- 'packages/zai/**'
- '.github/workflows/run-zai-tests.yml'
permissions:
id-token: write
contents: read
jobs:
run-zai-tests:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_OPTIONS: '--max_old_space_size=8192'
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
with:
extra_filters: '-F @botpress/zai'
- name: Login
env:
BP_API_URL: 'https://api.botpress.dev'
BP_WORKSPACE_ID: ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }}
BP_TOKEN: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
pnpm bp login
- name: Run Zai Tests
id: 'run-tests'
env:
CLOUD_PAT: ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }}
run: |
bot_id=$(pnpm bp bots new --json | jq -r ".id")
echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT"
export CLOUD_API_ENDPOINT='https://api.botpress.dev'
export CLOUD_BOT_ID="$bot_id"
pnpm -F zai run test:e2e
- name: Cleanup
if: ${{ always() }}
env:
BOT_ID: ${{ steps.run-tests.outputs.bot_id }}
run: |
pnpm bp bots rm "$BOT_ID"