# Pipeline Configuration file

ReadyMage supports user defined configuration file that can inject various actions into different points of build/deploy pipeline or customize existing pipeline logic.

## Used terms

**Vanilla Magento theme** - a theme which uses Magento built in mechanisms of [theme server-side compilation](https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/css-guide/css_quick_guide_mode.html). For example `Magento/Luma`.

## How to use

Add the `readymage.yaml` file to Magento 2 root folder. It's the folder which contains base Magento 2`composer.*` files.

```
├── 📁 app
├── 📄 composer.json
├── 📄 composer.lock
└── 📄 readymage.yaml
```

## Examples

<details>

<summary>Default</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
environments:
- name: readymage-test
  build:
    themes:
      all: 
	area: all
	languages: [ 'en_US' ]
	scandipwa/theme:
     area: frontend
	playbook: scandipwa
	directory: scandipwa
	languages: [ 'en_US' ]
```

{% endcode %}

**Scenario**: You always want to generate static files for all available themes.

</details>

<details>

<summary>Build speed optimized</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
environments:
- name: readymage-test
  build:
    themes:
      Magento/backend:
        area: adminhtml
        languages: [ 'en_US' ]
      scandipwa/theme:
        area: frontend
        playbook: scandipwa
        directory: scandipwa
        languages: [ 'en_US' ]
```

{% endcode %}

**Scenario**: You know which exact themes are used in the website and need static file generation, thus saving time on the build phase by not generating files for themes that are not going to be used.

</details>

<details>

<summary>Using post build hook</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
environments:
- name: readymage-test
  build:
    hooks:
      post_build:
      - copy:
          app/etc/config.php: scandipwa/config-copy.php
          scandipwa/config-copy.php: scandipwa/config-copy2.php
          scandipwa/config-copy2.php: scandipwa/config-copy-move.php
      - move:
          scandipwa/config-copy-move.php: scandipwa/config-move.php
      - symlink:
          scandipwa/config-symlink.php: scandipwa/config-copy.php
          scandipwa/config-symlink-persistent.php: persistent:config-symlink-perst.php
```

{% endcode %}

**Scenario**: You need to execute some actions after automated build phase has completed.

</details>

<details>

<summary>Using post deploy hook</summary>

```yaml
schema_version: 1.0.0
environments:
- name: readymage-test
  build:
    ...
  deploy:
    hooks:
      post_deploy:
        - php:
            command: bin/magento indexer:reindex
        - curl:
            directory: /mnt/
            filename: <filename>
            url: <download-link>
```

**Scenario**: You need to execute some actions after deployment has completed.

{% hint style="info" %}
When using the `curl` command, only use the `/mnt/` directory or any sub-directory under it as the value for the key `directory`. Anything that doesn't fall under `/mnt/` will be lost.
{% endhint %}

</details>

<details>

<summary>Compiling with custom playbook</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
playbooks:
  test-book:
  - npm:
      command: ci
  - npm:
      command: run build
      env_vars:
        BUILD_MODE: magento
environments:
- name: readymage-test
  build:
    themes:
      Magento/backend:
        area: adminhtml
        languages: [ 'en_US' ]
      scandipwa/theme:
        area: frontend
        playbook: test-book
        directory: scandipwa
        languages: [ 'en_US' ]
```

{% endcode %}

**Scenario**: You want to compile your custom theme during the build phase.

</details>

<details>

<summary>Compiling vanilla Magento 2 themes</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
environments:
- name: readymage-test
  build:
    themes:
      Magento/luma:
        area: frontend
        languages: [ 'en_US', 'en_GB', 'lv_LV' ]
      Magento/blank:
        area: frontend
        languages: [ 'en_US', 'en_GB', 'lv_LV' ]
      Magento/backend:
        area: adminhtml
        languages: [ 'en_US' ]
```

{% endcode %}

**Scenario**: You want to compile default vanilla Magento 2 themes.

</details>

<details>

<summary>Compiling PWA Studio</summary>

{% code title="readymage.yaml" %}

```yaml
schema_version: 1.0.0
playbooks:
  pwastudio:
  - npm:
      command: ci
      env_vars:
        NODE_ENV: development
  - npm:
      command: run build
      env_vars:
        MAGENTO_BACKEND_URL: https://test.readymage.com
        MAGENTO_BACKEND_EDITION: CE
        CHECKOUT_BRAINTREE_TOKEN: sandbox_8yrzsvtm_s2bg8fs563crhqzk
environments:
- name: readymage-test
  build:
    themes:
      Magento/backend:
        area: adminhtml
        languages: [ 'en_US' ]
      Magento/Luma:
        playbook: pwastudio
        area: frontend
        directory: pwastudio
        languages: ['en_US']
