Fix dependency conflict, remove deprecated models, and align credential validation #191
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Pre PR Check Per Plugin | |
| on: | |
| pull_request_target: | |
| types: [opened, synchronize, ready_for_review, review_requested, edited] | |
| branches: | |
| - main | |
| jobs: | |
| detect-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| plugins: ${{ steps.filter.outputs.plugins }} | |
| has_changes: ${{ steps.filter.outputs.has_changes }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - id: filter | |
| name: Detect changed plugins | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then | |
| CHANGED_FILES=$(gh pr view -R ${{ github.repository }} ${{ github.event.pull_request.number }} --json files --jq '.files[].path') | |
| else | |
| if [ "${{ github.event.before }}" == "0000000000000000000000000000000000000000" ]; then | |
| BASE_SHA="HEAD~1" | |
| else | |
| BASE_SHA="${{ github.event.before }}" | |
| fi | |
| CHANGED_FILES=$(git diff --name-only $BASE_SHA HEAD) | |
| fi | |
| # Find all manifest.yaml files | |
| MANIFESTS=$(find . -name "manifest.yaml" -not -path "*/.*") | |
| VALID_PLUGINS=() | |
| for m in $MANIFESTS; do | |
| PLUGIN_PATH=$(dirname "$m" | sed 's|^\./||') | |
| # If any changed file starts with this plugin path | |
| if echo "$CHANGED_FILES" | grep -q "^$PLUGIN_PATH/"; then | |
| VALID_PLUGINS+=("$PLUGIN_PATH") | |
| fi | |
| done | |
| if [ ${#VALID_PLUGINS[@]} -eq 0 ]; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "plugins=[]" >> $GITHUB_OUTPUT | |
| else | |
| JSON=$(printf '%s\n' "${VALID_PLUGINS[@]}" | jq -R . | jq -s -c .) | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "plugins=$JSON" >> $GITHUB_OUTPUT | |
| echo "Detected plugins: $JSON" | |
| fi | |
| test: | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.has_changes == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| plugin_path: ${{ fromJson(needs.detect-changes.outputs.plugins) }} | |
| fail-fast: false | |
| # Using the full plugin path as the environment name | |
| environment: ${{ matrix.plugin_path }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Clone Marketplace Toolkit | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh repo clone langgenius/dify-marketplace-toolkit -- .scripts/ | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Setup uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| version: "latest" | |
| activate-environment: false | |
| - name: yq - portable yaml processor | |
| uses: mikefarah/yq@v4.44.5 | |
| - name: Download Dify CLI | |
| env: | |
| GH_TOKEN: ${{ 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 | |
| mv .scripts/dify-plugin-linux-amd64 .scripts/dify | |
| - name: Expose Dify CLI to PATH | |
| run: | | |
| echo "$GITHUB_WORKSPACE/.scripts" >> $GITHUB_PATH | |
| echo "DIFY_CLI_PATH=$GITHUB_WORKSPACE/.scripts/dify" >> $GITHUB_ENV | |
| - name: Export All Secrets to Environment | |
| uses: oNaiPs/secrets-to-env-action@v1 | |
| with: | |
| secrets: ${{ toJSON(secrets) }} | |
| exclude: GITHUB_TOKEN, ORG_SCOPE_GITHUB_TOKEN, RAG_SSH_HOST, MARKETPLACE_TOKEN | |
| - name: Check Plugin Manifest Author | |
| run: | | |
| if ! yq '.author' "${{ matrix.plugin_path }}/manifest.yaml" | grep -q "langgenius"; then | |
| echo "!!! Plugin manifest.yaml author must be langgenius" | |
| exit 1 | |
| fi | |
| - name: Check If Version Exists | |
| run: | | |
| VERSION=$(yq '.version' "${{ matrix.plugin_path }}/manifest.yaml") | |
| AUTHOR=$(yq '.author' "${{ matrix.plugin_path }}/manifest.yaml") | |
| NAME=$(yq '.name' "${{ matrix.plugin_path }}/manifest.yaml") | |
| echo "Checking plugin version: $VERSION" | |
| RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" "${{ secrets.MARKETPLACE_BASE_URL }}/api/v1/plugins/$AUTHOR/$NAME/$VERSION") | |
| if [ "$RESPONSE_CODE" = "200" ]; then | |
| RESPONSE=$(curl -s "${{ secrets.MARKETPLACE_BASE_URL }}/api/v1/plugins/$AUTHOR/$NAME/$VERSION") | |
| if [ "$(echo "$RESPONSE" | jq -r '.code')" = "0" ]; then | |
| echo "!!! Plugin version $VERSION already exists, please update the version number in manifest.yaml" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Check for Disallowed Virtualenv Directories | |
| run: | | |
| if find "${{ matrix.plugin_path }}" -maxdepth 1 -type d \( -name ".venv*" -o -name "venv*" \) | grep -q .; then | |
| echo "!!! Please remove .venv or venv* directory in plugin path before submitting the PR" | |
| exit 1 | |
| fi | |
| - name: Check Plugin pyproject.toml | |
| run: | | |
| cd "${{ matrix.plugin_path }}" | |
| if [ ! -f "pyproject.toml" ]; then | |
| echo "!!! pyproject.toml is required for all plugins" | |
| exit 1 | |
| fi | |
| - name: Check Packaging | |
| run: | | |
| uv run --with requests --with dify_plugin python .scripts/uploader/upload-package.py -d "${{ matrix.plugin_path }}" -t "${{ secrets.MARKETPLACE_TOKEN }}" --plugin-daemon-path .scripts/dify -u "${{ secrets.MARKETPLACE_BASE_URL }}" -f --test | |
| - name: Package plugin | |
| run: | | |
| SAFE_NAME=$(echo "${{ matrix.plugin_path }}" | tr '/' '-') | |
| PKG_NAME="test-${SAFE_NAME}-package.difypkg" | |
| EXTRACT_DIR="test-${SAFE_NAME}-unpacked" | |
| echo "SAFE_NAME=$SAFE_NAME" >> $GITHUB_ENV | |
| echo "PKG_NAME=$PKG_NAME" >> $GITHUB_ENV | |
| echo "EXTRACT_DIR=$EXTRACT_DIR" >> $GITHUB_ENV | |
| echo "### Packaging plugin at: ${{ matrix.plugin_path }} ###" | |
| .scripts/dify plugin package ${{ matrix.plugin_path }} --output_path "$PKG_NAME" | |
| echo "### Extracting package ###" | |
| unzip -q "$PKG_NAME" -d "$EXTRACT_DIR" | |
| - name: Validate Dependencies with uv | |
| run: | | |
| cd "${{ matrix.plugin_path }}" | |
| uv sync --all-groups --python 3.12 | |
| - name: Check Plugin Install | |
| run: | | |
| export INSTALL_METHOD=serverless | |
| export SERVERLESS_PORT=8080 | |
| export SERVERLESS_HOST=0.0.0.0 | |
| uv run --project "${{ matrix.plugin_path }}" --with requests python .scripts/validator/test-plugin-install.py -d "${{ matrix.plugin_path }}" | |
| - name: Check for tests directory | |
| id: check_tests | |
| run: | | |
| if [ -d "${{ env.EXTRACT_DIR }}/tests" ]; then | |
| echo "has_tests=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_tests=false" >> $GITHUB_OUTPUT | |
| echo "No tests directory found in plugin" | |
| fi | |
| - name: Install dependencies | |
| if: steps.check_tests.outputs.has_tests == 'true' | |
| working-directory: ${{ env.EXTRACT_DIR }} | |
| run: | | |
| uv sync --all-groups --python 3.12 | |
| - name: Run tests | |
| if: steps.check_tests.outputs.has_tests == 'true' | |
| working-directory: ${{ env.EXTRACT_DIR }} | |
| run: | | |
| export PLUGIN_FILE_PATH="$(realpath ../${{ env.PKG_NAME }})" | |
| uv run --with pytest pytest | |
| check-complete: | |
| name: Check Complete | |
| needs: | |
| - detect-changes | |
| - test | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify check results | |
| run: | | |
| if [ "${{ needs.detect-changes.result }}" != "success" ]; then | |
| echo "detect-changes failed." | |
| exit 1 | |
| fi | |
| if [ "${{ needs.detect-changes.outputs.has_changes }}" != "true" ]; then | |
| echo "No plugin changes detected." | |
| exit 0 | |
| fi | |
| if [ "${{ needs.test.result }}" = "success" ]; then | |
| echo "Plugin checks passed." | |
| exit 0 | |
| fi | |
| echo "Plugin checks failed." | |
| exit 1 |