Skip to main content

Background

Updating a plugin that others actively use is tedious by hand: modify the code, bump the version, push changes, create a branch, package the file, and open a PR—every release. Plugin Auto-PR is a GitHub Actions workflow that automates the whole sequence. One push packages the plugin and opens the Marketplace PR, so you can focus on building.

Concepts

GitHub Actions

GitHub Actions automates development tasks in GitHub. When triggered (for example, by a code push), it runs your workflow in a cloud-based virtual machine, handling everything from build to deployment.
Workflow
GitHub Actions usage limits:
  • Public repositories: Unlimited.
  • Private repositories: 2000 minutes per month.

Plugin Auto-PR

The workflow runs these steps:
  1. Triggers when you push code to the main branch of your plugin source repository.
  2. Reads plugin information from the manifest.yaml file.
  3. Packages the plugin as a .difypkg file.
  4. Pushes the packaged file to your forked dify-plugins repository.
  5. Creates a new branch and commits the changes.
  6. Creates a PR to merge into the upstream repository.

Prerequisites

Repositories

  • Your own plugin source code repository (e.g., your-name/plugin-source).
  • Your own fork of the plugin repository (e.g., your-name/dify-plugins).
  • The plugin directory structure already in place in your fork:
dify-plugins/
└── your-author-name
    └── plugin-name

Permissions

Create a GitHub Personal Access Token (PAT) that can push code to your forked repository and create PRs to the upstream repository.

Parameters and Configuration

Setup Requirements

Auto-publishing needs two things in place. The manifest.yaml file drives the automation:
  • name: Your plugin’s name (affects package and branch names).
  • version: Semantic version number (increment with each release).
  • author: Your GitHub username (determines repository paths).
The PLUGIN_ACTION secret in your plugin source repository holds the credentials:
  • Value: A Personal Access Token (PAT) with sufficient permissions.
  • Permissions: Push branches to your forked repository and create PRs to the upstream repository.

Automatically Generated Parameters

Once set up, the workflow derives these parameters for you:
  • GitHub username: Read from the author field in manifest.yaml.
  • Author folder name: Matches the author field.
  • Plugin name: Read from the name field in manifest.yaml.
  • Branch name: bump-{plugin-name}-plugin-{version}.
  • Package filename: {plugin-name}-{version}.difypkg.
  • PR title and content: Generated from the plugin name and version.

Step-by-Step Guide

1

Prepare Repositories

Ensure you have forked the official dify-plugins repository and have your own plugin source repository.
2

Configure Secret

In your plugin source repository, go to Settings > Secrets and variables > Actions > New repository secret and create a secret:
  • Name: PLUGIN_ACTION
  • Value: A GitHub Personal Access Token (PAT) with write permissions to the target repository (your-name/dify-plugins)
Create Secrets
3

Create Workflow File

Create a .github/workflows/ directory in your repository, add a file named plugin-publish.yml, and paste in the workflow below.At a high level, the workflow runs on every push to main, downloads the Dify CLI, packages the plugin from the manifest, checks out your dify-plugins fork, and opens a PR against langgenius/dify-plugins with the new .difypkg.
# .github/workflows/plugin-publish.yml
name: Auto Create PR on Main Push

on:
  push:
    branches: [ main ]  # Trigger on push to main
  workflow_dispatch:    # Allow manual runs from the Actions tab

