Accéder au contenu principal

7min.

The Castor Task Runner is Now Stable!

Cet article est aussi disponible en 🇫🇷 Français : Le task runner Castor est maintenant disponible en version 1 !.

When we unveiled Castor to the world, we shared the reasons that prompted us to develop our own task runner.

Since that article from 2023, many things have evolved in the project. And we now consider Castor and its public API to be stable enough to finally deserve the v1.0.0 milestone.

Let’s take a look at what Castor looks like now… but before that, a quick recap of the project.

Castor Version 1.0

Section intitulée did-you-say-castorDid You Say Castor?

Castor is the PHP task runner we’ve been developing for several years. Its goal? To replace our Makefiles (or Fabric, Invoke, or shell scripts) by allowing us to create our tasks using simple PHP functions, which are easy to read, understand, and write.

No classes, no OOP, no YAML configuration, or overly complex layers to implement.

Castor’s main feature is the Developer eXperience (DX) it offers. A castor.php file, an AsTask attribute—that’s all you need to get started:

// castor.php

use Castor\Attribute\AsTask;
use function Castor\run;

#[AsTask()]
function start(''): void
{
    run('composer install');
    run('bin/console assets:install');
    run('yarn install');
    // …
}

You can then execute your task:

castor start

Despite this apparent simplicity, Castor has much more to offer: a notion of context to adapt your tasks based on the environment, imports and namespaces to structure your Castor project however you like, events to hook into Castor’s internals, and much more.

Many native utilities are, of course, available to serve as building blocks in your tasks: environment variable management, input/output, logs, HTTP calls, SSH, etc. Check out the exhaustive list of available utilities.

Missing a tool? Add it naturally, just as you would in your usual PHP project. And if you think it could benefit everyone, come discuss it with us, open an issue, or even better, a PR!

Section intitulée key-highlightsKey Highlights

Section intitulée the-public-apiThe Public API

All the natively provided functions and their signatures form the public part of Castor’s API. They are guaranteed not to change within minor Castor versions.

If we need to modify or remove a function, a deprecation will always be added before its definitive removal in a major version, similar to what Symfony does to respect Semver and avoid Backward compatibility (BC) breaks.

Info

This compatibility promise has been in place since the very first 0.x versions!

This public API also includes all classes and behaviors mentioned in the documentation. For instance, this includes the classes for the Context or events. Generally speaking, all classes not marked with the @internal annotation are part of this public API.

Thanks to this promise, we have been able to progressively improve Castor’s internal workings throughout the 0.x versions:

  • added new features;
  • improved the code;
  • simplified maintenance.

All of this without breaking projects already using Castor since the early v0.x versions.

Section intitulée user-experienceUser Experience

As we’ve said, DX is at the heart of the project. We do everything to make Castor:

  • easy to install;
  • simple to pick up;
  • understandable at a glance;
  • and easy to debug (thanks to logs, in particular).

When you use Castor, it automatically generates a .castor.stub.php file containing all the definitions of the public API’s functions and classes. This allows your IDE to better understand your Castor project and offer autocompletion and suggestions, as if Castor were installed in your project’s dependencies.

Castor also provides autocompletion in your favorite shell, with completion for available tasks, their arguments, and options.

The tool must serve developers, and everything is done to make the experience smoother, more natural, and more pleasant than with alternatives.

Section intitulée documentation-and-examplesDocumentation and Examples

Having lots of features is great. But if they’re not documented anywhere, they’ll never be used. Therefore, a significant effort has been made to document all the functionalities offered by Castor:

  • everything you need to quickly get started with Castor;
  • all native functions and helpers;
  • supported advanced usages.

Astuce

If you only remember one thing: take a look at the project documentation!

The documentation is divided into 2 main sections:

And because nothing beats code, you’ll find numerous examples directly in the jolicode/castor repository to show the different features in action.

Psst, easter egg: these examples also serve as a complete test suite to ensure we don’t break anything when modifications are made to Castor.

Section intitulée numerous-featuresNumerous Features

Castor has been considerably enriched over the versions. Let’s look at the main things our favorite rodent can do now.

Section intitulée native-helpersNative Helpers

We have added several functions that are commonly used in the tasks we execute daily.

