An open API service indexing awesome lists of open source software.

https://github.com/hellofresh/action-changed-files

GitHub Action for matrix generation based on changed files matched against regular expressions
https://github.com/hellofresh/action-changed-files

github-actions open-source wiz-reliability-platform-cloud-runtime

Last synced: 3 months ago
JSON representation

GitHub Action for matrix generation based on changed files matched against regular expressions

Awesome Lists containing this project

README

          

# action-changed-files

![GitHub release (latest by date)](https://img.shields.io/github/v/release/hellofresh/action-changed-files?style=for-the-badge)
![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/hellofresh/action-changed-files?style=for-the-badge)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/hellofresh/action-changed-files/test.yaml?label=Status&style=for-the-badge&branch=master)
![GitHub last commit](https://img.shields.io/github/last-commit/hellofresh/action-changed-files?style=for-the-badge)
![GitHub Release Date](https://img.shields.io/github/release-date/hellofresh/action-changed-files?style=for-the-badge)
![GitHub issues](https://img.shields.io/github/issues-raw/hellofresh/action-changed-files?style=for-the-badge)

![GitHub](https://img.shields.io/github/license/hellofresh/action-changed-files?style=for-the-badge)

Generate a GitHub Actions job matrix based on changed files (with an extra twist).

## Problem statement

Repositories are often composed of multiple modules or directories that are built & deployed differently. They can represent a part of the system, or a specific environment. Modules like this also often share some common files.

The (traditional) and easiest way to guarantee that all changes are properly tested in CI is to run all jobs for every single change, but this can lead to a very long verification time.

Ideally, you want to be able to trigger (and skip) jobs based on the contents (and type) of a change.

[Trigger paths](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#example-including-paths) and [matrix job strategy](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) are two great features that can help reducing verification time, but they're still not flexible enough.

## Example

### Sample repository

`neo` helps with generating a job matrix based on the changed files in a pull-request, or after merging it to the target branch.

Consider the following repository directory structure:

```
├── infrastructure
│ ├── live # depends on terraform-modules
| |── staging # depends on terraform-modules
├── library
│ ├── common
│ ├── parser # depends on library/common
│ ├── network # depends on library/common
|── terraform-modules
|── deploy.sh # used in CI to deploy infrastructure
|── Makefile # used in CI to build library
```

and that we want to:

* verify & deploy changes to infrastructure as code affecting the `live` and `staging` environments
* build & test changes to `library/parser` and `library/network`

### Sample workflow

```yaml
name: Sample workflow

on:
pull_request:
branches:
- master

jobs:
generate-matrix:
name: Generate job matrices
runs-on: ubuntu-latest
# don't forget to declare outputs here!
outputs:
matrix-infrastructure: ${{ steps.neo-infrastructure.outputs.matrix }}
matrix-library: ${{ steps.neo-library.outputs.matrix }}
steps:
- name: Generate matrix | Infrastructure
id: neo-infrastructure
uses: hellofresh/action-changed-files@v3
with:
pattern: infrastructure/(?P[^/]+)
default-patterns: |
terraform-modules
deploy.sh

- name: Generate matrix | Library
id: neo-library
uses: hellofresh/action-changed-files@v3
with:
pattern: library/(?P(?!common)[^/]+)
default-patterns: |
library/common

infrastructure:
needs: [ generate-matrix ] # don't forget this!
strategy:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-infrastructure) }}
if: ${{ fromJson(needs.generate-matrix.outputs.matrix-infrastructure).include[0] }} # skip if the matrix is empty!
steps:
- name: Deploy infrastructure
run: echo "Deploying ${{ matrix.environment }}"

build:
needs: [ generate-matrix ]
strategy:
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix-build) }}
if: ${{ fromJson(needs.generate-matrix.outputs.matrix-build).include[0] }}
steps:
- name: Building library
run: echo "Building ${{ matrix.lib }}"
```

Let's break down what will happen here with a few examples:


Changed files
Behaviour



infrastructure/live/main.tf

infrastructure/staging/main.tf



jobs.deploy[live]

jobs.deploy[staging]





library/parser/json.c

library/network/tcp.c



jobs.build[parser]

jobs.build[network]





terraform-modules/aws.tf

library/common/printer.c



jobs.deploy[live]

jobs.deploy[staging]

jobs.build[parser]

jobs.build[network]


### Change statuses

Each matrix entry in the output JSON will also be annotated with an additional `reason` field that can help handling corner-cases like deleting a directory. If all matches of a set of groups have the same status, the `reason` field will be set to it.

Example: if you use pattern `(?Pdatabase-us|database-fr)` and all files in the `database-us` directory are deleted, the job matrix will look like:

```json
[
{
"module": "database-us",
"reason": "deleted"
},
{
"module": "database-fr",
"reason": "?"
}
]
```

The same applies to any status, like `added` or `modified`.

Note: if a pattern matching to the same set of groups were caused by multiple type of changes, the `reason` field is marked as `?`.

### Logging and debugging
By default the log level for the action is `INFO` but can be overriden by setting `NEO_LOG_LEVEL` env variable
example:
```yaml
sample-job:
name: Test action
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.sample-step.outputs.matrix }}
matrix-length: ${{ steps.sample-step.outputs.matrix-length }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Generate matrix
id: sample-step
uses: hellofresh/action-changed-files@v3
env:
NEO_LOG_LEVEL: DEBUG
with:
pattern: (?P[^/]+)/
defaults: true
default-patterns: |
.github/**

```

## Reference


Input parameter name
Type
Required
Description


pattern
string
yes

Regular expression pattern with named groups. Changed files will be matched against this pattern and named groups will be extracted into the matrix. See the relevant section of the Python documentation for the syntax reference.



defaults
boolean
no

if true, and no changed files match the pattern, recursively apply the pattern on all the files of the repository to generate a matrix of all possible combinations (a.k.a. run everything for changes to common files)



default-patterns
list[string]
no

similar to the 'defaults' flag, except we match changed files on the provided UNIX-style glob pattern