PHPackages                             aerendir/bin-github-actions-matrix - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. aerendir/bin-github-actions-matrix

ActiveApplication[DevOps &amp; Deployment](/categories/devops)

aerendir/bin-github-actions-matrix
==================================

Updates the matrix of required status checks in branch protection rules of a repository hosted on GitHub.

2.0.1(1mo ago)02.9kMITPHPPHP ^8.3CI passing

Since Apr 18Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/Aerendir/bin-github-actions-matrix)[ Packagist](https://packagist.org/packages/aerendir/bin-github-actions-matrix)[ RSS](/packages/aerendir-bin-github-actions-matrix/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (4)Dependencies (26)Versions (13)Used By (0)

 [ ![](https://camo.githubusercontent.com/5041251627a7ec1bf9335a20531d818d198f5315fc6e12d88c4694c9dcfd5bc7/687474703a2f2f7777772e736572656e64697069747968712e636f6d2f6173736574732f6f70656e2d736f757263652d70726f6a656374732f4c6f676f2d536572656e64697069747948512d49636f6e2d546578742d507572706c652e706e67) ](http://www.serendipityhq.com)

GitHub Actions Matrix
=====================

[](#github-actions-matrix)

A CLI tool to sync configured workflows with branch protection rules.

 [![](https://camo.githubusercontent.com/9038b1cc903e29b86a7c9fc8f448b865581712cb2e177b41258c031f820b1c31/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269782e7376673f7374796c653d666c61742d737175617265)](https://github.com/Aerendir/bin-github-actions-matrix/releases) [![](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://opensource.org/licenses/MIT) [![](https://camo.githubusercontent.com/a82ddb8cc3c1259897750af768b12c3f32c000fccd8ea88a8216471e449198c0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f616572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269783f636f6c6f723d253233383839324246267374796c653d666c61742d737175617265266c6f676f3d706870)](https://github.com/Aerendir/bin-github-actions-matrix/releases)

 Supports: [![](https://camo.githubusercontent.com/1a9c384f3add7720776a98c04e69e303f8e0bfda2cb9192b0a98c540ce33abf1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d253545372e342d3333333f7374796c653d666c61742d737175617265266c6f676f3d73796d666f6e79 "Supports Symfony ^7.4")](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Amaster "Supports Symfony ^7.4") [![](https://camo.githubusercontent.com/efd0242bc44dcddb75c8d8936ab0456de2510bcb726f910e3a0ba14722ee0761/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d253545382e302d3333333f7374796c653d666c61742d737175617265266c6f676f3d73796d666f6e79 "Supports Symfony ^8.0")](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Amaster "Supports Symfony ^8.0")

 Tested with: [![](https://camo.githubusercontent.com/1a9c384f3add7720776a98c04e69e303f8e0bfda2cb9192b0a98c540ce33abf1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d253545372e342d3333333f7374796c653d666c61742d737175617265266c6f676f3d73796d666f6e79 "Supports Symfony ^7.4")](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Amaster "Supports Symfony ^7.4") [![](https://camo.githubusercontent.com/efd0242bc44dcddb75c8d8936ab0456de2510bcb726f910e3a0ba14722ee0761/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d253545382e302d3333333f7374796c653d666c61742d737175617265266c6f676f3d73796d666f6e79 "Supports Symfony ^8.0")](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Amaster "Supports Symfony ^8.0")

Current Status
--------------

[](#current-status)

[![Maintainability Rating](https://camo.githubusercontent.com/d9e54bfa38dda3f6d8e060c4fd9772b2b36d6681bdaad420cf8bcf81fa1e534f/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d7371616c655f726174696e67)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)[![Quality Gate Status](https://camo.githubusercontent.com/44623ed66823a73ea1a70c67411dc82340ae4adb3691834528e01898bb0b3c52/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)[![Reliability Rating](https://camo.githubusercontent.com/dbdfb35eb54546dc05c96de28f9e0d4d13988cce7ea598f7ad93650e1c5c949f/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d72656c696162696c6974795f726174696e67)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)[![Security Rating](https://camo.githubusercontent.com/09f3e606e532976b03ef321c32d0d7ab1850f1322a865c687dbbcc6a0a47ae8f/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d73656375726974795f726174696e67)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)[![Technical Debt](https://camo.githubusercontent.com/14ea4a6d84b5a722de3d32831692ae203fa4f38ddca0c7b4885310e52a058c5b/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d7371616c655f696e646578)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)[![Vulnerabilities](https://camo.githubusercontent.com/604d2e9fad4706c8ad8fecfbf9b5d091c2b58e918eb475fe3be4409ea3f92474/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d416572656e6469725f62696e2d6769746875622d616374696f6e732d6d6174726978266d65747269633d76756c6e65726162696c6974696573)](https://sonarcloud.io/dashboard?id=Aerendir_bin-github-actions-matrix)

[![PHPStan](https://github.com/Aerendir/bin-github-actions-matrix/workflows/PHPStan/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)[![PSalm](https://github.com/Aerendir/bin-github-actions-matrix/workflows/PSalm/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)[![PHPUnit](https://github.com/Aerendir/bin-github-actions-matrix/workflows/PHPunit/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)[![Composer](https://github.com/Aerendir/bin-github-actions-matrix/workflows/Composer/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)[![PHP CS Fixer](https://github.com/Aerendir/bin-github-actions-matrix/workflows/PHP%20CS%20Fixer/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)[![Rector](https://github.com/Aerendir/bin-github-actions-matrix/workflows/Rector/badge.svg)](https://github.com/Aerendir/bin-github-actions-matrix/actions?query=branch%3Adev)

[![codecov](https://camo.githubusercontent.com/67108d3690d90c1dc119f92fb8d48aefe4518753e081b0f8fa1e94821e8aa632/68747470733a2f2f636f6465636f762e696f2f67682f416572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269782f6272616e63682f6465762f67726170682f62616467652e7376673f746f6b656e3d695a694947756b393167)](https://codecov.io/gh/Aerendir/bin-github-actions-matrix)

[![CodeCov SunBurst](https://camo.githubusercontent.com/89b538b1c3879e4b6df57bdbcb4f2370bcdbedde830fda8c1d508c44df4d69a0/68747470733a2f2f636f6465636f762e696f2f67682f416572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269782f6272616e63682f6465762f6772617068732f73756e62757273742e7376673f746f6b656e3d695a694947756b393167)](https://codecov.io/gh/Aerendir/bin-github-actions-matrix)[![CodeCov Tree](https://camo.githubusercontent.com/f592da8e85dafdfbe61d490aa1baa5f50cf790efe950d5213b0c071ee6ac1786/68747470733a2f2f636f6465636f762e696f2f67682f416572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269782f6272616e63682f6465762f6772617068732f747265652e7376673f746f6b656e3d695a694947756b393167)](https://codecov.io/gh/Aerendir/bin-github-actions-matrix)[![CodeCov I Cicle](https://camo.githubusercontent.com/a17082ad04abb7da03dd8964beefe8b21f5b7c583ce5eb4d685be60f6eda8995/68747470733a2f2f636f6465636f762e696f2f67682f416572656e6469722f62696e2d6769746875622d616374696f6e732d6d61747269782f6272616e63682f6465762f6772617068732f696369636c652e7376673f746f6b656e3d695a694947756b393167)](https://codecov.io/gh/Aerendir/bin-github-actions-matrix)

---

###  **Do you like this library?**
 **[LEAVE A ★](#js-repo-pjax-container)**

[](#----do-you-like-this-library----leave-a-)

 or run
 `composer global require symfony/thanks && composer thanks`
 to say thank you to all libraries you use in your current project, this included!

---

Install Serendipity HQ Bin GitHub Actions Matrix
------------------------------------------------

[](#install-serendipity-hq-bin-github-actions-matrix)

```
$ composer require aerendir/bin-github-actions-matrix

```

This library follows the  versioning conventions.

Usage
-----

[](#usage)

This tool provides the `sync` command to manage GitHub branch protection rules for your repository's workflows.

### Available Commands

[](#available-commands)

#### `sync` - Sync workflows with protection rules

[](#sync---sync-workflows-with-protection-rules)

Synchronize workflows configured in the repository with the current matrix of protection rules on GitHub.

```
vendor/bin/github-actions-matrix sync [options]
```

**Options:**

- `-u, --username=USERNAME` - Your GitHub username
- `-r, --repo=REPO` - The name of the GitHub repository
- `-b, --branch=BRANCH` - The branch to sync
- `-t, --token=TOKEN` - Your GitHub access token
- `-p, --project-dir=PROJECT-DIR` - The project root that contains the `.github/workflows` folder
- `-w, --workflows-dir=WORKFLOWS-DIR` - The folder that directly contains the workflow `*.yml`/`*.yaml` files (non-standard layouts)
- `-f, --force` - Apply the changes without asking for confirmation (e.g. in CI)
- `--dry-run` - Show what would change without touching the branch protection (read-only preview)
- `--check` - CI gate: read-only, exit `0` if aligned, `1` if drift, `2` on error (implies `--dry-run`)

**Example:**

```
vendor/bin/github-actions-matrix sync --username=myuser --branch=main
```

This command will:

1. Remove obsolete protection rules
2. Add new protection rules based on your workflow matrices

Before applying any change, `sync` shows the plan and asks for confirmation. Pass `-f, --force` to skip the prompt (for example in CI).

To **verify** alignment in CI without changing anything, use `sync --check`: it is read-only and encodes the result in the exit code — `0` if the branch protection matches the workflows, `1` if it drifts, `2` on error (bad token, network, parse). See [Token permissions](#token-permissions) below.

#### Matrix expansion (`include` / `exclude`)

[](#matrix-expansion-include--exclude)

The tool expands `strategy.matrix` into the same required-check contexts GitHub generates, honouring both `exclude` and `include` with GitHub's documented semantics (see GitHub's docs: [Using a matrix for your jobs](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs), in particular [Excluding matrix configurations](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#excluding-matrix-configurations) and [Expanding or adding matrix configurations](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations)):

- **`exclude`** removes the matching combinations from the cartesian product.
- **`include`** is applied **after** `exclude`, processing its entries **in order**. An entry is merged into every base combination it does not conflict with — it may not overwrite an **original** matrix value, but it may add new keys or overwrite values added by an earlier `include` entry, and a single entry can extend many combinations. An entry that fits no base combination becomes a **new** combination. An `include`-only matrix (no other keys) produces exactly one combination per entry.

```
strategy:
  matrix:
    fruit: [apple, pear]
    animal: [cat, dog]
    include:
      - color: green
      - color: pink
        animal: cat
      - fruit: apple
        shape: circle
      - fruit: banana
```

resolves to the contexts `job (apple, cat, pink, circle)`, `job (apple, dog, green, circle)`, `job (pear, cat, pink)`, `job (pear, dog, green)` and `job (banana)` — matching GitHub exactly.

#### Non-derivable contexts (interpolated names / dynamic matrices)

[](#non-derivable-contexts-interpolated-names--dynamic-matrices)

Some required-check context names **cannot be derived statically** from the YAML, so the tool must not guess them:

- an interpolated job **name**, e.g. `name: build ${{ matrix.os }}` — GitHub shows the resolved value, not `job (values)`;
- a **dynamic matrix**, e.g. `matrix: ${{ fromJson(needs.setup.outputs.matrix) }}` or matrix keys/values built from expressions — the values do not exist as literal arrays in the file (and may even be branch-dependent).

When such a job is detected, the tool **does not compute a (wrong) context** for it and prints a clear **warning** before any change. Because it cannot know the real context name, `sync` would otherwise risk removing it, so you have two clean options:

1. **Declare the real context name** so `sync` preserves it (it is treated like an external required check and never removed): ```
    $config->addRequiredCheck('build ubuntu-latest');
    $config->addRequiredCheck('build windows-latest');
    ```
2. **Use a static "gate" job** (recommended for dynamic matrices): a single job with a static name that `needs:` the dynamic matrix job, and make *that* gate job the required check. The tool derives the gate job's context normally, and it stays green only when the whole matrix passes.

### Configuration File

[](#configuration-file)

To avoid repeatedly providing the same options, you can create a configuration file `gh-actions-matrix.php` in your project root.

#### Setup

[](#setup)

1. Copy the example configuration file:

    ```
    cp gh-actions-matrix.dist.php gh-actions-matrix.php
    ```
2. Edit `gh-actions-matrix.php` to set your default values:

    ```