Since the idea was not to reinvent the wheel, we fully leverage PHP and its very complete ecosystem. Several functions exposed by Castor are therefore totally based on Symfony components. For example:

  • cache(), which utilizes symfony/cache and PSR-6;
  • io(), which offers the interactivity capabilities of symfony/console;
  • http_request(), which allows HTTP requests thanks to symfony/http-client;
  • run() to execute commands using symfony/process;
  • fs() for filesystem manipulation with symfony/filesystem and finder() for searching files/folders thanks to symfony/finder;
  • yaml_parse() and yaml_dump() for manipulating YAML files with symfony/yaml.

In addition, Castor includes:

To conclude this far-from-exhaustive list, note that it’s also possible to monitor the file system to restart commands upon disk changes or even to encrypt/decrypt files.

Once again, we can only encourage you to take a look at the exhaustive list of functions to discover everything that can be done natively with Castor.

Section intitulée installation-methodsInstallation Methods

Castor now offers several installation modes. The simplest way:

curl "https://castor.jolicode.com/install" | bash

If you have PHP >= 8.2 installed, you can benefit from the PHAR, as with most PHP projects that offer an executable (Composer, Rector, PHPStan, etc.).

Don’t have PHP or is your PHP too old? No problem, the installation script allows you to install Castor as a standalone binary that includes the correct PHP version:

curl "https://castor.jolicode.com/install" | bash -s -- --static

And because we also use GitHub Actions in most of our projects, we created a castor-php/setup-castor Action that allows you to install Castor directly in your workflow:

jobs:
  my-job:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup castor
        uses: castor-php/setup-castor@v0.1.0

      - name: Run castor "hello" task
        run: castor hello

As with the rest, everything is explained in the installation documentation.

Section intitulée castor-as-a-cli-frameworkCastor as a CLI Framework

Castor makes it easy for you to code your everyday tasks. Imagine you have a set of Castor tasks that you would like to share with other users or within other projects?

Castor now allows you to “repack” your project, which means building a PHAR containing Castor and all your tasks, as if it were your own executable.

It is even possible to hide the default Castor logo, or more recently, to configure your own logo 🎨.

And in the same way that Castor is available for installation as a PHAR, but also as a binary, it is possible to build a binary containing your own repacked project.

Section intitulée remote-importsRemote Imports

In cases where you need a feature that is not natively included in Castor, it is now possible to import tasks, functions, or even classes from external packages.

Again, the idea was not to re-develop an entire plugin management and download system. Instead, we chose to reuse the best package manager we know: Composer. Castor directly embeds Composer and allows you to configure the different packages to import (from packagist.org or from your own internal repository) in the same way you would in your project’s composer.json.

<?php

import('composer://vendor/package/', file: 'functions.php');

This feature required several iterations before reaching a reliable and satisfactory implementation. However, we prefer to consider this feature experimental for some time to fine-tune the final details.

Section intitulée adoptionAdoption

We designed Castor to simplify our daily lives: driving our Docker/Ansible stacks, automating tasks, etc. All our developers are delighted to no longer have a Python environment to install, to be able to easily contribute tasks, and to no longer have dependency issues, etc.

We also use Castor to develop Castor. The project’s CI runs in GitHub Actions with Castor, the release system is a Castor task that handles creating the tag and the release with the gh CLI, then attaching the different artifacts (PHARs, binaries) to the release, and the documentation is generated by MkDocs via Castor tasks. In short, we are Castor’s first users 🦫

When we open-sourced Castor, we received a lot of very positive feedback from people who were also thrilled to be able to write their tasks simply in PHP. We have more and more contributions from people outside the project, which confirms the enthusiasm and interest around Castor.

Positive review of Castor

Thank you for your ⭐, which motivates us even more!

History of stars on GitHub

Section intitulée a-final-wordA Final Word

Castor v1 is available, and we hope it will meet all your needs.

Let us know if you’d be interested in learning how Castor works internally, how we automated the build of the different Linux/macOS/Windows versions, how we built the test suite, etc.

Commentaires et discussions

Nos formations sur ce sujet

Notre expertise est aussi disponible sous forme de formations professionnelles !

Voir toutes nos formations

Ces clients ont profité de notre expertise