-
Notifications
You must be signed in to change notification settings - Fork 0
289 lines (238 loc) · 10.6 KB
/
weekly-governance-audit.yml
File metadata and controls
289 lines (238 loc) · 10.6 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
name: Weekly Governance Audit
on:
schedule:
# Run weekly on Sunday at midnight UTC
- cron: '0 0 * * 0'
workflow_dispatch:
inputs:
run_all_audits:
description: 'Run all audit checks (including planned ones)'
required: false
default: 'false'
type: boolean
jobs:
audit:
runs-on: ubuntu-latest
name: Weekly Governance Audit
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
# GATE-003: Trace Link Validation (Weekly Scan)
- name: GATE-003 - Trace Link Validation (Weekly Scan)
id: trace_links
run: |
echo "🔍 Running weekly trace link validation..."
set +e
OUTPUT=$(python scripts/validate_trace_links.py --check-all --verbose 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
# Count broken links
BROKEN_COUNT=$(echo "$OUTPUT" | grep -c "BROKEN LINKS" || echo "0")
echo "broken_links=$BROKEN_COUNT" >> $GITHUB_OUTPUT
if [ $EXIT_CODE -ne 0 ]; then
echo "trace_status=failed" >> $GITHUB_OUTPUT
else
echo "trace_status=passed" >> $GITHUB_OUTPUT
fi
continue-on-error: true
# GATE-016: Staleness Detection (Weekly Scan)
- name: GATE-016 - Staleness Detection
id: staleness
run: |
echo "🔍 Checking for stale artifacts..."
if [ -f "scripts/check_staleness.py" ]; then
set +e
OUTPUT=$(python scripts/check_staleness.py --all 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
if [ $EXIT_CODE -eq 0 ]; then
echo "staleness_status=passed" >> $GITHUB_OUTPUT
else
echo "staleness_status=failed" >> $GITHUB_OUTPUT
fi
else
echo "⚠️ Staleness check script not yet implemented (planned)"
echo "staleness_status=planned" >> $GITHUB_OUTPUT
fi
continue-on-error: true
# GATE-017: Shadow Registry Detection (Weekly Scan)
- name: GATE-017 - Shadow Registry Detection
id: shadow_registry
run: |
echo "🔍 Detecting shadow registries..."
if [ -f "scripts/detect_shadow_registries.py" ]; then
set +e
OUTPUT=$(python scripts/detect_shadow_registries.py --namespaces ATA99 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
if [ $EXIT_CODE -eq 0 ]; then
echo "shadow_status=passed" >> $GITHUB_OUTPUT
else
echo "shadow_status=failed" >> $GITHUB_OUTPUT
fi
else
echo "⚠️ Shadow registry detection script not yet implemented (planned)"
echo "shadow_status=planned" >> $GITHUB_OUTPUT
fi
continue-on-error: true
# GATE-002: Schema Registry Validation (Weekly)
- name: GATE-002 - Schema Registry Audit
id: schema_audit
run: |
echo "🔍 Auditing schema registry..."
set +e
OUTPUT=$(python scripts/validate_schema_registry.py --check-all --verbose 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q "REGISTRY_MISSING"; then
echo "schema_status=registry_missing" >> $GITHUB_OUTPUT
elif [ $EXIT_CODE -ne 0 ]; then
echo "schema_status=failed" >> $GITHUB_OUTPUT
else
echo "schema_status=passed" >> $GITHUB_OUTPUT
fi
continue-on-error: true
# GATE-001: Nomenclature Audit (Weekly)
- name: GATE-001 - Nomenclature Audit
id: nomenclature_audit
run: |
echo "🔍 Running weekly nomenclature audit..."
set +e
OUTPUT=$(python validate_nomenclature.py --standard v6.0 --check-all --strict --verbose 2>&1)
EXIT_CODE=$?
set -e
echo "$OUTPUT"
# Count invalid files
INVALID_COUNT=$(echo "$OUTPUT" | grep -c "^✗" || echo "0")
echo "invalid_count=$INVALID_COUNT" >> $GITHUB_OUTPUT
if [ $EXIT_CODE -ne 0 ]; then
echo "nomenclature_status=failed" >> $GITHUB_OUTPUT
else
echo "nomenclature_status=passed" >> $GITHUB_OUTPUT
fi
continue-on-error: true
# Generate Audit Summary
- name: Generate Audit Report
id: report
run: |
REPORT_DATE=$(date -u +"%Y-%m-%d")
cat << EOF > audit_report.md
# Weekly Governance Audit Report
**Date:** ${REPORT_DATE}
**Run ID:** ${{ github.run_id }}
## Audit Summary
| Gate | Status | Description |
|------|--------|-------------|
| GATE-001 | ${{ steps.nomenclature_audit.outputs.nomenclature_status == 'passed' && '✅ PASS' || '❌ FAIL' }} | Nomenclature Compliance |
| GATE-002 | ${{ steps.schema_audit.outputs.schema_status == 'passed' && '✅ PASS' || (steps.schema_audit.outputs.schema_status == 'registry_missing' && '⚠️ MISSING' || '❌ FAIL') }} | Schema Registry |
| GATE-003 | ${{ steps.trace_links.outputs.trace_status == 'passed' && '✅ PASS' || '❌ FAIL' }} | Trace Link Integrity |
| GATE-016 | ${{ steps.staleness.outputs.staleness_status == 'passed' && '✅ PASS' || (steps.staleness.outputs.staleness_status == 'planned' && '⏭️ PLANNED' || '❌ FAIL') }} | Staleness Detection |
| GATE-017 | ${{ steps.shadow_registry.outputs.shadow_status == 'passed' && '✅ PASS' || (steps.shadow_registry.outputs.shadow_status == 'planned' && '⏭️ PLANNED' || '❌ FAIL') }} | Shadow Registry Detection |
## Details
### Nomenclature Compliance (GATE-001)
- Status: ${{ steps.nomenclature_audit.outputs.nomenclature_status }}
- Invalid files: ${{ steps.nomenclature_audit.outputs.invalid_count }}
### Schema Registry (GATE-002)
- Status: ${{ steps.schema_audit.outputs.schema_status }}
### Trace Link Integrity (GATE-003)
- Status: ${{ steps.trace_links.outputs.trace_status }}
### Staleness Detection (GATE-016)
- Status: ${{ steps.staleness.outputs.staleness_status }}
### Shadow Registry Detection (GATE-017)
- Status: ${{ steps.shadow_registry.outputs.shadow_status }}
## Legend
- ✅ PASS: Audit check passed
- ❌ FAIL: Audit check failed
- ⚠️ MISSING: Required resource missing
- ⏭️ PLANNED: Audit not yet implemented
---
*Generated by Weekly Governance Audit workflow*
EOF
# Store date for use in JavaScript
echo "report_date=${REPORT_DATE}" >> $GITHUB_OUTPUT
cat audit_report.md
# Create issue if any audits failed
- name: Create Issue for Audit Failures
if: |
always() && (
steps.trace_links.outputs.trace_status == 'failed' ||
steps.nomenclature_audit.outputs.nomenclature_status == 'failed' ||
steps.schema_audit.outputs.schema_status == 'failed'
)
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Read the audit report
let reportContent = '';
try {
reportContent = fs.readFileSync('audit_report.md', 'utf8');
} catch (e) {
reportContent = 'Audit report generation failed. See workflow logs for details.';
}
// Use the date from the report step output for consistency
const date = '${{ steps.report.outputs.report_date }}' || new Date().toISOString().split('T')[0];
const title = `📋 Weekly Governance Audit - ${date}`;
// Check for existing open issue with exact title match
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'weekly-audit,governance',
state: 'open'
});
const body = `## Weekly Governance Audit Results
${reportContent}
### Required Actions
Please review and address the audit findings:
1. **Nomenclature violations**: Rename files to follow the nomenclature standard
2. **Broken trace links**: Fix or remove broken links
3. **Schema issues**: Register missing schemas or fix conflicts
### Reference
- **Workflow**: Weekly Governance Audit
- **Run ID**: ${{ github.run_id }}
- **Gate Index**: \`00_AMPEL360_SPACET_Q10_GEN_PLUS_BB_GEN_LC01_K04_DATA__ci-governance-gates_I01-R01.md\`
---
*This issue was automatically created by the weekly governance audit.*`;
// Find existing issue with exact title match for this week's audit
const existingIssue = issues.data.find(issue => issue.title === title);
if (existingIssue) {
// Update existing issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: body
});
console.log(`Updated existing audit issue #${existingIssue.number}`);
} else {
// Create new issue
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['weekly-audit', 'governance', 'K06']
});
console.log(`Created new audit issue #${issue.data.number}`);
}
# Upload audit report as artifact
- name: Upload Audit Report
if: always()
uses: actions/upload-artifact@v4
with:
name: weekly-audit-report
path: audit_report.md
retention-days: 90