jobs:
  create_pr: # Renamed job for clarity
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Print working directory # Kept for debugging
        run: |
          pwd
          ls -la

      - name: Download CLI tool
        run: |
          # Create bin directory in runner temp
          mkdir -p $RUNNER_TEMP/bin
          cd $RUNNER_TEMP/bin

          # Download CLI tool
          wget https://github.com/langgenius/dify-plugin-daemon/releases/latest/download/dify-plugin-linux-amd64
          chmod +x dify-plugin-linux-amd64

          # Show download location and file
          echo "CLI tool location:"
          pwd
          ls -la dify-plugin-linux-amd64

      - name: Get basic info from manifest # Changed step name and content
        id: get_basic_info
        run: |
          PLUGIN_NAME=$(grep "^name:" manifest.yaml | cut -d' ' -f2)
          echo "Plugin name: $PLUGIN_NAME"
          echo "plugin_name=$PLUGIN_NAME" >> $GITHUB_OUTPUT

          VERSION=$(grep "^version:" manifest.yaml | cut -d' ' -f2)
          echo "Plugin version: $VERSION"
          echo "version=$VERSION" >> $GITHUB_OUTPUT

          # If the author's name is not your github username, you can change the author here
          AUTHOR=$(grep "^author:" manifest.yaml | cut -d' ' -f2)
          echo "Plugin author: $AUTHOR"
          echo "author=$AUTHOR" >> $GITHUB_OUTPUT

      - name: Package Plugin
        id: package
        run: |
          # Use the downloaded CLI tool to package
          cd $GITHUB_WORKSPACE
          # Use variables for package name
          PACKAGE_NAME="${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}.difypkg"
          # Use CLI from runner temp
          $RUNNER_TEMP/bin/dify-plugin-linux-amd64 plugin package . -o "$PACKAGE_NAME"

          # Show packaging result
          echo "Package result:"
          ls -la "$PACKAGE_NAME"
          echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT

          # Show full file path and directory structure (kept for debugging)
          echo "\\nFull file path:"
          pwd
          echo "\\nDirectory structure:"
          tree || ls -R

      - name: Checkout target repo
        uses: actions/checkout@v3
        with:
          # Use author variable for repository
          repository: ${{steps.get_basic_info.outputs.author}}/dify-plugins
          path: dify-plugins
          token: ${{ secrets.PLUGIN_ACTION }}
          fetch-depth: 1 # Fetch only the last commit to speed up checkout
          persist-credentials: true # Persist credentials for subsequent git operations

      - name: Prepare and create PR
        run: |
          # Debug info (kept)
          echo "Debug: Current directory $(pwd)"
          # Use variable for package name
          PACKAGE_NAME="${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}.difypkg"
          echo "Debug: Package name: $PACKAGE_NAME"
          ls -la

          # Move the packaged file to the target directory using variables
          mkdir -p dify-plugins/${{ steps.get_basic_info.outputs.author }}/${{ steps.get_basic_info.outputs.plugin_name }}
          mv "$PACKAGE_NAME" dify-plugins/${{ steps.get_basic_info.outputs.author }}/${{ steps.get_basic_info.outputs.plugin_name }}/

          # Enter the target repository directory
          cd dify-plugins

          # Configure git
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"

          # Ensure we are on the latest main branch
          git fetch origin main
          git checkout main
          git pull origin main

          # Create and switch to a new branch using variables and new naming convention
          BRANCH_NAME="bump-${{ steps.get_basic_info.outputs.plugin_name }}-plugin-${{ steps.get_basic_info.outputs.version }}"
          git checkout -b "$BRANCH_NAME"

          # Add and commit changes (using git add .)
          git add .
          git status # for debugging
          # Use variables in commit message
          git commit -m "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin to version ${{ steps.get_basic_info.outputs.version }}"

          # Push to remote (use force just in case the branch existed before from a failed run)
          git push -u origin "$BRANCH_NAME" --force

          # Confirm branch has been pushed and wait for sync (GitHub API might need a moment)
          git branch -a
          echo "Waiting for branch to sync..."
          sleep 10  # Wait 10 seconds for branch sync

      - name: Create PR via GitHub API
        env:
          GH_TOKEN: ${{ secrets.PLUGIN_ACTION }} # Use the provided token for authentication
        run: |
          gh pr create \
            --repo langgenius/dify-plugins \
            --head "${{ steps.get_basic_info.outputs.author }}:${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}" \
            --base main \
            --title "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin to version ${{ steps.get_basic_info.outputs.version }}" \
            --body "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin package to version ${{ steps.get_basic_info.outputs.version }}

            Changes:
            - Updated plugin package file" || echo "PR already exists or creation skipped." # Handle cases where PR already exists

      - name: Print environment info # Kept for debugging
        run: |
          echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE"
          echo "Current directory contents:"
          ls -R
4

Update manifest.yaml

Make sure these fields are set correctly:
version: 0.0.x  # Version number
author: your-github-username  # GitHub username/Author name
name: your-plugin-name  # Plugin name

Usage Guide

First-Time Setup

Before the first automated release, confirm that:
  1. You have forked the official dify-plugins repository.
  2. Your plugin source repository structure is correct.
  3. The PLUGIN_ACTION secret is set in your plugin source repository.
  4. The workflow file .github/workflows/plugin-publish.yml exists.
  5. The name and author fields in manifest.yaml are configured correctly.

Subsequent Updates

To publish new versions after setup:
  1. Modify the code.
  2. Update the version field in manifest.yaml.
    Release
  3. Push all changes to the main branch.
  4. Wait for GitHub Actions to complete packaging, branch creation, and PR submission.

Outcome

When you push code to the main branch of your plugin source repository, GitHub Actions runs the publishing process automatically:
  • Packages the plugin in {plugin-name}-{version}.difypkg format.
  • Pushes the packaged file to the target repository.
  • Creates a PR to merge into the fork repository.
Outcome

Example Repository

See the example repository for a working configuration and best practices.
Edit this page | Report an issue