diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 31561dc5..19f7c43f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,13 +40,13 @@ jobs: path: dir1 - name: Show output run: | - echo "${{ toJSON(steps.changed-files-dir1.outputs) }}" + echo '${{ toJSON(steps.changed-files-dir1.outputs) }}' shell: bash - name: List all modified files run: | for file in "${{ steps.changed-files-dir1.outputs.modified_files }}"; do - echo $file + echo "$file" done shell: bash @@ -62,13 +62,13 @@ jobs: path: dir2 - name: Show output run: | - echo "${{ toJSON(steps.changed-files-dir2.outputs) }}" + echo '${{ toJSON(steps.changed-files-dir2.outputs) }}' shell: bash - name: List all modified files run: | for file in "${{ steps.changed-files-dir2.outputs.modified_files }}"; do - echo $file + echo "$file" done shell: bash @@ -114,7 +114,7 @@ jobs: uses: ./ - name: Show output run: | - echo "${{ toJSON(steps.changed-files.outputs) }}" + echo '${{ toJSON(steps.changed-files.outputs) }}' shell: bash - name: List all modified files @@ -130,6 +130,26 @@ jobs: echo "Your README.md has been modified ${{ steps.changed-files.outputs.modified_files }}." shell: bash + - name: Run changed-files with forward slash separator + id: changed-files-forward-slash + uses: ./ + with: + separator: "/" + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-forward-slash.outputs) }}' + shell: + bash + - name: Run changed-files with pipe separator + id: changed-files-pipe + uses: ./ + with: + separator: "|" + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-pipe.outputs) }}' + shell: + bash - name: Run changed-files with comma separator id: changed-files-comma uses: ./ @@ -137,7 +157,7 @@ jobs: separator: "," - name: Show output run: | - echo "${{ toJSON(steps.changed-files-comma.outputs) }}" + echo '${{ toJSON(steps.changed-files-comma.outputs) }}' shell: bash - name: Run changed-files with specific files @@ -147,6 +167,11 @@ jobs: files: | .github/workflows/test.yml action.yml + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-specific.outputs) }}' + shell: + bash - name: Verify any_changed files if: "!contains(steps.changed-files-specific.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific.outputs.all_modified_files, '.github/workflows/test.yml')" run: | @@ -156,11 +181,6 @@ jobs: fi shell: bash - - name: Show output - run: | - echo "${{ toJSON(steps.changed-files-specific.outputs) }}" - shell: - bash - name: Run changed-files with specific files comma check duplicates id: changed-files-specific-duplicate-output uses: ./ @@ -188,11 +208,60 @@ jobs: .github/workflows/test.yml action.yml separator: "," + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-specific-comma.outputs) }}' + shell: + bash - name: Verify any_changed files comma separator if: "!contains(steps.changed-files-specific-comma.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-comma.outputs.all_modified_files, '.github/workflows/test.yml')" + run: | + if [[ "${{ steps.changed-files-specific-comma.outputs.any_changed }}" != "false" ]]; then + echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific-comma.outputs.any_changed }})" + exit 1 + fi + shell: + bash + - name: Run changed-files with specific files pipe separator + id: changed-files-specific-pipe + uses: ./ + with: + files: | + .github/workflows/test.yml + action.yml + separator: "|" + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-specific-pipe.outputs) }}' + shell: + bash + - name: Verify any_changed files comma separator + if: "!contains(steps.changed-files-specific-pipe.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-pipe.outputs.all_modified_files, '.github/workflows/test.yml')" + run: | + if [[ "${{ steps.changed-files-specific-pipe.outputs.any_changed }}" != "false" ]]; then + echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific-pipe.outputs.any_changed }})" + exit 1 + fi + shell: + bash + - name: Run changed-files with specific files forward slash separator + id: changed-files-specific-forward-slash + uses: ./ + with: + files: | + .github/workflows/test.yml + action.yml + separator: "/" + - name: Show output + run: | + echo '${{ toJSON(steps.changed-files-specific-forward-slash.outputs) }}' + shell: + bash + - name: Verify any_changed files comma separator + if: "!contains(steps.changed-files-specific-forward-slash.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-forward-slash.outputs.all_modified_files, '.github/workflows/test.yml')" run: | if [[ "${{ steps.changed-files-specific.outputs.any_changed }}" != "false" ]]; then - echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific.outputs.any_changed }})" + echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific-forward-slash.outputs.any_changed }})" exit 1 fi shell: @@ -207,17 +276,17 @@ jobs: files: | .github/workflows/rebase.yml - name: Verify any_changed files - if: "!contains(steps.changed-files-specific.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific.outputs.all_modified_files, '.github/workflows/test.yml')" + if: "!contains(steps.changed-files-specific-source-file.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-source-file.outputs.all_modified_files, '.github/workflows/test.yml')" run: | - if [[ "${{ steps.changed-files-specific.outputs.any_changed }}" != "false" ]]; then - echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific.outputs.any_changed }})" + if [[ "${{ steps.changed-files-specific-source-file.outputs.any_changed }}" != "false" ]]; then + echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific-source-file.outputs.any_changed }})" exit 1 fi shell: bash - name: Show output run: | - echo "${{ toJSON(steps.changed-files-specific.outputs) }}" + echo '${{ toJSON(steps.changed-files-specific-source-file.outputs) }}' shell: bash - name: Run changed-files with specific files from a source file using a comma separator @@ -228,17 +297,17 @@ jobs: test/changed-files-list.txt separator: "," - name: Verify any_changed files comma separator - if: "!contains(steps.changed-files-specific-comma.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-comma.outputs.all_modified_files, '.github/workflows/test.yml')" + if: "!contains(steps.changed-files-specific-comma-source-file.outputs.all_modified_files, 'action.yml') && !contains(steps.changed-files-specific-comma-source-file.outputs.all_modified_files, '.github/workflows/test.yml')" run: | - if [[ "${{ steps.changed-files-specific.outputs.any_changed }}" != "false" ]]; then - echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific.outputs.any_changed }})" + if [[ "${{ steps.changed-files-specific-comma-source-file.outputs.any_changed }}" != "false" ]]; then + echo "Invalid output: Expected (false) got (${{ steps.changed-files-specific-comma-source-file.outputs.any_changed }})" exit 1 fi shell: bash - name: Show output run: | - echo "${{ toJSON(steps.changed-files-specific-comma.outputs) }}" + echo '${{ toJSON(steps.changed-files-specific-comma-source-file.outputs) }}' shell: bash - name: Run changed-files with custom sha @@ -248,7 +317,7 @@ jobs: sha: ${{ github.event.pull_request.head.sha }} - name: Show output run: | - echo "${{ toJSON(steps.changed-files-custom-sha.outputs) }}" + echo '${{ toJSON(steps.changed-files-custom-sha.outputs) }}' shell: bash - name: Get branch name @@ -267,7 +336,7 @@ jobs: base_sha: ${{ steps.last_successful_commit.outputs.commit_hash }} - name: Show output run: | - echo "${{ toJSON(steps.changed-files-custom-base-sha.outputs) }}" + echo '${{ toJSON(steps.changed-files-custom-base-sha.outputs) }}' shell: bash - name: Run changed-files with specific files (only-changed) @@ -287,6 +356,6 @@ jobs: bash - name: Show output run: | - echo "${{ toJSON(steps.changed-files-specific-only-changed.outputs) }}" + echo '${{ toJSON(steps.changed-files-specific-only-changed.outputs) }}' shell: bash diff --git a/action.yml b/action.yml index 10b31e7d..ec10159f 100644 --- a/action.yml +++ b/action.yml @@ -74,16 +74,7 @@ runs: using: 'composite' steps: - run: | - FILES=() - - if [[ -n $INPUT_FILES_FROM_SOURCE_FILE ]]; then - for file in $INPUT_FILES_FROM_SOURCE_FILE - do - FILES+=$(cat $file | sort -u | tr "\n" " " ) - done - fi - - echo "::set-output name=files::$FILES" + bash $GITHUB_ACTION_PATH/sourcefiles.sh id: source-input-files shell: bash env: @@ -101,7 +92,7 @@ runs: INPUT_SHA: ${{ inputs.sha }} INPUT_BASE_SHA: ${{ inputs.base_sha }} INPUT_TOKEN: ${{ inputs.token }} - INPUT_FILES: ${{ join(format('{0} {1}', inputs.files, steps.source-input-files.outputs.files), ' ') }} + INPUT_FILES: ${{ steps.source-input-files.outputs.files }} INPUT_SEPARATOR: ${{ inputs.separator }} INPUT_PATH: ${{ inputs.path }} diff --git a/entrypoint.sh b/entrypoint.sh index 2a33bbbe..268bf1ec 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -62,20 +62,18 @@ fi echo "Retrieving changes between $PREVIOUS_SHA ($TARGET_BRANCH) → $CURRENT_SHA ($CURRENT_BRANCH)" -UNIQUE_FILES=$(echo "$INPUT_FILES" | tr " " "\n" | sort -u | xargs -0) - -if [[ -z "$UNIQUE_FILES" ]]; then +if [[ -z "${INPUT_FILES[*]}" ]]; then echo "Getting diff..." - ADDED=$(git diff --diff-filter=A --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - COPIED=$(git diff --diff-filter=C --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - DELETED=$(git diff --diff-filter=D --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - MODIFIED=$(git diff --diff-filter=M --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - RENAMED=$(git diff --diff-filter=R --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - TYPE_CHANGED=$(git diff --diff-filter=T --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - UNMERGED=$(git diff --diff-filter=U --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - UNKNOWN=$(git diff --diff-filter=X --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - ALL_CHANGED=$(git diff --diff-filter="*ACDMRTUX" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") - ALL_MODIFIED_FILES=$(git diff --diff-filter="ACMR" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | tr "\n" "$INPUT_SEPARATOR" | sed "s/.$//") + ADDED=$(git diff --diff-filter=A --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + COPIED=$(git diff --diff-filter=C --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + DELETED=$(git diff --diff-filter=D --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + MODIFIED=$(git diff --diff-filter=M --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + RENAMED=$(git diff --diff-filter=R --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + TYPE_CHANGED=$(git diff --diff-filter=T --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + UNMERGED=$(git diff --diff-filter=U --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + UNKNOWN=$(git diff --diff-filter=X --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + ALL_CHANGED=$(git diff --diff-filter="*ACDMRTUX" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + ALL_MODIFIED_FILES=$(git diff --diff-filter="ACMR" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') else ADDED_ARRAY=() COPIED_ARRAY=() @@ -88,7 +86,7 @@ else ALL_CHANGED_ARRAY=() ALL_MODIFIED_FILES_ARRAY=() - for path in ${UNIQUE_FILES} + for path in ${INPUT_FILES} do echo "Checking for file changes: \"${path}\"..." IFS=" " @@ -114,26 +112,37 @@ else ALL_MODIFIED_FILES_ARRAY+=($(git diff --diff-filter="ACMR" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA" | grep -E "(${path})" | xargs -0 || true)) done - # shellcheck disable=SC2001 - ADDED=$(echo "${ADDED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - COPIED=$(echo "${COPIED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - DELETED=$(echo "${DELETED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - MODIFIED=$(echo "${MODIFIED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - RENAMED=$(echo "${RENAMED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - TYPE_CHANGED=$(echo "${TYPE_CHANGED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - UNMERGED=$(echo "${UNMERGED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - UNKNOWN=$(echo "${UNKNOWN_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - ALL_CHANGED=$(echo "${ALL_CHANGED_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) - # shellcheck disable=SC2001 - ALL_MODIFIED_FILES=$(echo "${ALL_MODIFIED_FILES_ARRAY[*]}" | sed 's/ */'"$INPUT_SEPARATOR"'/g' | tr " " "\n" | sort -u | xargs -0) + ADDED=$(echo "${ADDED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + COPIED=$(echo "${COPIED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + DELETED=$(echo "${DELETED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + MODIFIED=$(echo "${MODIFIED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + RENAMED=$(echo "${RENAMED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + TYPE_CHANGED=$(echo "${TYPE_CHANGED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + UNMERGED=$(echo "${UNMERGED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + UNKNOWN=$(echo "${UNKNOWN_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + ALL_CHANGED=$(echo "${ALL_CHANGED_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + ALL_MODIFIED_FILES=$(echo "${ALL_MODIFIED_FILES_ARRAY[*]}" | tr " " "\n" | sort -u | awk -v d="$INPUT_SEPARATOR" '{s=(NR==1?s:s d)$0}END{print s}') + + ALL_OTHER_CHANGED_FILES=$(git diff --diff-filter="ACMR" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA") + IFS=" " read -r -a UNIQUE_ALL_MODIFIED_FILES <<< "$(echo "${ALL_MODIFIED_FILES_ARRAY[*]}" | tr " " "\n" | sort -u | tr "\n" " ")" + IFS=" " read -r -a OTHER_CHANGED_FILES <<< "$(echo "${ALL_OTHER_CHANGED_FILES[@]}" "${UNIQUE_ALL_MODIFIED_FILES[@]}" | tr " " "\n" | sort | uniq -u | tr "\n" " ")" + + echo "Input files: ${INPUT_FILES[*]}" + echo "Matching modified files: ${UNIQUE_ALL_MODIFIED_FILES[*]}" + + if [[ -n "${UNIQUE_ALL_MODIFIED_FILES[*]}" ]]; then + echo "::set-output name=any_changed::true" + else + echo "::set-output name=any_changed::false" + fi + + if [[ -n "${OTHER_CHANGED_FILES[*]}" ]]; then + echo "Non Matching modified files: ${OTHER_CHANGED_FILES[*]}" + echo "::set-output name=only_changed::false" + echo "::set-output name=other_changed_files::$OTHER_CHANGED_FILES" + else + echo "::set-output name=only_changed::true" + fi fi echo "Added files: $ADDED" @@ -147,32 +156,6 @@ echo "Unknown files: $UNKNOWN" echo "All changed files: $ALL_CHANGED" echo "All modified files: $ALL_MODIFIED_FILES" -if [[ -n "$UNIQUE_FILES" ]]; then - # shellcheck disable=SC2001 - ALL_INPUT_FILES=$(echo "$UNIQUE_FILES" | tr "\n" " " | xargs -0) - ALL_OTHER_CHANGED_FILES=$(git diff --diff-filter="ACMR" --name-only "$PREVIOUS_SHA" "$CURRENT_SHA") - - OTHER_CHANGED_FILES=$(echo "${ALL_OTHER_CHANGED_FILES[@]}" "${ALL_MODIFIED_FILES[@]}" | tr " " "\n" | sort | uniq -u | tr "\n" " " | xargs -0) - - echo "Input files: ${ALL_INPUT_FILES[*]}" - echo "Matching modified files: ${ALL_MODIFIED_FILES[*]}" - - if [[ -n "$ALL_MODIFIED_FILES" ]]; then - echo "::set-output name=any_changed::true" - else - echo "::set-output name=any_changed::false" - fi - - if [[ -n "$OTHER_CHANGED_FILES" ]]; then - echo "Non Matching modified files: ${OTHER_CHANGED_FILES[*]}" - echo "::set-output name=only_changed::false" - echo "::set-output name=other_changed_files::$OTHER_CHANGED_FILES" - else - echo "::set-output name=only_changed::true" - fi - -fi - git remote remove temp_changed_files echo "::set-output name=added_files::$ADDED" diff --git a/sourcefiles.sh b/sourcefiles.sh new file mode 100644 index 00000000..f7ba12a7 --- /dev/null +++ b/sourcefiles.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -e + +echo "::group::changed-files-from-source-file" + +IFS=" " read -r -a FILES <<< "$(echo "${INPUT_FILES[@]}" | sort -u | tr "\n" " ")" + +if [[ -n $INPUT_FILES_FROM_SOURCE_FILE ]]; then + for file in $INPUT_FILES_FROM_SOURCE_FILE + do + while read -r fileName; do + FILES+=("$fileName") + done <"$file" + done +fi + +echo "Input Files: ${FILES[*]}" + +IFS=" " read -r -a ALL_UNIQUE_FILES <<< "$(echo "${FILES[@]}" | tr " " "\n" | sort -u | tr "\n" " ")" + +echo "All Unique Input files: ${ALL_UNIQUE_FILES[*]}" + +echo "::set-output name=files::${ALL_UNIQUE_FILES[*]}" + +echo "::endgroup::"