Skip to content

Commit 6e32376

Browse files
generate summary from copyright script
1 parent 03fa26f commit 6e32376

3 files changed

Lines changed: 168 additions & 489 deletions

File tree

.github/workflows/copyright-check.yml

Lines changed: 19 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -177,107 +177,30 @@ jobs:
177177
else
178178
echo "❌ Copyright validation failed"
179179
echo "status=failed" >> $GITHUB_OUTPUT
180-
exit 1
180+
# Still proceed to allow summary extraction and proper job summary; final job result handled later
181181
fi
182182
183-
- name: Detailed Summary
183+
- name: Job Summary (Markdown block extraction)
184184
if: steps.changed-files.outputs.skip-validation != 'true'
185185
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
186+
summary_file="$GITHUB_STEP_SUMMARY"
187+
if [ ! -f validation_output.txt ]; then
188+
echo "No validation output captured" >> "$summary_file"
189+
exit 0
190+
fi
191+
awk '/^<<<COPYRIGHT-CHECK:MARKDOWN>>>/{flag=1;next}/^<<<END COPYRIGHT-CHECK:MARKDOWN>>>/{flag=0}flag' validation_output.txt >> "$summary_file"
273192
274-
- name: Summary
275-
if: always()
193+
- name: Fail if needed
194+
if: steps.changed-files.outputs.skip-validation != 'true'
276195
run: |
277-
if [ "${{ steps.changed-files.outputs.skip-validation }}" = "true" ]; then
278-
echo "::notice title=Copyright Check::No files to validate"
279-
elif [ "${{ steps.validate.outputs.status }}" = "success" ]; then
280-
echo "::notice title=Copyright Check Passed::All files valid"
196+
if [ "${{ steps.validate.outputs.status }}" != "success" ]; then
197+
echo "::error title=Copyright Check Failed::Some files invalid"
198+
exit 1
281199
else
282-
echo "::error title=Copyright Check Failed::Some files invalid"; exit 1
200+
echo "::notice title=Copyright Check Passed::All files valid"
283201
fi
202+
203+
- name: No-op summary
204+
if: steps.changed-files.outputs.skip-validation == 'true'
205+
run: |
206+
echo "::notice title=Copyright Check::No files to validate"

0 commit comments

Comments
 (0)