tj-actions/changed-files

repository·main·Indexed 24 days ago

https://github.com/tj-actions/changed-files

A GitHub Action to retrieve added, copied, modified, deleted, renamed, type changed, unmerged, and unknown files and directories. It supports monorepos, custom comparison logic via base SHAs or timestamps, and filtering using glob patterns or YAML configurations. The action can output results as space-separated strings, JSON arrays for matrix jobs, or write them directly to files in the .github/outputs/ directory.

Tokens
7.9K
Snippets
22
Records
43
Agent score
82%

What's inside tj-actions/changed-files

  1. Overview of changed-files action

    main

    tj-actions/changed-files is a GitHub Action that tracks changed files and directories relative to a target branch, the current branch (preceding commit or last remote commit), multiple branches, or custom commits. It returns relative paths from the project root.

    Note: This action identifies files changed during specific GitHub events (like pull_request or push). It does not detect uncommitted changes created during the workflow execution. For detecting uncommitted changes, use tj-actions/verify-changed-files instead.

  2. Understand the versioning scheme

    main

    The tj-actions/changed-files GitHub Action follows Semantic Versioning (SemVer).

    • major: Significant changes or new features that may not be backward compatible.
    • minor: Minor changes or new features that are backward compatible.
    • patch: Bug fixes or other small changes that are backward compatible.
  3. Migrate file patterns to glob syntax

    main

    Starting from version v13, tj-actions/changed-files switched from using grep's Extended regex for matching files to using native workflow glob pattern matching syntax. If you are upgrading from an older version, you must update your files patterns from regex to glob patterns.

    Regex (Old):

    • \.sh$
    • .(sql|py)$
    • ^(dir1|dir2)

    Glob (New):

    • **/*.{sh,sql,py}
    • {dir1,dir2}/**
          - name: Get specific changed files
            id: changed-files-specific
            uses: tj-actions/changed-files@v24
            with:
              files: |
    -            \.sh$
    -            .(sql|py)$
    -            ^(dir1|dir2)
    +            **/*.{sh,sql,py}
    +            {dir1,dir2}/**
  4. Detect changed files in a Pull Request using GitHub API

    main

    For pull_request events, you can use GitHub's API to retrieve changed files.

    Limitations:

    • Limited to pull_request events.
    • Maximum of 3000 files can be returned.
    • Requires pull-requests: read permissions.

    This method does not require a specific fetch-depth in actions/checkout because it queries the API rather than the local git history.

    name: CI
    
    on:
      pull_request:
        branches: [main]
      merge_group:
    
    jobs:
      changed_files:
        runs-on: ubuntu-latest
        permissions:
          pull-requests: read
        steps:
          - name: Get changed files
            id: changed-files
            uses: tj-actions/changed-files@v47.0.6
    
          - name: List all changed files
            env:
              ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
            run: |
              for file in ${ALL_CHANGED_FILES}; do
                echo "$file was changed"
              done
  5. Use changed-files for matrix jobs

    main
    To use the output of changed-files as a matrix in a GitHub Actions workflow, set the json input to true. This produces a JSON array of filenames that can be passed directly to a strategy.matrix configuration. For a format specifically optimized for matrix jobs (without JSON escaping), use the matrix input instead.
  6. Configure actions/checkout for changed-files

    main

    To ensure tj-actions/changed-files can correctly detect changes, you must configure actions/checkout correctly:

    • For Push Events: Set fetch-depth to either 0 (full history) or 2 (to retrieve the preceding commit). If fetch-depth is not 0, you must also set persist-credentials: true.
    • For Pull Request Events (Mono Repositories): You can use the default fetch-depth: 1 to avoid pulling the entire branch history.
    • Matching Files: Use globstar patterns (e.g., dir_name/**) to match all files and folders under a directory.
  7. Detect changed files in a Pull Request using local .git

    main

    When running on pull_request events, you can use the local .git directory to compare the current commit against the target branch or the last pushed commit. This method provides more flexibility than the GitHub API and has no file limit.

    To compare changes between the current commit and the last pushed remote commit, set since_last_remote_commit: true.

    name: CI
    
    on: pull_request
        branches: [main]
    
    jobs:
      changed_files:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - name: Get changed files
            id: changed-files
            uses: tj-actions/changed-files@v47.0.6
            with:
              since_last_remote_commit: true
    
          - name: List all changed files
            env:
              ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
            run: |
              for file in ${ALL_CHANGED_FILES}; do
                echo "$file was changed"
              done
  8. Detect changed files on Push events

    main

    To detect changes on push events, you must use the local .git history. GitHub's API is not supported for push events.

    Ensure actions/checkout is configured with fetch-depth: 0 or 2. By default, since_last_remote_commit: true is implied and falls back to the previous local commit.

    name: CI
    
    on:
      push:
        branches: [main]
    
    jobs:
      changed_files:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
            with:
              fetch-depth: 0
    
          - name: Get changed files
            id: changed-files
            uses: tj-actions/changed-files@v47.0.6
    
          - name: List all changed files
            env:
              ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
            run: |
              for file in ${ALL_CHANGED_FILES}; do
                echo "$file was changed"
              done
  9. Get old and new names for renamed files

    main
    To retrieve both the old and new names of renamed files, you must set the include_all_old_new_renamed_files input to true. The resulting output is all_old_new_renamed_files. Note that this output is global and will not be nested within outputs generated when using the *_yaml_* inputs.
  10. Determine change detection method (Git vs REST API)

    main

    The action selects its detection strategy based on the following logic:

    1. GitHub REST API: Used if useRestApi is set to true and the event is supported (pull_request, push, or merge_group). This is useful if a local .git directory is not available (e.g., in shallow checkouts where history is missing).
    2. Local Git History: Used by default if a local .git directory is found in the specified path. This method relies on local git commands and requires a proper checkout (e.g., actions/checkout).

    Error Condition: If useRestApi is enabled but the event is not supported, the action will throw an error. If no .git directory is found and useRestApi is not enabled, the action will fail with an error instructing you to run actions/checkout first.

  11. Handle spaces in file names

    main
    While tj-actions/changed-files is designed to handle spaces in file names, using spaces in file names can introduce bugs when processing the output in bash loops. It is highly recommended to use a separator (such as a newline or a specific character) to prevent hidden issues when consuming the list of changed files in subsequent workflow steps.
  12. Handle non-ASCII filenames

    main

    To support filenames containing non-ASCII characters (e.g., test-è.txt), set quotepath to false.

        - name: Run changed-files with quotepath disabled
          id: changed-files-quotepath
          uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
          with:
            quotepath: "false"