Skip to content

Commit 03fa26f

Browse files
Include detailed summary
1 parent a15f545 commit 03fa26f

1 file changed

Lines changed: 97 additions & 11 deletions

File tree

.github/workflows/copyright-check.yml

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ jobs:
124124
echo "skip-validation=false" >> $GITHUB_OUTPUT
125125
fi
126126
127-
- name: Validate copyright headers
127+
- name: Validate
128128
id: validate
129129
if: steps.changed-files.outputs.skip-validation != 'true'
130130
run: |
131+
set -o pipefail
131132
echo "Starting copyright validation..."
132133
133134
# Debug: List current directory contents
@@ -170,7 +171,7 @@ jobs:
170171
echo "Running copyright validation..."
171172
echo "🔧 Command: python3 $script_path --config $config_file --working-dir target-repo $files_to_check"
172173
173-
if python3 "$script_path" --config "$config_file" --working-dir target-repo $files_to_check; then
174+
if python3 "$script_path" --config "$config_file" --working-dir target-repo $files_to_check > validation_output.txt 2>&1; then
174175
echo "✅ Copyright validation passed"
175176
echo "status=success" >> $GITHUB_OUTPUT
176177
else
@@ -179,19 +180,104 @@ jobs:
179180
exit 1
180181
fi
181182
183+
- name: Detailed Summary
184+
if: steps.changed-files.outputs.skip-validation != 'true'
185+
run: |
186+
python3 - <<'PY'
187+
import re, os
188+
summary_file = os.environ.get('GITHUB_STEP_SUMMARY')
189+
out_path = 'validation_output.txt'
190+
if not os.path.exists(out_path):
191+
with open(summary_file,'a') as s: s.write("No validation output captured.\n")
192+
raise SystemExit(0)
193+
with open(out_path,'r') as f:
194+
lines = f.read().splitlines()
195+
counts={'total':0,'valid':0,'invalid':0,'excluded':0}
196+
for line in lines:
197+
t=line.strip()
198+
for key,label in [('Total files checked','total'),('Valid files','valid'),('Invalid files','invalid'),('Excluded files','excluded')]:
199+
if t.startswith(key+':'):
200+
try: counts[label]=int(t.split(':',1)[1].strip())
201+
except: pass
202+
# Collect sections
203+
def collect_after(header):
204+
res=[]; active=False
205+
for l in lines:
206+
s=l.strip()
207+
if s==header:
208+
active=True; continue
209+
if active:
210+
if not s: break
211+
if s.endswith(':') and s in ('Excluded files:','Valid files:'): break
212+
if '/' in s:
213+
path=s[s.index('/'):] # from first slash
214+
res.append(path.strip())
215+
return res
216+
excluded = collect_after('Excluded files:')
217+
valid_sec = collect_after('Valid files:')
218+
# Invalid blocks
219+
invalid=[]
220+
i=0
221+
n=len(lines)
222+
while i<n:
223+
s=lines[i].strip()
224+
if '/' in s and not any(s.startswith(h) for h in ('Total files checked','Valid files:','Invalid files:','Excluded files:')) and 'Validation Results' not in s:
225+
path = s[s.index('/'):] if '/' in s else None
226+
found=expected=error=None
227+
j=i+1
228+
while j<n:
229+
t=lines[j].strip()
230+
if not t: break
231+
if t.startswith('Found:'): found=t.split('Found:',1)[1].strip()
232+
elif t.startswith('Expected:'): expected=t.split('Expected:',1)[1].strip()
233+
elif t.startswith('Error:'): error=t.split('Error:',1)[1].strip()
234+
elif '/' in t and t.split('/',1)[0].strip()=='' and expected: break
235+
j+=1
236+
if path and expected:
237+
invalid.append({'file':path,'found':found,'expected':expected,'error':error})
238+
i=j; continue
239+
i+=1
240+
# Deduplicate
241+
seen=set(); uniq=[]
242+
for item in invalid:
243+
if item['file'] not in seen:
244+
uniq.append(item); seen.add(item['file'])
245+
invalid=uniq
246+
success = counts.get('invalid',0)==0
247+
header = '## ✅ Copyright Validation Passed' if success else '## ❌ Copyright Validation Failed'
248+
parts=[f"Total: {counts['total']}", f"Passed: {counts['valid']}", f"Failed: {counts['invalid']}"]
249+
if counts.get('excluded'): parts.append(f"Skipped: {counts['excluded']}")
250+
md=[header,' | '.join(parts),'']
251+
if invalid:
252+
md.append('### Failed Files')
253+
for f in invalid:
254+
md.append(f"❌ `{f['file']}`")
255+
if f.get('found'): md.append(f" Found: {f['found']}")
256+
if f.get('expected'): md.append(f" Expected: {f['expected']}")
257+
if f.get('error'): md.append(f" Error: {f['error']}")
258+
md.append('')
259+
if excluded:
260+
md.append('### Skipped Files')
261+
for f in excluded: md.append(f"⏭️ `{f}`")
262+
md.append('')
263+
if valid_sec:
264+
md.append('### Passed Files')
265+
for f in valid_sec: md.append(f"✅ `{f}`")
266+
md.append('')
267+
if not success:
268+
md.append('### Fix Guidance')
269+
md.append('Update headers to match Expected line above; then push changes.')
270+
with open(summary_file,'a') as s:
271+
s.write('\n'.join(md)+'\n')
272+
PY
273+
182274
- name: Summary
183275
if: always()
184276
run: |
185-
files_count="${{ steps.changed-files.outputs.files-count }}"
186-
187277
if [ "${{ steps.changed-files.outputs.skip-validation }}" = "true" ]; then
188-
echo "ℹ️ No files to validate - skipped copyright check"
189-
echo "::notice title=Copyright Check::No files changed or all files excluded"
278+
echo "::notice title=Copyright Check::No files to validate"
190279
elif [ "${{ steps.validate.outputs.status }}" = "success" ]; then
191-
echo "✅ Copyright validation completed successfully"
192-
echo "::notice title=Copyright Check Passed::All $files_count changed files have valid copyright headers"
280+
echo "::notice title=Copyright Check Passed::All files valid"
193281
else
194-
echo "❌ Copyright validation failed"
195-
echo "::error title=Copyright Check Failed::Some of the $files_count changed files have invalid or missing copyright headers. Check the logs above for details."
196-
exit 1
282+
echo "::error title=Copyright Check Failed::Some files invalid"; exit 1
197283
fi

0 commit comments

Comments
 (0)