---
title: "Automatically Publish Plugins via PR"
---


{/* 
  CONTRIBUTOR NOTE:
  ----------------
  This is a legacy document that is being deprecated.
  Please DO NOT make changes to this version.
  All updates should be directed to the new version at:
  /plugin-dev-en/0321-plugin-auto-publish-pr
*/}

<Card title="This Documentation is Being Deprecated" icon="circle-exclamation" href="/plugin-dev-en/0321-plugin-auto-publish-pr">
  <p>This page is being phased out as part of our documentation reorganization.</p>
  
  <p><strong>Click this card</strong> to be redirected to the updated version with the most current information.</p>
  
  <p>If you notice any discrepancies or areas needing improvement in the new documentation, please use the "Report an issue" button at the bottom of the page.</p>
</Card>

### Background

Updating plugins that others are actively using can be tedious. Traditionally, you would need to modify code, bump versions, push changes, create branches, package files, and submit PRs manually - a repetitive process that slows down development.

Thus, we have created **Plugin Auto-PR**, a GitHub Actions workflow that automates the entire process. Now you can package, push, and create PRs with a single action, focusing on building great plugins.

### Concepts

#### GitHub Actions

GitHub Actions automates your development tasks in GitHub.

**How it works**: When triggered (e.g., by a code push), it runs your workflow in a cloud-based virtual machine, handling everything from build to deployment automatically.

![Workflow](https://assets-docs.dify.ai/2025/04/60534de8e220f860947b32a8329a8349.png)

**Limits**:

* Public repositories: Unlimited
* Private repositories: 2000 minutes per month

#### Plugin Auto-PR

**How it works**:

1. Workflow triggers when you push code to the main branch of your plugin source repository
2. Workflow reads plugin information from the `manifest.yaml` file
3. Automatically 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 changes
6. Automatically creates a PR to merge into the upstream repository

### Prerequisites

#### Repository

* You already have your own plugin source code repository (e.g., `your-name/plugin-source`)
* You already have your own forked plugin repository (e.g., `your-name/dify-plugins`)
* Your forked repository already has the plugin directory structure:

```
dify-plugins/
└── your-author-name
    └── plugin-name
```

#### Permission

This workflow requires appropriate permissions to function:

* You need to create a GitHub Personal Access Token (PAT) with sufficient permissions
* The PAT must have permission to push code to your forked repository
* The PAT must have permission to create PRs to the upstream repository

### Parameters and Configuration

#### Setup Requirements

To get started with auto-publishing, you will need two key components:

**manifest.yaml file**: This file drives the automation process:

* `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)

**PLUGIN\_ACTION Secret**: You need to add this secret to your plugin source repository:

* Value: Must be a Personal Access Token (PAT) with sufficient permissions
* Permission: Ability to push branches to your forked repository and create PRs to the upstream repository

#### Automatically-Generated Parameters

Once set up, the workflow automatically handles these parameters:

* GitHub username: Read from the `author` field in `manifest.yaml`
* Author folder name: Consistent with 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: Automatically generated based on plugin name and version

### Step-by-Step Guide

<Steps>
  <Step title="Prepare Repositories">
    Ensure you have forked the official `dify-plugins` repository and have your own plugin source repository.
  </Step>
  <Step title="Configure Secret">
    Navigate to your plugin source repository, click **Settings > Secrets and variables > Actions > New repository secret**, and create a GitHub Secret:

    * Name: `PLUGIN_ACTION`
    * Value: GitHub Personal Access Token (PAT) with write permissions to the target repository (`your-name/dify-plugins`)

    <img src="https://assets-docs.dify.ai/2025/04/8abd72b677dd24752910c304c76f1c26.png" alt="Create Secrets" />
  </Step>
  <Step title="Create Workflow File">
    Create a `.github/workflows/` directory in your repository, create a file named `plugin-publish.yml` in this directory, and copy the following content into the file:

    ```yaml
    # .github/workflows/auto-pr.yml
    name: Auto Create PR on Main Push

    on:
      push:
        branches: [ main ]  # Trigger on push to main

    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/download/0.0.6/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
    ```
  </Step>
  <Step title="Update manifest.yaml">
    Ensure those following fields are correctly set:

    ```yaml
    version: 0.0.x  # Version number
    author: your-github-username  # GitHub username/Author name
    name: your-plugin-name  # Plugin name
    ```
  </Step>
</Steps>

### Usage Guide

#### First-time Setup

When setting up the auto-publish workflow for the first time, complete these steps:

1. Ensure you have forked the official `dify-plugins` repository
2. Ensure your plugin source repository structure is correct
3. Set up the `PLUGIN_ACTION Secret` in your plugin source repository
4. Create the workflow file `.github/workflows/plugin-publish.yml`
5. Ensure the `name` and `author` fields in the `manifest.yaml` file are correctly configured

#### Subsequent Update

To publish new versions after setup:

1. Modify the code
2. Update the `version` field in `manifest.yaml`

![Release](https://assets-docs.dify.ai/2025/04/9eed2b9110e91e18008b399e58198f03.png)

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 will automatically execute the publishing process:

* Package the plugin in `{plugin-name}-{version}.difypkg` format
* Push the packaged file to the target repository
* Create a PR to merge into the fork repository

![Outcome](https://assets-docs.dify.ai/2025/04/60d5de910c6ce2482c67ddec3320311f.png)

### Example Repository

See [example repository](https://github.com/Yevanchen/exa-in-dify) to understand configuration and best practices.

{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}

---

[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/plugins/publish-plugins/plugin-auto-publish-pr.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

