Getting Started

In this example you are the maintainer of two PHP packages maestrophp/example-math and maestrophp/example-science.

Installation

You can install it as a project dependency:

$ composer require dantleech/maestro

Create a configuration file

Let’s start by creating a maestro.json configuration file:

{
    "nodes": {
        "maestrophp/example-math": {
            "type": "package",
            "args": {
                "url": "https://github.com/maestrophp/example-math"
            }
        },
        "maestrophp/example-science": {
            "type": "package",
            "args": {
                "url": "https://github.com/maestrophp/example-science"
            }
        }
    }
}

Now run the plan:

$ ./vendor/bin/maestro run -v

You should see something like:

Run Report
==========

 Summary of all tasks executed during run

+----------------------------+----------+--------------------------------+----+--+
| package                    | label    | action                         ||  |
+----------------------------+----------+--------------------------------+----+--+
| maestrophp/example-math    | checkout | checking out git@github.com:ma ||  |
|                            |          | estrophp/example-math          |    |  |
+----------------------------+----------+--------------------------------+----+--+
| maestrophp/example-science | checkout | checking out git@github.com:ma ||  |
|                            |          | estrophp/example-science       |    |  |
+----------------------------+----------+--------------------------------+----+--+
 5 nodes, 0 pending 5 succeeded, 0 cancelled, 0 failed

This is the default run report. It shows the status of the tasks that have been executed.

Applying templates

Now lets add some tasks. We want all of our packages to have a README file, create the following Twig template somewhere relative to your maestro.json:

This is {{ package.name }}.

The {{ animal }} says "{{ greeting }}".
  • We used the package variable, this refers to the current package object.
  • We specified two custom variables which we will define below.

And add a task to apply it in your configuration:

{
    "vars": {
        "animal": "cow",
        "greeting": "moo"
    },
    "nodes": {
        "maestrophp/example-math": {
            "type": "package",
            "args": {
                "url": "https://github.com/maestrophp/example-math"
            },
            "nodes": {
                "readme": {
                    "type": "template",
                    "args": {
                        "path": "templates/readme.md.twig",
                        "targetPath": "README.md"
                    }
                }
            }
        },
        "maestrophp/example-science": {
            "type": "package",
            "args": {
                "url": "https://github.com/maestrophp/example-science"
            }
        }
    }
}

Using Prototypes

We don’t want to repeat information. Frequently packages in the same ecosystem will have similar requirements. Maestro allows you to use prototypes :

{
    "vars": {
        "animal": "cow",
        "greeting": "moo"
    },
    "nodes": {
        "maestrophp/example-math": {
            "prototype": "example"
        },
        "maestrophp/example-science": {
            "prototype": "example"
        }
    },
    "prototypes": {
        "example": {
            "type": "package",
            "args": {
                "url": "https://github.com/$PACKAGE_NAME"
            },
            "nodes": {
                "readme": {
                    "type": "template",
                    "args": {
                        "path": "templates/readme.md.twig",
                        "targetPath": "README.md"
                    }
                }
            }
        }
    }
}
  • We declared a new prototype example.
  • We made both of our packages use the prototype.
  • We used a special environment variable $PACKAGE_NAME in our URL.

Declaring Versions

Declare versions for your packages and then generate a version report.

{
    "vars": {
        "animal": "cow",
        "greeting": "moo"
    },
    "nodes": {
        "maestrophp/example-math": {
            "args": {
                "version": "1.0.0"
            },
            "prototype": "example"
        },
        "maestrophp/example-science": {
            "args": {
                "version": "0.1.0"
            },
            "prototype": "example"
        }
    },
    "prototypes": {
        "example": {
            "type": "package",
            "args": {
                "url": "https://github.com/$PACKAGE_NAME"
            },
            "nodes": {
                "readme": {
                    "type": "template",
                    "args": {
                        "path": "templates/readme.md.twig",
                        "targetPath": "README.md"
                    }
                },
                "tag": {
                    "type": "tag",
                    "depends": ["readme"]
                },
                "survey": {
                    "type": "survey",
                    "depends": ["tag"]
                }
            }
        }
    }
}

Note:

  • We added the version key to each of our packages.
  • We added a tag task to the prototype: this will automatically tag the version if it is not existing.
  • The tag task depends on the README task to succeed. In real life this would depend on all tests passing.

Then, for extra points we:

  • We added a survey task to gather versioning information.

We can then run our plan and generate both Run and a Version reports:

./bin/maestro run -v --report=run --report=version

Including Files

When you have a large number of packages you may want to dedicate a file to each package.

The following example is the same as the previous one but each package has it’s own file:

{
    "vars": {
        "animal": "cow",
        "greeting": "moo"
    },
    "nodes": {
        "include": "packages/*.json"
    },
    "prototypes": {
        "include": "prototypes/*.json"
    }
}

packages/example-math.json:

{
    "prototype": "example",
    "name": "phpactor/container",
    "vars": {
        "version": "1.0.0"
    }
}

packages/example-science.json:

{
    "name": "maestrophp/example-science",
    "vars": {
        "version": "0.1.0"
    },
    "prototype": "example"
}

Summary

This tutorial demonstrates some basic functionality of Maestro. Checkout the Reference for more detailed informations.