Skip to content

HarryVasanth/smart-changed-files

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ Smart Changed Files Matrix Generator

A blazing-fast, dependency-free GitHub Action that detects changed files and intelligently outputs a JSON array to power dynamic matrix strategies in your CI/CD pipelines.

Instead of waiting 10+ seconds for Node.js-based diff tools to boot up, this Composite Action runs natively in milliseconds using pure Bash, git, and jq.

✨ Features

  • ⚑️ Instant Execution: Native composite action, zero Docker startup time.
  • 🧠 Monorepo Smart: Automatically parses deeply nested file changes into their top-level application folders.
  • πŸ‘» Ghost-Job Prevention: Automatically ignores deleted folders so your matrix jobs don't crash with "folder not found".
  • πŸ›‘οΈ Regex Filtering: Effortlessly ignore documentation, tests, or config changes.
  • πŸš€ Initial Commit Safe: Gracefully handles first-time pushes without crashing.

πŸ“₯ Inputs

Input Description Required Default
target_folder The parent folder to monitor. Outputs immediate subdirectories. Use . for root. No .
exclude Comma-separated patterns to ignore (e.g., README.md,docs/,*.txt). No ""
base_sha Base commit SHA to compare against. No PR Base or Previous Push
head_sha Head commit SHA to compare. No Current SHA

πŸ“€ Outputs

Output Description Example
matrix JSON array of changed folders (drop-in ready for strategy.matrix). ["apps/web", "apps/api"]
files JSON array of exactly what files changed. ["apps/web/src/App.tsx"]
any_changed Boolean indicating if anything changed after exclusions. true or false

πŸ› οΈ Usage Examples

1. The Monorepo Matrix (Dynamic Builds)

Imagine a repository with an apps/ directory containing frontend and backend. If a pull request only modifies apps/backend/src/main.go, this workflow will dynamically only spin up a build job for the backend.

name: CI

on: [pull_request]

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.changes.outputs.matrix }}
      any_changed: ${{ steps.changes.outputs.any_changed }}
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0 # Required to accurately compare commits

      - name: Get Changed Apps
        id: changes
        uses: harryvasanth/smart-changed-files@v1
        with:
          target_folder: "apps"
          exclude: "README.md,*.md,.gitignore"

  build:
    needs: detect-changes
    if: needs.detect-changes.outputs.any_changed == 'true'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        app: ${{ fromJson(needs.detect-changes.outputs.matrix) }}

    steps:
      - uses: actions/checkout@v6
      - name: Build ${{ matrix.app }}
        run: |
          cd ${{ matrix.app }}
          npm run build

2. Simple Boolean Check

Just want to know if you should run your linting pipeline?

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Check for JS/TS changes
        id: changes
        uses: harryvasanth/smart-changed-files@v1

      - name: Run Linter
        if: steps.changes.outputs.any_changed == 'true'
        run: npm run lint

About

[πŸ“ GitHub Action] Lightning-fast changed files detection that outputs JSON arrays for dynamic GitHub Action matrices.

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages