Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pup workflows and add docs #17

Merged
merged 5 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .puprc-defaults
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"build": [],
"build_dev": [],
"workflows": {},
"checks": {
"tbd": {
"fail_method": "error",
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ This is a CLI utility built by [StellarWP](https://stellarwp.com) for running pr
* [`pup check:tbd`](/docs/commands.md#pup-checktbd)
* [`pup check:version-conflict`](/docs/commands.md#pup-checkversion-conflict)
* [`pup clean`](/docs/commands.md#pup-clean)
* [`pup do`](/docs/commands.md#pup-do)
* [`pup get-version`](/docs/commands.md#pup-get-version)
* [`pup help`](/docs/commands.md#pup-help)
* [`pup i18n`](/docs/commands.md#pup-i18n)
* [`pup info`](/docs/commands.md#pup-info)
* [`pup package`](/docs/commands.md#pup-package)
* [`pup workflow`](/docs/commands.md#pup-workflow)
* [`pup zip`](/docs/commands.md#pup-zip)
* [`pup zip-name`](/docs/commands.md#pup-zip-name)
* [Command flow for `pup zip`](/docs/flow.md)
Expand All @@ -35,5 +37,9 @@ This is a CLI utility built by [StellarWP](https://stellarwp.com) for running pr
* [Creating custom checks](#creating-custom-checks)
* [Simple checks](#simple-checks)
* [Class-based checks](#class-based-checks)
* [Workflows](/docs/workflows.md)
* [Defining workflows](/docs/workflows.md#defining-workflows)
* [Calling workflows](/docs/workflows.md#calling-workflows)
* [Pseudo-workflows](/docs/workflows.md#pseudo-workflows)
* Examples
* [GitHub Workflow: Zipping](/examples/workflows/zip.yml) - Breaks up the `pup zip` command into multiple steps so debugging is easy.
68 changes: 68 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* [`pup check:tbd`](/docs/commands.md#pup-checktbd)
* [`pup check:version-conflict`](/docs/commands.md#pup-checkversion-conflict)
* [`pup clean`](/docs/commands.md#pup-clean)
* [`pup do`](/docs/commands.md#pup-do)
* [`pup get-version`](/docs/commands.md#pup-get-version)
* [`pup help`](/docs/commands.md#pup-help)
* [`pup i18n`](/docs/commands.md#pup-i18n)
* [`pup info`](/docs/commands.md#pup-info)
* [`pup package`](/docs/commands.md#pup-package)
* [`pup workflow`](/docs/commands.md#pup-workflow)
* [`pup zip`](/docs/commands.md#pup-zip)
* [`pup zip-name`](/docs/commands.md#pup-zip-name)

Expand Down Expand Up @@ -129,6 +131,24 @@ composer -- pup clean
|----------|------------------------------------------------------------------------------|
| `--root` | **Optional.** Run the command from a different directory from the current. |


## `pup do`
Alias for `pup workflow`. See `pup help workflow` for more information.

### Usage
```bash
pup do <workflow>
# or
composer -- pup do <workflow>
```

### Arguments
| Argument | Description |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `workflow` | **Required.** The workflow you would like to run. |
| `--root` | **Optional.** Run the command from a different directory from the current. |


## `pup get-version`
Gets your project's version number.

Expand Down Expand Up @@ -250,6 +270,54 @@ composer -- pup package <version>
| `version` | **Required.** The version number to use when packaging. You can generate this using [`pup get-version`](/docs/commands.md#pup-get-version) if desired. | |
| `--root` | **Optional.** Run the command from a different directory from the current. |


## `pup workflow`
Run a command workflow.

An example workflow might look like this:

```json
{
"workflow": {
"my-workflow": [
"npm ci",
"npm run build",
"@composer run some-script"
]
}
}
```

Executing this workflow would work like this:

```bash
pup workflow my-workflow
# OR
pup do my-workflow
# OR
composer -- pup workflow my-workflow
# OR
composer -- pup do my-workflow
```

### Usage
```bash
pup workflow <workflow>
# or
pup do <workflow>
# or
composer -- pup workflow <workflow>
# or
composer -- pup do <workflow>
```

### Arguments
| Argument | Description |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| `workflow` | **Required.** The workflow you would like to run. |
| `--root` | **Optional.** Run the command from a different directory from the current. |


## `pup zip`
Runs the full `pup` set of commands to create a zip file.

Expand Down
21 changes: 11 additions & 10 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ root of the project. This file is a JSON file that contains the configuration op

## Top-level properties

| Property | Type | Description |
|-------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------|
| `build` | `array` | An array of CLI commands to execute for the build process of your project. |
| `build_dev` | `array` | An array of CLI commands to execute for the `--dev` build process of your project. If empty, it defaults to the value of `build` |
| `checks` | `object` | An object of check configurations indexed by the check's slug. See the [docs for checks](/docs/checks.md) for more info. |
| `paths` | `object` | An object containing paths used by `pup`. [See below](#paths). |
| `repo` | `string`/`null` | The git repo used to clone the project. If not provided, at github URL is generated based on the `name` property of `composer.json` |
| `zip_use_default_ignore` | `boolean` | Whether or not additionally ignore files based on the [`.distignore-defaults`](/.distignore-defaults) file. Defaults to `true`. |
| `zip_name` | `string` | The name of the zip file to be generated. Defaults to the name of the project as set in `composer.json`. |
| Property | Type | Description |
|-------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `build` | `array` | An array of CLI commands to execute for the build process of your project. |
| `build_dev` | `array` | An array of CLI commands to execute for the `--dev` build process of your project. If empty, it defaults to the value of `build` |
| `checks` | `object` | An object of check configurations indexed by the check's slug. See the [docs for checks](/docs/checks.md) for more info. |
| `paths` | `object` | An object containing paths used by `pup`. [See below](#paths). |
| `repo` | `string`/`null` | The git repo used to clone the project in the format of `<org>/<repo>`. If not provided, at github URL is generated based on the `name` property of `composer.json` |
| `workflows` | `object` | An object of workflow configurations. The index is the workflow slug and the values are arrays of strings that hold commands. See the [docs for workflows](/docs/workflows.md) for more info. |
| `zip_use_default_ignore` | `boolean` | Whether or not additionally ignore files based on the [`.distignore-defaults`](/.distignore-defaults) file. Defaults to `true`. |
| `zip_name` | `string` | The name of the zip file to be generated. Defaults to the name of the project as set in `composer.json`. |

## Paths

Expand Down Expand Up @@ -135,4 +136,4 @@ This is what you should add as a `paths.versions` entry:
]
}
}
```
```
46 changes: 46 additions & 0 deletions docs/workflows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Workflows

Workflows are a way to declare a series of commands that you want to run in a specific order. This allows you to specify
workflows that differ from the `build` and `build_dev` commands.

* [Defining workflows](#defining-workflows)
* [Calling workflows](#calling-workflows)
* [Pseudo-workflows](#pseudo-workflows)

## Defining workflows

Workflows are defined in the `workflows` property of your `.puprc` file.

```json
{
"workflows": {
"my-workflow": [
"npm ci",
"npm run build",
"@composer run some-script"
],
"my-other-workflow": [
"@composer run some-other-script",
"@composer run make-pot"
]
}
}
```

## Calling workflows

You can call a workflow by running the `workflow` command (or its alias `do`) with the name of the workflow as an argument.

```bash
pup workflow my-workflow
# OR
pup do my-workflow
```

## Pseudo-workflows

The `build` and `build_dev` properties within your `.puprc` file are also callable via the `workflow` command.

```bash
pup workflow build
```
2 changes: 1 addition & 1 deletion pup
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace StellarWP\Pup;

const PUP_VERSION = '1.2.5';
const PUP_VERSION = '1.3.0';
define( '__PUP_DIR__', __DIR__ );

if ( ! \Phar::running() ) {
Expand Down
1 change: 1 addition & 0 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function __construct( string $version ) {
$this->add( new Commands\I18n() );
$this->add( new Commands\Info() );
$this->add( new Commands\Package() );
$this->add( new Commands\Workflow() );
$this->add( new Commands\Zip() );
$this->add( new Commands\ZipName() );

Expand Down
97 changes: 97 additions & 0 deletions src/Commands/Workflow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace StellarWP\Pup\Commands;

use StellarWP\Pup\App;
use StellarWP\Pup\Exceptions\BaseException;
use StellarWP\Pup\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class Workflow extends Command {
/**
* @inheritDoc
*
* @return void
*/
protected function configure() {
$this->setName( 'workflow' )
->setAliases( [ 'do' ] )
->addArgument( 'workflow', InputArgument::REQUIRED, 'The workflow you would like to run.' )
->addOption( 'root', null, InputOption::VALUE_REQUIRED, 'Set the root directory for running commands.' )
->setDescription( 'Run a command workflow.' )
->setHelp( 'Run a command workflow.' );
}

/**
* @inheritDoc
*/
protected function execute( InputInterface $input, OutputInterface $output ) {
parent::execute( $input, $output );
$config = App::getConfig();
$root = $input->getOption( 'root' );
$workflow_slug = $input->getArgument( 'workflow' );
$io = $this->getIO();
$application = $this->getApplication();
if ( ! $application ) {
throw new BaseException( 'Could not run pup.' );
}

$collection = $config->getWorkflows();

if ( $collection->count() === 0 ) {
$io->writeln( '📣 The .puprc does not have any workflows configured.' );
$io->writeln( '💡 If you would like to use workflows, simply add a "<comment>workflows</comment>" property in <comment>.puprc</comment> similar to:' );
$io->writeln( '' );
$io->writeln( '"workflows": {' );
$io->writeln( ' "my-workflow": [' );
$io->writeln( ' "composer install",' );
$io->writeln( ' "npm run build"' );
$io->writeln( ' ]' );
$io->writeln( '}' );
$io->writeln( '' );
return 0;
}

$workflow = $collection->get( $workflow_slug );
if ( ! $workflow ) {
$io->writeln( "<error>The workflow '{$workflow_slug}' does not exist.</error>" );
return 1;
}

if ( $root ) {
chdir( $root );
}

$io->writeln( "<comment>Running {$workflow_slug} workflow steps...</comment>" );
foreach ( $workflow->getCommands() as $step ) {
$bail_on_failure = true;
if ( strpos( $step, '@' ) === 0 ) {
$bail_on_failure = false;
$step = substr( $step, 1 );
}
$io->section( "> <fg=cyan>{$step}</>" );
system( $step, $result );
$io->newLine();

if ( $result ) {
$io->writeln( "[FAIL] Workflow step failed: {$step}" );

if ( $bail_on_failure ) {
$io->writeln( "<fg=red>Exiting...</>" );
return $result;
}
}

if ( $root ) {
chdir( $config->getWorkingDir() );
}

$io->writeln( '<info>Workflow complete.</info>' );
}

return 0;
}
}
35 changes: 35 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,37 @@ public function __construct() {
$this->puprc_file_path = $this->working_dir . '.puprc';

$this->mergeConfigWithDefaults();
$this->buildWorkflows();
$this->parseCheckConfig();
$this->parseVersionFiles();
$this->validateConfig();
}

/**
* Builds the workflows from the config.
*
* @return void
*/
public function buildWorkflows() {
$collection = new Workflow\Collection();

if ( empty( $this->config->workflows->build ) && ! empty( $this->config->build ) ) {
$collection->add( new Workflow\Workflow( 'build', $this->config->build ) );
}

if ( empty( $this->config->workflows->build_dev ) && ! empty( $this->config->build_dev ) ) {
$collection->add( new Workflow\Workflow( 'build_dev', $this->config->build_dev ) );
}

if ( ! empty( $this->config->workflows ) ) {
foreach ( $this->config->workflows as $slug => $commands ) {
$collection->add( new Workflow\Workflow( $slug, $commands ) );
}
}

$this->config->workflows = $collection;
}

/**
* Merges the local .puprc (if it exists) with the default .puprc-defaults.
*
Expand Down Expand Up @@ -478,6 +504,15 @@ public function getVersionFiles() : array {
return $this->config->paths['versions'];
}

/**
* Get the workflows from the config.
*
* @return Workflow\Collection
*/
public function getWorkflows(): Workflow\Collection {
return $this->config->workflows;
}

/**
* @return string
*/
Expand Down
3 changes: 2 additions & 1 deletion src/VersionFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ public function getRegex(): string {
/**
* @inheritdoc
*/
#[\ReturnTypeWillChange]
public function jsonSerialize() {
return [
'file' => $this->getPath(),
'regex' => $this->getRegex(),
];
}
}
}