```

{% endcode %}

**Scenario**: You want to compile custom PWA Studio based theme.

</details>

## Schema

By default, ReadyMage will attempt to validate configuration file before running its directives. If its invalid, the build will automatically fail with a relevant error about which parts of the schema are invalid or failed to be ran.

#### <mark style="color:red;">`schema_version`</mark>

Required. Specifies which schema version is used in the configuration file. Allowed values: `1.0.0`

#### <mark style="color:red;">`environments`</mark>

Optional. Array of environment specific configurations

{% hint style="info" %}
If there are no themes specified for the environment, all available Magento themes will be built for all areas, with the default language of `en_US` or, if specified, languages defined in `config.php`
{% endhint %}

* <mark style="color:red;">**`name`**</mark>

  Required. Environment full name.
* <mark style="color:red;">**`build`**</mark>

  Optional. Nested dictionary containing build specific configurations.

  * <mark style="color:red;">**`themes`**</mark>

    Optional. Dictionary of environment themes. Themes directive allows to specify which of themes should be built. This includes theme compilation and locale specific [static file generation](https://devdocs.magento.com/guides/v2.4/config-guide/cli/config-cli-subcommands-static-view.html#config-cli-subcommands-staticview.).

    * <mark style="color:red;">**`{theme}`**</mark>

      Theme ID `<Vendor>/<theme>` as defined in [registration.php](https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/themes/theme-create.html#fedg_create_theme_reg). Use `all` to generate static files for all Magento themes.

      * <mark style="color:red;">**`area`**</mark>

        Optional. Allowed values: `all`, `frontend`, `adminhtml`. If not defined, will fallback to `all`
      * <mark style="color:red;">**`languages`**</mark>

        Optional. Allowed values: array of strings. If not defined, will fallback to locales specified in `config.php` or if none found - to `en_US`
      * <mark style="color:red;">**`playbook`**</mark>

        Optional. Specifies which of the playbooks should be called during theme compilation. Ignored if theme ID is set to `all`
      * <mark style="color:red;">**`directory`**</mark>

        Required if playbook field is set. Specifies in which directory the theme is located at. Ignored if theme ID is set to `all`&#x20;
  * <mark style="color:red;">**`hooks`**</mark> Optional. Hooks are a way to inject custom logic around automated actions (e.g. build). For example, if you need to swap `config.php` file for specific environment before the build. Allowed values: `pre_build`, `post_build.` To customize theme compilation and static content file generation logic, use playbook and theme directives instead of using the hooks.
    * <mark style="color:red;">**`pre_build`**</mark> This hook is run before automated build phase. Can contain only [actions](#actions). Any actions here will permanently disable build cache until all of the actions are removed. **It will result in permanently increased build times.**
    * <mark style="color:red;">**`post_build`**</mark> This hook is run after automated build phase. Can contain only [actions](#actions).&#x20;
* <mark style="color:red;">**`deploy`**</mark>\
  Optional. Nested dictionary containing deploy specific configurations.
  * <mark style="color:red;">**`hooks`**</mark>\
    Optional. Hooks in this context offer a way to execute the needed commands throughout the deployment.&#x20;
    * <mark style="color:red;">**`post_deploy`**</mark>\
      This hook runs after the deployment has completed successfully. Available commands are `php` and `curl` only.

#### <mark style="color:red;">**`playbooks`**</mark>

Optional. Dictionary of playbooks.

A playbook is set of actions that are called on the theme build/compilation step. It’s invoked during the build pipeline before automated `setup:static-content:deploy`. To customize static-content deployment, use themes directive.

Playbooks can only contain [actions](#actions). All the actions defined inside a playbook will be executed in sequentially manner.

<details>

<summary>Example</summary>

```yaml
...
playbooks:
  my-playbook:
  - npm:
      command: ci
      directory: some_directory
  - npm:
      command: build
      directory: some_directory
      env_vars:
        BUILD_MODE: magento
   - copy:
       app/etc/config.php: app/etc/config2.php
       app/etc/config2.php: app/etc/config3.php
...
```

</details>

Out of the box ReadyMage provides several playbooks, alongside with the possibility of defining fully custom playbooks.

#### `scandipwa`, `scandipwa_npm`

Curated, builtin playbook which is actively maintained and test against 3.x and higher ScandiPWA themes. The approximation of the curated playbook can be expressed using following [actions](#actions):

```yaml
playbooks:
  scandipwa_npm_aprox:
  - npm:
      command: ci
      directory: scandipwa
  - npm:
      command: build
      directory: scandipwa
      env_vars:
        BUILD_MODE: magento
```

#### `scandipwa_yarn`

Curated, builtin playbook which is actively maintained and test against 3.x and higher ScandiPWA themes. The approximation of the curated playbook can be expressed using following [actions](#actions):

```yaml
playbooks:
  scandipwa_yarn_aprox:
  - yarn:
      command: install --immutable --immutable-cache --check-cache
      directory: scandipwa
  - yarn:
      command: build
      directory: scandipwa
      env_vars:
        BUILD_MODE: magento
