GitHub Actions: Create WordPress zip on Release

Create a GitHub Action Workflow to create a zip of your WordPress plugin.

Your managing your WordPress plugin on GitHub like everyone else. But you continue to create your zip manually. How about using GitHub Actions?

Inspired to share this post after reading Robert‘s article, and discussion on X.

File Structure

You need to follow the GitHub Action structure: .github/workflows/$name.yml. In my case I used publish.yml.

Lets give it a name, and an “on” action.

name: "Generate Installable Plugin and Upload as Release Asset"

on:
  release:
    types: [ published ]

permissions:
  contents: write

The above workflow will show up in your GitHub repo’s Action tab, under workflows on the left.

The “on” action syntax in this case uses one event: release.

release: This event will run when a release is created. See Managing releases in a repository.

Jobs

The meat of this workflow is to trigger a job on select events. So we will create a single multi step job.

jobs:
  Build:
    name: Build and Upload Release
    runs-on: ubuntu-latest 

Steps

Now that we have our named job, we have to create the steps. Each step has a purpose, and some steps are required to run after another in a select order. Some steps are optional, and some may no be relevant to your development (I use Composer in all my projects).

The following steps will do a few select actions:

  1. Checkout the current repo code.
  2. Set Release Version as an environment variable (optional)
  3. Make sure PHP is setup with additional (optional tools) using shivammathur/setup-php
  4. Run Composer install
  5. Run Composer update to delete development dependencies (--no-dev).
  6. Create the artifact (zip).
  7. Upload the artifact.
  8. Optional duplicate artifact with release version for GitHub Updater (assets).
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set Release Version env
        run: |
          VERSION=${{ github.event.release.tag_name }}
          echo "Release Version: ${VERSION//v}"
          echo "RELEASE_VERSION=${VERSION//v}" >> $GITHUB_ENV

      # see https://github.com/shivammathur/setup-php
      - name: Use PHP 8.1
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.1
          coverage: none
        env:
          COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build project for production
        run: |
          echo "Release Version: ${{ github.event.release.tag_name }}"
          composer update --no-dev --optimize-autoloader
          mkdir build

      - name: Create artifact
        uses: montudor/action-zip@v1
        with:
          args: zip -X -r build/${{ github.event.repository.name }}.zip . -x *.git* bin** node_modules/\* .* "*/\.*" *.dist *.xml *.neon composer.lock package*.json tests** build**

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ github.event.repository.name }}
          path: build/${{ github.event.repository.name }}.zip

      - name: Upload to release
        uses: softprops/action-gh-release@v2
        with:
          files: build/${{ github.event.repository.name }}.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token

      - name: Duplicate asset for GitHub Updater
        # @see https://github.com/afragen/github-updater/wiki/Settings#release-assets
        uses: montudor/action-zip@v1
        with:
          args: zip -X -r build/${{ github.event.repository.name }}-${{ env.RELEASE_VERSION }}.zip . -x *.git* bin** node_modules/\* .* "*/\.*" *.dist *.xml *.neon composer.lock package*.json tests** build**

      - name: Upload duplicate to release
        uses: softprops/action-gh-release@v2
        with:
          files: build/${{ github.event.repository.name }}-${{ env.RELEASE_VERSION }}.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token

Final thoughts

With this simple workflow, I can now auto create downloadable artifacts attached to the release. See the full script on some of my open source plugins:

####################################################################################
# GitHub Action:
# Whenever creating a new release of the source code.
####################################################################################
# Steps to execute:
# - Checkout the source code
# - Run "composer install" for production (required dependencies are already under vendor/)
# - Create a .zip file, excluding:
#   - All hidden files (.git, .gitignore, etc)
#   - All development files, ending in .dist or .xml
#   - All composer files <= after installing dependencies, no need for them anymore
#   - Markdown files concerning development
#   - JS Package files.
#   - Folder build/ <= created only to store the .zip file
#   - Folder bin/ <= not needed for the plugin
#   - Folder tests/ <= not needed for the plugin
# - Upload the .zip file as an artifact to the action (this step is possibly optional)
# - Upload the .zip file as a release, for download
####################################################################################
name: Generate Installable Plugin and Upload as Release Asset

on:
  release:
    types: [ published ]

permissions:
  contents: write

jobs:
  Build:
    name: Build and Upload Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set Release Version env
        run: |
          VERSION=${{ github.event.release.tag_name }}
          echo "Release Version: ${VERSION//v}"
          echo "RELEASE_VERSION=${VERSION//v}" >> $GITHUB_ENV

      # see https://github.com/shivammathur/setup-php
      - name: Use PHP 8.1
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.1
          coverage: none
        env:
          COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build project for production
        run: |
          echo "Release Version: ${{ github.event.release.tag_name }}"
          composer update --no-dev --optimize-autoloader
          mkdir build

      - name: Create artifact
        uses: montudor/action-zip@v1
        with:
          args: zip -X -r build/${{ github.event.repository.name }}.zip . -x *.git* bin** node_modules/\* .* "*/\.*" *.dist *.xml *.neon composer.lock package*.json tests** build**

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ github.event.repository.name }}
          path: build/${{ github.event.repository.name }}.zip

      - name: Upload to release
        uses: softprops/action-gh-release@v2
        with:
          files: build/${{ github.event.repository.name }}.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token

      - name: Duplicate asset for GitHub Updater
        # @see https://github.com/afragen/github-updater/wiki/Settings#release-assets
        uses: montudor/action-zip@v1
        with:
          args: zip -X -r build/${{ github.event.repository.name }}-${{ env.RELEASE_VERSION }}.zip . -x *.git* bin** node_modules/\* .* "*/\.*" *.dist *.xml *.neon composer.lock package*.json tests** build**

      - name: Upload duplicate to release
        uses: softprops/action-gh-release@v2
        with:
          files: build/${{ github.event.repository.name }}-${{ env.RELEASE_VERSION }}.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
Austin
Austin

πŸ’πŸ½β€β™‚οΈ Husband to Jeana.
⚾️ Dodgers & Brewers.
πŸ’» PHP Engineer.
πŸŒπŸΌβ€β™‚οΈGolfer; ~13 HDC.
🌱 Hydroponic Gardner.
🍿 Plex nerd.
πŸš™ '15 WRX, '22 Model 3 LR, & '66 Corvette C2.

Follow me on Twitter @TheFrosty & Instagram @TheFrosty.

Articles: 295

One Comment