Sage 10: What is the best way to build theme locally and push to github, ready for remote use?

Hey all,

I’m working on a Sage 10 project. How would I accomplice the following?
I want to build a theme locally and have it ready to use for remote usage.

  • I work on a theme locally
  • Build theme it locally yarn build:production
  • Push local git to GitHub and make a release
  • Download and install theme directly into remote Wordpress

Last bullet is the least important. I’ve already made a updater class to check and download latest version from my github.

This is my current .gitignore


I’ve commented-out /dist and /vendors since I know they need those files.

But my workflow is not correct from what I see. When installing the theme I get errors like:

  • Fatal error: Uncaught Error: Class 'Illuminate\Contracts\Container\BindingResolutionException' not found in ...
  • Fatal error: Uncaught Error: Class 'Symfony\Component\ErrorHandler\Error\FatalError' not found in ...

Can anyone point me into the right direction? :slight_smile: :slight_smile:

The theme build will result in build artifacts. Not all files in the theme workdir are actually needed for the theme (namely resources/Also the PHP runtime for the theme is required (composer.json), hence your error. You have to run compoer install in the theme directory to have the required PHP files installed.

When using Trellis the usual deploy approach is to first clone the theme with its source code onto the deployment target, then build the theme on the workstation (where the theme is already cloned, too) and push these build artifacts separately onto the deployment target. Bedrock WordPress sites use composer to core, themes and plugins as packages.

Build artifacts can be hosted on GitHub, but one can also use a private composer repository or build artifact host (e.g. for theme ZIP files). E.g. when using a CI pipeline, new theme source pushes are build and then the theme is packaged as theme without the source files, then published as composer package release on the private composer repository - or uploaded as theme ZIP to a private build repository.

@strarsis, thanks for the reply. Yes, composer is installed. Also I’ve ran yarn clean and composer dump-autoload right before install and build, just to be sure.

Currently I’m the only Roots product I use is Sage, so I’m not (yet) using Trellis. One new thing at the time :slight_smile: I’m running Mamp locally to develop and host locally. So I also don’t build with trellis.

I found a new thing. Only when updating the them I get this error.

  • So WP->update http://localhost/mytheme/wp-admin/update-core.php?action=do-theme-upgrade
  • Not when I download the same zip directly from the same git and use wp->themes->install from zip. http://localhost/grokaalbox/wp-admin/theme-install.php Here I can install the same them and files without errors.

So now I’m thinking. The theme is already installed on the remote site. Then it downloads the update though update-core. Would the autoloader be called too early during the update process itself?

Would that mean the files are ok, but Sage 10 is ran during the update and not being able to find the classes?

I’ve noticed the error occurs after installation of the update.

  • Installing theme
  • 1/1 updates are succeeded
  • deactivating maintenance mode
  • Error print about the classes.

So, could it be it still has the old theme files in memory at that point. Then it want to grab an asset from the previous version. But since it’s a new build Composer changed the asset id. Something-Something like that?

So WordPress installs the theme as ZIP file?
Does the ZIP file contain vendor/ and the files that would composer install.

Yes, Wordpress downloads the latest release .zip file from GitHub and installs it from that .zip

It does contain the necessary files (to my knowledge).
So it contains the /vendor and the /dist folders.

Also, manually unpacking the files in the theme folder and activating the theme also works fine.

So only when the theme is installed by WordPress during the theme updating process, something goes wrong?

Yes, from what I see now it only goes wrong during theme update, when the theme is already installed. Maybe some hook is called to early after install.

Also no problems occur after refresh or other page after update. Just, right after update on the same page where the update is called from.

Ok, Now, I think I found out what happened. But I don’t yet know how to fix it :slight_smile:

So if I install a theme manually the theme root folder is called something like: my-theme. Updating the theme downloads a new set of files with a different theme folder name. Something like my-theme-3d547d1. Next update its again being renamed, something like my-theme-58fa412.

There you have it. For that split moment on the same page it’s searching for it’s old/previous folder name/path.

Now what I should find out is what the reason of the new folder name is and how to keep it like the original intended name. This also would keep the folder path the same. And this would, as I suspect, prevent my errors.

The theme is updated via add_filter('pre_set_site_transient_update_themes', array($this, 'my-function'), 10, 1); This does some version checking and sets the new download url. Wordpress takes it from there to download and install it. So I have to prevent Wordpress from renaming the theme root folder.

This might become a bit off-topic for Roots / Sage. But I hope someone knows more about this

I’m not sure how exactly you’re getting your files from GitHub, but those numbers look like commit hashes. GitHub is probably appending them automatically when you download.

Yes :slight_smile: I think so too. By now I’m certain it’s not a Roots/Sage problem. Than number one. I know I have to find a WP hook between download and before installing to rename the downloaded zip to a correct name. But that’s becoming off-topic for this forum.

I’m browsing trough github to find clues on this. Thanks all for the help. Love this community :slight_smile:

Problem solved.
filter upgrader_source_selection can be used to check zip file name against repo or theme name and rename to desired (original) theme name. Found an example that helped me out here:

1 Like

In my company, we bundle a composer.json with any plugin or theme that we need to load from repos. The critical thing is that it contains the correct name and URL, installer path and installer type.


    "name": "organization/theme-name",
    "homepage": "",
    "license": "GPL-2.0-only",
    "authors": [
        "name": "Theme Name",
        "homepage": ""
    "extra": {
        "installer-name": "theme-name"
    "type": "wordpress-theme"

This topic was automatically closed after 42 days. New replies are no longer allowed.