Skip to content

Commit a0dd2a2

Browse files
samtuckerdavisopen-paws-bot
andauthored
ci: add CodeQL and desloppify quality gate (#28)
* ci: add CodeQL workflow (Python, security-extended) * ci: add desloppify quality gate (threshold 70, scan path .) * ci: add coderabbit.yaml for desloppify Add Tier 3 data pre-merge check and update tone instructions to include movement terminology. Aligns with org-wide coderabbit config standards. --------- Co-authored-by: open-paws-bot <bot@openpaws.ai>
1 parent f4365d0 commit a0dd2a2

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

.coderabbit.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# desloppify — Multi-language code quality scanner with advocacy extensions.
33
# Meta: the quality scanner is reviewed by the quality scanner.
44
language: en-US
5-
tone_instructions: "Direct and concise. Apply extra rigor — DRY violations and shallow abstractions here are especially ironic."
5+
tone_instructions: "Direct and concise. Flag actionable issues only. DRY violations here are especially ironic — apply extra rigor. Use movement terminology: campaign, investigation, coalition, farmed animal, slaughterhouse."
66

77
reviews:
88
profile: assertive
@@ -54,6 +54,9 @@ reviews:
5454
- name: "No speciesist idioms"
5555
mode: "error"
5656
instructions: "Fail on: 'livestock', 'master/slave', 'whitelist/blacklist', 'cattle vs pets', 'kill two birds', 'guinea pig' as test subject, 'farm' as industry euphemism."
57+
- name: "No Tier 3 data committed"
58+
mode: "error"
59+
instructions: "Fail if files contain activist or whistleblower identities, legal strategy or privileged attorney communications, operational security protocols with specific implementation details, investigative footage or chain of custody records, activist PII combining name and contact info and advocacy role, NGO internal financials or strategy docs from partner organizations, or critical credentials."
5760

5861
finishing_touches:
5962
unit_tests:

.github/workflows/codeql.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: "CodeQL"
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["main"]
8+
schedule:
9+
- cron: "17 4 * * 1"
10+
workflow_dispatch:
11+
12+
permissions:
13+
security-events: write
14+
packages: read
15+
actions: read
16+
contents: read
17+
18+
jobs:
19+
analyze:
20+
name: Analyze (${{ matrix.language }})
21+
runs-on: ubuntu-latest
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
language: ["python"]
26+
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Initialize CodeQL
31+
uses: github/codeql-action/init@v3
32+
with:
33+
languages: ${{ matrix.language }}
34+
queries: security-extended
35+
36+
- name: Autobuild
37+
uses: github/codeql-action/autobuild@v3
38+
39+
- name: Perform CodeQL Analysis
40+
uses: github/codeql-action/analyze@v3
41+
with:
42+
category: "/language:${{ matrix.language }}"

.github/workflows/desloppify.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Desloppify Quality Gate
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
quality:
12+
name: Code Quality Gate (score >= 70)
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
submodules: false
21+
22+
- uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.12'
25+
26+
- name: Cache desloppify install
27+
id: cache-desloppify
28+
uses: actions/cache@v4
29+
with:
30+
path: /tmp/desloppify
31+
key: desloppify-${{ runner.os }}-${{ hashFiles('.github/workflows/desloppify.yml') }}
32+
33+
- name: Clone desloppify
34+
if: steps.cache-desloppify.outputs.cache-hit != 'true'
35+
run: |
36+
git clone --no-recurse-submodules https://github.com/Open-Paws/desloppify.git /tmp/desloppify
37+
38+
- name: Install desloppify
39+
run: pip install "/tmp/desloppify[full]"
40+
41+
- name: Run quality gate
42+
run: |
43+
SCAN_PATH="."
44+
THRESHOLD=70
45+
SCAN_OUTPUT=$(desloppify scan --path "${SCAN_PATH}" --profile ci --no-badge 2>&1)
46+
echo "${SCAN_OUTPUT}"
47+
SCORE=$(echo "${SCAN_OUTPUT}" | grep -oP 'objective \K[\d.]+(?=/100)')
48+
if [ -z "${SCORE}" ]; then
49+
echo "ERROR: could not extract objective score from desloppify output"
50+
exit 1
51+
fi
52+
echo "Objective score: ${SCORE}/100"
53+
python3 -c "
54+
score = float('${SCORE}')
55+
threshold = ${THRESHOLD}
56+
if score < threshold:
57+
print(f'FAIL: objective score {score} is below the minimum {threshold}')
58+
raise SystemExit(1)
59+
print(f'PASS: objective score {score} >= {threshold}')
60+
"
61+
echo "## Desloppify Quality Gate" >> "${GITHUB_STEP_SUMMARY}"
62+
echo "" >> "${GITHUB_STEP_SUMMARY}"
63+
echo "| | |" >> "${GITHUB_STEP_SUMMARY}"
64+
echo "|---|---|" >> "${GITHUB_STEP_SUMMARY}"
65+
echo "| Objective score | **${SCORE}/100** |" >> "${GITHUB_STEP_SUMMARY}"
66+
echo "| Threshold | ${THRESHOLD} |" >> "${GITHUB_STEP_SUMMARY}"
67+
echo "| Scan path | \`${SCAN_PATH}\` |" >> "${GITHUB_STEP_SUMMARY}"
68+
python3 -c "
69+
score = float('${SCORE}')
70+
result = 'PASS' if score >= ${THRESHOLD} else 'FAIL'
71+
print(f'| Result | **{result}** |')
72+
" >> "${GITHUB_STEP_SUMMARY}"

0 commit comments

Comments
 (0)