Taking the development of a Github hosted WordPress plugin from “old” to automatic

This article is about cristidraghici/wp-just-an-admin-button. The content is about taking it from the form of a basic git project with many manual actions – yes, old is not a good word, maybe classic is a better one – to one automatically published to the WordPress plugin repository.

Some testing should be added, but we will leave that as something to be implemented in the future. Also, this is still the first iteration with my first Jenkins pipeline – therefore, if you have suggestions, they are more than welcome.

Updating the repository

Create a release

Since it is a plugin that has been used for a while – not that much though ? – and yet it hasn’t had a proper release, I should do that. Creating a release is done by going to Repository > Code > <x> release where you should create a new tag and a release. Do remember to fetch/pull after this is done.

Repo restrictions

The next thing to do is to add some rules for the repository. For this we need to go to Repository > Settings > Branches > Branch protection rules. Here we can add rules summed up like “Never merge directly to master” or “Require reviews before merge”.

Updating the code

The main functionality was not updated. However, the repository needs:

  • container based development; apart from the two containers necessary for WP, another one is set up for running commands in the same environment, regardless of the OS you are working on;
  • a way to update automatically the version;
  • a script to push the changes to the WordPress plugin repository.

Automated release and publish using Jenkins

Setting up a pipeline

  1. Login to Jenkins;
  2. Click on Open Blue Ocean to access the new interface for creating pipelines;
  3. Click on New Pipeline;
  4. Select Github and then Create an access token here;
  5. Continue with connecting your account using the generated access token and select the repository wp-just-an-admin-button;
  6. The repository already contains a Jenkinsfile, but if yours doesn’t, it will be created and commited by jenkins.

Personal opinion on Blue Ocean: it looks really-really nice, but it still lacks a lot of options and I would go for manually editing the Jenkinsfile anytime.

Set the webhook in Github.com

In order for Jenkins to “know” that it needs to build something, a special hook needs to be added in the settings of the repository. Small summary: every time x even happens on github, then a special call is made to the webhook.

The following image is rather self-explanatory:

The Jenkinsfile

After a lot of testing and commits and build minutes, I got to the following content:

pipeline {
  agent {
    dockerfile {
      filename './docker/Dockerfile'
      label 'builder'
    }

  }
  stages {
    stage('Prepare') {
      steps {
        echo 'Branch check is done in the scripts run.'
        echo 'To save resources, this should be moved to jenkins'
      }
    }
    stage('Release') {
      parallel {
        stage('default') {
          steps {
            echo 'This step is skipped if the commit message does not contain the `release` instruction'
          }
        }
        stage('patch') {
          when {
            expression {
              sh(script: "git log -1 | grep 'release patch'", returnStatus: true) == true
            }

          }
          steps {
            sh './cli.sh release patch'
          }
        }
        stage('minor') {
          when {
            expression {
              sh(script: "git log -1 | grep 'release minor'", returnStatus: true) == true
            }

          }
          steps {
            sh './cli.sh release minor'
          }
        }
        stage('major') {
          when {
            expression {
              sh(script: "git log -1 | grep 'release major'", returnStatus: true) == true
            }

          }
          steps {
            sh './cli.sh release major'
          }
        }
      }
    }

    stage('Publish') {
      steps {
        checkout scm
        sh 'cp .env.example .env'
        sh 'chmod +x ./cli.sh'

        withCredentials(bindings: [
                    string(credentialsId: 'WP_ORG_USERNAME', variable: 'WP_ORG_USERNAME'),
                    string(credentialsId: 'WP_ORG_PASSWORD', variable: 'WP_ORG_PASSWORD')
                  ]) {
            sh './cli.sh publish'
          }

        }
      }

      stage('Finish') {
        steps {
          echo 'Operation completed...'
        }
      }
    }
  }
Code language: PHP (php)

Good to mention

  • Credentials (secrets) are never to be stored in repositories;
  • There is much to improve in the current workflow of the pipeline, the scripts, the file structure (basically everything), therefore take the repo as an example or a starting point;

Fun fact ?below

Take a look at the number of commits, most in less than 24 hours 🙂

A preview from Blue Ocean

Related articles

Sources