Category: Reflection

  • My weekend release snafu

    sna•fu
      noun
        a confused or chaotic state; a mess.

    This past weekend I released v1.2.0 of WPGraphQL.

    And 1.2.1, and 1.2.2, and 1.2.3, and 1.2.4, and 1.2.5.

    I made some changes to the Github repo that caused deploys to not behave as intended, and to call it a “snafu” might be an understatement.

    Plugin distribution

    For the first 4 years of WPGraphQL, the plugin was not distributed on the WordPress.org plugin repository, one of the most common distribution channels for WordPress plugins. The plugin has been versioned on Github and primarily distributed on Github and Packagist.org. Users that wanted to install WPGraphQL would either clone the plugin or download the zip from Github, or use Composer to install the plugin from packagist.org.

    Vendor Dependencies

    Since downloading a Zip from Github was a pretty common way for folks to get the plugin, and I wanted users to be able to download the Zip, install it to WordPress and be immediately productive, without having to run composer commands to install dependencies. So, I made the decision to version the plugins external dependencies in the repository, even against the advice of Composer.

    For quite some time the plan was to deploy the plugin to WordPress.org after the v1.0 release, and then stop versioning the Composer dependencies as Github would no longer be the primary method of distribution.

    WPGraphQL reached v1.0 in November and has been distributed on WordPress.org since, so I began to work on implementing the plan to no longer version the vendor dependencies in the Git repo.

    Github Workflows

    I already had a Github Workflow that installed the vendor dependencies and deployed to WordPress.org using the fantastic WordPress deploy action from 10up.

    This workflow was in place starting in v1.0 of the plugin.

    The workflow installs composer dependencies, then deploys the plugin to WordPress.org.

    I was pretty sure that since the Workflow already included the composer install --no-dev step prior to the deploy action that I was already good to go. All I needed to do was add a new part of the workflow to create a Zip file of the plugin, including the installed dependencies, and upload that compiled Zip to the release as a release asset, so that users that still want to be able to download a zip from Github could do so.

    I added that new part of the workflow.

    The next step was remove the vendor directory and tell .gitignore that I no longer want to version that directory. This would allow me and other contributors to install the vendor dependencies while working locally, but not worry about committing them to the repo. So, I updated the .gitignore to ignore the vendor directory.

    Broken release!

    I released v1.2.0. And shortly after was told that it was breaking things for users.

    Users were reporting seeing the following screen:

    Screenshot showing the wp_die() screen users were reporting.

    I checked out the deploy action to see if it failed for some reason.

    Updating Deploy Action

    Github was reporting that my arguments for the “generate-zip” option on the 10up deploy action were not accurate.

    Screenshot showing a warning from Github about the “generate-zip” option

    I thought perhaps this was maybe causing something to not work quite right. So I checked the 10up action docs and it appeared this option perhaps wasn’t needed, so I removed the option, re-released, and watched the deploy process.

    Still no luck. WordPress.org was missing files.

    Aha!

    The error that was reported to me made it clear that WordPress.org was excluding the vendor directory from the plugin, but I wasn’t sure why, as the workflow runs composer install before deploying.

    I dug into the code for the 1oup action, and realized that if a .distignore isn’t present, then tit uses the git archive command, which ignores files from the `.gitignore` and the `.gitattributes` files.

    Aha!

    This means that when I added the vendor directory to the .gitignore file to stop versioning the directory, the deploy action was leaving that directory out of what gets deployed to WordPress.org. So my step in the workflow that runs composer install was being nullified by the update to the .gitignore file.

    :man-facepalming:

    I did more investigating and found that the 10up action reads the .distignore file, if it exists. This was the missing piece!

    I can use a .gitignore to ignore files used in local development from being versioned in Git, but separately configure what to ignore for distribution.

    So, I added a .distignore file that ignores a lot of files that are useful for development but are not needed to run the plugin, and I configured this file to NOT ignore the vendor directory.

    Success!

    Now the plugin was deploying to WordPress.org with the vendor dependencies.

    Fixed! But, still broken.

    I had confirmation that installing from WordPress.org was working for users. It was fixed!

    But now I was now getting reports that users installing the plugin from Composer, specifically as a dependency of Trellis / Bedrock were running into the same wp_die() screen that folks reported seeing when installing from WordPress.org where the vendor directory was missing.

    So this seemed to mean that installing the plugin from Composer was also excluding the vendor dependencies?

    Ooph!

    I spun up a Trellis environment locally. It was super easy by the way – I typically use localwp.com for my local WordPress installs, but Trellis made it a breeze to get a local WordPress install running. Kudos to Ben and the other contributors of the project! ????.

    From my Trellis-built WordPress environment, I installed WPGraphQL from WordPress.org, and it worked fine. ????

    I deleted the plugin and installed from wpackagist (a wordpress specific Composer repository) and it worked fine. ????

    But then, I installed the plugin from packagist.org, and I was met with the wp_die() screen others had reported. ????

    Composer Dependencies!

    It turns out that Composer installs the dependencies in the vendor directory of the parent project. I knew this, but my brain didn’t want to connect these dots.

    This means that this code here was problematic.

    Since the vendor directory was previously always installed in the wp-graphql/vendor directory, as it was versioned with the plugin, the file_exists() check was always true.

    Now that the vendor directory isn’t versioned in the plugin, it can be installed anywhere within the project, so this check isn’t always true anymore.

    When installing WPGraphQL from Packagist, the dependencies are not going to be installed in the wp-graphql/vendor, but instead in the vendor directory of the project that’s including WPGraphQL as a dependency.

    So, I was able to update this part of the code to use the autoload from the WPGraphQL plugin if it exists, which it will when installing from WordPress.org or downloading the Zip from the Github release, and otherwise check for the existence of the dependency class (GraphQL\GraphQL) to make sure dependencies are installed whether in the plugin or the parent project.

    Back in business!

    Now, the plugin deploys to WordPress.org fine, can be installed with Composer from WPackagist and Packagist, and follows the recommendation of Composer to not version the dependencies in the Git repo.

  • Setting up a new developer environment to contribute to WPGraphQL..

    I just announced that I am now employed by WP Engine to work on WPGraphQL.

    With new employment comes a new Macbook, which I need to setup as a dev machine to continue working on WPGraphQL.

    It’s always a tedious process to get a new computer setup to be an effective developer, so I thought I’d record all the steps I take, as I take them, and hopefully provide some help to others.

    Local WordPress Environment

    One of the first things I need to do to work on WPGraphQL, is have a local WordPress environment.

    For the past 3 years or so, my preferred ways to setup WordPress locally is to use Local, a desktop application that makes it easy to setup WordPress sites with a few button clicks.

    I enjoy Local so much, I even picked it as my “Sick Pick” on the Syntax.fm episode about WordPress and GraphQL!

    When working locally, I usually have a number of different WordPress sites with different environments. For example, I have a site that I use locally to test WPGraphQL with WPGraphQL for Advanced Custom Fields, and another environment where I test things with WPGraphQL and WPGraphQL for WooCommerce. Having different sites allows me to separate concerns and test different situations in isolation.

    However, the constant is WPGraphQL. I want to be able to use the same version of WPGraphQL, that I’m actively making changes to, in both environments.

    This is where symlinking comes in.

    In the command line, I navigate to my local site’s plugins directory. For me, it’s at /Users/jason.bahl/Local Sites/wpgraphql/app/public/wp-content/plugins

    Then, with the following command, I symlink WPGraphQL to the Local WordPress site: ln -s /Users/jason.bahl/Sites/libs/wp-graphql

    This allows me to keep WPGraphQL cloned in one directory on my machine, but use it as an active plugin on many Local WordPress sites. As I create more sites using Local, I follow this same step, and repeat for additional plugins, such as WPGatsby or WPGraphQL for Advanced Custom Fields.

    XDebug for PHPStorm Extension

    PHPStorm is my IDE of choice, and Local provides an extension that makes it easy to get PHPStorm configured to work with XDebug. I recommend this extension if you use Local and PHPStorm.

    TablePlus Extension

    I used to use SequelPro, but have been transitioning to use TablePlus, and Local has a community extension that opens Local databases in TablePlus.

    PHPStorm

    For as long as I’ve been working on WPGraphQL, PHPStorm has been my IDE of choice. I won’t get into the weeds, and you are free to use other IDEs / Code Editors, but I find that PHPStorm makes my day to day work easier.

    Pro tip: To save time configuring the IDE, export the settings from from PHPStorm on your old machine and import them on your new machine.

    SourceTree

    SourceTree is a free GUI tool for working with code versioned with Git. While Git is often used in the command line, sometimes I like to click buttons instead of write commands to accomplish tasks. I also find it super helpful to visualize Git trees to see the status of various branches, etc. I find the code diffs easier to read in SourceTree than in the command line too, although I like Github’s UI for code diffs the best.

    In any case, I use SourceTree daily. I think it’s fantastic, and you can’t beat the price!

    Note: If you try using SourceTree before using Git in the command line, it might fail. This is because you need to add github.com (or whatever git host you use) to your ssh known hosts. You can read more about this here.

    MySQL

    Local sets up MySQL for each site, but for running Codeception tests for WPGraphQL, I like to have a general MySQL install unassociated with any specific Local site that I can configure for Codeception to use.

    I download and install MySQL v5.7.26 for macOS here.

    I then ensured that I updated my .zshrc file to include this export, as described here, to ensure the mysqld command will work.

    TablePlus

    I used to use SequelPro, but it’s been deprecated, so I’ve begun using TablePlus. You can download it here.

    Docker Desktop

    WPGraphQL ships with a Docker environment that developers can spin up locally, and the tests also have a Docker environment so they can be run in isolation.

    In order to spin up the local Docker environment or run tests with Docker, Docker Desktop needs to be installed and logged into.

    Homebrew

    Homebrew is a package manager for MacOS (or Linux). It makes it easy to install packages that are useful for development on a Mac.

    I used Homebrew to install the below packages.

    Command Line Tools for XCode

    This is something I seem to forget almost any time I setup a new Mac. When trying to install things from the command line, I’m always prompted to install Command Line Tools for Xcode and agree to their licensing. For me, as I was installing Homebrew, I was prompted to Download and Install this. If you want to install it separately, follow these instructions.

    Git

    Since WPGraphQL is maintained on Github, Git is essential to my daily work.

    With Homebrew installed, I use it to install Git, which is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

    Having git installed locally allows me to clone repositories from Github to my local machine, make commits to code, and push code back up to Github.

    In order to use Git with 2-Factor Authentication enabled, I also had to get SSH keys setup for Github.

    Composer

    Composer is a PHP package manager. WPGraphQL uses Composer for test dependencies, so it’s important to have Composer installed in order to run tests. I used the command brew install composer to install Composer.

    Note: I also had to make sure I was running a version of PHP that the zip module, so I followed these steps to get that working.

    Node & NVM

    Since I do a lot of work with JavaScript applications, such as Gatsby and the WP Engine Headless Framework, having Node installed locally is a must, and having nvm (Node Version Manager) to allow switching Node versions quickly is very helpful.

    I followed this guide to get Node and NVM installed using Homebrew.

    Time to contribute!

    Now that I have my local environment setup and all my regular tools, I’m ready to contribute to WPGraphQL again!