Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54479c37f5 | ||
|
|
6d89069134 | ||
|
|
3bbaba4ae7 | ||
|
|
18c62c592a | ||
|
|
c39b06f825 | ||
|
|
4c2f8eda37 | ||
|
|
2c8123e91e | ||
|
|
e1754a427f | ||
|
|
f573054697 | ||
|
|
c3c3db7fee | ||
|
|
480e87dd66 | ||
|
|
7fcd53ac00 | ||
|
|
749fe3bb28 | ||
|
|
d7af20bab3 | ||
|
|
690b721958 | ||
|
|
77f9e6c7c6 | ||
|
|
c82a34e7e5 | ||
|
|
7a1c64e8b1 | ||
|
|
71290f02ff | ||
|
|
ecf455a884 | ||
|
|
432e0c810c | ||
|
|
fcdeb5b3d7 | ||
|
|
01e83d6024 | ||
|
|
c706c70eed | ||
|
|
d4f86e9d16 | ||
|
|
d9105a4631 | ||
|
|
0621d936c0 | ||
|
|
024cd58ac6 | ||
|
|
c9a1c56f6d | ||
|
|
54a8c99a03 | ||
|
|
9bf09145c3 | ||
|
|
c25c77a67a | ||
|
|
ea90b5ced9 | ||
|
|
d144c0c92d | ||
|
|
341b80da8b | ||
|
|
6cf9c8246e | ||
|
|
955946132d | ||
|
|
1f2cb3b00f | ||
|
|
c9124514c3 | ||
|
|
90ef0b1b22 | ||
|
|
c648759d89 | ||
|
|
b9ea510e42 |
276
.github/workflows/test.yml
vendored
276
.github/workflows/test.yml
vendored
@@ -36,10 +36,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
- name: shellcheck
|
||||
uses: reviewdog/action-shellcheck@v1.17
|
||||
uses: reviewdog/action-shellcheck@v1.18
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Run eslint on changed files
|
||||
uses: tj-actions/eslint-changed-files@v19
|
||||
if: github.event_name != 'push'
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
config_path: ".eslintrc.json"
|
||||
@@ -80,14 +80,14 @@ jobs:
|
||||
- name: Verify Changed files
|
||||
uses: tj-actions/verify-changed-files@v15
|
||||
id: changed_files
|
||||
if: github.event_name != 'push'
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
files: |
|
||||
src
|
||||
dist
|
||||
|
||||
- name: Commit files
|
||||
if: steps.changed_files.outputs.files_changed == 'true' && github.event_name != 'push'
|
||||
if: steps.changed_files.outputs.files_changed == 'true' && github.event_name == 'pull_request'
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
@@ -188,7 +188,7 @@ jobs:
|
||||
if: github.event_name == 'push'
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
@@ -245,7 +245,7 @@ jobs:
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
@@ -282,7 +282,7 @@ jobs:
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
@@ -318,7 +318,7 @@ jobs:
|
||||
input-fetch_depth: [1, 50]
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
@@ -348,7 +348,7 @@ jobs:
|
||||
if: github.event_name != 'push'
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
@@ -380,7 +380,7 @@ jobs:
|
||||
fetch-depth: [1, 2, 0]
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: ${{ matrix.fetch-depth }}
|
||||
@@ -408,7 +408,7 @@ jobs:
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download build assets
|
||||
@@ -461,7 +461,7 @@ jobs:
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download build assets
|
||||
@@ -519,7 +519,7 @@ jobs:
|
||||
fetch-depth: [0, 1, 2]
|
||||
|
||||
steps:
|
||||
- name: Checkout to branch
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
@@ -550,6 +550,205 @@ jobs:
|
||||
echo "${{ toJSON(steps.changed-files.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
test-yaml:
|
||||
name: Test changed-files with yaml
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
matrix:
|
||||
fetch-depth: [0, 1, 2]
|
||||
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
submodules: recursive
|
||||
fetch-depth: ${{ matrix.fetch-depth }}
|
||||
|
||||
- name: Download build assets
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-assets
|
||||
|
||||
- name: Run changed-files with files_yaml
|
||||
id: changed-files
|
||||
uses: ./
|
||||
with:
|
||||
files_yaml: |
|
||||
test:
|
||||
- test/**.txt
|
||||
- test/**.md
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Run changed-files with files_yaml_from_source_file
|
||||
id: changed-files-from-source-file
|
||||
uses: ./
|
||||
with:
|
||||
files_yaml_from_source_file: |
|
||||
test/changed-files.yml
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files-from-source-file.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
test_recover_deleted_file:
|
||||
name: Test changed-files recover deleted file
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
matrix:
|
||||
fetch-depth: [0, 1, 2]
|
||||
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
submodules: recursive
|
||||
fetch-depth: ${{ matrix.fetch-depth }}
|
||||
|
||||
- name: Download build assets
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-assets
|
||||
|
||||
- name: Run changed-files with recover_deleted_files
|
||||
id: changed-files-recover-deleted-files
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: "fcdeb5b3d797752d95f6dbe98552a95c29dad338"
|
||||
sha: "432e0c810c60ef1332850a971c5ec39022034b4c"
|
||||
recover_deleted_files: true
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files-recover-deleted-files.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Verify deleted files
|
||||
if: steps.changed-files-recover-deleted-files.outputs.deleted_files != 'test/test deleted.txt'
|
||||
run: |
|
||||
echo "Expected: (test/test deleted.txt) got ${{ steps.changed-files-recover-deleted-files.outputs.deleted_files }}"
|
||||
exit 1
|
||||
|
||||
- name: Verify that test/test deleted.txt is restored
|
||||
run: |
|
||||
if [ ! -f "test/test deleted.txt" ]; then
|
||||
echo "Expected: (test/test deleted.txt) to exist"
|
||||
exit 1
|
||||
else
|
||||
cat "test/test deleted.txt"
|
||||
rm "test/test deleted.txt"
|
||||
fi
|
||||
|
||||
- name: Run changed-files with recover_deleted_files and files input
|
||||
id: changed-files-recover-deleted-files-with-files
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: "fcdeb5b3d797752d95f6dbe98552a95c29dad338"
|
||||
sha: "432e0c810c60ef1332850a971c5ec39022034b4c"
|
||||
files: |
|
||||
test
|
||||
recover_deleted_files: true
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files-recover-deleted-files-with-files.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Verify deleted files
|
||||
if: steps.changed-files-recover-deleted-files-with-files.outputs.deleted_files != 'test/test deleted.txt'
|
||||
run: |
|
||||
echo "Expected: (test/test deleted.txt) got ${{ steps.changed-files-recover-deleted-files-with-files.outputs.deleted_files }}"
|
||||
exit 1
|
||||
|
||||
- name: Verify that test/test deleted.txt is restored
|
||||
run: |
|
||||
if [ ! -f "test/test deleted.txt" ]; then
|
||||
echo "Expected: (test/test deleted.txt) to exist"
|
||||
exit 1
|
||||
else
|
||||
cat "test/test deleted.txt"
|
||||
rm "test/test deleted.txt"
|
||||
fi
|
||||
|
||||
- name: Run changed-files with recover_deleted_files and files_yaml input
|
||||
id: changed-files-recover-deleted-files-with-files-yaml
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: "fcdeb5b3d797752d95f6dbe98552a95c29dad338"
|
||||
sha: "432e0c810c60ef1332850a971c5ec39022034b4c"
|
||||
files_yaml: |
|
||||
test:
|
||||
- test/**.txt
|
||||
- test/**.md
|
||||
recover_deleted_files: true
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files-recover-deleted-files-with-files-yaml.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Verify deleted files
|
||||
if: steps.changed-files-recover-deleted-files-with-files-yaml.outputs.test_deleted_files != 'test/test deleted.txt'
|
||||
run: |
|
||||
echo "Expected: (test/test deleted.txt) got ${{ steps.changed-files-recover-deleted-files-with-files-yaml.outputs.test_deleted_files }}"
|
||||
exit 1
|
||||
|
||||
- name: Verify that test/test deleted.txt is restored
|
||||
run: |
|
||||
if [ ! -f "test/test deleted.txt" ]; then
|
||||
echo "Expected: (test/test deleted.txt) to exist"
|
||||
exit 1
|
||||
else
|
||||
cat "test/test deleted.txt"
|
||||
rm "test/test deleted.txt"
|
||||
fi
|
||||
|
||||
- name: Run changed-files with recover_deleted_files and recover_deleted_files_to_destination
|
||||
id: changed-files-recover-deleted-files-to-destination
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: "fcdeb5b3d797752d95f6dbe98552a95c29dad338"
|
||||
sha: "432e0c810c60ef1332850a971c5ec39022034b4c"
|
||||
recover_deleted_files: true
|
||||
recover_deleted_files_to_destination: "deleted_files"
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo "${{ toJSON(steps.changed-files-recover-deleted-files-to-destination.outputs) }}"
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Verify deleted files
|
||||
if: steps.changed-files-recover-deleted-files-to-destination.outputs.deleted_files != 'test/test deleted.txt'
|
||||
run: |
|
||||
echo "Expected: (test/test deleted.txt) got ${{ steps.changed-files-recover-deleted-files-to-destination.outputs.deleted_files }}"
|
||||
exit 1
|
||||
|
||||
- name: Verify that test/test deleted.txt is restored
|
||||
run: |
|
||||
if [ ! -f "deleted_files/test/test deleted.txt" ]; then
|
||||
echo "Expected: (deleted_files/test/test deleted.txt) to exist"
|
||||
exit 1
|
||||
else
|
||||
cat "deleted_files/test/test deleted.txt"
|
||||
fi
|
||||
|
||||
test:
|
||||
name: Test changed-files
|
||||
@@ -849,6 +1048,13 @@ jobs:
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Check the renamed_files output
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files-1.outputs.renamed_files, 'test/test rename-1.txt')"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files-1.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Run changed-files for old new filenames test rename 2
|
||||
id: changed-files-all-old-new-renamed-files-2
|
||||
uses: ./
|
||||
@@ -869,6 +1075,48 @@ jobs:
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Check the renamed_files output
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files-2.outputs.renamed_files, 'test/test rename-2.txt')"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename-2.txt) got (${{ steps.changed-files-all-old-new-renamed-files-2.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Run changed-files for old new filenames test rename 2 output as deleted and added
|
||||
id: changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: 4d04215
|
||||
sha: fe238e6
|
||||
fetch_depth: 60000
|
||||
include_all_old_new_renamed_files: true
|
||||
output_renamed_files_as_deleted_and_added: true
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
- name: Check all_old_new_renamed_files output
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.all_old_new_renamed_files, 'test/test rename 2.txt,test/test rename-2.txt')"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename 2.txt test/test rename-2.txt) got (${{ steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.all_old_new_renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Check deleted_files output
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.deleted_files, 'test/test rename 2.txt')"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename 2.txt) got (${{ steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.deleted_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Check added_files output
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.added_files, 'test/test rename-2.txt')"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename-2.txt) got (${{ steps.changed-files-all-old-new-renamed-files-2-output-as-deleted-and-added.outputs.added_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
- name: Run changed-files with specific files
|
||||
id: changed-files-specific
|
||||
uses: ./
|
||||
|
||||
157
HISTORY.md
157
HISTORY.md
@@ -1,5 +1,162 @@
|
||||
# Changelog
|
||||
|
||||
# [36.4.0](https://github.com/tj-actions/changed-files/compare/v36.3.0...v36.4.0) - (2023-06-17)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
- Add support for returning changed file counts ([#1273](https://github.com/tj-actions/changed-files/issues/1273)) ([f573054](https://github.com/tj-actions/changed-files/commit/f573054697fceee32a3bbc0ecf27286247aabb56)) - (Tonye Jack)
|
||||
- Move deleted file recovery to leverage filter ([#1272](https://github.com/tj-actions/changed-files/issues/1272)) ([c3c3db7](https://github.com/tj-actions/changed-files/commit/c3c3db7feee6dc9447b2c03b41ae18e63e043fe2)) - (Tonye Jack)
|
||||
- Add support for recovering deleted files ([#1269](https://github.com/tj-actions/changed-files/issues/1269)) ([77f9e6c](https://github.com/tj-actions/changed-files/commit/77f9e6c7c636ec1a11598091308b26a1c1ccf131)) - (Tonye Jack)
|
||||
- Add support for recovering deleted files ([d9105a4](https://github.com/tj-actions/changed-files/commit/d9105a4631593f0dc11f3ae6bfbcb5ac43625523)) - (Tonye Jack)
|
||||
|
||||
## <!-- 16 -->➕ Add
|
||||
|
||||
- Added deleted file
|
||||
([fcdeb5b](https://github.com/tj-actions/changed-files/commit/fcdeb5b3d797752d95f6dbe98552a95c29dad338)) - (Tonye Jack)
|
||||
- Added missing changes and modified dist assets.
|
||||
([01e83d6](https://github.com/tj-actions/changed-files/commit/01e83d602481802f6822004896b864b1e5e56cfb)) - (GitHub Action)
|
||||
|
||||
## <!-- 17 -->➖ Remove
|
||||
|
||||
- Removed test file
|
||||
([432e0c8](https://github.com/tj-actions/changed-files/commit/432e0c810c60ef1332850a971c5ec39022034b4c)) - (Tonye Jack)
|
||||
|
||||
## <!-- 26 -->🔄 Update
|
||||
|
||||
- Updated README.md ([#1274](https://github.com/tj-actions/changed-files/issues/1274))
|
||||
|
||||
Co-authored-by: repo-ranger[bot] <repo-ranger[bot]@users.noreply.github.com> ([e1754a4](https://github.com/tj-actions/changed-files/commit/e1754a427f478b8778d349341b8f1d80f1f47f44)) - (tj-actions[bot])
|
||||
- Updated README.md ([#1270](https://github.com/tj-actions/changed-files/issues/1270))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([7fcd53a](https://github.com/tj-actions/changed-files/commit/7fcd53ac001f9faf1b1f57a58e10cd958da114ed)) - (tj-actions[bot])
|
||||
- Update README.md ([d7af20b](https://github.com/tj-actions/changed-files/commit/d7af20bab3d42577ec79dffc4e793c14d0df65b3)) - (Tonye Jack)
|
||||
- Update README.md ([690b721](https://github.com/tj-actions/changed-files/commit/690b721958b0220fa3f827e13559c5023d277b61)) - (Tonye Jack)
|
||||
- Updated the test
|
||||
([c82a34e](https://github.com/tj-actions/changed-files/commit/c82a34e7e5e87a5c69ee4aff0facae82e5177e3b)) - (Tonye Jack)
|
||||
- Updated the test
|
||||
([7a1c64e](https://github.com/tj-actions/changed-files/commit/7a1c64e8b15493fe087b9289d565d0502f1a97ab)) - (Tonye Jack)
|
||||
- Updated dist assets
|
||||
([71290f0](https://github.com/tj-actions/changed-files/commit/71290f02ff8f886712b65679f29e64216aa3e131)) - (Tonye Jack)
|
||||
- Updated test
|
||||
([ecf455a](https://github.com/tj-actions/changed-files/commit/ecf455a884019154bc08fa00fa237fd5a07b2287)) - (Tonye Jack)
|
||||
- Update README.md ([024cd58](https://github.com/tj-actions/changed-files/commit/024cd58ac6e73a0f9617287edc3954db32e85394)) - (Tonye Jack)
|
||||
- Update README.md ([c9a1c56](https://github.com/tj-actions/changed-files/commit/c9a1c56f6da50ec6d7986486064919eaeea692cc)) - (Tonye Jack)
|
||||
|
||||
## <!-- 30 -->📝 Other
|
||||
|
||||
- Merge branch 'feat/add-support-for-recovering-deleted-files'
|
||||
([749fe3b](https://github.com/tj-actions/changed-files/commit/749fe3bb283cc8d46fc71f976e78eb6e1669f37d)) - (Tonye Jack)
|
||||
- Merge d4f86e9d1689a5d2ddb94e173669f31cc3497351 into 0621d936c0d15c7a5a116268ea1f7c362b76c50b
|
||||
([c706c70](https://github.com/tj-actions/changed-files/commit/c706c70eed92c7d5843cd3921da0a078663423e8)) - (Tonye Jack)
|
||||
- Merge branch 'main' into feat/add-support-for-recovering-deleted-files ([d4f86e9](https://github.com/tj-actions/changed-files/commit/d4f86e9d1689a5d2ddb94e173669f31cc3497351)) - (Tonye Jack)
|
||||
|
||||
## <!-- 7 -->⚙️ Miscellaneous Tasks
|
||||
|
||||
- **deps:** Lock file maintenance ([#1271](https://github.com/tj-actions/changed-files/issues/1271)) ([480e87d](https://github.com/tj-actions/changed-files/commit/480e87dd66bdf2a6036db2fd2ea72906a92cfde2)) - (renovate[bot])
|
||||
- **deps:** Update dependency eslint to v8.43.0 ([#1268](https://github.com/tj-actions/changed-files/issues/1268)) ([0621d93](https://github.com/tj-actions/changed-files/commit/0621d936c0d15c7a5a116268ea1f7c362b76c50b)) - (renovate[bot])
|
||||
|
||||
## <!-- 9 -->⬆️ Upgrades
|
||||
|
||||
- Upgraded to v36.3.0 ([#1267](https://github.com/tj-actions/changed-files/issues/1267))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([54a8c99](https://github.com/tj-actions/changed-files/commit/54a8c99a03eb57f7f561696dd7879bea7587e469)) - (tj-actions[bot])
|
||||
|
||||
# [36.3.0](https://github.com/tj-actions/changed-files/compare/v36.2.1...v36.3.0) - (2023-06-16)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
- Add support for complex filters ([#1265](https://github.com/tj-actions/changed-files/issues/1265)) ([c25c77a](https://github.com/tj-actions/changed-files/commit/c25c77a67a4da177bd7550612cacb74714d054f6)) - (Tonye Jack)
|
||||
|
||||
## <!-- 26 -->🔄 Update
|
||||
|
||||
- Updated README.md ([#1266](https://github.com/tj-actions/changed-files/issues/1266))
|
||||
|
||||
Co-authored-by: repo-ranger[bot] <repo-ranger[bot]@users.noreply.github.com> ([9bf0914](https://github.com/tj-actions/changed-files/commit/9bf09145c3560e451e8d8e87b42ccb3fef5b692d)) - (tj-actions[bot])
|
||||
- Updated README.md ([#1264](https://github.com/tj-actions/changed-files/issues/1264))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com>
|
||||
Co-authored-by: GitHub Action <action@github.com> ([d144c0c](https://github.com/tj-actions/changed-files/commit/d144c0c92d678494b332227c803cea83b4f7bdee)) - (tj-actions[bot])
|
||||
- Update README.md ([341b80d](https://github.com/tj-actions/changed-files/commit/341b80da8b4d69e7a389dc6f2df8c8ee41ea5736)) - (Tonye Jack)
|
||||
|
||||
## <!-- 7 -->⚙️ Miscellaneous Tasks
|
||||
|
||||
- Update test.yml ([ea90b5c](https://github.com/tj-actions/changed-files/commit/ea90b5ced9a0c8d0d18077656d2ecada2bb67ff3)) - (Tonye Jack)
|
||||
- Move check out of loop ([6cf9c82](https://github.com/tj-actions/changed-files/commit/6cf9c8246e3225cbcdc00d6c86ba6d6a05b2e231)) - (Tonye Jack)
|
||||
- **deps:** Lock file maintenance ([#1263](https://github.com/tj-actions/changed-files/issues/1263)) ([9559461](https://github.com/tj-actions/changed-files/commit/955946132d0133d584404b86a03462e591ff30b3)) - (renovate[bot])
|
||||
|
||||
## <!-- 9 -->⬆️ Upgrades
|
||||
|
||||
- Upgraded to v36.2.1 ([#1262](https://github.com/tj-actions/changed-files/issues/1262))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([1f2cb3b](https://github.com/tj-actions/changed-files/commit/1f2cb3b00f32f8700ede1b03398337e39a64d448)) - (tj-actions[bot])
|
||||
|
||||
# [36.2.1](https://github.com/tj-actions/changed-files/compare/v36.2.0...v36.2.1) - (2023-06-14)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
- Add support for outputting renamed files as deleted and added ([#1260](https://github.com/tj-actions/changed-files/issues/1260)) ([90ef0b1](https://github.com/tj-actions/changed-files/commit/90ef0b1b22b674a0dea8c832029e63eed9fb8e13)) - (Tonye Jack)
|
||||
|
||||
## <!-- 26 -->🔄 Update
|
||||
|
||||
- Updated README.md ([#1261](https://github.com/tj-actions/changed-files/issues/1261))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([c912451](https://github.com/tj-actions/changed-files/commit/c9124514c375de5dbb9697afa6f2e36a236ee58c)) - (tj-actions[bot])
|
||||
|
||||
## <!-- 7 -->⚙️ Miscellaneous Tasks
|
||||
|
||||
- Rename git fetch arguments ([#1259](https://github.com/tj-actions/changed-files/issues/1259)) ([b9ea510](https://github.com/tj-actions/changed-files/commit/b9ea510e42795d425d659914078b74f51c774869)) - (Tonye Jack)
|
||||
|
||||
## <!-- 9 -->⬆️ Upgrades
|
||||
|
||||
- Upgraded to v36.2.0 ([#1258](https://github.com/tj-actions/changed-files/issues/1258))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com>
|
||||
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com> ([c648759](https://github.com/tj-actions/changed-files/commit/c648759d899fd6217a96579680bdae3ac01e6219)) - (tj-actions[bot])
|
||||
|
||||
# [36.2.0](https://github.com/tj-actions/changed-files/compare/v36.1.0...v36.2.0) - (2023-06-14)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
- Switch to use name status ([#1230](https://github.com/tj-actions/changed-files/issues/1230)) ([174a2a6](https://github.com/tj-actions/changed-files/commit/174a2a6360b54a2019877c254c4be78106efc94f)) - (Tonye Jack)
|
||||
|
||||
## <!-- 26 -->🔄 Update
|
||||
|
||||
- Updated README.md ([#1255](https://github.com/tj-actions/changed-files/issues/1255))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([2c6893c](https://github.com/tj-actions/changed-files/commit/2c6893c21a91f8238df9e0ed2f3e4488efc0629f)) - (tj-actions[bot])
|
||||
- Update action.yml ([17ca5bb](https://github.com/tj-actions/changed-files/commit/17ca5bb3e554d4d9b631e09414186b64b6e64cd6)) - (Tonye Jack)
|
||||
- Updated README.md ([#1249](https://github.com/tj-actions/changed-files/issues/1249))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com> ([a625ca3](https://github.com/tj-actions/changed-files/commit/a625ca325f498d75648b0ec941834edc16e71a40)) - (tj-actions[bot])
|
||||
- Updated README.md ([#1248](https://github.com/tj-actions/changed-files/issues/1248))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com>
|
||||
Co-authored-by: Tonye Jack <jtonye@ymail.com> ([752970e](https://github.com/tj-actions/changed-files/commit/752970edd01e2a1b9e1a9ef37207bd59a34c90f4)) - (tj-actions[bot])
|
||||
- Update action.yml ([7b64c76](https://github.com/tj-actions/changed-files/commit/7b64c76932d2ddd0a2be638832dc8f72eacec74c)) - (Tonye Jack)
|
||||
- Updated README.md ([#1246](https://github.com/tj-actions/changed-files/issues/1246))
|
||||
|
||||
Co-authored-by: repo-ranger[bot] <repo-ranger[bot]@users.noreply.github.com> ([9333a5c](https://github.com/tj-actions/changed-files/commit/9333a5cf0c1a85e3dd5876284bb075ade076a9e0)) - (tj-actions[bot])
|
||||
|
||||
## <!-- 7 -->⚙️ Miscellaneous Tasks
|
||||
|
||||
- **deps:** Update peter-evans/create-pull-request action to v5.0.2 ([#1256](https://github.com/tj-actions/changed-files/issues/1256)) ([2d0b52f](https://github.com/tj-actions/changed-files/commit/2d0b52f4408b791c0c5c1eca405d8461b320dd01)) - (renovate[bot])
|
||||
- **deps:** Update typescript-eslint monorepo to v5.59.11 ([#1253](https://github.com/tj-actions/changed-files/issues/1253)) ([d0e3a7c](https://github.com/tj-actions/changed-files/commit/d0e3a7c3aa15c15ace59f95a9fda1bcadf9ab3e2)) - (renovate[bot])
|
||||
- **deps:** Lock file maintenance ([#1252](https://github.com/tj-actions/changed-files/issues/1252)) ([61845c2](https://github.com/tj-actions/changed-files/commit/61845c2b19ec2ad7e3d79a6955e192e66d41cb80)) - (renovate[bot])
|
||||
- **deps:** Update tj-actions/verify-changed-files action to v15 ([#1251](https://github.com/tj-actions/changed-files/issues/1251)) ([417f924](https://github.com/tj-actions/changed-files/commit/417f924dea3b9800ea861d576eee55162ab6607c)) - (renovate[bot])
|
||||
- **deps:** Lock file maintenance ([#1250](https://github.com/tj-actions/changed-files/issues/1250)) ([c51a48d](https://github.com/tj-actions/changed-files/commit/c51a48d4f6bf95820aa0f9e3f3e6516bd427ae7a)) - (renovate[bot])
|
||||
- Update README.md ([6d9ee62](https://github.com/tj-actions/changed-files/commit/6d9ee62035acb0c3942fba9757033c677246f2f4)) - (Tonye Jack)
|
||||
- Update README.md ([b27dcc2](https://github.com/tj-actions/changed-files/commit/b27dcc252ada558d34ecd368bd253994df77acb1)) - (Tonye Jack)
|
||||
- **deps:** Update dependency @types/uuid to v9.0.2 ([#1247](https://github.com/tj-actions/changed-files/issues/1247)) ([b60e479](https://github.com/tj-actions/changed-files/commit/b60e479ceab551d9a8f832d5a989eb3e492d4bf4)) - (renovate[bot])
|
||||
- Update README.md ([#1237](https://github.com/tj-actions/changed-files/issues/1237)) ([8ec721e](https://github.com/tj-actions/changed-files/commit/8ec721eb3b7d57b7afc0d63748bd7242292989b1)) - (tj-actions[bot])
|
||||
- Update README.md ([#1240](https://github.com/tj-actions/changed-files/issues/1240)) ([7d1d4d2](https://github.com/tj-actions/changed-files/commit/7d1d4d2cce628fd1797af3acb779dd1d26b61d31)) - (tj-actions[bot])
|
||||
|
||||
## <!-- 9 -->⬆️ Upgrades
|
||||
|
||||
- Upgraded to v36.1.0 ([#1245](https://github.com/tj-actions/changed-files/issues/1245))
|
||||
|
||||
Co-authored-by: jackton1 <jackton1@users.noreply.github.com>
|
||||
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com> ([ab84931](https://github.com/tj-actions/changed-files/commit/ab8493166b33b74edc5101f3e814b63cd87f05ab)) - (tj-actions[bot])
|
||||
|
||||
# [36.1.0](https://github.com/tj-actions/changed-files/compare/v36.0.18...v36.1.0) - (2023-06-08)
|
||||
|
||||
## <!-- 0 -->🚀 Features
|
||||
|
||||
164
README.md
164
README.md
@@ -19,7 +19,7 @@
|
||||
|
||||
## changed-files
|
||||
|
||||
Retrieve all changed files and directories relative to a target branch, preceeding commit or the last remote commit returning **relative paths** from the project root.
|
||||
Effortlessly track all changed files and directories relative to a target branch, preceding commit or the last remote commit returning **relative paths** from the project root.
|
||||
|
||||
## Table of contents
|
||||
|
||||
@@ -39,29 +39,36 @@ Retrieve all changed files and directories relative to a target branch, preceedi
|
||||
|
||||
## Features
|
||||
|
||||
* Fast execution (0-10 seconds on average).
|
||||
* Easy to debug.
|
||||
* Scales to large repositories.
|
||||
* Provides fast execution, averaging 0-10 seconds.
|
||||
* Facilitates easy debugging.
|
||||
* Scales to handle large repositories.
|
||||
* Supports Git submodules.
|
||||
* Escaped JSON output which can be used to run matrix jobs based on changed files.
|
||||
* List changed directories.
|
||||
* Limit the matching changed directories to a maximum depth.
|
||||
* Optionally exclude the current directory
|
||||
* Write outputs to a `.txt` or `.json` file at a specified location for further processing.
|
||||
* Monorepos (Fetches a fixed number of commits).
|
||||
* Supports all platforms (Linux, MacOS, Windows).
|
||||
* [GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) support
|
||||
* [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.3/admin/github-actions/getting-started-with-github-actions-for-your-enterprise/getting-started-with-github-actions-for-github-enterprise-server) support.
|
||||
* [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) support.
|
||||
* List all files and directories that have changed:
|
||||
* Generates escaped JSON output for running matrix jobs based on changed files.
|
||||
* Lists changed directories.
|
||||
* Allows limiting the matching changed directories to a specified maximum depth.
|
||||
* Optionally excludes the current directory.
|
||||
* Writes outputs to a designated `.txt` or `.json` file for further processing.
|
||||
* Restores deleted files to their previous location or a newly specified location.
|
||||
* Supports Monorepos by fetching a fixed number of commits.
|
||||
* Compatible with all platforms (Linux, MacOS, Windows).
|
||||
* Supports [GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners).
|
||||
* Supports [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.3/admin/github-actions/getting-started-with-github-actions-for-your-enterprise/getting-started-with-github-actions-for-github-enterprise-server).
|
||||
* Supports [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners).
|
||||
* Lists all files and directories that have changed:
|
||||
* Between the current pull request branch and the last commit on the target branch.
|
||||
* Between the last commit and the current pushed change.
|
||||
* Between the last remote branch commit and the current HEAD.
|
||||
* Restrict change detection to a subset of files and directories:
|
||||
* Boolean output indicating that certain files have been changed.
|
||||
* Using [Glob pattern](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet) matching.
|
||||
* Globstar.
|
||||
* Brace expansion.
|
||||
* Restricts change detection to a subset of files and directories:
|
||||
* Provides boolean output indicating changes in specific files.
|
||||
* Uses [Glob pattern](https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet) matching.
|
||||
* Supports Globstar.
|
||||
* Supports brace expansion.
|
||||
* Supports negation.
|
||||
* Uses [YAML](https://yaml.org/) syntax for specifying patterns.
|
||||
* Supports [YAML anchors & aliases](https://www.educative.io/blog/advanced-yaml-syntax-cheatsheet#anchors).
|
||||
* Supports [YAML multi-line strings](https://learnxinyminutes.com/docs/yaml/).
|
||||
|
||||
And many more.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -69,9 +76,9 @@ Retrieve all changed files and directories relative to a target branch, preceedi
|
||||
>
|
||||
> * **IMPORTANT:** For `push` events when configuring [`actions/checkout`](https://github.com/actions/checkout#usage) the `fetch-depth` should be set to either `fetch-depth: 0` **OR** `fetch-depth: 2` depending on your use case.
|
||||
> * For monorepos where pulling all the branch history might not be desired, you can omit [`actions/checkout`](https://github.com/actions/checkout#usage) - `fetch-depth` for `pull_request` events.
|
||||
> * All multiline inputs should not use double or single quotes since the value is already a string seperated by a newline character. See [Examples](#examples) for more information.
|
||||
> * All multiline inputs should not use double or single quotes since the value is already a string separated by a newline character. See [Examples](#examples) for more information.
|
||||
> * Ensure that `persist-credentials` is set to `true` when configuring [`actions/checkout`](https://github.com/actions/checkout#usage) if `fetch-depth` isn't set to `0`.
|
||||
> * For repositories that have PR's generated from forks when configuring [`actions/checkout`](https://github.com/actions/checkout#usage) set the `repository` to `${{ github.event.pull_request.head.repo.full_name }}`. See: [Example](https://github.com/tj-actions/changed-files/blob/main/.github/workflows/test.yml#L47-L51)
|
||||
> * For repositories that have PRs generated from forks when configuring [`actions/checkout`](https://github.com/actions/checkout#usage) set the `repository` to `${{ github.event.pull_request.head.repo.full_name }}`. See: [Example](https://github.com/tj-actions/changed-files/blob/main/.github/workflows/test.yml#L47-L51)
|
||||
|
||||
```yaml
|
||||
name: CI
|
||||
@@ -85,7 +92,7 @@ on:
|
||||
- main
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
# Event `push`: Compare the preceeding commit -> to the current commit of the main branch.
|
||||
# Event `push`: Compare the preceding commit -> to the current commit of the main branch.
|
||||
# Event `pull_request`: Compare the last commit of main -> to the current commit of a Pull Request branch.
|
||||
# ------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -141,6 +148,35 @@ jobs:
|
||||
run: |
|
||||
echo "One or more .js file(s) or any file in the static folder but not in the doc folder has changed."
|
||||
echo "List all the files that have changed: ${{ steps.changed-files-excluded.outputs.all_changed_files }}"
|
||||
|
||||
# Example 4
|
||||
- name: Get all test, doc and src files that have changed
|
||||
id: changed-files-yml
|
||||
uses: tj-actions/changed-files@v36
|
||||
with:
|
||||
files_yaml: |
|
||||
doc:
|
||||
- *.md
|
||||
- docs/**
|
||||
- !docs/README.md
|
||||
test:
|
||||
- test/**
|
||||
- !test/README.md
|
||||
src:
|
||||
- src/**
|
||||
# Optionally set `files_yaml_from_source_file` to read the YAML from a file. e.g `files_yaml_from_source_file: .github/changed-files.yml`
|
||||
|
||||
- name: Run step if test file(s) change
|
||||
if: steps.changed-files-yml.outputs.test_any_changed == 'true'
|
||||
run: |
|
||||
echo "One or more test file(s) has changed."
|
||||
echo "List all the files that have changed: ${{ steps.changed-files-yml.outputs.test_all_changed_files }}"
|
||||
|
||||
- name: Run step if doc file(s) change
|
||||
if: steps.changed-files-yml.outputs.doc_any_changed == 'true'
|
||||
run: |
|
||||
echo "One or more doc file(s) has changed."
|
||||
echo "List all the files that have changed: ${{ steps.changed-files-yml.outputs.doc_all_changed_files }}"
|
||||
```
|
||||
|
||||
To access more examples, navigate to the [Examples](#examples) section.
|
||||
@@ -172,29 +208,44 @@ Support this project with a :star:
|
||||
|
||||
<!-- AUTO-DOC-OUTPUT:START - Do not remove or modify this section -->
|
||||
|
||||
| OUTPUT | TYPE | DESCRIPTION |
|
||||
|--------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| added\_files | string | Returns only files that are <br>Added (A). |
|
||||
| all\_changed\_and\_modified\_files | string | Returns all changed and modified <br>files i.e. *a combination of (ACMRDTUX)* |
|
||||
| all\_changed\_files | string | Returns all changed files i.e. <br>*a combination of all added, copied, modified and renamed files (ACMR)* |
|
||||
| all\_modified\_files | string | Returns all changed files i.e. <br>*a combination of all added, copied, modified, renamed and deleted files (ACMRD)*. |
|
||||
| all\_old\_new\_renamed\_files | string | Returns only files that are <br>Renamed and list their old <br>and new names. **NOTE:** This <br>requires setting `include_all_old_new_renamed_files` to `true` <br>(R) |
|
||||
| any\_changed | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has changed. i.e. <br>*using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| any\_deleted | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has been deleted. <br>(D) |
|
||||
| any\_modified | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has been modified. <br>i.e. *using a combination of all added, copied, modified, renamed, and deleted files (ACMRD)*. |
|
||||
| copied\_files | string | Returns only files that are <br>Copied (C). |
|
||||
| deleted\_files | string | Returns only files that are <br>Deleted (D). |
|
||||
| modified\_files | string | Returns only files that are <br>Modified (M). |
|
||||
| only\_changed | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has changed. i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| only\_deleted | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has been deleted. (D) |
|
||||
| only\_modified | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has been modified. (ACMRD). |
|
||||
| other\_changed\_files | string | Returns all other changed files <br>not listed in the files <br>input i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| other\_deleted\_files | string | Returns all other deleted files <br>not listed in the files <br>input i.e. *a combination of all deleted files (D)* |
|
||||
| other\_modified\_files | string | Returns all other modified files <br>not listed in the files <br>input i.e. *a combination of all added, copied, modified, and deleted files (ACMRD)* |
|
||||
| renamed\_files | string | Returns only files that are <br>Renamed (R). |
|
||||
| type\_changed\_files | string | Returns only files that have <br>their file type changed (T). |
|
||||
| unknown\_files | string | Returns only files that are <br>Unknown (X). |
|
||||
| unmerged\_files | string | Returns only files that are <br>Unmerged (U). |
|
||||
| OUTPUT | TYPE | DESCRIPTION |
|
||||
|--------------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| added\_files | string | Returns only files that are <br>Added (A). |
|
||||
| added\_files\_count | string | Returns the number of `added_files` |
|
||||
| all\_changed\_and\_modified\_files | string | Returns all changed and modified <br>files i.e. *a combination of (ACMRDTUX)* |
|
||||
| all\_changed\_and\_modified\_files\_count | string | Returns the number of `all_changed_and_modified_files` |
|
||||
| all\_changed\_files | string | Returns all changed files i.e. <br>*a combination of all added, copied, modified and renamed files (ACMR)* |
|
||||
| all\_changed\_files\_count | string | Returns the number of `all_changed_files` |
|
||||
| all\_modified\_files | string | Returns all changed files i.e. <br>*a combination of all added, copied, modified, renamed and deleted files (ACMRD)*. |
|
||||
| all\_modified\_files\_count | string | Returns the number of `all_modified_files` |
|
||||
| all\_old\_new\_renamed\_files | string | Returns only files that are <br>Renamed and lists their old <br>and new names. **NOTE:** This <br>requires setting `include_all_old_new_renamed_files` to `true`. <br>Also, keep in mind that <br>this output is global and <br>wouldn't be nested in outputs <br>generated when the `*_yaml_*` input <br>is used. (R) |
|
||||
| all\_old\_new\_renamed\_files\_count | string | Returns the number of `all_old_new_renamed_files` |
|
||||
| any\_changed | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has changed. i.e. <br>*using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| any\_deleted | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has been deleted. <br>(D) |
|
||||
| any\_modified | string | Returns `true` when any of <br>the filenames provided using the <br>`files*` or `files_ignore*` inputs has been modified. <br>i.e. *using a combination of all added, copied, modified, renamed, and deleted files (ACMRD)*. |
|
||||
| copied\_files | string | Returns only files that are <br>Copied (C). |
|
||||
| copied\_files\_count | string | Returns the number of `copied_files` |
|
||||
| deleted\_files | string | Returns only files that are <br>Deleted (D). |
|
||||
| deleted\_files\_count | string | Returns the number of `deleted_files` |
|
||||
| modified\_files | string | Returns only files that are <br>Modified (M). |
|
||||
| modified\_files\_count | string | Returns the number of `modified_files` |
|
||||
| only\_changed | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has changed. i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| only\_deleted | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has been deleted. (D) |
|
||||
| only\_modified | string | Returns `true` when only files <br>provided using the `files*` or `files_ignore*` inputs <br>has been modified. (ACMRD). |
|
||||
| other\_changed\_files | string | Returns all other changed files <br>not listed in the files <br>input i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*. |
|
||||
| other\_changed\_files\_count | string | Returns the number of `other_changed_files` |
|
||||
| other\_deleted\_files | string | Returns all other deleted files <br>not listed in the files <br>input i.e. *a combination of all deleted files (D)* |
|
||||
| other\_deleted\_files\_count | string | Returns the number of `other_deleted_files` |
|
||||
| other\_modified\_files | string | Returns all other modified files <br>not listed in the files <br>input i.e. *a combination of all added, copied, modified, and deleted files (ACMRD)* |
|
||||
| other\_modified\_files\_count | string | Returns the number of `other_modified_files` |
|
||||
| renamed\_files | string | Returns only files that are <br>Renamed (R). |
|
||||
| renamed\_files\_count | string | Returns the number of `renamed_files` |
|
||||
| type\_changed\_files | string | Returns only files that have <br>their file type changed (T). |
|
||||
| type\_changed\_files\_count | string | Returns the number of `type_changed_files` |
|
||||
| unknown\_files | string | Returns only files that are <br>Unknown (X). |
|
||||
| unknown\_files\_count | string | Returns the number of `unknown_files` |
|
||||
| unmerged\_files | string | Returns only files that are <br>Unmerged (U). |
|
||||
| unmerged\_files\_count | string | Returns the number of `unmerged_files` |
|
||||
|
||||
<!-- AUTO-DOC-OUTPUT:END -->
|
||||
|
||||
@@ -212,25 +263,34 @@ Support this project with a :star:
|
||||
| dir\_names\_max\_depth | string | false | | Limit the directory output to <br>a maximum depth e.g `test/test1/test2` <br>with max depth of `2` <br>returns `test/test1`. |
|
||||
| escape\_json | string | false | `"true"` | Escape JSON output. |
|
||||
| fetch\_depth | string | false | `"50"` | Depth of additional branch history <br>fetched. **NOTE**: This can be <br>adjusted to resolve errors with <br>insufficient history. |
|
||||
| files | string | false | | File and directory patterns to <br>detect changes using only these <br>list of file(s) (Defaults to the entire repo) **NOTE:** <br>Multiline file/directory patterns should not <br>include quotes. |
|
||||
| files | string | false | | File and directory patterns used <br>to detect changes (Defaults to the entire repo if unset) **NOTE:** <br>Multiline file/directory patterns should not <br>include quotes. |
|
||||
| files\_from\_source\_file | string | false | | Source file(s) used to populate <br>the `files` input. |
|
||||
| files\_from\_source\_file\_separator | string | false | `"\n"` | Separator used to split the <br>`files_from_source_file` input |
|
||||
| files\_ignore | string | false | | Ignore changes to these file(s) <br>**NOTE:** Multiline file/directory patterns should <br>not include quotes. |
|
||||
| files\_ignore\_from\_source\_file | string | false | | Source file(s) used to populate <br>the `files_ignore` input |
|
||||
| files\_ignore\_from\_source\_file\_separator | string | false | `"\n"` | Separator used to split the <br>`files_ignore_from_source_file` input |
|
||||
| files\_ignore\_separator | string | false | `"\n"` | Separator used to split the <br>`files_ignore` input |
|
||||
| files\_ignore\_yaml | string | false | | YAML used to define a <br>set of file patterns to <br>ignore changes |
|
||||
| files\_ignore\_yaml\_from\_source\_file | string | false | | Source file(s) used to populate <br>the `files_ignore_yaml` input. [Example](https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml) |
|
||||
| files\_ignore\_yaml\_from\_source\_file\_separator | string | false | `"\n"` | Separator used to split the <br>`files_ignore_yaml_from_source_file` input |
|
||||
| files\_separator | string | false | `"\n"` | Separator used to split the <br>`files` input |
|
||||
| files\_yaml | string | false | | YAML used to define a <br>set of file patterns to <br>detect changes |
|
||||
| files\_yaml\_from\_source\_file | string | false | | Source file(s) used to populate <br>the `files_yaml` input. [Example](https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml) |
|
||||
| files\_yaml\_from\_source\_file\_separator | string | false | `"\n"` | Separator used to split the <br>`files_yaml_from_source_file` input |
|
||||
| include\_all\_old\_new\_renamed\_files | string | false | `"false"` | Include `all_old_new_renamed_files` output. Note this <br>can generate a large output <br>See: [#501](https://github.com/tj-actions/changed-files/issues/501). |
|
||||
| json | string | false | `"false"` | Output list of changed files <br>in a JSON formatted string <br>which can be used for <br>matrix jobs. |
|
||||
| old\_new\_files\_separator | string | false | `" "` | Split character for old and <br>new renamed filename pairs. |
|
||||
| old\_new\_separator | string | false | `","` | Split character for old and <br>new filename pairs. |
|
||||
| output\_dir | string | false | `".github/outputs"` | Directory to store output files. |
|
||||
| output\_renamed\_files\_as\_deleted\_and\_added | string | false | `"false"` | Output renamed files as deleted <br>and added files. |
|
||||
| path | string | false | `"."` | Specify a relative path under <br>`$GITHUB_WORKSPACE` to locate the repository. |
|
||||
| quotepath | string | false | `"true"` | Use non ascii characters to <br>match files and output the <br>filenames completely verbatim by setting <br>this to `false` |
|
||||
| quotepath | string | false | `"true"` | Use non-ascii characters to match <br>files and output the filenames <br>completely verbatim by setting this <br>to `false` |
|
||||
| recover\_deleted\_files | string | false | `"false"` | Recover deleted files. |
|
||||
| recover\_deleted\_files\_to\_destination | string | false | | Recover deleted files to a <br>new destination directory, defaults to <br>the original location. |
|
||||
| separator | string | false | `" "` | Split character for output strings |
|
||||
| sha | string | false | | Specify a different commit SHA <br>used for comparing changes |
|
||||
| since | string | false | | Get changed files for commits <br>whose timestamp is older than <br>the given time. |
|
||||
| since\_last\_remote\_commit | string | false | `"false"` | Use the last commit on <br>the remote branch as the <br>`base_sha`. Defaults to the last <br>non merge commit on the <br>target branch for pull request <br>events and the previous remote <br>commit of the current branch <br>for push events. |
|
||||
| since\_last\_remote\_commit | string | false | `"false"` | Use the last commit on <br>the remote branch as the <br>`base_sha`. Defaults to the last <br>non-merge commit on the target <br>branch for pull request events <br>and the previous remote commit <br>of the current branch for <br>push events. |
|
||||
| until | string | false | | Get changed files for commits <br>whose timestamp is earlier than <br>the given time. |
|
||||
| write\_output\_files | string | false | `"false"` | Write outputs to the `output_dir` <br>defaults to `.github/outputs` folder. **NOTE:** <br>This creates a `.txt` file <br>by default and a `.json` <br>file if `json` is set <br>to `true`. |
|
||||
|
||||
@@ -242,11 +302,11 @@ This GitHub Action follows the principles of [Semantic Versioning](https://semve
|
||||
|
||||
The format of the version string is as follows:
|
||||
|
||||
major: is a major release number that indicates significant changes or new features that may not be backward compatible.
|
||||
* major: indicates significant changes or new features that may not be backward compatible.
|
||||
|
||||
minor: is a minor release number that indicates minor changes or new features that are backward compatible.
|
||||
* minor: indicates minor changes or new features that are backward compatible.
|
||||
|
||||
patch : is a patch release number that indicates bug fixes or other small changes that are backward compatible.
|
||||
* patch: indicates bug fixes or other small changes that are backward compatible.
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
76
action.yml
76
action.yml
@@ -1,5 +1,5 @@
|
||||
name: Changed Files
|
||||
description: Get all Added, Copied, Modified, Deleted, Renamed, Type changed, Unmerged, Unknown files.
|
||||
description: Get all Added, Copied, Modified, Deleted, Renamed, Type changed, Unmerged, and Unknown files.
|
||||
author: tj-actions
|
||||
|
||||
inputs:
|
||||
@@ -28,13 +28,37 @@ inputs:
|
||||
default: "\n"
|
||||
required: false
|
||||
files:
|
||||
description: "File and directory patterns to detect changes using only these list of file(s) (Defaults to the entire repo) **NOTE:** Multiline file/directory patterns should not include quotes."
|
||||
description: "File and directory patterns used to detect changes (Defaults to the entire repo if unset) **NOTE:** Multiline file/directory patterns should not include quotes."
|
||||
required: false
|
||||
default: ""
|
||||
files_separator:
|
||||
description: "Separator used to split the `files` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
files_yaml:
|
||||
description: "YAML used to define a set of file patterns to detect changes"
|
||||
required: false
|
||||
default: ""
|
||||
files_yaml_from_source_file:
|
||||
description: "Source file(s) used to populate the `files_yaml` input. [Example](https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml)"
|
||||
required: false
|
||||
default: ""
|
||||
files_yaml_from_source_file_separator:
|
||||
description: 'Separator used to split the `files_yaml_from_source_file` input'
|
||||
default: "\n"
|
||||
required: false
|
||||
files_ignore_yaml:
|
||||
description: "YAML used to define a set of file patterns to ignore changes"
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_yaml_from_source_file:
|
||||
description: "Source file(s) used to populate the `files_ignore_yaml` input. [Example](https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml)"
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_yaml_from_source_file_separator:
|
||||
description: 'Separator used to split the `files_ignore_yaml_from_source_file` input'
|
||||
default: "\n"
|
||||
required: false
|
||||
files_ignore:
|
||||
description: "Ignore changes to these file(s) **NOTE:** Multiline file/directory patterns should not include quotes."
|
||||
required: false
|
||||
@@ -70,7 +94,7 @@ inputs:
|
||||
required: false
|
||||
default: "."
|
||||
quotepath:
|
||||
description: "Use non ascii characters to match files and output the filenames completely verbatim by setting this to `false`"
|
||||
description: "Use non-ascii characters to match files and output the filenames completely verbatim by setting this to `false`"
|
||||
default: "true"
|
||||
required: false
|
||||
diff_relative:
|
||||
@@ -106,7 +130,7 @@ inputs:
|
||||
required: false
|
||||
default: "50"
|
||||
since_last_remote_commit:
|
||||
description: "Use the last commit on the remote branch as the `base_sha`. Defaults to the last non merge commit on the target branch for pull request events and the previous remote commit of the current branch for push events."
|
||||
description: "Use the last commit on the remote branch as the `base_sha`. Defaults to the last non-merge commit on the target branch for pull request events and the previous remote commit of the current branch for push events."
|
||||
required: false
|
||||
default: "false"
|
||||
write_output_files:
|
||||
@@ -117,50 +141,92 @@ inputs:
|
||||
description: "Directory to store output files."
|
||||
required: false
|
||||
default: ".github/outputs"
|
||||
output_renamed_files_as_deleted_and_added:
|
||||
description: "Output renamed files as deleted and added files."
|
||||
required: false
|
||||
default: "false"
|
||||
recover_deleted_files:
|
||||
description: "Recover deleted files."
|
||||
required: false
|
||||
default: "false"
|
||||
recover_deleted_files_to_destination:
|
||||
description: "Recover deleted files to a new destination directory, defaults to the original location."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
outputs:
|
||||
added_files:
|
||||
description: "Returns only files that are Added (A)."
|
||||
added_files_count:
|
||||
description: "Returns the number of `added_files`"
|
||||
copied_files:
|
||||
description: "Returns only files that are Copied (C)."
|
||||
copied_files_count:
|
||||
description: "Returns the number of `copied_files`"
|
||||
deleted_files:
|
||||
description: "Returns only files that are Deleted (D)."
|
||||
deleted_files_count:
|
||||
description: "Returns the number of `deleted_files`"
|
||||
modified_files:
|
||||
description: "Returns only files that are Modified (M)."
|
||||
modified_files_count:
|
||||
description: "Returns the number of `modified_files`"
|
||||
renamed_files:
|
||||
description: "Returns only files that are Renamed (R)."
|
||||
renamed_files_count:
|
||||
description: "Returns the number of `renamed_files`"
|
||||
all_old_new_renamed_files:
|
||||
description: "Returns only files that are Renamed and list their old and new names. **NOTE:** This requires setting `include_all_old_new_renamed_files` to `true` (R)"
|
||||
description: "Returns only files that are Renamed and lists their old and new names. **NOTE:** This requires setting `include_all_old_new_renamed_files` to `true`. Also, keep in mind that this output is global and wouldn't be nested in outputs generated when the `*_yaml_*` input is used. (R)"
|
||||
all_old_new_renamed_files_count:
|
||||
description: "Returns the number of `all_old_new_renamed_files`"
|
||||
type_changed_files:
|
||||
description: "Returns only files that have their file type changed (T)."
|
||||
type_changed_files_count:
|
||||
description: "Returns the number of `type_changed_files`"
|
||||
unmerged_files:
|
||||
description: "Returns only files that are Unmerged (U)."
|
||||
unmerged_files_count:
|
||||
description: "Returns the number of `unmerged_files`"
|
||||
unknown_files:
|
||||
description: "Returns only files that are Unknown (X)."
|
||||
unknown_files_count:
|
||||
description: "Returns the number of `unknown_files`"
|
||||
all_changed_and_modified_files:
|
||||
description: "Returns all changed and modified files i.e. *a combination of (ACMRDTUX)*"
|
||||
all_changed_and_modified_files_count:
|
||||
description: "Returns the number of `all_changed_and_modified_files`"
|
||||
all_changed_files:
|
||||
description: "Returns all changed files i.e. *a combination of all added, copied, modified and renamed files (ACMR)*"
|
||||
all_changed_files_count:
|
||||
description: "Returns the number of `all_changed_files`"
|
||||
any_changed:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs has changed. i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*."
|
||||
only_changed:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs has changed. i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*."
|
||||
other_changed_files:
|
||||
description: "Returns all other changed files not listed in the files input i.e. *using a combination of all added, copied, modified and renamed files (ACMR)*."
|
||||
other_changed_files_count:
|
||||
description: "Returns the number of `other_changed_files`"
|
||||
all_modified_files:
|
||||
description: "Returns all changed files i.e. *a combination of all added, copied, modified, renamed and deleted files (ACMRD)*."
|
||||
all_modified_files_count:
|
||||
description: "Returns the number of `all_modified_files`"
|
||||
any_modified:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs has been modified. i.e. *using a combination of all added, copied, modified, renamed, and deleted files (ACMRD)*."
|
||||
only_modified:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs has been modified. (ACMRD)."
|
||||
other_modified_files:
|
||||
description: "Returns all other modified files not listed in the files input i.e. *a combination of all added, copied, modified, and deleted files (ACMRD)*"
|
||||
other_modified_files_count:
|
||||
description: "Returns the number of `other_modified_files`"
|
||||
any_deleted:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs has been deleted. (D)"
|
||||
only_deleted:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs has been deleted. (D)"
|
||||
other_deleted_files:
|
||||
description: "Returns all other deleted files not listed in the files input i.e. *a combination of all deleted files (D)*"
|
||||
other_deleted_files_count:
|
||||
description: "Returns the number of `other_deleted_files`"
|
||||
|
||||
runs:
|
||||
using: 'node16'
|
||||
|
||||
26594
dist/index.js
generated
vendored
26594
dist/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
17
dist/licenses.txt
generated
vendored
17
dist/licenses.txt
generated
vendored
@@ -296,3 +296,20 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
yaml
|
||||
ISC
|
||||
Copyright Eemeli Aro <eemeli@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
11
package.json
11
package.json
@@ -35,7 +35,8 @@
|
||||
"@actions/core": "1.10.0",
|
||||
"@actions/exec": "1.1.1",
|
||||
"lodash": "^4.17.15",
|
||||
"micromatch": "^4.0.5"
|
||||
"micromatch": "^4.0.5",
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.2",
|
||||
@@ -43,12 +44,12 @@
|
||||
"@types/micromatch": "^4.0.2",
|
||||
"@types/node": "20.2.1",
|
||||
"@types/uuid": "9.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "5.59.11",
|
||||
"@typescript-eslint/parser": "5.59.11",
|
||||
"@typescript-eslint/eslint-plugin": "5.60.0",
|
||||
"@typescript-eslint/parser": "5.60.0",
|
||||
"@vercel/ncc": "0.36.1",
|
||||
"eslint": "8.42.0",
|
||||
"eslint": "8.43.0",
|
||||
"eslint-plugin-github": "4.8.0",
|
||||
"eslint-plugin-jest": "27.2.1",
|
||||
"eslint-plugin-jest": "27.2.2",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jest": "29.5.0",
|
||||
"prettier": "2.8.8",
|
||||
|
||||
@@ -23,7 +23,7 @@ export const getRenamedFiles = async ({
|
||||
hasSubmodule: boolean
|
||||
diffResult: DiffResult
|
||||
submodulePaths: string[]
|
||||
}): Promise<string> => {
|
||||
}): Promise<{paths: string; count: string}> => {
|
||||
const renamedFiles = await gitRenamedFiles({
|
||||
cwd: workingDirectory,
|
||||
sha1: diffResult.previousSha,
|
||||
@@ -63,10 +63,16 @@ export const getRenamedFiles = async ({
|
||||
}
|
||||
|
||||
if (inputs.json) {
|
||||
return jsonOutput({value: renamedFiles, shouldEscape: inputs.escapeJson})
|
||||
return {
|
||||
paths: jsonOutput({value: renamedFiles, shouldEscape: inputs.escapeJson}),
|
||||
count: renamedFiles.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return renamedFiles.join(inputs.oldNewFilesSeparator)
|
||||
return {
|
||||
paths: renamedFiles.join(inputs.oldNewFilesSeparator),
|
||||
count: renamedFiles.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
export enum ChangeTypeEnum {
|
||||
@@ -88,18 +94,21 @@ export const getAllDiffFiles = async ({
|
||||
workingDirectory,
|
||||
hasSubmodule,
|
||||
diffResult,
|
||||
submodulePaths
|
||||
submodulePaths,
|
||||
outputRenamedFilesAsDeletedAndAdded
|
||||
}: {
|
||||
workingDirectory: string
|
||||
hasSubmodule: boolean
|
||||
diffResult: DiffResult
|
||||
submodulePaths: string[]
|
||||
outputRenamedFilesAsDeletedAndAdded: boolean
|
||||
}): Promise<ChangedFiles> => {
|
||||
const files = await getAllChangedFiles({
|
||||
cwd: workingDirectory,
|
||||
sha1: diffResult.previousSha,
|
||||
sha2: diffResult.currentSha,
|
||||
diff: diffResult.diff
|
||||
diff: diffResult.diff,
|
||||
outputRenamedFilesAsDeletedAndAdded
|
||||
})
|
||||
|
||||
if (hasSubmodule) {
|
||||
@@ -124,7 +133,8 @@ export const getAllDiffFiles = async ({
|
||||
sha2: submoduleShaResult.currentSha,
|
||||
diff: diffResult.diff,
|
||||
isSubmodule: true,
|
||||
parentDir: submodulePath
|
||||
parentDir: submodulePath,
|
||||
outputRenamedFilesAsDeletedAndAdded
|
||||
})
|
||||
|
||||
for (const changeType of Object.keys(
|
||||
@@ -176,16 +186,22 @@ export const getChangeTypeFiles = async ({
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
changeTypes: ChangeTypeEnum[]
|
||||
}): Promise<string> => {
|
||||
}): Promise<{paths: string; count: string}> => {
|
||||
const files = [
|
||||
...new Set(getChangeTypeFilesGenerator({inputs, changedFiles, changeTypes}))
|
||||
]
|
||||
|
||||
if (inputs.json) {
|
||||
return jsonOutput({value: files, shouldEscape: inputs.escapeJson})
|
||||
return {
|
||||
paths: jsonOutput({value: files, shouldEscape: inputs.escapeJson}),
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return files.join(inputs.separator)
|
||||
return {
|
||||
paths: files.join(inputs.separator),
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
function* getAllChangeTypeFilesGenerator({
|
||||
@@ -215,14 +231,20 @@ export const getAllChangeTypeFiles = async ({
|
||||
}: {
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
}): Promise<string> => {
|
||||
}): Promise<{paths: string; count: string}> => {
|
||||
const files = [
|
||||
...new Set(getAllChangeTypeFilesGenerator({inputs, changedFiles}))
|
||||
]
|
||||
|
||||
if (inputs.json) {
|
||||
return jsonOutput({value: files, shouldEscape: inputs.escapeJson})
|
||||
return {
|
||||
paths: jsonOutput({value: files, shouldEscape: inputs.escapeJson}),
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return files.join(inputs.separator)
|
||||
return {
|
||||
paths: files.join(inputs.separator),
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
387
src/changedFilesOutput.ts
Normal file
387
src/changedFilesOutput.ts
Normal file
@@ -0,0 +1,387 @@
|
||||
import * as core from '@actions/core'
|
||||
import {
|
||||
ChangedFiles,
|
||||
ChangeTypeEnum,
|
||||
getAllChangeTypeFiles,
|
||||
getChangeTypeFiles
|
||||
} from './changedFiles'
|
||||
import {DiffResult} from './commitSha'
|
||||
import {Inputs} from './inputs'
|
||||
import {getFilteredChangedFiles, recoverDeletedFiles, setOutput} from './utils'
|
||||
|
||||
const getOutputKey = (key: string, outputPrefix: string): string => {
|
||||
return outputPrefix ? `${outputPrefix}_${key}` : key
|
||||
}
|
||||
|
||||
export const setChangedFilesOutput = async ({
|
||||
allDiffFiles,
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffResult,
|
||||
filePatterns = [],
|
||||
outputPrefix = ''
|
||||
}: {
|
||||
allDiffFiles: ChangedFiles
|
||||
filePatterns?: string[]
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
diffResult: DiffResult
|
||||
outputPrefix?: string
|
||||
}): Promise<void> => {
|
||||
const allFilteredDiffFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
core.debug(`All filtered diff files: ${JSON.stringify(allFilteredDiffFiles)}`)
|
||||
|
||||
await recoverDeletedFiles({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
deletedFiles: allFilteredDiffFiles[ChangeTypeEnum.Deleted],
|
||||
sha: diffResult.previousSha
|
||||
})
|
||||
|
||||
const addedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Added]
|
||||
})
|
||||
core.debug(`Added files: ${addedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('added_files', outputPrefix),
|
||||
value: addedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
await setOutput({
|
||||
key: getOutputKey('added_files_count', outputPrefix),
|
||||
value: addedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const copiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Copied]
|
||||
})
|
||||
core.debug(`Copied files: ${copiedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('copied_files', outputPrefix),
|
||||
value: copiedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('copied_files_count', outputPrefix),
|
||||
value: copiedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const modifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Modified]
|
||||
})
|
||||
core.debug(`Modified files: ${modifiedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('modified_files', outputPrefix),
|
||||
value: modifiedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('modified_files_count', outputPrefix),
|
||||
value: modifiedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const renamedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Renamed]
|
||||
})
|
||||
core.debug(`Renamed files: ${renamedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('renamed_files', outputPrefix),
|
||||
value: renamedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('renamed_files_count', outputPrefix),
|
||||
value: renamedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const typeChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.TypeChanged]
|
||||
})
|
||||
core.debug(`Type changed files: ${typeChangedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('type_changed_files', outputPrefix),
|
||||
value: typeChangedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('type_changed_files_count', outputPrefix),
|
||||
value: typeChangedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const unmergedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unmerged]
|
||||
})
|
||||
core.debug(`Unmerged files: ${unmergedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('unmerged_files', outputPrefix),
|
||||
value: unmergedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('unmerged_files_count', outputPrefix),
|
||||
value: unmergedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const unknownFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unknown]
|
||||
})
|
||||
core.debug(`Unknown files: ${unknownFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('unknown_files', outputPrefix),
|
||||
value: unknownFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('unknown_files_count', outputPrefix),
|
||||
value: unknownFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allChangedAndModifiedFiles = await getAllChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles
|
||||
})
|
||||
core.debug(`All changed and modified files: ${allChangedAndModifiedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_and_modified_files', outputPrefix),
|
||||
value: allChangedAndModifiedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_and_modified_files_count', outputPrefix),
|
||||
value: allChangedAndModifiedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All changed files: ${allChangedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_files', outputPrefix),
|
||||
value: allChangedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_files_count', outputPrefix),
|
||||
value: allChangedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_changed', outputPrefix),
|
||||
value: allChangedFiles.paths.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All other changed files: ${allOtherChangedFiles}`)
|
||||
|
||||
const otherChangedFiles = allOtherChangedFiles.paths
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
(filePath: string) =>
|
||||
!allChangedFiles.paths.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyChanged =
|
||||
otherChangedFiles.length === 0 &&
|
||||
allChangedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_changed', outputPrefix),
|
||||
value: onlyChanged,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_changed_files', outputPrefix),
|
||||
value: otherChangedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_changed_files_count', outputPrefix),
|
||||
value: otherChangedFiles.length.toString(),
|
||||
inputs
|
||||
})
|
||||
|
||||
const allModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
core.debug(`All modified files: ${allModifiedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_modified_files', outputPrefix),
|
||||
value: allModifiedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_modified_files_count', outputPrefix),
|
||||
value: allModifiedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_modified', outputPrefix),
|
||||
value: allModifiedFiles.paths.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
|
||||
const otherModifiedFiles = allOtherModifiedFiles.paths
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
(filePath: string) =>
|
||||
!allModifiedFiles.paths.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyModified =
|
||||
otherModifiedFiles.length === 0 &&
|
||||
allModifiedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_modified', outputPrefix),
|
||||
value: onlyModified,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_modified_files', outputPrefix),
|
||||
value: otherModifiedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_modified_files_count', outputPrefix),
|
||||
value: otherModifiedFiles.length.toString(),
|
||||
inputs
|
||||
})
|
||||
|
||||
const deletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
core.debug(`Deleted files: ${deletedFiles}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('deleted_files', outputPrefix),
|
||||
value: deletedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('deleted_files_count', outputPrefix),
|
||||
value: deletedFiles.count,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_deleted', outputPrefix),
|
||||
value: deletedFiles.paths.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherDeletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
|
||||
const otherDeletedFiles = allOtherDeletedFiles.paths
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
filePath => !deletedFiles.paths.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyDeleted =
|
||||
otherDeletedFiles.length === 0 &&
|
||||
deletedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_deleted', outputPrefix),
|
||||
value: onlyDeleted,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_deleted_files', outputPrefix),
|
||||
value: otherDeletedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_deleted_files_count', outputPrefix),
|
||||
value: otherDeletedFiles.length.toString(),
|
||||
inputs
|
||||
})
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export const getSHAForPushEvent = async (
|
||||
workingDirectory: string,
|
||||
isShallow: boolean,
|
||||
hasSubmodule: boolean,
|
||||
gitExtraArgs: string[],
|
||||
gitFetchExtraArgs: string[],
|
||||
isTag: boolean
|
||||
): Promise<DiffResult> => {
|
||||
let targetBranch = env.GITHUB_REF_NAME
|
||||
@@ -102,7 +102,7 @@ export const getSHAForPushEvent = async (
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
@@ -114,7 +114,7 @@ export const getSHAForPushEvent = async (
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
@@ -128,7 +128,7 @@ export const getSHAForPushEvent = async (
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
@@ -263,7 +263,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
workingDirectory: string,
|
||||
isShallow: boolean,
|
||||
hasSubmodule: boolean,
|
||||
gitExtraArgs: string[]
|
||||
gitFetchExtraArgs: string[]
|
||||
): Promise<DiffResult> => {
|
||||
let targetBranch = env.GITHUB_EVENT_PULL_REQUEST_BASE_REF
|
||||
const currentBranch = env.GITHUB_EVENT_PULL_REQUEST_HEAD_REF
|
||||
@@ -277,7 +277,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
let prFetchExitCode = await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
'origin',
|
||||
@@ -289,7 +289,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
prFetchExitCode = await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
@@ -310,7 +310,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
@@ -323,7 +323,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
@@ -370,12 +370,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
|
||||
if (!previousSha) {
|
||||
if (inputs.sinceLastRemoteCommit) {
|
||||
previousSha =
|
||||
env.GITHUB_EVENT_BEFORE ||
|
||||
(await getRemoteBranchHeadSha({
|
||||
cwd: workingDirectory,
|
||||
branch: currentBranch
|
||||
}))
|
||||
previousSha = env.GITHUB_EVENT_BEFORE
|
||||
|
||||
if (
|
||||
!previousSha ||
|
||||
@@ -384,9 +379,18 @@ export const getSHAForPullRequestEvent = async (
|
||||
0)
|
||||
) {
|
||||
core.warning(
|
||||
'Unable to locate the remote branch head sha. Falling back to the pull request base sha.'
|
||||
'Unable to locate the remote branch head sha. Falling back to the previous commit in the local history.'
|
||||
)
|
||||
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
|
||||
previousSha = await getParentSha({
|
||||
cwd: workingDirectory
|
||||
})
|
||||
|
||||
if (!previousSha) {
|
||||
core.warning(
|
||||
'Unable to locate the previous commit in the local history. Falling back to the pull request base sha.'
|
||||
)
|
||||
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
|
||||
}
|
||||
}
|
||||
} else {
|
||||
previousSha = await getRemoteBranchHeadSha({
|
||||
@@ -400,12 +404,12 @@ export const getSHAForPullRequestEvent = async (
|
||||
|
||||
if (isShallow) {
|
||||
if (
|
||||
await canDiffCommits({
|
||||
!(await canDiffCommits({
|
||||
cwd: workingDirectory,
|
||||
sha1: previousSha,
|
||||
sha2: currentSha,
|
||||
diff
|
||||
})
|
||||
}))
|
||||
) {
|
||||
core.debug(
|
||||
'Merge base is not in the local history, fetching remote target branch...'
|
||||
@@ -415,7 +419,7 @@ export const getSHAForPullRequestEvent = async (
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitExtraArgs,
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
|
||||
15
src/env.ts
15
src/env.ts
@@ -2,23 +2,25 @@ import {promises as fs} from 'fs'
|
||||
import * as core from '@actions/core'
|
||||
|
||||
export type Env = {
|
||||
GITHUB_EVENT_PULL_REQUEST_HEAD_REF: string
|
||||
GITHUB_EVENT_PULL_REQUEST_BASE_REF: string
|
||||
GITHUB_EVENT_BEFORE: string
|
||||
GITHUB_REF_NAME: string
|
||||
GITHUB_REF: string
|
||||
GITHUB_WORKSPACE: string
|
||||
GITHUB_EVENT_ACTION: string
|
||||
GITHUB_EVENT_NAME: string
|
||||
GITHUB_EVENT_FORCED: string
|
||||
GITHUB_EVENT_BEFORE: string
|
||||
GITHUB_EVENT_BASE_REF: string
|
||||
GITHUB_EVENT_RELEASE_TARGET_COMMITISH: string
|
||||
GITHUB_EVENT_HEAD_REPO_FORK: string
|
||||
GITHUB_WORKSPACE: string
|
||||
GITHUB_EVENT_FORCED: string
|
||||
GITHUB_EVENT_PULL_REQUEST_NUMBER: string
|
||||
GITHUB_EVENT_PULL_REQUEST_BASE_SHA: string
|
||||
GITHUB_EVENT_PULL_REQUEST_HEAD_SHA: string
|
||||
GITHUB_EVENT_NAME: string
|
||||
GITHUB_EVENT_PULL_REQUEST_HEAD_REF: string
|
||||
GITHUB_EVENT_PULL_REQUEST_BASE_REF: string
|
||||
}
|
||||
|
||||
type GithubEvent = {
|
||||
action?: string
|
||||
forced?: string
|
||||
pull_request?: {
|
||||
head: {
|
||||
@@ -65,6 +67,7 @@ export const getEnv = async (): Promise<Env> => {
|
||||
GITHUB_EVENT_PULL_REQUEST_BASE_SHA: eventJson.pull_request?.base?.sha || '',
|
||||
GITHUB_EVENT_PULL_REQUEST_HEAD_SHA: eventJson.pull_request?.head?.sha || '',
|
||||
GITHUB_EVENT_FORCED: eventJson.forced || '',
|
||||
GITHUB_EVENT_ACTION: eventJson.action || '',
|
||||
GITHUB_REF_NAME: process.env.GITHUB_REF_NAME || '',
|
||||
GITHUB_REF: process.env.GITHUB_REF || '',
|
||||
GITHUB_WORKSPACE: process.env.GITHUB_WORKSPACE || '',
|
||||
|
||||
@@ -5,10 +5,16 @@ export type Inputs = {
|
||||
filesSeparator: string
|
||||
filesFromSourceFile: string
|
||||
filesFromSourceFileSeparator: string
|
||||
filesYaml: string
|
||||
filesYamlFromSourceFile: string
|
||||
filesYamlFromSourceFileSeparator: string
|
||||
filesIgnore: string
|
||||
filesIgnoreSeparator: string
|
||||
filesIgnoreFromSourceFile: string
|
||||
filesIgnoreFromSourceFileSeparator: string
|
||||
filesIgnoreYaml: string
|
||||
filesIgnoreYamlFromSourceFile: string
|
||||
filesIgnoreYamlFromSourceFileSeparator: string
|
||||
separator: string
|
||||
includeAllOldNewRenamedFiles: boolean
|
||||
oldNewSeparator: string
|
||||
@@ -30,6 +36,9 @@ export type Inputs = {
|
||||
sinceLastRemoteCommit: boolean
|
||||
writeOutputFiles: boolean
|
||||
outputDir: string
|
||||
outputRenamedFilesAsDeletedAndAdded: boolean
|
||||
recoverDeletedFiles: boolean
|
||||
recoverDeletedFilesToDestination: string
|
||||
}
|
||||
|
||||
export const getInputs = (): Inputs => {
|
||||
@@ -53,6 +62,17 @@ export const getInputs = (): Inputs => {
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesYaml = core.getInput('files_yaml', {required: false})
|
||||
const filesYamlFromSourceFile = core.getInput('files_yaml_from_source_file', {
|
||||
required: false
|
||||
})
|
||||
const filesYamlFromSourceFileSeparator = core.getInput(
|
||||
'files_yaml_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesIgnoreFromSourceFile = core.getInput(
|
||||
'files_ignore_from_source_file',
|
||||
{required: false}
|
||||
@@ -64,6 +84,18 @@ export const getInputs = (): Inputs => {
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesIgnoreYaml = core.getInput('files_ignore_yaml', {required: false})
|
||||
const filesIgnoreYamlFromSourceFile = core.getInput(
|
||||
'files_ignore_yaml_from_source_file',
|
||||
{required: false}
|
||||
)
|
||||
const filesIgnoreYamlFromSourceFileSeparator = core.getInput(
|
||||
'files_ignore_yaml_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const separator = core.getInput('separator', {
|
||||
required: true,
|
||||
trimWhitespace: false
|
||||
@@ -111,16 +143,33 @@ export const getInputs = (): Inputs => {
|
||||
required: false
|
||||
})
|
||||
const outputDir = core.getInput('output_dir', {required: false})
|
||||
const outputRenamedFilesAsDeletedAndAdded = core.getBooleanInput(
|
||||
'output_renamed_files_as_deleted_and_added',
|
||||
{required: false}
|
||||
)
|
||||
const recoverDeletedFiles = core.getBooleanInput('recover_deleted_files', {
|
||||
required: false
|
||||
})
|
||||
const recoverDeletedFilesToDestination = core.getInput(
|
||||
'recover_deleted_files_to_destination',
|
||||
{required: false}
|
||||
)
|
||||
|
||||
const inputs: Inputs = {
|
||||
files,
|
||||
filesSeparator,
|
||||
filesFromSourceFile,
|
||||
filesFromSourceFileSeparator,
|
||||
filesYaml,
|
||||
filesYamlFromSourceFile,
|
||||
filesYamlFromSourceFileSeparator,
|
||||
filesIgnore,
|
||||
filesIgnoreSeparator,
|
||||
filesIgnoreFromSourceFile,
|
||||
filesIgnoreFromSourceFileSeparator,
|
||||
filesIgnoreYaml,
|
||||
filesIgnoreYamlFromSourceFile,
|
||||
filesIgnoreYamlFromSourceFileSeparator,
|
||||
separator,
|
||||
includeAllOldNewRenamedFiles,
|
||||
oldNewSeparator,
|
||||
@@ -139,7 +188,10 @@ export const getInputs = (): Inputs => {
|
||||
escapeJson,
|
||||
sinceLastRemoteCommit,
|
||||
writeOutputFiles,
|
||||
outputDir
|
||||
outputDir,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
recoverDeletedFiles,
|
||||
recoverDeletedFilesToDestination
|
||||
}
|
||||
|
||||
if (fetchDepth) {
|
||||
|
||||
358
src/main.ts
358
src/main.ts
@@ -1,12 +1,7 @@
|
||||
import * as core from '@actions/core'
|
||||
import path from 'path'
|
||||
import {
|
||||
getAllChangeTypeFiles,
|
||||
getAllDiffFiles,
|
||||
getChangeTypeFiles,
|
||||
getRenamedFiles,
|
||||
ChangeTypeEnum
|
||||
} from './changedFiles'
|
||||
import {getAllDiffFiles, getRenamedFiles} from './changedFiles'
|
||||
import {setChangedFilesOutput} from './changedFilesOutput'
|
||||
import {
|
||||
DiffResult,
|
||||
getSHAForPullRequestEvent,
|
||||
@@ -16,8 +11,8 @@ import {getEnv} from './env'
|
||||
import {getInputs} from './inputs'
|
||||
import {
|
||||
getFilePatterns,
|
||||
getFilteredChangedFiles,
|
||||
getSubmodulePath,
|
||||
getYamlFilePatterns,
|
||||
isRepoShallow,
|
||||
setOutput,
|
||||
submoduleExists,
|
||||
@@ -59,8 +54,10 @@ export async function run(): Promise<void> {
|
||||
)
|
||||
const isShallow = await isRepoShallow({cwd: workingDirectory})
|
||||
const hasSubmodule = await submoduleExists({cwd: workingDirectory})
|
||||
let gitExtraArgs = ['--no-tags', '--prune', '--recurse-submodules']
|
||||
let gitFetchExtraArgs = ['--no-tags', '--prune', '--recurse-submodules']
|
||||
const isTag = env.GITHUB_REF?.startsWith('refs/tags/')
|
||||
const outputRenamedFilesAsDeletedAndAdded =
|
||||
inputs.outputRenamedFilesAsDeletedAndAdded
|
||||
let submodulePaths: string[] = []
|
||||
|
||||
if (hasSubmodule) {
|
||||
@@ -68,7 +65,7 @@ export async function run(): Promise<void> {
|
||||
}
|
||||
|
||||
if (isTag) {
|
||||
gitExtraArgs = ['--prune', '--no-recurse-submodules']
|
||||
gitFetchExtraArgs = ['--prune', '--no-recurse-submodules']
|
||||
}
|
||||
|
||||
let diffResult: DiffResult
|
||||
@@ -81,12 +78,14 @@ export async function run(): Promise<void> {
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
hasSubmodule,
|
||||
gitExtraArgs,
|
||||
gitFetchExtraArgs,
|
||||
isTag
|
||||
)
|
||||
} else {
|
||||
core.info(
|
||||
`Running on a ${env.GITHUB_EVENT_NAME || 'pull_request'} event...`
|
||||
`Running on a ${env.GITHUB_EVENT_NAME || 'pull_request'} (${
|
||||
env.GITHUB_EVENT_ACTION
|
||||
}) event...`
|
||||
)
|
||||
diffResult = await getSHAForPullRequestEvent(
|
||||
inputs,
|
||||
@@ -94,7 +93,7 @@ export async function run(): Promise<void> {
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
hasSubmodule,
|
||||
gitExtraArgs
|
||||
gitFetchExtraArgs
|
||||
)
|
||||
}
|
||||
|
||||
@@ -108,286 +107,72 @@ export async function run(): Promise<void> {
|
||||
`Retrieving changes between ${diffResult.previousSha} (${diffResult.targetBranch}) → ${diffResult.currentSha} (${diffResult.currentBranch})`
|
||||
)
|
||||
|
||||
const allDiffFiles = await getAllDiffFiles({
|
||||
workingDirectory,
|
||||
hasSubmodule,
|
||||
diffResult,
|
||||
submodulePaths,
|
||||
outputRenamedFilesAsDeletedAndAdded
|
||||
})
|
||||
core.debug(`All diff files: ${JSON.stringify(allDiffFiles)}`)
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
|
||||
const filePatterns = await getFilePatterns({
|
||||
inputs,
|
||||
workingDirectory
|
||||
})
|
||||
core.debug(`File patterns: ${filePatterns}`)
|
||||
|
||||
const allDiffFiles = await getAllDiffFiles({
|
||||
workingDirectory,
|
||||
hasSubmodule,
|
||||
diffResult,
|
||||
submodulePaths
|
||||
})
|
||||
core.debug(`All diff files: ${JSON.stringify(allDiffFiles)}`)
|
||||
if (filePatterns.length > 0) {
|
||||
core.startGroup('changed-files-patterns')
|
||||
await setChangedFilesOutput({
|
||||
allDiffFiles,
|
||||
filePatterns,
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffResult
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
const allFilteredDiffFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
core.debug(`All filtered diff files: ${JSON.stringify(allFilteredDiffFiles)}`)
|
||||
|
||||
const addedFiles = await getChangeTypeFiles({
|
||||
const yamlFilePatterns = await getYamlFilePatterns({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Added]
|
||||
})
|
||||
core.debug(`Added files: ${addedFiles}`)
|
||||
await setOutput({
|
||||
key: 'added_files',
|
||||
value: addedFiles,
|
||||
inputs
|
||||
workingDirectory
|
||||
})
|
||||
core.debug(`Yaml file patterns: ${JSON.stringify(yamlFilePatterns)}`)
|
||||
|
||||
const copiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Copied]
|
||||
})
|
||||
core.debug(`Copied files: ${copiedFiles}`)
|
||||
await setOutput({
|
||||
key: 'copied_files',
|
||||
value: copiedFiles,
|
||||
inputs
|
||||
})
|
||||
if (Object.keys(yamlFilePatterns).length > 0) {
|
||||
for (const key of Object.keys(yamlFilePatterns)) {
|
||||
core.startGroup(`changed-files-yaml-${key}`)
|
||||
await setChangedFilesOutput({
|
||||
allDiffFiles,
|
||||
filePatterns: yamlFilePatterns[key],
|
||||
outputPrefix: key,
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffResult
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
}
|
||||
|
||||
const modifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Modified]
|
||||
})
|
||||
core.debug(`Modified files: ${modifiedFiles}`)
|
||||
await setOutput({
|
||||
key: 'modified_files',
|
||||
value: modifiedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const renamedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Renamed]
|
||||
})
|
||||
core.debug(`Renamed files: ${renamedFiles}`)
|
||||
await setOutput({
|
||||
key: 'renamed_files',
|
||||
value: renamedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const typeChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.TypeChanged]
|
||||
})
|
||||
core.debug(`Type changed files: ${typeChangedFiles}`)
|
||||
await setOutput({
|
||||
key: 'type_changed_files',
|
||||
value: typeChangedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const unmergedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unmerged]
|
||||
})
|
||||
core.debug(`Unmerged files: ${unmergedFiles}`)
|
||||
await setOutput({
|
||||
key: 'unmerged_files',
|
||||
value: unmergedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const unknownFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unknown]
|
||||
})
|
||||
core.debug(`Unknown files: ${unknownFiles}`)
|
||||
await setOutput({
|
||||
key: 'unknown_files',
|
||||
value: unknownFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allChangedAndModifiedFiles = await getAllChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles
|
||||
})
|
||||
core.debug(`All changed and modified files: ${allChangedAndModifiedFiles}`)
|
||||
await setOutput({
|
||||
key: 'all_changed_and_modified_files',
|
||||
value: allChangedAndModifiedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All changed files: ${allChangedFiles}`)
|
||||
await setOutput({
|
||||
key: 'all_changed_files',
|
||||
value: allChangedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'any_changed',
|
||||
value: allChangedFiles.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All other changed files: ${allOtherChangedFiles}`)
|
||||
|
||||
const otherChangedFiles = allOtherChangedFiles
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
filePath => !allChangedFiles.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyChanged =
|
||||
otherChangedFiles.length === 0 &&
|
||||
allChangedFiles.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: 'only_changed',
|
||||
value: onlyChanged,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'other_changed_files',
|
||||
value: otherChangedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
|
||||
const allModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
core.debug(`All modified files: ${allModifiedFiles}`)
|
||||
await setOutput({
|
||||
key: 'all_modified_files',
|
||||
value: allModifiedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'any_modified',
|
||||
value: allModifiedFiles.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
|
||||
const otherModifiedFiles = allOtherModifiedFiles
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
filePath => !allModifiedFiles.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyModified =
|
||||
otherModifiedFiles.length === 0 &&
|
||||
allModifiedFiles.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: 'only_modified',
|
||||
value: onlyModified,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'other_modified_files',
|
||||
value: otherModifiedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
|
||||
const deletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
core.debug(`Deleted files: ${deletedFiles}`)
|
||||
await setOutput({
|
||||
key: 'deleted_files',
|
||||
value: deletedFiles,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'any_deleted',
|
||||
value: deletedFiles.length > 0 && filePatterns.length > 0,
|
||||
inputs
|
||||
})
|
||||
|
||||
const allOtherDeletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
|
||||
const otherDeletedFiles = allOtherDeletedFiles
|
||||
.split(inputs.separator)
|
||||
.filter(
|
||||
filePath => !deletedFiles.split(inputs.separator).includes(filePath)
|
||||
)
|
||||
|
||||
const onlyDeleted =
|
||||
otherDeletedFiles.length === 0 &&
|
||||
deletedFiles.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: 'only_deleted',
|
||||
value: onlyDeleted,
|
||||
inputs
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: 'other_deleted_files',
|
||||
value: otherDeletedFiles.join(inputs.separator),
|
||||
inputs
|
||||
})
|
||||
if (filePatterns.length === 0 && Object.keys(yamlFilePatterns).length === 0) {
|
||||
core.startGroup('changed-files-all')
|
||||
await setChangedFilesOutput({
|
||||
allDiffFiles,
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffResult
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
if (inputs.includeAllOldNewRenamedFiles) {
|
||||
core.startGroup('changed-files-all-old-new-renamed-files')
|
||||
const allOldNewRenamedFiles = await getRenamedFiles({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
@@ -398,14 +183,17 @@ export async function run(): Promise<void> {
|
||||
core.debug(`All old new renamed files: ${allOldNewRenamedFiles}`)
|
||||
await setOutput({
|
||||
key: 'all_old_new_renamed_files',
|
||||
value: allOldNewRenamedFiles,
|
||||
value: allOldNewRenamedFiles.paths,
|
||||
inputs
|
||||
})
|
||||
await setOutput({
|
||||
key: 'all_old_new_renamed_files_count',
|
||||
value: allOldNewRenamedFiles.count,
|
||||
inputs
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
core.info('All Done!')
|
||||
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
/* istanbul ignore if */
|
||||
|
||||
282
src/utils.ts
282
src/utils.ts
@@ -2,9 +2,12 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import {createReadStream, promises as fs} from 'fs'
|
||||
import {readFile} from 'fs/promises'
|
||||
import {flattenDeep} from 'lodash'
|
||||
import mm from 'micromatch'
|
||||
import * as path from 'path'
|
||||
import {createInterface} from 'readline'
|
||||
import {parseDocument} from 'yaml'
|
||||
import {ChangedFiles, ChangeTypeEnum} from './changedFiles'
|
||||
|
||||
import {Inputs} from './inputs'
|
||||
@@ -157,7 +160,7 @@ const getFilesFromSourceFile = async ({
|
||||
filePaths: string[]
|
||||
excludedFiles?: boolean
|
||||
}): Promise<string[]> => {
|
||||
const lines = []
|
||||
const lines: string[] = []
|
||||
for (const filePath of filePaths) {
|
||||
for await (const line of lineOfFileGenerator({filePath, excludedFiles})) {
|
||||
lines.push(line)
|
||||
@@ -410,7 +413,8 @@ export const getAllChangedFiles = async ({
|
||||
sha2,
|
||||
diff,
|
||||
isSubmodule = false,
|
||||
parentDir = ''
|
||||
parentDir = '',
|
||||
outputRenamedFilesAsDeletedAndAdded = false
|
||||
}: {
|
||||
cwd: string
|
||||
sha1: string
|
||||
@@ -418,6 +422,7 @@ export const getAllChangedFiles = async ({
|
||||
diff: string
|
||||
isSubmodule?: boolean
|
||||
parentDir?: string
|
||||
outputRenamedFilesAsDeletedAndAdded?: boolean
|
||||
}): Promise<ChangedFiles> => {
|
||||
const {exitCode, stdout, stderr} = await exec.getExecOutput(
|
||||
'git',
|
||||
@@ -466,13 +471,21 @@ export const getAllChangedFiles = async ({
|
||||
const lines = stdout.split('\n').filter(Boolean)
|
||||
|
||||
for (const line of lines) {
|
||||
const [changeType, filePath] = line.split('\t')
|
||||
const [changeType, filePath, newPath = ''] = line.split('\t')
|
||||
const normalizedFilePath = isSubmodule
|
||||
? normalizePath(path.join(parentDir, filePath))
|
||||
: normalizePath(filePath)
|
||||
const normalizedNewPath = isSubmodule
|
||||
? normalizePath(path.join(parentDir, newPath))
|
||||
: normalizePath(newPath)
|
||||
|
||||
if (changeType.startsWith('R')) {
|
||||
changedFiles[ChangeTypeEnum.Renamed].push(normalizedFilePath)
|
||||
if (outputRenamedFilesAsDeletedAndAdded) {
|
||||
changedFiles[ChangeTypeEnum.Deleted].push(normalizedFilePath)
|
||||
changedFiles[ChangeTypeEnum.Added].push(normalizedNewPath)
|
||||
} else {
|
||||
changedFiles[ChangeTypeEnum.Renamed].push(normalizedNewPath)
|
||||
}
|
||||
} else {
|
||||
changedFiles[changeType as ChangeTypeEnum].push(normalizedFilePath)
|
||||
}
|
||||
@@ -497,11 +510,10 @@ export const getFilteredChangedFiles = async ({
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const hasFilePatterns = filePatterns.length > 0
|
||||
|
||||
for (const changeType of Object.keys(allDiffFiles)) {
|
||||
const files = allDiffFiles[changeType as ChangeTypeEnum]
|
||||
const hasFilePatterns = filePatterns.length > 0
|
||||
|
||||
if (hasFilePatterns) {
|
||||
changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, {
|
||||
dot: true,
|
||||
@@ -799,10 +811,10 @@ export const getFilePatterns = async ({
|
||||
if (pattern.endsWith('/')) {
|
||||
return `${pattern}**`
|
||||
} else {
|
||||
const pathParts = pattern.split('/')
|
||||
const pathParts = pattern.split(path.sep)
|
||||
const lastPart = pathParts[pathParts.length - 1]
|
||||
if (!lastPart.includes('.')) {
|
||||
return `${pattern}/**`
|
||||
return `${pattern}${path.sep}**`
|
||||
} else {
|
||||
return pattern
|
||||
}
|
||||
@@ -810,6 +822,193 @@ export const getFilePatterns = async ({
|
||||
})
|
||||
}
|
||||
|
||||
// Example YAML input:
|
||||
// filesYaml: |
|
||||
// frontend:
|
||||
// - frontend/**
|
||||
// backend:
|
||||
// - backend/**
|
||||
// test: test/**
|
||||
// shared: &shared
|
||||
// - common/**
|
||||
// lib:
|
||||
// - *shared
|
||||
// - lib/**
|
||||
// Return an Object:
|
||||
// {
|
||||
// frontend: ['frontend/**'],
|
||||
// backend: ['backend/**'],
|
||||
// test: ['test/**'],
|
||||
// shared: ['common/**'],
|
||||
// lib: ['common/**', 'lib/**']
|
||||
// }
|
||||
|
||||
type YamlObject = {
|
||||
[key: string]: string | string[] | [string[], string]
|
||||
}
|
||||
|
||||
const getYamlFilePatternsFromContents = async ({
|
||||
content = '',
|
||||
filePath = '',
|
||||
excludedFiles = false
|
||||
}: {
|
||||
content?: string
|
||||
filePath?: string
|
||||
excludedFiles?: boolean
|
||||
}): Promise<Record<string, string[]>> => {
|
||||
const filePatterns: Record<string, string[]> = {}
|
||||
let source = ''
|
||||
|
||||
if (filePath) {
|
||||
if (!(await exists(filePath))) {
|
||||
core.error(`File does not exist: ${filePath}`)
|
||||
throw new Error(`File does not exist: ${filePath}`)
|
||||
}
|
||||
|
||||
source = await readFile(filePath, 'utf8')
|
||||
} else {
|
||||
source = content
|
||||
}
|
||||
|
||||
const doc = parseDocument(source, {merge: true, schema: 'failsafe'})
|
||||
|
||||
if (doc.errors.length > 0) {
|
||||
if (filePath) {
|
||||
core.warning(`YAML errors in ${filePath}: ${doc.errors}`)
|
||||
} else {
|
||||
core.warning(`YAML errors: ${doc.errors}`)
|
||||
}
|
||||
}
|
||||
|
||||
if (doc.warnings.length > 0) {
|
||||
if (filePath) {
|
||||
core.warning(`YAML warnings in ${filePath}: ${doc.warnings}`)
|
||||
} else {
|
||||
core.warning(`YAML warnings: ${doc.warnings}`)
|
||||
}
|
||||
}
|
||||
|
||||
const yamlObject = doc.toJS() as YamlObject
|
||||
|
||||
for (const key in yamlObject) {
|
||||
let value = yamlObject[key]
|
||||
|
||||
if (typeof value === 'string' && value.includes('\n')) {
|
||||
value = value.split('\n')
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
value = value.trim()
|
||||
|
||||
if (value) {
|
||||
filePatterns[key] = [
|
||||
excludedFiles && !value.startsWith('!') ? `!${value}` : value
|
||||
]
|
||||
}
|
||||
} else if (Array.isArray(value)) {
|
||||
filePatterns[key] = flattenDeep(value)
|
||||
.filter(v => v.trim() !== '')
|
||||
.map(v => {
|
||||
if (excludedFiles && !v.startsWith('!')) {
|
||||
v = `!${v}`
|
||||
}
|
||||
return v
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return filePatterns
|
||||
}
|
||||
|
||||
export const getYamlFilePatterns = async ({
|
||||
inputs,
|
||||
workingDirectory
|
||||
}: {
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
}): Promise<Record<string, string[]>> => {
|
||||
let filePatterns: Record<string, string[]> = {}
|
||||
if (inputs.filesYaml) {
|
||||
filePatterns = {
|
||||
...(await getYamlFilePatternsFromContents({content: inputs.filesYaml}))
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs.filesYamlFromSourceFile) {
|
||||
const inputFilesYamlFromSourceFile = inputs.filesYamlFromSourceFile
|
||||
.split(inputs.filesYamlFromSourceFileSeparator)
|
||||
.filter(p => p !== '')
|
||||
.map(p => path.join(workingDirectory, p))
|
||||
|
||||
core.debug(`files yaml from source file: ${inputFilesYamlFromSourceFile}`)
|
||||
|
||||
for (const filePath of inputFilesYamlFromSourceFile) {
|
||||
const newFilePatterns = await getYamlFilePatternsFromContents({filePath})
|
||||
for (const key in newFilePatterns) {
|
||||
if (key in filePatterns) {
|
||||
core.warning(
|
||||
`files_yaml_from_source_file: Duplicated key ${key} detected in ${filePath}, the ${filePatterns[key]} will be overwritten by ${newFilePatterns[key]}.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
filePatterns = {
|
||||
...filePatterns,
|
||||
...newFilePatterns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs.filesIgnoreYaml) {
|
||||
const newIgnoreFilePatterns = await getYamlFilePatternsFromContents({
|
||||
content: inputs.filesIgnoreYaml,
|
||||
excludedFiles: true
|
||||
})
|
||||
|
||||
for (const key in newIgnoreFilePatterns) {
|
||||
if (key in filePatterns) {
|
||||
core.warning(
|
||||
`files_ignore_yaml: Duplicated key ${key} detected, the ${filePatterns[key]} will be overwritten by ${newIgnoreFilePatterns[key]}.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs.filesIgnoreYamlFromSourceFile) {
|
||||
const inputFilesIgnoreYamlFromSourceFile =
|
||||
inputs.filesIgnoreYamlFromSourceFile
|
||||
.split(inputs.filesIgnoreYamlFromSourceFileSeparator)
|
||||
.filter(p => p !== '')
|
||||
.map(p => path.join(workingDirectory, p))
|
||||
|
||||
core.debug(
|
||||
`files ignore yaml from source file: ${inputFilesIgnoreYamlFromSourceFile}`
|
||||
)
|
||||
|
||||
for (const filePath of inputFilesIgnoreYamlFromSourceFile) {
|
||||
const newIgnoreFilePatterns = await getYamlFilePatternsFromContents({
|
||||
filePath,
|
||||
excludedFiles: true
|
||||
})
|
||||
|
||||
for (const key in newIgnoreFilePatterns) {
|
||||
if (key in filePatterns) {
|
||||
core.warning(
|
||||
`files_ignore_yaml_from_source_file: Duplicated key ${key} detected in ${filePath}, the ${filePatterns[key]} will be overwritten by ${newIgnoreFilePatterns[key]}.`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
filePatterns = {
|
||||
...filePatterns,
|
||||
...newIgnoreFilePatterns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filePatterns
|
||||
}
|
||||
|
||||
export const setOutput = async ({
|
||||
key,
|
||||
value,
|
||||
@@ -823,7 +1022,7 @@ export const setOutput = async ({
|
||||
core.setOutput(key, cleanedValue)
|
||||
|
||||
if (inputs.writeOutputFiles) {
|
||||
const outputDir = inputs.outputDir || '.github/outputs'
|
||||
const outputDir = inputs.outputDir
|
||||
const extension = inputs.json ? 'json' : 'txt'
|
||||
const outputFilePath = path.join(outputDir, `${key}.${extension}`)
|
||||
|
||||
@@ -833,3 +1032,68 @@ export const setOutput = async ({
|
||||
await fs.writeFile(outputFilePath, cleanedValue.replace(/\\"/g, '"'))
|
||||
}
|
||||
}
|
||||
|
||||
const getDeletedFileContents = async ({
|
||||
cwd,
|
||||
filePath,
|
||||
sha
|
||||
}: {
|
||||
cwd: string
|
||||
filePath: string
|
||||
sha: string
|
||||
}): Promise<string> => {
|
||||
const {stdout, exitCode, stderr} = await exec.getExecOutput(
|
||||
'git',
|
||||
['show', `${sha}:${filePath}`],
|
||||
{
|
||||
cwd,
|
||||
silent: process.env.RUNNER_DEBUG !== '1',
|
||||
ignoreReturnCode: true
|
||||
}
|
||||
)
|
||||
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(
|
||||
`Error getting file content from git history "${filePath}": ${stderr}`
|
||||
)
|
||||
}
|
||||
|
||||
return stdout
|
||||
}
|
||||
|
||||
export const recoverDeletedFiles = async ({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
deletedFiles,
|
||||
sha
|
||||
}: {
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
deletedFiles: string[]
|
||||
sha: string
|
||||
}): Promise<void> => {
|
||||
if (inputs.recoverDeletedFiles) {
|
||||
for (const deletedFile of deletedFiles) {
|
||||
let target = path.join(workingDirectory, deletedFile)
|
||||
|
||||
if (inputs.recoverDeletedFilesToDestination) {
|
||||
target = path.join(
|
||||
workingDirectory,
|
||||
inputs.recoverDeletedFilesToDestination,
|
||||
deletedFile
|
||||
)
|
||||
}
|
||||
|
||||
const deletedFileContents = await getDeletedFileContents({
|
||||
cwd: workingDirectory,
|
||||
filePath: deletedFile,
|
||||
sha
|
||||
})
|
||||
|
||||
if (!(await exists(path.dirname(target)))) {
|
||||
await fs.mkdir(path.dirname(target), {recursive: true})
|
||||
}
|
||||
await fs.writeFile(target, deletedFileContents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
test/changed-files.yml
Normal file
16
test/changed-files.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
test:
|
||||
- test/**.txt
|
||||
src:
|
||||
- src/*.ts
|
||||
- '!src/__tests__/**'
|
||||
dist:
|
||||
- dist/**
|
||||
shared: &shared
|
||||
- .github/**
|
||||
common:
|
||||
- *shared
|
||||
- .gitignore
|
||||
multiline: |
|
||||
test/**
|
||||
src/*.ts
|
||||
.github/**
|
||||
Reference in New Issue
Block a user