```

#### Custom

To create custom theme build/compilation logic which falls outside the curated playbooks, simply create a custom playbook where all of the necessary build actions can be defined. This can be accomplished by defining a set of actions grouped inside the playbook that will be responsible for theme compilation. The resulting playbook will be available on any environments themes playbook field.

{% hint style="info" %}
To build vanilla Magento themes, there is no need to specify playbook.
{% endhint %}

#### <mark style="color:red;">`actions`</mark>

Actions are generic, cherry-picked commands that are executed in pre-defined places inside the deployment pipeline. Actions can only be used inside [playbooks](#playbooks) or hooks.

* <mark style="color:red;">**`copy`**</mark>\
  Copies from source to destination. The path is relative to the Magento installation directory. Will overwrite file/directory if it exists at destination.
  * <mark style="color:red;">**`{source}: {destination}`**</mark>

<details>

<summary>Example</summary>

```yaml
...
- copy:
    app/etc/config.php: scandipwa/config.php
...
```

</details>

* <mark style="color:red;">**`move`**</mark>\
  Moves from source to destination. The path is relative to the Magento installation directory. Will overwrite the file/directory if it exists at destination.
  * <mark style="color:red;">**`{source}: {destination}`**</mark>

<details>

<summary>Example</summary>

```yaml
...
- move:
    app/etc/config.php: scandipwa/config.php
...
```

</details>

* #### <mark style="color:red;">`symlink`</mark>

  Creates symbolic link at the path pointing to the target. The path is relative to the Magento installation directory. The target is relative to the Magento installation directory, unless prefiexed with `persistent:` Will overwrite the file/directory if it exists at path.

  * <mark style="color:red;">**`{path}: {target}`**</mark>\
    Use `persistent:` prefix in target to set a symlink persistent and shared directory.

<details>

<summary>Example</summary>

```yaml
...
- symlink:
    app/test.xml: app/design/frontend/Ricards/test.xml
    app/test2.xml: persistent:test.xml
...
```

</details>

* #### <mark style="color:red;">`composer`</mark>

  Runs custom composer v1 or v2 commands. Use only if you have additional non-magento composer installations inside the project that have to be initialized after the main build.

  * <mark style="color:red;">**`command`**</mark> - Required.
  * <mark style="color:red;">**`version`**</mark> - Required. Allowed values: `1`, `2`
  * <mark style="color:red;">**`directory`**</mark> - Optional. If not defined, will fallback to theme directory.

{% hint style="warning" %}
Composer state should be **always** managed by `composer.json` and `composer.lock` files instead of configuration file actions!
{% endhint %}

* #### <mark style="color:red;">`npm`</mark>&#x20;
  * <mark style="color:red;">**`command`**</mark> - Required.
  * <mark style="color:red;">**`directory`**</mark> - Optional. If not defined, will fallback to theme directory.
  * <mark style="color:red;">**`env_vars`**</mark> - Optional. Nested field, contains all environmental variables that should be passed to the command

<details>

<summary>Example</summary>

```yaml
...
- npm:
    command: run build
    directory: scandipwa
    env_vars:
      BUILD_MODE: magento
...
```

</details>

* #### <mark style="color:red;">`yarn`</mark>&#x20;
  * <mark style="color:red;">**`command`**</mark> - Required.
  * <mark style="color:red;">**`directory`**</mark> - Optional. If not defined, will fallback to theme directory.
  * <mark style="color:red;">**`env_vars`**</mark> - Optional. Nested field, contains all environmental variables that should be passed to the command

<details>

<summary>Example</summary>

```yaml
...
- yarn:
    command: run build
    directory: scandipwa 
    env_vars: 
      BUILD_MODE: magento
...
```

</details>

* #### <mark style="color:red;">`php`</mark> (available on post\_deploy hooks only)&#x20;
  * <mark style="color:red;">**`command`**</mark> - Required.
  * <mark style="color:red;">**`directory`**</mark> - Optional. If not defined, will fallback to the root directory `/var/www/public/`.

<details>

<summary>Example</summary>

```yaml
...
- php:
    command: bin/magento indexer:reindex
...
```

</details>

#### <mark style="color:red;">`curl`</mark> (available on post\_deploy hooks only)&#x20;

* <mark style="color:red;">**`command`**</mark> - Required.
* <mark style="color:red;">**`directory`**</mark> - Required. Must specify an absolute path to the `/mnt/` directory.
* <mark style="color:red;">**`filename`**</mark> - Required. Must specify the name of the downloaded file.

<details>

<summary>Example</summary>

```yaml
...
- curl:
    directory: /mnt/
    filename: <filename>
    url: <download-link>
...
```

</details>

## Schema migrations

{% content-ref url="pipeline-configuration-file/migration-guide-from-0.x.x-to-1.0.0" %}
[migration-guide-from-0.x.x-to-1.0.0](https://help.readymage.com/application-management/deploy-changes-to-your-instance/pipeline-configuration-file/migration-guide-from-0.x.x-to-1.0.0)
{% endcontent-ref %}
