-
Notifications
You must be signed in to change notification settings - Fork 0
/
action.yml
138 lines (114 loc) · 4.92 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Copyright (c) Gabriel Santerre
# SPDX-License-Identifier: MIT
name: Setup
description: The only action you'll need before running the main step of a CI job.
inputs:
output-changed-files:
required: false
description: Wether or not to output the changed files list.
default: "false"
changed-files-filters:
required: false
description: Using glob patterns to filter changed files.
outputs:
changed-files:
description: Changed Files
value: ${{ steps.metadata-changed-files.outputs.changed-files }}
runs:
using: composite
steps:
- name: Checkout Metadata
id: metadata-checkout
if: ${{ inputs.output-changed-files == 'true' }}
shell: bash
run: |
FETCH_DEPTH=$(( ${{ github.event.pull_request.commits || 1 }} + 1 ))
echo "fetch-depth=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
CURRENT_COMMIT_SHA="${{ github.event.pull_request.head.sha || github.sha }}"
echo "current-commit-sha=$CURRENT_COMMIT_SHA" >> "$GITHUB_OUTPUT"
- name: Checkout Repository
uses: actions/[email protected]
with:
fetch-depth: ${{ steps.metadata-checkout.outputs.fetch-depth || 1 }}
ref: ${{ steps.metadata-checkout.outputs.current-commit-sha }}
- name: Output Changed Files
id: metadata-changed-files
if: ${{ inputs.output-changed-files == 'true' }}
shell: bash
run: |
PARENT_COMMIT_COUNT=$(( ${{ steps.metadata-checkout.outputs.fetch-depth }} - 1 ))
BASE_COMMIT_SHA=$(git rev-list -n 1 ${{ steps.metadata-checkout.outputs.current-commit-sha }}~$PARENT_COMMIT_COUNT)
CHANGED_FILES=$(git diff --name-status $BASE_COMMIT_SHA..${{ steps.metadata-checkout.outputs.current-commit-sha }} | grep -E '^[ACMR]' | sed -e 's/^[ACMR]\s*//' -e 's/\s*$//' -e 's/ /\\ /g')
# Globstar pattern for filtering file paths
CHANGED_FILES_FILTERS="${{ inputs.changed-files-filters }}"
# Return all changed files if no filter provided
if [[ -z "$CHANGED_FILES_FILTERS" ]]; then
CHANGED_FILES=$(echo $CHANGED_FILES | tr '\n' ' ')
echo "changed-files=$CHANGED_FILES" >> "$GITHUB_OUTPUT"
exit 0
fi
# Enable glob
shopt -s globstar
shopt -s extglob
shopt -s dotglob
# Convert CHANGED_FILES_FILTERS to an array
CHANGED_FILES_FILTER_ARRAY=()
while IFS= read -r line; do
TRIMMED_LINE="${line#"${line%%[![:space:]]*}"}"
TRIMMED_LINE="${TRIMMED_LINE%"${TRIMMED_LINE##*[![:space:]]}"}"
if [[ -n "$TRIMMED_LINE" ]]; then
CHANGED_FILES_FILTER_ARRAY+=("$TRIMMED_LINE")
fi
done <<< "$CHANGED_FILES_FILTERS"
echo "::group::CHANGED_FILES_FILTER_ARRAY"
for CHANGED_FILES_FILTERS in "${CHANGED_FILES_FILTER_ARRAY[@]}"; do
echo "$CHANGED_FILES_FILTERS"
done
echo "::endgroup::"
# Convert CHANGED_FILES to an array
CHANGED_FILE_ARRAY=()
while IFS= read -r line; do
TRIMMED_LINE="${line#"${line%%[![:space:]]*}"}"
TRIMMED_LINE="${TRIMMED_LINE%"${TRIMMED_LINE##*[![:space:]]}"}"
if [[ -n "$TRIMMED_LINE" ]]; then
CHANGED_FILE_ARRAY+=("$TRIMMED_LINE")
fi
done <<< "$CHANGED_FILES"
echo "::group::CHANGED_FILE_ARRAY"
for CHANGED_FILE in "${CHANGED_FILE_ARRAY[@]}"; do
echo "$CHANGED_FILE"
done
echo "::endgroup::"
# Use filters to gather a list of files on the system
MATCHED_FILE_ARRAY=()
for CHANGED_FILE_FILTER in "${CHANGED_FILES_FILTER_ARRAY[@]}"; do
MATCHING_OUTPUT=$(ls --almost-all --escape -1 --color=never $CHANGED_FILE_FILTER)
# Read each line of the output into the array
while IFS= read -r line; do
MATCHED_FILE_ARRAY+=("$line")
done <<< "$MATCHING_OUTPUT"
done
echo "::group::MATCHED_FILE_ARRAY"
for MATCHED_FILE in "${MATCHED_FILE_ARRAY[@]}"; do
echo "$MATCHED_FILE"
done
echo "::endgroup::"
# Create an associative array to track unique elements
declare -A FILTERED_CHANGED_FILE_ASSOCIATIVE_ARRAY
# Intersect matched files with changed files
for MATCHED_FILE in "${MATCHED_FILE_ARRAY[@]}"; do
for CHANGED_FILE in "${CHANGED_FILE_ARRAY[@]}"; do
if [[ "$MATCHED_FILE" == "$CHANGED_FILE" ]]; then
FILTERED_CHANGED_FILE_ASSOCIATIVE_ARRAY["$MATCHED_FILE"]=1
fi
done
done
# Convert associative array to array
FILTERED_CHANGED_FILE_ARRAY=("${!FILTERED_CHANGED_FILE_ASSOCIATIVE_ARRAY[@]}")
echo "::group::FILTERED_CHANGED_FILE_ARRAY"
for CHANGED_FILE in "${FILTERED_CHANGED_FILE_ARRAY[@]}"; do
echo "$CHANGED_FILE"
done
echo "::endgroup::"
FILTERED_CHANGED_FILES="${FILTERED_CHANGED_FILE_ARRAY[@]}"
echo "changed-files=$FILTERED_CHANGED_FILES" >> "$GITHUB_OUTPUT"