What is the best git workflow for small teams?

In my development, I use Git all the time. It was a little tricky to figure out at first but, I feel like I have a good understanding of how to use it.

When I’ve worked with other developers I see them struggling with a few concepts that I use regularly and thought it might be helpful to document my workflow.

On our team, we use feature branches and pull requests. I don’t have a strong preference of whether the feature branch is in our main repo or in a developers fork of our repo. For this post, I’ll assume feature branches are in the main repo.

Let’s start with the following master branch.

I’m going to work on a new feature so I create a new branch off of master and start committing my changes.

During that time, other developers merged in features.

I’m ready to submit my PR, but first I need to rebase off of master, potentially resolving conflicts that emerge.

I need to make changes based on a code review, so I commit those to my repo. Meanwhile, other features are merged into master.

Before I have my new changes reviewed I once again need to rebase off of master.

To push up to the main repo I need to do a force push because I’m overwriting what was previously there.

My PR is accepted, so it’s squashed and merged into master as H (via GitHub), the feature branch is deleted.

Once something is merged into master it’s locked. Other than specific edge cases, you shouldn’t ever have to force push to master, only to feature branches.

With our main SaaS applications I also use Git to deploy to staging and production. I wouldn’t use this for library development or any applications that have multiple deployments.

I have special branches staging and production which our continuous integration platform watch. When I push changes into those branches they are tested (as with all pushes) and if tests pass, they are deployed to that environment.

So if we wanted to deploy my latest feature, I’d merge it into staging and have our team review it to determine if there are any issues that need to be resolved before deploying to production.

If there are changes we create a new feature branch and start at the top of this workflow.

If there are no changes to be made then we merge into production, it’s tested and deployed.

That’s it! Developers I’ve worked with tend to get hung up on rebasing. I know some workflows never rebase and always merge, but I strongly prefer keeping things clean with rebasing.

I know that there are a million ways to use Git and different teams have different workflows. What do you think of my process? Anything you’d change?

Using Action-Domain-Responder on the command line

I’ve created a new proof of concept ADR library that works like Radar, only for the command line interface.

Yesterday I was working on a project in Radar and needed to create a command line tool for it.

In the past, I’ve always used Symfony Console which I like. Since my application was already built using Radar and adhering to Action-Domain-Responder and Clean Architecture, I wanted a solution that was more consistent with the rest of the codebase.

The selling point to Clean Architecture is that your domain logic is separate from the delivery mechanism. So if Radar was my delivery mechanism, I should be able to have a different command line delivery mechanism and my domain shouldn’t know or care.

I took a look at Aura.Cli which seems nice. However, it’s very much a command line library. Out of the box, it’s not a framework for building command line tools adhering to ADR.

So I took a stab at writing one (that uses Aura.Cli), it’s called Cadre.CliAdr.

At this point, it’s more of a proof of concept rather than a production solution. It’s heavily based on Radar and uses the same patterns.

Here is an example of how you’d use it. It will seem very familiar if you’ve used Radar.

Expect revisions and documentation to come. In the meantime, please post any comments here or as an issue on GitHub.

Introducing Cadre.Module

I created a new library that works with Aura.DI to allow specifying dependent modules to be auto loaded.

Today I published a new component Cadre.Module.

This component was born out of my side project that’s using Radar.

Stock Radar

Radar is built around Aura.Di which is a very nice dependency injection container. If you’re interested in learning more about Radar check out Radar Under the Hood.

One thing that’s great about Aura.Di is the concept of ContainerConfig objects.

Here is an example:

This is nice because I can package my DI configuration into smaller classes that configure a single thing. An example of this could be one ContainerConfig that configures Twig and another that configured Atlas.Orm.

The problem I ran into was where to put things if they are related to different areas. Also, there was an issue about how to make things work between dev and production if they needed a different configuration.

The specific use case that prompted the development of this library was configuring PHP Debug Bar which I’ve been working with a lot lately.

PHP Debug Bar can collect data from many different sources. I’m using it currently with Twig and Atlas.Orm. When I push my project to production, I will not want to be loading PHP Debug Bar, but it’s very useful during development.

It’s also possible that I’ll want to reuse this code in the future on projects that may not use Twig and/or Atlas.Orm.

Cadre.Module

In Cadre.Module I introduce the Module and ModuleLoader classes. Both are useable as ContainerConfig objects. Modules define four additional methods that are inspired by Composer.

Each module can define what other modules they require, require in dev, conflict with and replace.

I started out also implementing provide and suggest, but decided that they had limited to no application in this use case.

While the new modules are just ContainerConfigs with extra metadata, the module loader does the heavy lifting.

