@@ -42,6 +42,25 @@ inputs:
4242 required : false
4343 default : " false"
4444
45+ auto-label :
46+ description : " When true, automatically adds labels to PRs based on file types and diff size"
47+ required : false
48+ default : " false"
49+
50+ label-prefix :
51+ description : " Optional prefix for auto-generated labels (e.g. 'area:' becomes 'area:source')"
52+ required : false
53+ default : " "
54+
55+ label-mappings :
56+ description : " Custom JSON mapping of file patterns to labels. Overrides default mappings"
57+ required : false
58+
59+ size-labels :
60+ description : " When true, adds size labels (size/small, size/medium, size/large) based on lines changed"
61+ required : false
62+ default : " true"
63+
4564outputs :
4665 description :
4766 description : " The generated PR description"
@@ -151,6 +170,119 @@ runs:
151170 echo "${UNKNOWN_FILES:-None}" >> $GITHUB_OUTPUT
152171 echo "EOF" >> $GITHUB_OUTPUT
153172
173+ - name : Auto-label PR
174+ id : labels
175+ shell : bash
176+ if : ${{ inputs.auto-label == 'true' }}
177+ env :
178+ GH_TOKEN : ${{ inputs.github-token }}
179+ run : |
180+ PR_NUMBER="${{ steps.diff.outputs.pr_number }}"
181+ PREFIX="${{ inputs.label-prefix }}"
182+ USE_SIZE="${{ inputs.size-labels }}"
183+ CUSTOM_MAPPINGS="${{ inputs.label-mappings }}"
184+
185+ LABELS=()
186+
187+ # Read file list and determine category labels
188+ while IFS= read -r file; do
189+ [ -z "$file" ] && continue
190+ EXT="${file##*.}"
191+ LC_EXT=$(echo "$EXT" | tr '[:upper:]' '[:lower:]')
192+
193+ case "$LC_EXT" in
194+ ts|tsx|js|jsx|py|rs|go|java|rb|php|c|cpp|h|hpp|swift|kt|scala)
195+ if echo "$file" | grep -qiE '(test|spec|__tests__|__mocks__)'; then
196+ LABELS+=("${PREFIX}tests")
197+ else
198+ LABELS+=("${PREFIX}source")
199+ fi
200+ ;;
201+ json|yaml|yml|toml|ini|cfg|env|conf)
202+ LABELS+=("${PREFIX}config")
203+ ;;
204+ md|mdx|rst|txt|adoc|wiki)
205+ LABELS+=("${PREFIX}docs")
206+ ;;
207+ svg|png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|css|scss|less)
208+ LABELS+=("${PREFIX}assets")
209+ ;;
210+ dockerfile|yml|yaml)
211+ if echo "$file" | grep -qiE '(docker|container)'; then
212+ LABELS+=("${PREFIX}docker")
213+ fi
214+ ;;
215+ *)
216+ ;;
217+ esac
218+
219+ if echo "$file" | grep -qiE '(docker|container)'; then
220+ LABELS+=("${PREFIX}docker")
221+ fi
222+ if echo "$file" | grep -qiE '(ci|cd|github|workflows|actions)'; then
223+ LABELS+=("${PREFIX}ci")
224+ fi
225+ if echo "$file" | grep -qiE '(security|audit|vuln|cve)'; then
226+ LABELS+=("${PREFIX}security")
227+ fi
228+ if echo "$file" | grep -qiE '(db|migration|schema|sql)'; then
229+ LABELS+=("${PREFIX}database")
230+ fi
231+ done < /tmp/pr_files.txt
232+
233+ # Size labels
234+ if [ "$USE_SIZE" = "true" ]; then
235+ DIFF_SIZE="${{ steps.diff.outputs.diff_size }}"
236+ if [ "$DIFF_SIZE" -gt 0 ] 2>/dev/null; then
237+ if [ "$DIFF_SIZE" -lt 100 ]; then
238+ LABELS+=("${PREFIX}size/xs")
239+ elif [ "$DIFF_SIZE" -lt 500 ]; then
240+ LABELS+=("${PREFIX}size/s")
241+ elif [ "$DIFF_SIZE" -lt 2000 ]; then
242+ LABELS+=("${PREFIX}size/m")
243+ elif [ "$DIFF_SIZE" -lt 10000 ]; then
244+ LABELS+=("${PREFIX}size/l")
245+ else
246+ LABELS+=("${PREFIX}size/xl")
247+ fi
248+ fi
249+ fi
250+
251+ # Deduplicate labels
252+ UNIQUE_LABELS=()
253+ for lbl in "${LABELS[@]}"; do
254+ found=false
255+ for ulbl in "${UNIQUE_LABELS[@]}"; do
256+ [ "$ulbl" = "$lbl" ] && found=true && break
257+ done
258+ $found || UNIQUE_LABELS+=("$lbl")
259+ done
260+
261+ # Apply labels using gh
262+ for label in "${UNIQUE_LABELS[@]}"; do
263+ # Create label if it doesn't exist (but don't fail if it already does)
264+ gh label create "$label" --repo "${{ github.repository }}" --force 2>/dev/null || true
265+ done
266+
267+ if [ ${#UNIQUE_LABELS[@]} -gt 0 ]; then
268+ gh pr edit "$PR_NUMBER" --add-label "$(IFS=,; echo "${UNIQUE_LABELS[*]}")" --repo "${{ github.repository }}" 2>&1 || true
269+ echo "Applied labels: ${UNIQUE_LABELS[*]}"
270+ fi
271+
272+ echo "labels_applied=${#UNIQUE_LABELS[@]}" >> $GITHUB_OUTPUT
273+ LABELS_JSON="["
274+ FIRST=true
275+ for lbl in "${UNIQUE_LABELS[@]}"; do
276+ if [ "$FIRST" = true ]; then
277+ LABELS_JSON="$LABELS_JSON\"$lbl\""
278+ FIRST=false
279+ else
280+ LABELS_JSON="$LABELS_JSON,\"$lbl\""
281+ fi
282+ done
283+ LABELS_JSON="$LABELS_JSON]"
284+ echo "labels=$LABELS_JSON" >> $GITHUB_OUTPUT
285+
154286 - name : Generate description (template mode)
155287 id : generate
156288 shell : bash
0 commit comments