Generating ZIP file for plugin release

Plugins require a ZIP file to be attached to Github release.
The ZIP file must expand to a folder named as the plugin slug like my-plugin and not like my-plugin-v1.0.2.
Here there are two ways to generate the ZIP file correctly from the command line.

Using wp-cli

Steps to do once in your system:

  • If you don’t have wp-cli install it following those instructions.
  • If you don’t have wp dist-archive command install it with wp package install wp-cli/dist-archive-command

Steps to do once in your plugin

  • Set up .distignore to exclude unwanted files (data in .git, .gitignore and whatever you don’t want in the release) as described in the command help.

To create the file:

  • Go inside your plugin main folder
  • Issue wp dist-archive

You’ll get a ZIP file outside the folder named your-plugin.1.0.1.zip (the version is automatically discovered by wp-cli).
Then inspect your ZIP file to be sure it includes everything that is needed and no hidden files.

Using git archive

  • Setup .gitattributes to exclude files you don’t want in the release (documentation here)
  • Check that everything is committed to GitHub (maybe using git status)
  • Go inside your plugin main folder (say that is my-plugin and you are going to release 1.0.1)
  • Issue git archive -o "../my-plugin.1.0.1.zip" --prefix my-plugin/ HEAD

You’ll get a ZIP file outside the folder named your-plugin.1.0.1.zip.
Then inspect your ZIP file to be sure it includes everything that is needed and no hidden files.

Bonus: automatic release creation with hub

You can learn more about hub here.
After you have generated your ZIP file, with a command you can get the release drafted.
You can also wrap it up in a custom release script.
Inside your plugin main directory issue hub release create -d -a "../your-plugin.1.0.1.zip" -m "Your plugin 1.0.1" "1.0.1" where -d will do the release as draft, -a specify the attachment, -m the release message (first line is the title) and finally the tag.

3 Likes

This is really helpful.
There should be a Github action to help with this as well on release.

2 Likes

Great write up. We should consider publishing it in docs, what eventually will be plugin/theme handbooks.

3 Likes

I’m testing this GitHub workflow those days.
This works supposing that your plugin slug is the same as the repo name.
It just escludes git files, can be expanded to exclude other files.
This triggers on published releases.

I’m not so happy with this because I can’t get a ZIP file named my-plugin-1.0.1.zip that expands to my-plugin folder. I used ${{ github.ref_name }} to get version number but the file expands to my-plugin-1.0.1 folder.
Solved in the post below.

name: Generate ZIP file and Upload as Release Asset
on:
  release:
    types: [published]
jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Create artifact
        uses: montudor/[email protected]
        with:
          args: zip -X -r ${{ github.event.repository.name }}.zip . -x *.git* 
      - name: Upload artifact
        uses: actions/upload-artifact@v2
        with:
            name: ${{ github.event.repository.name }}
            path: ${{ github.event.repository.name }}.zip
      - name: Upload to release
        uses: JasonEtco/upload-to-release@master
        with:
          args: ${{ github.event.repository.name }}.zip application/zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 Like

Solved using git archive instead of zip.

name: Generate Installable Plugin, and Upload as Release Asset
on:
  release:
    types: [published]
jobs:
  build:
    name: Upload Release Asset
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: setup git config
        run: |
          git config user.name "GitHub Actions Bot"
          git config user.email "<>"
      - name: Create artifact
        run : |
          git archive -o ${{ github.event.repository.name }}-${{ github.ref_name }}.zip --prefix ${{ github.event.repository.name }}/ HEAD 
          ls
      - name: Upload artifact
        uses: actions/upload-artifact@v2
        with:
            name: ${{ github.event.repository.name }}-${{ github.ref_name }}
            path: ${{ github.event.repository.name }}-${{ github.ref_name }}.zip
      - name: Upload to release
        uses: JasonEtco/upload-to-release@master
        with:
          args: ${{ github.event.repository.name }}-${{ github.ref_name }}.zip application/zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 Like

This works great. We just need to note that one needs to use a classic token from Github.