From 2f8c0dde3a3f6fcdc58ba0105ab9bf9de9e527d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Levasseur?= Date: Mon, 6 Apr 2026 16:02:09 -0400 Subject: [PATCH 1/3] chore(llmz): lock lru-cache version dependency (#15094) --- packages/llmz/package.json | 4 ++-- pnpm-lock.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/llmz/package.json b/packages/llmz/package.json index 9b907546ca0..a239e108f11 100644 --- a/packages/llmz/package.json +++ b/packages/llmz/package.json @@ -2,7 +2,7 @@ "name": "llmz", "type": "module", "description": "LLMz - An LLM-native Typescript VM built on top of Zui", - "version": "0.0.68", + "version": "0.0.69", "types": "./dist/index.d.ts", "main": "./dist/index.cjs", "module": "./dist/index.js", @@ -43,7 +43,7 @@ "exponential-backoff": "^3.1.1", "handlebars": "^4.7.8", "lodash-es": "^4.17.21", - "lru-cache": "^11.0.2", + "lru-cache": "~11.0.2", "ms": "^2.1.3", "prettier": "^3.4.2", "quickjs-emscripten-core": "^0.31.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1d944acec0..873a5c71b60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2946,7 +2946,7 @@ importers: specifier: ^4.17.21 version: 4.17.21 lru-cache: - specifier: ^11.0.2 + specifier: ~11.0.2 version: 11.0.2 ms: specifier: ^2.1.3 From 5fb10425c9c0acd2e2b28482f05d4b28dc7f46ec Mon Sep 17 00:00:00 2001 From: Chris Grass Date: Mon, 6 Apr 2026 18:33:44 -0400 Subject: [PATCH 2/3] chore(ci): Add check-shells workflow (#15090) --- .../create-or-update-secret/action.yml | 4 +- .../actions/deploy-integrations/action.yml | 63 +++++++++++++------ .github/actions/deploy-interfaces/action.yml | 33 ++++++---- .github/actions/deploy-plugins/action.yml | 35 +++++++---- .github/actions/docker-build/action.yml | 4 +- .github/actions/setup/action.yml | 5 +- .github/scripts/integration-exists.sh | 11 ++-- .../scripts/integration-implements-sandbox.sh | 3 +- .github/scripts/interface-exists.sh | 11 ++-- .github/scripts/ls-sentry-integrations.sh | 7 ++- .github/scripts/plugin-exists.sh | 11 ++-- .../workflows/check-integration-versions.yml | 15 +++-- .github/workflows/check-plugin-versions.yml | 15 +++-- .github/workflows/check-shells.yml | 18 ++++++ .github/workflows/deploy-bots.yml | 13 ++-- .github/workflows/docker-chat.yml | 8 +-- .../prod-master-version-verification.yml | 19 ++++-- .github/workflows/purge-cache.yml | 13 ++-- ...esh-instagram-access-tokens-production.yml | 8 ++- .github/workflows/run-chat-tests.yml | 4 +- .github/workflows/run-cli-tests-windows.yml | 14 ++--- .github/workflows/run-cli-tests.yml | 9 ++- .github/workflows/run-cognitive-tests.yml | 11 ++-- .github/workflows/run-llmz-tests.yml | 11 ++-- .github/workflows/run-vai-tests.yml | 11 ++-- .github/workflows/run-zai-tests.yml | 11 ++-- 26 files changed, 239 insertions(+), 128 deletions(-) create mode 100644 .github/workflows/check-shells.yml diff --git a/.github/actions/create-or-update-secret/action.yml b/.github/actions/create-or-update-secret/action.yml index 7c9ac6f38b7..a6f775e69e4 100644 --- a/.github/actions/create-or-update-secret/action.yml +++ b/.github/actions/create-or-update-secret/action.yml @@ -27,5 +27,7 @@ runs: shell: bash env: GH_TOKEN: ${{ steps.generate-token.outputs.token }} + SECRET_NAME: ${{ inputs.secret_name }} + SECRET_VALUE: ${{ inputs.secret_value }} run: | - gh secret set ${{ inputs.secret_name }} --body "${{ inputs.secret_value }}" + gh secret set "$SECRET_NAME" --body "$SECRET_VALUE" diff --git a/.github/actions/deploy-integrations/action.yml b/.github/actions/deploy-integrations/action.yml index 2e860ed18dc..1f1f34048e6 100644 --- a/.github/actions/deploy-integrations/action.yml +++ b/.github/actions/deploy-integrations/action.yml @@ -42,56 +42,78 @@ runs: shell: bash run: | script_path="./.github/scripts/ls-sentry-integrations.sh" - chmod +x $script_path - filter=$($script_path) - echo "::set-output name=filter::$filter" + chmod +x "$script_path" + filter=$("$script_path") + echo "filter=$filter" >> "$GITHUB_OUTPUT" - name: Inject SourceMaps shell: bash - run: pnpm -r --stream ${{ steps.list_sentry_integrations.outputs.filter }} exec sentry-cli sourcemaps inject .botpress/dist + env: + SENTRY_FILTER: ${{ steps.list_sentry_integrations.outputs.filter }} + run: pnpm -r --stream "$SENTRY_FILTER" exec sentry-cli sourcemaps inject .botpress/dist - name: Upload SourceMaps shell: bash - run: pnpm -r --stream ${{ steps.list_sentry_integrations.outputs.filter }} exec sentry-cli sourcemaps upload --release=${{ github.sha }} --url-prefix '~' .botpress/dist env: SENTRY_AUTH_TOKEN: ${{ inputs.sentry_auth_token }} SENTRY_ORG: botpress-rm SENTRY_RELEASE: ${{ github.sha }} + SENTRY_FILTER: ${{ steps.list_sentry_integrations.outputs.filter }} + GITHUB_SHA: ${{ github.sha }} + run: pnpm -r --stream "$SENTRY_FILTER" exec sentry-cli sourcemaps upload --release="$GITHUB_SHA" --url-prefix '~' .botpress/dist - name: Deploys Integrations + shell: bash env: - ENVIRONMENT: ${{ inputs.environment }} + 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 }} SENTRY_RELEASE: ${{ github.sha }} SENTRY_ENVIRONMENT: ${{ inputs.environment }} - shell: bash run: | - api_url="${{ inputs.environment == 'staging' && 'https://api.botpress.dev' || 'https://api.botpress.cloud' }}" + 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" + pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT" # deploy - redeploy=${{ inputs.force == 'true' && 1 || 0 }} - dryrun="${{ inputs.dry_run == 'true' && '--dryRun' || '' }}" - is_dry_run=${{ inputs.dry_run == 'true' && 1 || 0 }} - all_filters="-F '{integrations/*}' ${{ inputs.extra_filter }}" + 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") | .[]") + 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) + integration=$(basename "$integration_path") + exists=$(./.github/scripts/integration-exists.sh "$integration") base_command="bp deploy -v -y --noBuild --visibility public --allowDeprecated $dryrun" upload_sandbox_scripts=false - if [ $exists -eq 0 ]; then + if [ "$exists" -eq 0 ]; then echo -e "\nDeploying integration: ### $integration ###\n" pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" -c exec -- "$base_command" upload_sandbox_scripts=true - elif [ $redeploy -eq 1 ]; then + elif [ "$redeploy" -eq 1 ]; then echo -e "\nRe-deploying integration: ### $integration ###\n" pnpm retry -n 2 -- pnpm -F "{integrations/$integration}" -c exec -- "$base_command" upload_sandbox_scripts=true @@ -100,10 +122,11 @@ runs: fi # upload sandbox scripts - integration_implements_sandbox=$(./.github/scripts/integration-implements-sandbox.sh $integration) - if [ $integration_implements_sandbox == "true" ] && [ $upload_sandbox_scripts == "true" ] && [ $is_dry_run -eq 0 ]; then + integration_implements_sandbox=$(./.github/scripts/integration-implements-sandbox.sh "$integration") + if [ "$integration_implements_sandbox" = "true" ] && [ "$upload_sandbox_scripts" = "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 done diff --git a/.github/actions/deploy-interfaces/action.yml b/.github/actions/deploy-interfaces/action.yml index 965401ea529..24dcd1d0503 100644 --- a/.github/actions/deploy-interfaces/action.yml +++ b/.github/actions/deploy-interfaces/action.yml @@ -30,35 +30,46 @@ runs: using: 'composite' steps: - name: Deploys Interfaces + shell: bash env: - ENVIRONMENT: ${{ inputs.environment }} + 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 }} - shell: bash run: | - api_url="${{ inputs.environment == 'staging' && 'https://api.botpress.dev' || 'https://api.botpress.cloud' }}" + 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" + pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT" # deploy - redeploy=${{ inputs.force == 'true' && 1 || 0 }} - all_filters="-F '{interfaces/*}' ${{ inputs.extra_filter }}" + 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") | .[]") + 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) + interface=$(basename "$interface_path") + exists=$(./.github/scripts/interface-exists.sh "$interface") base_command="bp deploy -v -y --visibility public" - if [ $exists -eq 0 ]; then + 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 + 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 diff --git a/.github/actions/deploy-plugins/action.yml b/.github/actions/deploy-plugins/action.yml index 8631300a2bc..ef6d153026e 100644 --- a/.github/actions/deploy-plugins/action.yml +++ b/.github/actions/deploy-plugins/action.yml @@ -30,36 +30,47 @@ runs: using: 'composite' steps: - name: Deploys Plugins + shell: bash env: - ENVIRONMENT: ${{ inputs.environment }} + 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 }} - shell: bash run: | - api_url="${{ inputs.environment == 'staging' && 'https://api.botpress.dev' || 'https://api.botpress.cloud' }}" + 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" + pnpm bp login -y --api-url "$api_url" --workspaceId "$CLOUD_OPS_WORKSPACE_ID" --token "$TOKEN_CLOUD_OPS_ACCOUNT" # deploy - redeploy=${{ inputs.force == 'true' && 1 || 0 }} - all_filters="-F '{plugins/*}' ${{ inputs.extra_filter }}" + 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") | .[]") + 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) + plugin=$(basename "$plugin_path") + exists=$(./.github/scripts/plugin-exists.sh "$plugin") base_command="bp deploy -v -y --visibility public" - - if [ $exists -eq 0 ]; then + + 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 + 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 diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index fa36b56cf4b..eab93cf0abc 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -64,9 +64,9 @@ runs: ECR_REGISTRY: ${{ steps.ecr.outputs.registry }} run: | aws --version - aws ecr create-repository --repository-name $ECR_REPOSITORY || true + 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 + 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 diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 0715f2c687b..3457155951f 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -39,4 +39,7 @@ runs: shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} env: BP_VERBOSE: 'true' - run: pnpm turbo run build ${{ inputs.extra_filters }} + EXTRA_FILTERS: ${{ inputs.extra_filters }} + run: | + # shellcheck disable=SC2086 # EXTRA_FILTERS contains multiple space-separated filter arguments + pnpm turbo run build $EXTRA_FILTERS diff --git a/.github/scripts/integration-exists.sh b/.github/scripts/integration-exists.sh index 969b03f9bc8..8bd841fb518 100755 --- a/.github/scripts/integration-exists.sh +++ b/.github/scripts/integration-exists.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -z "$1" ]; then echo "Error: integration name is not provided" >&2 exit 1 @@ -5,10 +6,10 @@ fi integration=$1 integration_path="integrations/$integration" -integration_def=$(pnpm bp read --work-dir $integration_path --json) +integration_def=$(pnpm bp read --work-dir "$integration_path" --json) -name=$(echo $integration_def | jq -r ".name") -version=$(echo $integration_def | jq -r ".version") +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 +exists=$(pnpm bp integrations ls --name "$name" --version-number "$version" --json | jq '[ .[] | select(.public) ] | length') # 0 if not exists +echo "$exists" diff --git a/.github/scripts/integration-implements-sandbox.sh b/.github/scripts/integration-implements-sandbox.sh index 2ae932d5c85..1e8b2ec506e 100755 --- a/.github/scripts/integration-implements-sandbox.sh +++ b/.github/scripts/integration-implements-sandbox.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -z "$1" ]; then echo "Error: integration name is not provided" >&2 exit 1 @@ -12,4 +13,4 @@ if [ -f "$sandbox_script" ]; then has_sandbox=true fi -echo $has_sandbox +echo "$has_sandbox" diff --git a/.github/scripts/interface-exists.sh b/.github/scripts/interface-exists.sh index e4e3455e176..a7e6a240f54 100755 --- a/.github/scripts/interface-exists.sh +++ b/.github/scripts/interface-exists.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -z "$1" ]; then echo "Error: interface name is not provided" >&2 exit 1 @@ -5,11 +6,11 @@ fi interface=$1 interface_path="interfaces/$interface" -interface_def=$(pnpm bp read --work-dir $interface_path --json) +interface_def=$(pnpm bp read --work-dir "$interface_path" --json) -name=$(echo $interface_def | jq -r ".name") -version=$(echo $interface_def | jq -r ".version") +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 +exists=$(eval "$command" && echo 1 || echo 0) +echo "$exists" diff --git a/.github/scripts/ls-sentry-integrations.sh b/.github/scripts/ls-sentry-integrations.sh index 21e7017e003..204c2843c5c 100755 --- a/.github/scripts/ls-sentry-integrations.sh +++ b/.github/scripts/ls-sentry-integrations.sh @@ -1,11 +1,12 @@ -sentry_integrations=( $(ls integrations/*/.sentryclirc) ) +#!/bin/bash +mapfile -t sentry_integrations < <(ls integrations/*/.sentryclirc) filter="" for sentry_integration in "${sentry_integrations[@]}"; do - actual_integration=$(echo $sentry_integration | sed 's/\.sentryclirc//g') + actual_integration="${sentry_integration//\.sentryclirc/}" filter="-F ./$actual_integration $filter" done -echo $filter +echo "$filter" diff --git a/.github/scripts/plugin-exists.sh b/.github/scripts/plugin-exists.sh index 92d3c7d4135..c8956325cb6 100755 --- a/.github/scripts/plugin-exists.sh +++ b/.github/scripts/plugin-exists.sh @@ -1,3 +1,4 @@ +#!/bin/bash if [ -z "$1" ]; then echo "Error: plugin name is not provided" >&2 exit 1 @@ -5,11 +6,11 @@ fi plugin=$1 plugin_path="plugins/$plugin" -plugin_def=$(pnpm bp read --work-dir $plugin_path --json) +plugin_def=$(pnpm bp read --work-dir "$plugin_path" --json) -name=$(echo $plugin_def | jq -r ".name") -version=$(echo $plugin_def | jq -r ".version") +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 +exists=$(eval "$command" && echo 1 || echo 0) +echo "$exists" diff --git a/.github/workflows/check-integration-versions.yml b/.github/workflows/check-integration-versions.yml index 5c4c0b0585f..50e9bd72047 100644 --- a/.github/workflows/check-integration-versions.yml +++ b/.github/workflows/check-integration-versions.yml @@ -15,7 +15,10 @@ jobs: - name: Setup uses: ./.github/actions/setup - name: Login to Botpress - run: pnpm bp login -y --token ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }} --workspace-id ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }} + 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 @@ -23,22 +26,24 @@ jobs: files: 'integrations/**/*.{ts,md,svg}' separator: '\n' - name: Check integration versions + env: + CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | - modified_integrations=$(echo -e "${{ steps.changed-files.outputs.all_changed_files }}" | awk -F'/' '{print $2}' | sort -u) + modified_integrations=$(echo -e "$CHANGED_FILES" | awk -F'/' '{print $2}' | sort -u) should_fail=0 for integration in $modified_integrations; do echo "Checking $integration" - exists=$(./.github/scripts/integration-exists.sh $integration) + exists=$(./.github/scripts/integration-exists.sh "$integration") - if [ $exists -ne 0 ]; then + 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 + if [ "$should_fail" -ne 0 ]; then echo "Please update the version of your integration before pushing your changes." exit 1 fi diff --git a/.github/workflows/check-plugin-versions.yml b/.github/workflows/check-plugin-versions.yml index 683a59c20e1..f2ba7b1eb24 100644 --- a/.github/workflows/check-plugin-versions.yml +++ b/.github/workflows/check-plugin-versions.yml @@ -15,7 +15,10 @@ jobs: - name: Setup uses: ./.github/actions/setup - name: Login to Botpress - run: pnpm bp login -y --token ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }} --workspace-id ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }} + 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 @@ -23,22 +26,24 @@ jobs: 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 "${{ steps.changed-files.outputs.all_changed_files }}" | awk -F'/' '{print $2}' | sort -u) + 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) + exists=$(./.github/scripts/plugin-exists.sh "$plugin") - if [ $exists -ne 0 ]; then + 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 + if [ "$should_fail" -ne 0 ]; then echo "Please update the version of your plugin before pushing your changes." exit 1 fi diff --git a/.github/workflows/check-shells.yml b/.github/workflows/check-shells.yml new file mode 100644 index 00000000000..fbe3776022d --- /dev/null +++ b/.github/workflows/check-shells.yml @@ -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 diff --git a/.github/workflows/deploy-bots.yml b/.github/workflows/deploy-bots.yml index 5ad5922cdad..262c4e10e1d 100644 --- a/.github/workflows/deploy-bots.yml +++ b/.github/workflows/deploy-bots.yml @@ -28,22 +28,25 @@ jobs: 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 "${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }}" --token "${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }}" + 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") | .[]") + bot_paths=$(eval "$bots" | jq -r 'map(.path) | .[]') for bot_path in $bot_paths; do - bot_name=$(basename $bot_path) + 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" + 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 diff --git a/.github/workflows/docker-chat.yml b/.github/workflows/docker-chat.yml index be88c0b3179..11766eb70ee 100644 --- a/.github/workflows/docker-chat.yml +++ b/.github/workflows/docker-chat.yml @@ -77,9 +77,9 @@ jobs: ECR_REPOSITORY: chat-integration run: | aws --version - aws ecr create-repository --repository-name $ECR_REPOSITORY || true + 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 + 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 @@ -156,9 +156,9 @@ jobs: IMAGE_TAG: ${{ github.sha }} run: | echo "Tagging image for ECR: $ECR_REGISTRY/chat-integration:$IMAGE_TAG" - docker tag chat-integration:test $ECR_REGISTRY/chat-integration:$IMAGE_TAG + docker tag chat-integration:test "$ECR_REGISTRY/chat-integration:$IMAGE_TAG" echo "Pushing to ECR..." - docker push $ECR_REGISTRY/chat-integration:$IMAGE_TAG + docker push "$ECR_REGISTRY/chat-integration:$IMAGE_TAG" echo "Successfully pushed image: $IMAGE_TAG" diff --git a/.github/workflows/prod-master-version-verification.yml b/.github/workflows/prod-master-version-verification.yml index 752504313d9..15e357e384c 100644 --- a/.github/workflows/prod-master-version-verification.yml +++ b/.github/workflows/prod-master-version-verification.yml @@ -14,12 +14,19 @@ jobs: - name: Setup uses: ./.github/actions/setup - name: Login to Botpress - run: pnpm bp login -y --token ${{ secrets.PRODUCTION_TOKEN_CLOUD_OPS_ACCOUNT }} --workspace-id ${{ secrets.PRODUCTION_CLOUD_OPS_WORKSPACE_ID }} + 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=("docusign" "zendesk" "zendesk-messaging-hitl") - integrations=$(ls -d integrations/*/ | xargs -n1 basename | sort -u) + integrations=$(find integrations -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -n1 basename | sort -u) should_fail=0 outdated_integrations="" skipped_integrations="" @@ -41,9 +48,9 @@ jobs: fi echo "Checking $integration" - exists=$(.github/scripts/integration-exists.sh $integration) + exists=$(.github/scripts/integration-exists.sh "$integration") - if [ $exists -eq 0 ]; then + 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" @@ -53,11 +60,11 @@ jobs: 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 ${{ github.server_url }}/${{ github.repository }}" + 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 ${{ secrets.SLACK_WORKFLOW_SEAGULL_WEBHOOK_URL }} \ + curl -X POST "$SLACK_WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d '{ "key": "prod-master-version-verification", diff --git a/.github/workflows/purge-cache.yml b/.github/workflows/purge-cache.yml index b4200bddbfb..d5aca72eef7 100644 --- a/.github/workflows/purge-cache.yml +++ b/.github/workflows/purge-cache.yml @@ -6,14 +6,15 @@ jobs: 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 - REPO=${{ github.repository }} - BRANCH=${{ github.ref_name }} - echo "Fetching list of cache keys for branch '$BRANCH'" - cacheKeysForBranch=$(gh actions-cache list --limit 100 -R $REPO -B $BRANCH | cut -f 1 ) + 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 @@ -22,9 +23,7 @@ jobs: for cacheKey in $cacheKeysForBranch do echo "Deleting entry: $cacheKey" - gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm + gh actions-cache delete "$cacheKey" -R "$REPO" -B "$BRANCH" --confirm done echo "Done" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/refresh-instagram-access-tokens-production.yml b/.github/workflows/refresh-instagram-access-tokens-production.yml index 84927fbe6ae..8bbd53af606 100644 --- a/.github/workflows/refresh-instagram-access-tokens-production.yml +++ b/.github/workflows/refresh-instagram-access-tokens-production.yml @@ -30,10 +30,14 @@ jobs: runs-on: depot-ubuntu-22.04-8 needs: [refresh-tokens] steps: - - run: curl -m 10 --retry 5 ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }} + - 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: - - run: curl -m 10 --retry 5 ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }}/fail + - env: + PING_URL: ${{ secrets.INSTAGRAM_REFRESH_TOKEN_PING_URL }} + run: curl -m 10 --retry 5 "$PING_URL/fail" diff --git a/.github/workflows/run-chat-tests.yml b/.github/workflows/run-chat-tests.yml index a71493f616b..72d0fb3b6be 100644 --- a/.github/workflows/run-chat-tests.yml +++ b/.github/workflows/run-chat-tests.yml @@ -21,10 +21,12 @@ jobs: - 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 ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} + --bp-token "$BP_TOKEN" diff --git a/.github/workflows/run-cli-tests-windows.yml b/.github/workflows/run-cli-tests-windows.yml index 02eda539edf..8941abfbf87 100644 --- a/.github/workflows/run-cli-tests-windows.yml +++ b/.github/workflows/run-cli-tests-windows.yml @@ -20,12 +20,10 @@ jobs: uses: ./.github/actions/setup with: extra_filters: '-F @botpress/cli' - - run: | - pnpm run -F cli test:e2e -v ` - --api-url https://api.botpress.dev ` - --workspace-id ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }} ` - --workspace-handle clitests ` - --token ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} ` - --sdk-path "$(pwd)/packages/sdk" ` - --client-path "$(pwd)/packages/client" + - 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 diff --git a/.github/workflows/run-cli-tests.yml b/.github/workflows/run-cli-tests.yml index f44ceac910e..38835619a63 100644 --- a/.github/workflows/run-cli-tests.yml +++ b/.github/workflows/run-cli-tests.yml @@ -20,11 +20,14 @@ jobs: uses: ./.github/actions/setup with: extra_filters: '-F @botpress/cli' - - run: | + - 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 ${{ secrets.STAGING_E2E_TESTS_WORKSPACE_ID }} \ + --workspace-id "$WORKSPACE_ID" \ --workspace-handle clitests \ - --token ${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} \ + --token "$TOKEN" \ --sdk-path "$(pwd)/packages/sdk" \ --client-path "$(pwd)/packages/client" diff --git a/.github/workflows/run-cognitive-tests.yml b/.github/workflows/run-cognitive-tests.yml index 22a887d1067..1f766dae4bc 100644 --- a/.github/workflows/run-cognitive-tests.yml +++ b/.github/workflows/run-cognitive-tests.yml @@ -31,16 +31,19 @@ jobs: 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 "::set-output name=bot_id::$bot_id" + echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT" export CLOUD_API_ENDPOINT='https://api.botpress.dev' - export CLOUD_BOT_ID=$bot_id - export CLOUD_PAT=${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} + 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 ${{ steps.run-tests.outputs.bot_id }} + pnpm bp bots rm "$BOT_ID" diff --git a/.github/workflows/run-llmz-tests.yml b/.github/workflows/run-llmz-tests.yml index d60cc62d26d..75b1622bf19 100644 --- a/.github/workflows/run-llmz-tests.yml +++ b/.github/workflows/run-llmz-tests.yml @@ -31,16 +31,19 @@ jobs: 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 "::set-output name=bot_id::$bot_id" + echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT" export CLOUD_API_ENDPOINT='https://api.botpress.dev' - export CLOUD_BOT_ID=$bot_id - export CLOUD_PAT=${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} + 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 ${{ steps.run-tests.outputs.bot_id }} + pnpm bp bots rm "$BOT_ID" diff --git a/.github/workflows/run-vai-tests.yml b/.github/workflows/run-vai-tests.yml index 737c0514bb2..a6de9203e4c 100644 --- a/.github/workflows/run-vai-tests.yml +++ b/.github/workflows/run-vai-tests.yml @@ -31,16 +31,19 @@ jobs: 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 "::set-output name=bot_id::$bot_id" + echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT" export CLOUD_API_ENDPOINT='https://api.botpress.dev' - export CLOUD_BOT_ID=$bot_id - export CLOUD_PAT=${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} + 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 ${{ steps.run-tests.outputs.bot_id }} + pnpm bp bots rm "$BOT_ID" diff --git a/.github/workflows/run-zai-tests.yml b/.github/workflows/run-zai-tests.yml index 781704c0705..e6d42429501 100644 --- a/.github/workflows/run-zai-tests.yml +++ b/.github/workflows/run-zai-tests.yml @@ -31,16 +31,19 @@ jobs: 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 "::set-output name=bot_id::$bot_id" + echo "bot_id=$bot_id" >> "$GITHUB_OUTPUT" export CLOUD_API_ENDPOINT='https://api.botpress.dev' - export CLOUD_BOT_ID=$bot_id - export CLOUD_PAT=${{ secrets.STAGING_TOKEN_CLOUD_OPS_ACCOUNT }} + 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 ${{ steps.run-tests.outputs.bot_id }} + pnpm bp bots rm "$BOT_ID" From 9ea119641bee451e827f6fd2232e2af7fff5e1d4 Mon Sep 17 00:00:00 2001 From: Chris Grass Date: Mon, 6 Apr 2026 19:19:39 -0400 Subject: [PATCH 3/3] fix(ci): Fix deploy integrations action (#15095) --- .github/actions/deploy-integrations/action.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/actions/deploy-integrations/action.yml b/.github/actions/deploy-integrations/action.yml index 1f1f34048e6..5a12d0f2d37 100644 --- a/.github/actions/deploy-integrations/action.yml +++ b/.github/actions/deploy-integrations/action.yml @@ -1,7 +1,7 @@ name: Deploy Integrations description: Deploys integrations -input: +inputs: environment: type: choice description: 'Environment to deploy to' @@ -49,7 +49,9 @@ runs: shell: bash env: SENTRY_FILTER: ${{ steps.list_sentry_integrations.outputs.filter }} - run: pnpm -r --stream "$SENTRY_FILTER" exec sentry-cli sourcemaps inject .botpress/dist + run: | + # shellcheck disable=SC2086 # SENTRY_FILTER contains multiple space-separated -F flags that must be split into individual arguments + pnpm -r --stream $SENTRY_FILTER exec sentry-cli sourcemaps inject .botpress/dist - name: Upload SourceMaps shell: bash env: @@ -58,7 +60,9 @@ runs: SENTRY_RELEASE: ${{ github.sha }} SENTRY_FILTER: ${{ steps.list_sentry_integrations.outputs.filter }} GITHUB_SHA: ${{ github.sha }} - run: pnpm -r --stream "$SENTRY_FILTER" exec sentry-cli sourcemaps upload --release="$GITHUB_SHA" --url-prefix '~' .botpress/dist + run: | + # shellcheck disable=SC2086 # SENTRY_FILTER contains multiple space-separated -F flags that must be split into individual arguments + pnpm -r --stream $SENTRY_FILTER exec sentry-cli sourcemaps upload --release="$GITHUB_SHA" --url-prefix '~' .botpress/dist - name: Deploys Integrations shell: bash env: