Skip to content

Merge pull request #1 from aimlapi/chore/aimlapi-v0.0.9 #2

Merge pull request #1 from aimlapi/chore/aimlapi-v0.0.9

Merge pull request #1 from aimlapi/chore/aimlapi-v0.0.9 #2

name: Upload Merged Plugin
on:
push:
branches:
- main
- dev
paths-ignore:
- ".github/**"
- ".gitignore"
- "unpacked_plugin/**"
- "README.md"
- "LICENSE"
env:
REPO_NAME: langgenius/dify-plugins
jobs:
upload-merged-plugin:
permissions:
# contents: write is only what lets the failure report post a commit
# comment. The toolkit and the CLI are cloned with
# ORG_SCOPE_GITHUB_TOKEN, not with this token.
contents: write
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
- name: Clone Marketplace Toolkit
env:
GH_TOKEN: ${{ secrets.ORG_SCOPE_GITHUB_TOKEN }}
run: |
gh repo clone langgenius/dify-marketplace-toolkit -- .scripts/
- name: Download Plugin Daemon
env:
GH_TOKEN: ${{ secrets.ORG_SCOPE_GITHUB_TOKEN }}
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 Python Dependencies
run: |
python -m pip install --upgrade pip
pip install requests jq
- name: Get Changed Files from Push
id: get_changed_files
run: |
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} | jq -R -s -c 'split("\n")[:-1] | map({path: .})')
echo "CHANGED_FILES=$CHANGED_FILES" >> $GITHUB_ENV
echo "CHANGED_FILES=$CHANGED_FILES"
- name: Validate Plugin Path
env:
PR_FILES: ${{ env.CHANGED_FILES }}
run: |
if PLUGIN_PATH=$(python3 .scripts/validator/check-pkg-paths.py); then
echo $PLUGIN_PATH
echo "PLUGIN_PATH=$PLUGIN_PATH" >> $GITHUB_ENV
else
echo "Only one .difypkg file change is allowed in a single push."
exit 1
fi
- name: yq - portable yaml processor
uses: mikefarah/yq@v4.44.5
with:
cmd: yq --version
- name: Unpack Plugin for Final Validation
run: |
mkdir -p unpacked_plugin
unzip "$PLUGIN_PATH" -d unpacked_plugin
- name: Final Package Validation
run: |
python3 .scripts/validator/check-package-contents.py \
-d unpacked_plugin \
--package-file "$PLUGIN_PATH" \
--error-file /tmp/package_contents_errors.txt \
--warning-file /tmp/package_contents_warnings.txt
python3 .scripts/validator/check-package-secrets.py \
-d unpacked_plugin \
--error-file /tmp/package_secrets_errors.txt \
--warning-file /tmp/package_secrets_warnings.txt
python3 .scripts/validator/check-package-binaries.py \
-d unpacked_plugin \
--error-file /tmp/package_binaries_errors.txt \
--warning-file /tmp/package_binaries_warnings.txt
python3 .scripts/validator/check-manifest-metadata.py \
-d unpacked_plugin \
--error-file /tmp/manifest_errors.txt \
--warning-file /tmp/manifest_warnings.txt
python3 .scripts/validator/check-readme-metadata.py \
-d unpacked_plugin \
--error-file /tmp/readme_errors.txt \
--warning-file /tmp/readme_warnings.txt
python3 .scripts/validator/check-package-dependencies.py \
-d unpacked_plugin \
--error-file /tmp/package_dependencies_errors.txt \
--warning-file /tmp/package_dependencies_warnings.txt
python3 .scripts/validator/check-prohibited-financial-activity.py \
-d unpacked_plugin \
--warning-file /tmp/prohibited_financial_activity_warnings.txt
- name: Extract Release Notes
env:
GH_TOKEN: ${{ github.token }}
run: |
LAST_SHA=$(git log -1 --format=%H -- "$PLUGIN_PATH")
PR_NUMBER=$(gh api "repos/${{ env.REPO_NAME }}/commits/$LAST_SHA/pulls" --jq '.[0].number // empty' || true)
if [ -n "$PR_NUMBER" ]; then
gh pr view "$PR_NUMBER" -R "${{ env.REPO_NAME }}" --json body --jq .body > /tmp/pr_body.md
else
echo "No associated PR found for $LAST_SHA; uploading without release notes."
: > /tmp/pr_body.md
fi
python3 .scripts/tools/extract-changelog.py --pr-body-file /tmp/pr_body.md > /tmp/changelog.md
echo "--- extracted release notes ---"
cat /tmp/changelog.md
- name: Upload Plugin (production)
run: |
python3 .scripts/uploader -p ${{ env.PLUGIN_PATH }} -t ${{ secrets.MARKETPLACE_TOKEN }} --plugin-daemon-path .scripts/dify-plugin-linux-amd64 -u ${{ secrets.MARKETPLACE_BASE_URL }} --with-changelog < /tmp/changelog.md
# Staging only becomes testable once uploads reach it: the backend rebuilds
# latest/recommended on an upload signal. Never blocking, though -- a red run
# invites a re-run, which re-uploads; -f keeps that idempotent.
- name: Upload Plugin (staging)
id: upload-staging
continue-on-error: true
env:
STAGING_BASE_URL: ${{ secrets.MARKETPLACE_STAGING_BASE_URL }}
STAGING_TOKEN: ${{ secrets.MARKETPLACE_STAGING_TOKEN }}
run: |
if [ -z "$STAGING_BASE_URL" ] || [ -z "$STAGING_TOKEN" ]; then
echo "MARKETPLACE_STAGING_BASE_URL / _TOKEN are not set; skipping the staging upload"
exit 0
fi
python3 .scripts/uploader -p "$PLUGIN_PATH" -t "$STAGING_TOKEN" \
--plugin-daemon-path .scripts/dify-plugin-linux-amd64 -u "$STAGING_BASE_URL" -f --with-changelog < /tmp/changelog.md
- name: Report a failed staging upload
if: steps.upload-staging.outcome == 'failure'
# Summary needs no token; the comment is best-effort. Neither may redden
# a production publish that already succeeded.
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
PLUGIN: ${{ env.PLUGIN_PATH }}
run: |
report=$(printf '%s\n' \
"**Staging upload failed** for \`$PLUGIN\`." \
"" \
"The plugin **is** published to production -- only <https://marketplace-staging.dify.dev> is missing it, so nothing needs re-merging or re-reviewing." \
"" \
"Reason: [workflow run]($RUN_URL). The next push of this plugin, or a backfill run, will bring staging back in line.")
printf '%s\n' "$report" >> "$GITHUB_STEP_SUMMARY"
gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/comments" -f body="$report"