Skip to content

Rebuild aimlapi v0.0.9 with the required manifest fields #2

Rebuild aimlapi v0.0.9 with the required manifest fields

Rebuild aimlapi v0.0.9 with the required manifest fields #2

name: Pre Check Plugin
on:
pull_request:
types: [opened, synchronize, ready_for_review]
branches:
- main
- dev
paths-ignore:
- ".github/**"
- ".gitignore"
- "**/.gitignore"
- "unpacked_plugin/**"
- "**/*.md"
- "LICENSE"
concurrency:
group: pre-check-plugin-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
REPO_NAME: langgenius/dify-plugins
MARKETPLACE_BASE_URL: https://marketplace.dify.ai
MARKETPLACE_TOKEN: placeholder
GH_TOKEN: ${{ github.token }}
jobs:
pre-check-plugin:
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 2
- name: Clone Marketplace Toolkit
run: |
gh repo clone langgenius/dify-marketplace-toolkit -- .scripts/
- name: Download Plugin Daemon
run: |
gh release download -R langgenius/dify-plugin-daemon --pattern "dify-plugin-linux-amd64" --dir .scripts
chmod +x .scripts/dify-plugin-linux-amd64
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12.7
- name: Install Dependencies
run: |
echo "Installing Python dependencies..."
pip install requests
# Remaining packages are only needed by "Check Plugin Deps";
# install in the background (the rest is preinstalled on the image).
echo "Installing system dependencies in the background..."
sudo rm -f /var/lib/man-db/auto-update # skip slow man-db trigger
sudo bash -c '
set -e
export DEBIAN_FRONTEND=noninteractive
# default EC2 apt mirror stalls; use the main archive
if [ -f /etc/apt/apt-mirrors.txt ]; then
echo "http://archive.ubuntu.com/ubuntu/" > /etc/apt/apt-mirrors.txt
fi
APT_OPTS="-o Acquire::Retries=3 -o Acquire::http::Timeout=15 -o Acquire::https::Timeout=15"
apt-get update -q $APT_OPTS
apt-get install -y -q --no-install-recommends $APT_OPTS \
ffmpeg \
libcairo2-dev libjpeg-dev libgif-dev
touch /tmp/apt-deps-ok
' </dev/null >/tmp/apt-deps.log 2>&1 &
echo "APT_DEPS_PID=$!" >> "$GITHUB_ENV"
- name: Verify Preinstalled Tools
run: |
jq --version
yq --version
- name: Get PR Path
run: |
echo "Retrieving PR files information..."
if ! PR_FILES=$(gh pr view -R ${{ env.REPO_NAME }} ${{ github.event.pull_request.number }} --json files --jq .files); then
echo "Failed to retrieve PR files. Make sure PR number and repository are correct."
exit 1
fi
gh pr view -R ${{ env.REPO_NAME }} ${{ github.event.pull_request.number }} --json body --jq .body > /tmp/pr_body.md
export PR_FILES
echo "Checking for plugin package file changes..."
if PLUGIN_PATH=$(python3 .scripts/validator/check-pkg-paths.py); then
echo "Found plugin path: $PLUGIN_PATH"
echo "PLUGIN_PATH=$PLUGIN_PATH" >> $GITHUB_ENV
echo "SUBMITTED_PLUGIN_PATH=$PLUGIN_PATH" >> $GITHUB_ENV
else
echo "ERROR: Only one .difypkg file change is allowed in a single PR."
exit 1
fi
- name: Unpack File
run: |
# Store the plugin path in a variable
PLUGIN_PATH_VALUE="${PLUGIN_PATH}"
echo "Moving plugin file to add .zip extension"
mv "$PLUGIN_PATH_VALUE" "$PLUGIN_PATH_VALUE.zip"
echo "Creating unpacked_plugin directory"
mkdir -p unpacked_plugin
echo "Unzipping plugin file to unpacked_plugin directory"
unzip "$PLUGIN_PATH_VALUE.zip" -d unpacked_plugin
# Update the PLUGIN_PATH for future steps
echo "PLUGIN_PATH=unpacked_plugin" >> $GITHUB_ENV
- name: Check Package Contents
continue-on-error: true
run: |
python3 .scripts/validator/check-package-contents.py \
-d "$PLUGIN_PATH" \
--package-file "$SUBMITTED_PLUGIN_PATH.zip" \
--error-file /tmp/package_contents_errors.txt \
--warning-file /tmp/package_contents_warnings.txt
- name: Check Package Secrets
continue-on-error: true
run: |
python3 .scripts/validator/check-package-secrets.py \
-d "$PLUGIN_PATH" \
--error-file /tmp/package_secrets_errors.txt \
--warning-file /tmp/package_secrets_warnings.txt
- name: Check Package Binaries
continue-on-error: true
run: |
python3 .scripts/validator/check-package-binaries.py \
-d "$PLUGIN_PATH" \
--error-file /tmp/package_binaries_errors.txt \
--warning-file /tmp/package_binaries_warnings.txt
- name: Check Plugin Manifest
continue-on-error: true
run: |
python3 .scripts/validator/check-manifest-metadata.py \
-d "$PLUGIN_PATH" \
--error-file /tmp/manifest_errors.txt \
--warning-file /tmp/manifest_warnings.txt
- name: Check README Metadata
continue-on-error: true
run: |
python3 .scripts/validator/check-readme-metadata.py \
-d "$PLUGIN_PATH" \
--error-file /tmp/readme_errors.txt \
--warning-file /tmp/readme_warnings.txt
- name: Check PR Body
continue-on-error: true
run: |
python3 .scripts/validator/check-pr-body.py \
--pr-body-file /tmp/pr_body.md \
--error-file /tmp/pr_body_errors.txt
- name: Check PR Review Notes
continue-on-error: true
run: |
python3 .scripts/validator/check-pr-review-notes.py \
--pr-body-file /tmp/pr_body.md \
--warning-file /tmp/pr_review_notes_warnings.txt
- name: Check Version Update
continue-on-error: true
run: |
python3 .scripts/validator/check-version-update.py \
-d "$PLUGIN_PATH" \
--package-path "$SUBMITTED_PLUGIN_PATH.zip" \
--pr-body-file /tmp/pr_body.md \
--error-file /tmp/version_update_errors.txt \
--warning-file /tmp/version_update_warnings.txt
- name: Check Package Dependencies
continue-on-error: true
run: |
python3 .scripts/validator/check-package-dependencies.py \
-d "$PLUGIN_PATH" \
--error-file /tmp/package_dependencies_errors.txt \
--warning-file /tmp/package_dependencies_warnings.txt
- name: Check Sensitive Capability Disclosure
continue-on-error: true
run: |
python3 .scripts/validator/check-sensitive-capabilities.py \
-d "$PLUGIN_PATH" \
--pr-body-file /tmp/pr_body.md \
--error-file /tmp/sensitive_capabilities_errors.txt \
--warning-file /tmp/sensitive_capabilities_warnings.txt
- name: Check Python Safety Warnings
continue-on-error: true
run: |
python3 .scripts/validator/check-python-safety-warnings.py \
-d "$PLUGIN_PATH" \
--warning-file /tmp/python_safety_warnings.txt
- name: Check Prohibited Financial Activity
continue-on-error: true
run: |
python3 .scripts/validator/check-prohibited-financial-activity.py \
-d "$PLUGIN_PATH" \
--warning-file /tmp/prohibited_financial_activity_warnings.txt
- name: Check Plugin Icon
continue-on-error: true
run: |
# Create error tracking file
ERROR_FILE="/tmp/icon_errors.txt"
touch $ERROR_FILE
# Get icon filename from manifest.yaml
PLUGIN_ICON_FILENAME=$(yq '.icon' "$PLUGIN_PATH/manifest.yaml")
echo "PLUGIN_ICON_FILENAME=$PLUGIN_ICON_FILENAME" >> $GITHUB_ENV
# Check if icon file exists
if [ ! -f "$PLUGIN_PATH/_assets/$PLUGIN_ICON_FILENAME" ]; then
ERROR_MSG="!!! Plugin icon file not found: _assets/$PLUGIN_ICON_FILENAME"
echo "$ERROR_MSG"
echo "$ERROR_MSG" >> $ERROR_FILE
exit 1
fi
# Check if icon contains template placeholder text
if grep -q "DIFY_MARKETPLACE_TEMPLATE_ICON_DO_NOT_USE" "$PLUGIN_PATH/_assets/$PLUGIN_ICON_FILENAME"; then
ERROR_MSG="!!! Plugin icon contains template placeholder text 'DIFY_MARKETPLACE_TEMPLATE_ICON_DO_NOT_USE', change default icon before submitting to marketplace."
echo "$ERROR_MSG"
echo "$ERROR_MSG" >> $ERROR_FILE
exit 1
fi
# Define default icon content
DEFAULT_ICON='<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M20 20 V80 M20 20 H60 Q80 20 80 40 T60 60 H20"
fill="none"
stroke="black"
stroke-width="5"/>
</svg>'
# Check if icon content matches default icon (normalize whitespace)
ICON_CONTENT=$(cat "$PLUGIN_PATH/_assets/$PLUGIN_ICON_FILENAME" | tr -d '\n\r\t ' | tr -s ' ')
DEFAULT_ICON_NORMALIZED=$(echo "$DEFAULT_ICON" | tr -d '\n\r\t ' | tr -s ' ')
if [ "$ICON_CONTENT" = "$DEFAULT_ICON_NORMALIZED" ]; then
ERROR_MSG="!!! Plugin icon is using the default template icon and must be customized"
echo "$ERROR_MSG"
echo "$ERROR_MSG" >> $ERROR_FILE
exit 1
fi
- name: Check If Version Exists
continue-on-error: true
run: |
# Create error tracking file
ERROR_FILE="/tmp/version_errors.txt"
touch $ERROR_FILE
# Extract plugin metadata
VERSION=$(yq '.version' "$PLUGIN_PATH/manifest.yaml")
AUTHOR=$(yq '.author' "$PLUGIN_PATH/manifest.yaml")
NAME=$(yq '.name' "$PLUGIN_PATH/manifest.yaml")
echo "Plugin information:"
echo "- Name: $NAME"
echo "- Author: $AUTHOR"
echo "- Version: $VERSION"
# Check if the version already exists in marketplace
echo "Checking if plugin version already exists in marketplace..."
API_URL="${MARKETPLACE_BASE_URL}/api/v1/plugins/${AUTHOR}/${NAME}/${VERSION}"
echo "API URL: $API_URL"
# Add a timeout to curl to prevent hanging
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL" --connect-timeout 10 --max-time 30)
echo "API Response Code: $RESPONSE_CODE"
if [ "$RESPONSE_CODE" = "200" ]; then
RESPONSE=$(curl -s "$API_URL" --connect-timeout 10 --max-time 30)
if [ "$(echo "$RESPONSE" | jq -r '.code')" = "0" ]; then
ERROR_MSG="!!! Plugin version $VERSION by $AUTHOR already exists in the marketplace. Please update the version number in manifest.yaml before submitting."
echo "$ERROR_MSG"
echo "$ERROR_MSG" >> $ERROR_FILE
exit 1
fi
else
echo "Version check passed: $VERSION is available for use."
fi
- name: Wait for System Dependencies
timeout-minutes: 10
run: |
echo "Waiting for background apt install (pid ${APT_DEPS_PID:-unknown})..."
if [ -n "${APT_DEPS_PID:-}" ]; then
tail --pid="$APT_DEPS_PID" -f /dev/null || true
fi
if [ ! -f /tmp/apt-deps-ok ]; then
echo "System dependency installation failed:"
cat /tmp/apt-deps.log
exit 1
fi
echo "System dependencies ready."
- name: Check Plugin Deps
continue-on-error: true
run: |
ERROR_FILE="/tmp/install_errors.txt"
touch $ERROR_FILE
if [ -f "$PLUGIN_PATH/requirements.txt" ]; then
echo "Trying to install plugin dependencies..."
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r "$PLUGIN_PATH/requirements.txt" || {
echo "Failed to install plugin dependencies" >> $ERROR_FILE
echo "Failed to install plugin dependencies"
exit 1
}
deactivate
else
echo "No requirements.txt found, skipping dependency installation"
fi
- name: Check Plugin Install
continue-on-error: true
run: |
# Create error tracking file
ERROR_FILE="/tmp/install_errors.txt"
touch $ERROR_FILE
if [ -f "$PLUGIN_PATH/requirements.txt" ]; then
source .venv/bin/activate || {
echo "Failed to activate virtual environment" >> $ERROR_FILE
echo "Failed to activate virtual environment"
exit 1
}
# Install packaging for version comparison
echo "Installing packaging module..."
pip install packaging || {
echo "Failed to install packaging module" >> $ERROR_FILE
echo "Failed to install packaging module"
exit 1
}
# Determine installation method based on dify_plugin version
echo "Detecting dify_plugin version..."
dify_version=$(pip list | grep -oE 'dify[-_]plugin[[:space:]]+[0-9][0-9.a-zA-Z]*' | awk '{print $2}')
if [ -z "$dify_version" ]; then
dify_version="not_found"
fi
if [ "$dify_version" = "not_found" ]; then
echo "dify_plugin not found in installed packages, using default configuration"
export INSTALL_METHOD=aws_lambda
export AWS_LAMBDA_PORT=8080
export AWS_LAMBDA_HOST=0.0.0.0
else
target_version="0.0.1b64"
echo "Found dify_plugin version: $dify_version"
echo "Comparing with target version: $target_version"
# Set environment variables based on version comparison
if python -c "from packaging.version import Version; exit(0 if Version('$dify_version') > Version('$target_version') else 1)"; then
echo "Using serverless installation method"
export INSTALL_METHOD=serverless
export SERVERLESS_PORT=8080
export SERVERLESS_HOST=0.0.0.0
else
echo "Using aws_lambda installation method"
export INSTALL_METHOD=aws_lambda
export AWS_LAMBDA_PORT=8080
export AWS_LAMBDA_HOST=0.0.0.0
fi
fi
# Run the plugin installation test with timeout
echo "Running plugin installation test..."
timeout 300 python3 .scripts/validator/test-plugin-install.py -d "$PLUGIN_PATH" || {
echo "Plugin installation test failed or timed out" >> $ERROR_FILE
echo "Plugin installation test failed or timed out"
exit 1
}
echo "Plugin installation test completed successfully"
else
echo "No requirements.txt found, skipping installation test"
fi
- name: Check Packaging
continue-on-error: true
run: |
# Create error tracking file
ERROR_FILE="/tmp/packaging_errors.txt"
touch $ERROR_FILE
echo "Running packaging check..."
# Check if plugin daemon exists (executable bit set at download time)
if [ ! -x ".scripts/dify-plugin-linux-amd64" ]; then
ERROR_MSG="Plugin daemon file not found or not executable"
echo "$ERROR_MSG" >> $ERROR_FILE
echo "$ERROR_MSG"
exit 1
fi
# Run the packaging check with a timeout
timeout 300 python3 .scripts/uploader -d "$PLUGIN_PATH" -t "$MARKETPLACE_TOKEN" --plugin-daemon-path .scripts/dify-plugin-linux-amd64 -u "$MARKETPLACE_BASE_URL" -f --test || {
ERROR_MSG="Packaging check failed or timed out"
echo "$ERROR_MSG" >> $ERROR_FILE
echo "$ERROR_MSG"
exit 1
}
echo "Packaging check completed successfully"
- name: Output Detailed Report (Step Summary)
if: always()
run: |
SUMMARY_FILE="${GITHUB_STEP_SUMMARY:-/tmp/github_step_summary.md}"
JOB_STATUS="${{ job.status }}"
echo "# Plugin Pre-Check Report" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "## Plugin Information" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
if [ -n "${PLUGIN_PATH:-}" ] && [ -f "$PLUGIN_PATH/manifest.yaml" ]; then
PLUGIN_NAME=$(yq '.name // "Unknown"' "$PLUGIN_PATH/manifest.yaml" 2>/dev/null || echo "Unknown")
PLUGIN_VERSION=$(yq '.version // "Unknown"' "$PLUGIN_PATH/manifest.yaml" 2>/dev/null || echo "Unknown")
PLUGIN_AUTHOR=$(yq '.author // "Unknown"' "$PLUGIN_PATH/manifest.yaml" 2>/dev/null || echo "Unknown")
PLUGIN_DESCRIPTION=$(yq '.description // "No description provided"' "$PLUGIN_PATH/manifest.yaml" 2>/dev/null || echo "No description provided")
echo "- **Name:** $PLUGIN_NAME" >> "$SUMMARY_FILE"
echo "- **Version:** $PLUGIN_VERSION" >> "$SUMMARY_FILE"
echo "- **Author:** $PLUGIN_AUTHOR" >> "$SUMMARY_FILE"
echo "- **Description:** $PLUGIN_DESCRIPTION" >> "$SUMMARY_FILE"
else
if [ -z "${PLUGIN_PATH:-}" ]; then
echo "- ⚠️ \`PLUGIN_PATH\` is not set (plugin package may not have been detected/unpacked)." >> "$SUMMARY_FILE"
else
echo "- ⚠️ \`manifest.yaml\` not found under \`$PLUGIN_PATH\`." >> "$SUMMARY_FILE"
fi
fi
echo "" >> "$SUMMARY_FILE"
echo "## CI Steps Status" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "| Check | Status |" >> "$SUMMARY_FILE"
echo "| ----- | ------ |" >> "$SUMMARY_FILE"
case "$JOB_STATUS" in
success) echo "| **Overall Status** | ✅ **Passed** |" >> "$SUMMARY_FILE" ;;
cancelled) echo "| **Overall Status** | ⚠️ **Cancelled** |" >> "$SUMMARY_FILE" ;;
*) echo "| **Overall Status** | ❌ **Failed** |" >> "$SUMMARY_FILE" ;;
esac
if [ -f "/tmp/manifest_errors.txt" ] && [ -s "/tmp/manifest_errors.txt" ]; then
echo "| **Manifest Validation** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/manifest_warnings.txt" ] && [ -s "/tmp/manifest_warnings.txt" ]; then
echo "| **Manifest Validation** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Manifest Validation** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/readme_errors.txt" ] && [ -s "/tmp/readme_errors.txt" ]; then
echo "| **README Metadata** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/readme_warnings.txt" ] && [ -s "/tmp/readme_warnings.txt" ]; then
echo "| **README Metadata** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **README Metadata** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/pr_body_errors.txt" ] && [ -s "/tmp/pr_body_errors.txt" ]; then
echo "| **PR Body** | ❌ Failed |" >> "$SUMMARY_FILE"
else
echo "| **PR Body** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/pr_review_notes_warnings.txt" ] && [ -s "/tmp/pr_review_notes_warnings.txt" ]; then
echo "| **PR Review Notes** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **PR Review Notes** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/icon_errors.txt" ] && [ -s "/tmp/icon_errors.txt" ]; then
echo "| **Icon Validation** | ❌ Failed |" >> "$SUMMARY_FILE"
else
echo "| **Icon Validation** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/version_errors.txt" ] && [ -s "/tmp/version_errors.txt" ]; then
echo "| **Version Check** | ❌ Failed |" >> "$SUMMARY_FILE"
else
echo "| **Version Check** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/version_update_errors.txt" ] && [ -s "/tmp/version_update_errors.txt" ]; then
echo "| **Version Update Increment** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/version_update_warnings.txt" ] && [ -s "/tmp/version_update_warnings.txt" ]; then
echo "| **Version Update Increment** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Version Update Increment** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/package_contents_errors.txt" ] && [ -s "/tmp/package_contents_errors.txt" ]; then
echo "| **Package Contents** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/package_contents_warnings.txt" ] && [ -s "/tmp/package_contents_warnings.txt" ]; then
echo "| **Package Contents** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Package Contents** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/package_secrets_errors.txt" ] && [ -s "/tmp/package_secrets_errors.txt" ]; then
echo "| **Package Secrets** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/package_secrets_warnings.txt" ] && [ -s "/tmp/package_secrets_warnings.txt" ]; then
echo "| **Package Secrets** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Package Secrets** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/package_binaries_errors.txt" ] && [ -s "/tmp/package_binaries_errors.txt" ]; then
echo "| **Package Binaries** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/package_binaries_warnings.txt" ] && [ -s "/tmp/package_binaries_warnings.txt" ]; then
echo "| **Package Binaries** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Package Binaries** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/package_dependencies_errors.txt" ] && [ -s "/tmp/package_dependencies_errors.txt" ]; then
echo "| **Package Dependencies** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/package_dependencies_warnings.txt" ] && [ -s "/tmp/package_dependencies_warnings.txt" ]; then
echo "| **Package Dependencies** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Package Dependencies** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/sensitive_capabilities_errors.txt" ] && [ -s "/tmp/sensitive_capabilities_errors.txt" ]; then
echo "| **Sensitive Capability Disclosure** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -f "/tmp/sensitive_capabilities_warnings.txt" ] && [ -s "/tmp/sensitive_capabilities_warnings.txt" ]; then
echo "| **Sensitive Capability Disclosure** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Sensitive Capability Disclosure** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/python_safety_warnings.txt" ] && [ -s "/tmp/python_safety_warnings.txt" ]; then
echo "| **Python Safety Warnings** | ⚠️ Review required |" >> "$SUMMARY_FILE"
else
echo "| **Python Safety Warnings** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/prohibited_financial_activity_warnings.txt" ] && [ -s "/tmp/prohibited_financial_activity_warnings.txt" ]; then
echo "| **Prohibited Financial Activity** | ⚠️ Strong manual review required |" >> "$SUMMARY_FILE"
else
echo "| **Prohibited Financial Activity** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/install_errors.txt" ] && [ -s "/tmp/install_errors.txt" ]; then
echo "| **Installation** | ❌ Failed |" >> "$SUMMARY_FILE"
elif [ -n "${PLUGIN_PATH:-}" ] && [ -f "$PLUGIN_PATH/requirements.txt" ]; then
echo "| **Installation** | ✅ Passed |" >> "$SUMMARY_FILE"
else
echo "| **Installation** | ⚠️ Skipped |" >> "$SUMMARY_FILE"
fi
if [ -f "/tmp/packaging_errors.txt" ] && [ -s "/tmp/packaging_errors.txt" ]; then
echo "| **Packaging** | ❌ Failed |" >> "$SUMMARY_FILE"
else
echo "| **Packaging** | ✅ Passed |" >> "$SUMMARY_FILE"
fi
escape_html() {
sed -e 's/&/&amp;/g' -e 's/</&lt;/g' -e 's/>/&gt;/g'
}
append_error_details() {
local title="$1"
local file="$2"
if [ -f "$file" ] && [ -s "$file" ]; then
echo "" >> "$SUMMARY_FILE"
echo "<details>" >> "$SUMMARY_FILE"
echo "<summary>${title} (details)</summary>" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "<pre><code class=\"language-text\">" >> "$SUMMARY_FILE"
escape_html < "$file" >> "$SUMMARY_FILE"
echo "</code></pre>" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "</details>" >> "$SUMMARY_FILE"
fi
}
append_grouped_report() {
local title="$1"
shift
echo "" >> "$SUMMARY_FILE"
echo "## ${title}" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
local found=0
for file in "$@"; do
if [ -f "$file" ] && [ -s "$file" ]; then
found=1
echo "- \`$file\`" >> "$SUMMARY_FILE"
fi
done
if [ "$found" = "0" ]; then
echo "_None._" >> "$SUMMARY_FILE"
fi
}
append_grouped_report "Blocking Errors" \
"/tmp/manifest_errors.txt" \
"/tmp/readme_errors.txt" \
"/tmp/pr_body_errors.txt" \
"/tmp/icon_errors.txt" \
"/tmp/version_errors.txt" \
"/tmp/version_update_errors.txt" \
"/tmp/package_contents_errors.txt" \
"/tmp/package_secrets_errors.txt" \
"/tmp/package_binaries_errors.txt" \
"/tmp/package_dependencies_errors.txt" \
"/tmp/sensitive_capabilities_errors.txt" \
"/tmp/install_errors.txt" \
"/tmp/packaging_errors.txt"
append_grouped_report "Warnings" \
"/tmp/manifest_warnings.txt" \
"/tmp/readme_warnings.txt" \
"/tmp/pr_review_notes_warnings.txt" \
"/tmp/version_update_warnings.txt" \
"/tmp/package_contents_warnings.txt" \
"/tmp/package_secrets_warnings.txt" \
"/tmp/package_binaries_warnings.txt" \
"/tmp/package_dependencies_warnings.txt" \
"/tmp/sensitive_capabilities_warnings.txt" \
"/tmp/python_safety_warnings.txt" \
"/tmp/prohibited_financial_activity_warnings.txt"
append_error_details "Manifest Validation" "/tmp/manifest_errors.txt"
append_error_details "Manifest Warnings" "/tmp/manifest_warnings.txt"
append_error_details "README Metadata" "/tmp/readme_errors.txt"
append_error_details "README Warnings" "/tmp/readme_warnings.txt"
append_error_details "PR Body" "/tmp/pr_body_errors.txt"
append_error_details "PR Review Notes Warnings" "/tmp/pr_review_notes_warnings.txt"
append_error_details "Icon Validation" "/tmp/icon_errors.txt"
append_error_details "Version Check" "/tmp/version_errors.txt"
append_error_details "Version Update Errors" "/tmp/version_update_errors.txt"
append_error_details "Version Update Warnings" "/tmp/version_update_warnings.txt"
append_error_details "Package Contents Errors" "/tmp/package_contents_errors.txt"
append_error_details "Package Contents Warnings" "/tmp/package_contents_warnings.txt"
append_error_details "Package Secrets Errors" "/tmp/package_secrets_errors.txt"
append_error_details "Package Secrets Warnings" "/tmp/package_secrets_warnings.txt"
append_error_details "Package Binaries Errors" "/tmp/package_binaries_errors.txt"
append_error_details "Package Binaries Warnings" "/tmp/package_binaries_warnings.txt"
append_error_details "Package Dependencies Errors" "/tmp/package_dependencies_errors.txt"
append_error_details "Package Dependencies Warnings" "/tmp/package_dependencies_warnings.txt"
append_error_details "Sensitive Capability Disclosure Errors" "/tmp/sensitive_capabilities_errors.txt"
append_error_details "Sensitive Capability Disclosure Warnings" "/tmp/sensitive_capabilities_warnings.txt"
append_error_details "Python Safety Warnings" "/tmp/python_safety_warnings.txt"
append_error_details "Prohibited Financial Activity Warnings" "/tmp/prohibited_financial_activity_warnings.txt"
append_error_details "Installation" "/tmp/install_errors.txt"
append_error_details "Packaging" "/tmp/packaging_errors.txt"
echo "" >> "$SUMMARY_FILE"
echo "## Plugin Files" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
append_file_content() {
local title="$1"
local file="$2"
local language="${3:-text}"
echo "<details>" >> "$SUMMARY_FILE"
echo "<summary>${title}</summary>" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
if [ -n "$file" ] && [ -f "$file" ]; then
echo "<pre><code class=\"language-${language}\">" >> "$SUMMARY_FILE"
escape_html < "$file" >> "$SUMMARY_FILE"
echo "</code></pre>" >> "$SUMMARY_FILE"
else
echo "_Not found: \`$file\`_" >> "$SUMMARY_FILE"
fi
echo "" >> "$SUMMARY_FILE"
echo "</details>" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
}
if [ -n "${PLUGIN_PATH:-}" ]; then
append_file_content "manifest.yaml" "$PLUGIN_PATH/manifest.yaml" "yaml"
append_file_content "README.md" "$PLUGIN_PATH/README.md" "markdown"
append_file_content "PRIVACY.md" "$PLUGIN_PATH/PRIVACY.md" "markdown"
append_file_content "requirements.txt" "$PLUGIN_PATH/requirements.txt" "text"
append_file_content "pyproject.toml" "$PLUGIN_PATH/pyproject.toml" "toml"
else
echo "_Plugin directory is unavailable (missing \`PLUGIN_PATH\`)._" >> "$SUMMARY_FILE"
fi
echo "" >> "$SUMMARY_FILE"
echo "## Workflow Details" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "- **Run ID:** ${{ github.run_id }}" >> "$SUMMARY_FILE"
echo "- **Repository:** ${{ github.repository }}" >> "$SUMMARY_FILE"
echo "- **Ref:** ${{ github.ref }}" >> "$SUMMARY_FILE"
echo "" >> "$SUMMARY_FILE"
echo "[View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> "$SUMMARY_FILE"
- name: Fail on Blocking Errors
if: always()
run: |
BLOCKING_ERROR_FILES=(
/tmp/manifest_errors.txt
/tmp/readme_errors.txt
/tmp/pr_body_errors.txt
/tmp/icon_errors.txt
/tmp/version_errors.txt
/tmp/version_update_errors.txt
/tmp/package_contents_errors.txt
/tmp/package_secrets_errors.txt
/tmp/package_binaries_errors.txt
/tmp/package_dependencies_errors.txt
/tmp/sensitive_capabilities_errors.txt
/tmp/install_errors.txt
/tmp/packaging_errors.txt
)
HAS_ERRORS=0
for file in "${BLOCKING_ERROR_FILES[@]}"; do
if [ -f "$file" ] && [ -s "$file" ]; then
echo "Blocking errors found in $file"
HAS_ERRORS=1
fi
done
if [ "$HAS_ERRORS" = "1" ]; then
echo "One or more blocking plugin checks failed. See the job summary for details."
exit 1
fi
echo "No blocking plugin check errors found."