microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/886-python-lint-fix

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.github/skills/shared/pr-reference/scripts/generate.sh

208lines · modecode

1#!/usr/bin/env bash
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4
5# generate.sh
6# Generates a PR reference file with commit history and full diff.
7# The output XML is consumed by GitHub Copilot to produce accurate PR descriptions.
8#
9# Compares the current branch with a specified base branch (default: main)
10# and writes an XML document containing commit history and diff information.
11
12set -euo pipefail
13
14# Display usage information
15show_usage() {
16 echo "Usage: ${0##*/} [OPTIONS]"
17 echo ""
18 echo "Options:"
19 echo " --no-md-diff Exclude markdown files (*.md) from the diff output"
20 echo " --base-branch Specify the base branch to compare against (default: main)"
21 echo " Use 'auto' to detect the remote default branch"
22 echo " --merge-base Use git merge-base for three-way comparison"
23 echo " --exclude-ext Comma-separated extensions to exclude (e.g., yml,yaml,json)"
24 echo " --exclude-path Comma-separated path prefixes to exclude (e.g., docs/,.github/)"
25 echo " --output Specify output file path (default: .copilot-tracking/pr/pr-reference.xml)"
26 echo " --help, -h Show this help message"
27 exit 1
28}
29
30# Get the repository root directory
31REPO_ROOT=$(git rev-parse --show-toplevel)
32
33# Resolve the remote default branch via symbolic-ref
34resolve_default_branch() {
35 local sym_ref
36 sym_ref=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || true)
37 if [[ -n "${sym_ref}" ]]; then
38 # Strip refs/remotes/ prefix to get origin/<branch>
39 echo "${sym_ref#refs/remotes/}"
40 else
41 echo "origin/main"
42 fi
43}
44
45# Process command line arguments
46NO_MD_DIFF=false
47USE_MERGE_BASE=false
48BASE_BRANCH="origin/main"
49EXCLUDE_EXT=""
50EXCLUDE_PATH=""
51OUTPUT_FILE="${REPO_ROOT}/.copilot-tracking/pr/pr-reference.xml"
52while [[ $# -gt 0 ]]; do
53 case "$1" in
54 --no-md-diff)
55 NO_MD_DIFF=true
56 shift
57 ;;
58 --merge-base)
59 USE_MERGE_BASE=true
60 shift
61 ;;
62 --base-branch)
63 if [[ -z "${2:-}" || "$2" == --* ]]; then
64 echo "Error: --base-branch requires an argument" >&2
65 show_usage
66 fi
67 BASE_BRANCH="$2"
68 shift 2
69 ;;
70 --exclude-ext)
71 if [[ -z "${2:-}" || "$2" == --* ]]; then
72 echo "Error: --exclude-ext requires an argument" >&2
73 show_usage
74 fi
75 EXCLUDE_EXT="$2"
76 shift 2
77 ;;
78 --exclude-path)
79 if [[ -z "${2:-}" || "$2" == --* ]]; then
80 echo "Error: --exclude-path requires an argument" >&2
81 show_usage
82 fi
83 EXCLUDE_PATH="$2"
84 shift 2
85 ;;
86 --output)
87 if [[ -z "${2:-}" || "$2" == --* ]]; then
88 echo "Error: --output requires an argument" >&2
89 show_usage
90 fi
91 OUTPUT_FILE="$2"
92 shift 2
93 ;;
94 --help|-h)
95 show_usage
96 ;;
97 *)
98 echo "Unknown option: $1" >&2
99 show_usage
100 ;;
101 esac
102done
103
104# Resolve auto base branch
105if [[ "${BASE_BRANCH}" == "auto" ]]; then
106 BASE_BRANCH=$(resolve_default_branch)
107fi
108
109# Verify the base branch exists
110if ! git rev-parse --verify "${BASE_BRANCH}" &>/dev/null; then
111 echo "Error: Branch '${BASE_BRANCH}' does not exist or is not accessible" >&2
112 exit 1
113fi
114
115# Resolve comparison ref via merge-base when requested
116COMPARISON_REF="${BASE_BRANCH}"
117if [[ "${USE_MERGE_BASE}" == "true" ]]; then
118 MERGE_BASE_REF=$(git merge-base HEAD "${BASE_BRANCH}" 2>/dev/null || true)
119 if [[ -n "${MERGE_BASE_REF}" ]]; then
120 COMPARISON_REF="${MERGE_BASE_REF}"
121 else
122 echo "Warning: merge-base resolution failed, using direct comparison" >&2
123 fi
124fi
125
126# Build pathspec exclusion arguments
127build_pathspec_args() {
128 local specs=()
129 if [[ "${NO_MD_DIFF}" == "true" ]]; then
130 specs+=(':!*.md')
131 fi
132 if [[ -n "${EXCLUDE_EXT}" ]]; then
133 IFS=',' read -ra exts <<< "${EXCLUDE_EXT}"
134 for ext in "${exts[@]}"; do
135 ext="${ext#.}"
136 if [[ -n "${ext}" ]]; then
137 specs+=(":!*.${ext}")
138 fi
139 done
140 fi
141 if [[ -n "${EXCLUDE_PATH}" ]]; then
142 IFS=',' read -ra paths <<< "${EXCLUDE_PATH}"
143 for p in "${paths[@]}"; do
144 p="${p%/}"
145 if [[ -n "${p}" ]]; then
146 specs+=(":!${p}/**")
147 fi
148 done
149 fi
150 if [[ ${#specs[@]} -gt 0 ]]; then
151 printf '%s\n' "${specs[@]}"
152 fi
153}
154
155mapfile -t PATHSPEC_ARGS < <(build_pathspec_args)
156
157# Set output file path and ensure parent directory exists
158PR_REF_FILE="${OUTPUT_FILE}"
159mkdir -p "$(dirname "${PR_REF_FILE}")"
160
161# Create the reference file with commit history using XML tags
162{
163 echo "<commit_history>"
164 echo " <current_branch>"
165 git --no-pager branch --show-current
166 echo " </current_branch>"
167 echo ""
168
169 echo " <base_branch>"
170 echo " ${BASE_BRANCH}"
171 echo " </base_branch>"
172 echo ""
173
174 echo " <commits>"
175 # Output commit information including subject and body
176 git --no-pager log --pretty=format:"<commit hash=\"%h\" date=\"%cd\"><message><subject><\![CDATA[%s]]></subject><body><\![CDATA[%b]]></body></message></commit>" --date=short "${COMPARISON_REF}"..HEAD
177 echo " </commits>"
178 echo ""
179
180 # Add the full diff, excluding specified files
181 echo " <full_diff>"
182 if [[ ${#PATHSPEC_ARGS[@]} -gt 0 ]]; then
183 git --no-pager diff "${COMPARISON_REF}" -- "${PATHSPEC_ARGS[@]}"
184 else
185 git --no-pager diff "${COMPARISON_REF}"
186 fi
187 echo " </full_diff>"
188 echo "</commit_history>"
189} >"${PR_REF_FILE}"
190
191LINE_COUNT=$(wc -l <"${PR_REF_FILE}" | awk '{print $1}')
192
193echo "Created ${PR_REF_FILE}"
194if [[ "${NO_MD_DIFF}" == "true" ]]; then
195 echo "Note: Markdown files were excluded from diff output"
196fi
197if [[ -n "${EXCLUDE_EXT}" ]]; then
198 echo "Note: Extensions excluded from diff: ${EXCLUDE_EXT}"
199fi
200if [[ -n "${EXCLUDE_PATH}" ]]; then
201 echo "Note: Paths excluded from diff: ${EXCLUDE_PATH}"
202fi
203if [[ "${USE_MERGE_BASE}" == "true" ]]; then
204 echo "Comparison mode: merge-base"
205fi
206echo "Lines: ${LINE_COUNT}"
207echo "Base branch: ${BASE_BRANCH}"
208echo "File name: ${PR_REF_FILE}"
209