mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-07 08:04:28 +08:00
190 lines
6.7 KiB
Bash
190 lines
6.7 KiB
Bash
#!/bin/bash
|
|
# Shared library for Sales Agent authoring bundle publish and activation
|
|
#
|
|
# Functions:
|
|
# publish_and_activate_agent <org-alias> <on-error-behavior> [output-style]
|
|
#
|
|
# Parameters:
|
|
# org-alias: Salesforce org alias
|
|
# on-error-behavior: "exit" (hard fail on error) or "return" (return non-zero)
|
|
# output-style: "plain" (default, plain echo) or "structured" (log_pass/log_info style)
|
|
#
|
|
# Returns:
|
|
# 0 on success
|
|
# 1 on failure
|
|
#
|
|
# Environment:
|
|
# SCRIPT_DIR must be set (parent script's directory)
|
|
|
|
# Source agent-detection helpers (pm_bot_latest_version, etc.)
|
|
# Use a local resolution that doesn't depend on the caller's SCRIPT_DIR.
|
|
# shellcheck source=./agent-detection.sh
|
|
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/agent-detection.sh"
|
|
|
|
publish_and_activate_agent() {
|
|
local ORG_ALIAS="$1"
|
|
local ON_ERROR="${2:-exit}"
|
|
local OUTPUT_STYLE="${3:-plain}"
|
|
|
|
# Clear exported state from any prior call to prevent stale values on failure
|
|
unset AGENT_VERSION
|
|
unset AGENT_API_NAME
|
|
|
|
local AGENT_BUNDLE="$SCRIPT_DIR/../assets/sales_management_agent.agent"
|
|
local BUNDLE_META="$SCRIPT_DIR/../assets/sales_management_agent.bundle-meta.xml"
|
|
|
|
# Output helper functions based on style
|
|
local msg_header msg_pass msg_error msg_info
|
|
if [[ "$OUTPUT_STYLE" == "structured" ]]; then
|
|
msg_header() { log_info "$1"; }
|
|
msg_pass() { log_pass "$1"; }
|
|
msg_error() { echo " ERROR: $1"; }
|
|
msg_info() { echo " $1"; }
|
|
else
|
|
msg_header() { echo "=== $1 ==="; }
|
|
msg_pass() { echo " ✓ $1"; }
|
|
msg_error() { echo " ERROR: $1"; }
|
|
msg_info() { echo " $1"; }
|
|
fi
|
|
|
|
# Check for bundle assets
|
|
if [[ ! -f "$AGENT_BUNDLE" || ! -f "$BUNDLE_META" ]]; then
|
|
msg_error "Agent bundle assets not found at: $AGENT_BUNDLE"
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
msg_header "Creating Sales Agent via authoring bundle"
|
|
|
|
# Create temp directory for bundle deployment
|
|
local TEMP_DIR
|
|
TEMP_DIR=$(mktemp -d -t sales-agent-bundle.XXXXXX)
|
|
# Use EXIT trap so it fires even on explicit exit calls
|
|
trap 'rm -rf "$TEMP_DIR"' EXIT
|
|
|
|
# Create sfdx-project.json in temp dir
|
|
cat > "$TEMP_DIR/sfdx-project.json" << 'SFDX'
|
|
{"packageDirectories": [{"path": "force-app", "default": true}], "sourceApiVersion": "67.0"}
|
|
SFDX
|
|
|
|
# Copy authoring bundle to temp deployment directory
|
|
mkdir -p "$TEMP_DIR/force-app/main/default/aiAuthoringBundles/SalesAgent"
|
|
if ! cp "$AGENT_BUNDLE" "$TEMP_DIR/force-app/main/default/aiAuthoringBundles/SalesAgent/SalesAgent.agent"; then
|
|
msg_error "Failed to stage bundle agent file"
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
if ! cp "$BUNDLE_META" "$TEMP_DIR/force-app/main/default/aiAuthoringBundles/SalesAgent/SalesAgent.bundle-meta.xml"; then
|
|
msg_error "Failed to stage bundle metadata file"
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
# Publish authoring bundle from temp directory
|
|
msg_info "Publishing Sales Agent authoring bundle..."
|
|
local PUBLISH_RESULT
|
|
PUBLISH_RESULT=$(cd "$TEMP_DIR" && sf agent publish authoring-bundle --json --api-name SalesAgent --target-org "$ORG_ALIAS" 2>/dev/null || echo '{"status":1}')
|
|
|
|
if ! echo "$PUBLISH_RESULT" | jq -e '.status == 0' >/dev/null 2>&1; then
|
|
local PUBLISH_ERR
|
|
PUBLISH_ERR=$(echo "$PUBLISH_RESULT" | jq -r '.message // .result.message // .result.errors[0].message // "unknown"' 2>/dev/null || echo "unknown")
|
|
msg_error "Authoring bundle publish failed: $PUBLISH_ERR"
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
msg_pass "Sales Agent published successfully"
|
|
|
|
# Query for the latest BotVersion with retry (async provisioning).
|
|
# Match the bot by AgentTemplate (the same field the scheduled flow uses),
|
|
# not by hardcoded DeveloperName — the bundle may publish under a different
|
|
# local name in some orgs.
|
|
msg_info "Querying for latest version..."
|
|
local LATEST_VERSION=""
|
|
for attempt in {1..3}; do
|
|
LATEST_VERSION=$(pm_bot_latest_version "$ORG_ALIAS")
|
|
|
|
if [[ -n "$LATEST_VERSION" ]]; then
|
|
break
|
|
fi
|
|
|
|
if [[ $attempt -lt 3 ]]; then
|
|
echo " Version not yet available, retrying in 5s... (attempt $attempt/3)"
|
|
sleep 5
|
|
fi
|
|
done
|
|
|
|
if [[ -z "$LATEST_VERSION" ]]; then
|
|
msg_error "Could not query BotVersion after publish. BotDefinition may still be provisioning. Wait 30s and check Setup → Agents."
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
# Resolve the actual published DeveloperName from AgentTemplate so we
|
|
# activate whatever name the bundle landed under (defaults to "SalesAgent"
|
|
# but the org may already have an upgraded NGA bot with a different name).
|
|
AGENT_API_NAME=$(pm_bot_developer_name "$ORG_ALIAS")
|
|
if [[ -z "$AGENT_API_NAME" ]]; then
|
|
AGENT_API_NAME="SalesAgent"
|
|
fi
|
|
|
|
# Activate the agent with dynamic version
|
|
msg_info "Activating $AGENT_API_NAME version $LATEST_VERSION..."
|
|
local ACTIVATE_RESULT
|
|
ACTIVATE_RESULT=$(sf agent activate --api-name "$AGENT_API_NAME" --version "$LATEST_VERSION" --target-org "$ORG_ALIAS" --json 2>/dev/null || echo '{"status":1}')
|
|
|
|
if ! echo "$ACTIVATE_RESULT" | jq -e '.status == 0' >/dev/null 2>&1; then
|
|
local ACTIVATE_ERR
|
|
ACTIVATE_ERR=$(echo "$ACTIVATE_RESULT" | jq -r '.message // .result.message // .result.errors[0].message // "unknown"' 2>/dev/null || echo "unknown")
|
|
msg_error "Agent activation failed: $ACTIVATE_ERR. The agent was published but activation failed."
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
if [[ "$ON_ERROR" == "exit" ]]; then
|
|
echo ""
|
|
echo "SETUP FAILED: A Pipeline Management BotDefinition is REQUIRED for user interaction."
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
msg_pass "$AGENT_API_NAME activated successfully (version $LATEST_VERSION)"
|
|
|
|
# Export version and resolved api-name for caller to use
|
|
export AGENT_VERSION="$LATEST_VERSION"
|
|
export AGENT_API_NAME
|
|
|
|
# Clean up temp directory before returning (EXIT trap only fires on exit, not return)
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT # Remove the trap since we've already cleaned up
|
|
|
|
return 0
|
|
}
|