While still behaving as a ContainerConfig, a module loader starts out with a list of modules in the same way composer.json defines your starting packages.

When it’s used, it goes through and loads each of the modules and loads their required modules. It also checks for conflicts and replacements along the way.

The define and modify methods just proxy through to all of the loaded modules.

The other neat feature of Cadre.Module is that modules can query the module loader to see if another module is loaded.

This is especially useful for optional modules or development modules that may not always be present.

Conclusion

I’m interested in what you think of Cadre.Module. Check out the documentation and ask questions either here in the comments or as an issue on GitHub.

Tracking Multiple Connections with PHP Debug Bar and Atlas ORM

My library AtlasOrm.DebugBar.Bridge now supports multiple connections.

On Friday I talked about a new library I created that helps integrate Atlas.ORM with PHP Debug Bar.

Hari K T replied asking about using multiple connections. For instance, if you use Atlas with a default master database for writes and multiple read-only slave databases. My library AtlasOrm.DebugBar.Bridge does not support this is any way out of the box.

I spent the weekend thinking about how to solve this.

First, I asked “How would I do this right now with what’s available?” and the answer was:

I wasn’t happy with this solution. Too complicated and too easy to mess up.

It was difficult, because of Atlas.ORM inheriting the Aura.SQL requirement that adding read and write connections require a callable that returns the connection. This is done because if we want to register multiple possible connections, we don’t want to connect to all of them right away. We only want to connect when we’re using the connection.

Finally, yesterday morning I came up with a possible solution.

If I created a new class ConnectionFactory that could be configured identically as a connection and be passed into AtlasContainer as a callable (I implement the __invoke method). It could then also be aware of the AtlasOrmCollector which would have a new method addConnectionFactory that registered itself with the ConnectionFactory object.

This way, I could easily configure new connections (via ConnectionFactory), add them to the AtlasContainer and AtlasOrmCollector and they would wire themselves up. The TraceablePDO connection would only get added to the collector when it was invoked which prevented me from invoking all of the connections up front whether they were used or not.

The new method of adding multiple connections is then:

I think it looks a lot cleaner and less prone to errors.

This code is currently sitting as a PR to allow any interested parties to comment before it gets merged. Introducing ConnectionFactory. Feel free to review and comment.

Collecting Data from Atlas ORM with PHP Debug Bar

My new library AtlasOrm.DebugBar.Bridge lets you collect data from Atlas.ORM using PHP Debug Bar.

In my last article, I talked about how I found an N+1 bug in Atlas ORM.

I had mentioned how it took a little work to get PHP Debug Bar configured with Atlas but didn’t really explain why it was difficult, or how I got them working together.

At first, it seemed like it would be easy. Debug Bar comes with a PDOCollector and Atlas is based on PDO. In Atlas\Orm\AtlasContainer it creates a new Aura\Sql\ConnectionLocator then creates and adds an Aura\Sql\ExtendedPdo connection to it.

PHP Debug Bar requires you wrap your PDO connection in DebugBar\DataCollector\PDO\TraceablePDO which extends PDO.

Aura\Sql\ExtendedPdo wraps a PDO connection and extends PDO however DebugBar\DataCollector\PDO\TraceablePDO is not a Aura\Sql\ExtendedPdo object.

That means that I need to wrap PDO in DebugBar\DataCollector\PDO\TraceablePDO which is then wrapped in Aura\Sql\ExtendedPdo.

There is no easy way of doing that without replacing some code.

The first step is to create a new ExtendedPdo class that extends Aura\Sql\ExtendedPdo that overrides connect() which instantiates the PDO connection. We want to wrap the newly created connection in DebugBar\DataCollector\PDO\TraceablePDO.

Next, we create a new AtlasContainer class that extends Atlas\Orm\AtlasContainer that overrides setConnectionLocator to instantiates my new ExtendedPdo instead of Aura\Sql\ExtendedPdo.

Finally, we can use the DebugBar\DataCollector\PDO\PDOCollector which requires a DebugBar\DataCollector\PDO\TraceablePDO connection. We can get that out of our AtlasContainer like this:

To make this step easier I created AtlasOrmCollector which extends DebugBar\DataCollector\PDO\PDOCollector but expects my AtlasContainer instead of a PDO connection in the constructor. This way I can pull out the DebugBar\DataCollector\PDO\TraceablePDO connection and pass it to the parent constructor.

I’ve packaged all of this up into the library AtlasOrm.DebugBar.Bridge which is also available on packagist as cadre/atlasorm-debugbar-bridge.

You can now integrate PHP Debug Bar into your applications that use Atlas ORM as simply as this: