22name : Secret Scan (Gitleaks) [Report-Only]
33
44on :
5- push :
6- branches : [main, develop]
75 pull_request :
86 branches : [main, develop]
7+ push :
8+ branches : [main]
99 workflow_dispatch :
1010
1111concurrency :
@@ -18,7 +18,7 @@ permissions:
1818
1919jobs :
2020 gitleaks :
21- name : Gitleaks Scan (SARIF + Artifacts ) [Report-Only]
21+ name : Gitleaks Scan (PR-fast / Main-full ) [Report-Only]
2222 runs-on : ubuntu-latest
2323 timeout-minutes : 15
2424
@@ -31,10 +31,11 @@ jobs:
3131 CONFIG_FILE : " .gitleaks.toml"
3232
3333 steps :
34- - name : Checkout (full history )
34+ - name : Checkout (PR-fast / Main-full )
3535 uses : actions/checkout@v4
3636 with :
37- fetch-depth : 0
37+ # PR: shallow is fine (fast). Main push: full history for maximum coverage.
38+ fetch-depth : ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && 0 || 2 }}
3839
3940 - name : Ensure output folder exists
4041 shell : bash
5253 sudo mv /tmp/gitleaks /usr/local/bin/gitleaks
5354 gitleaks version
5455
55- - name : Run Gitleaks (single run ) [Report-Only]
56+ - name : Run Gitleaks (PR-fast / Main-full ) [Report-Only]
5657 if : always()
5758 shell : bash
5859 run : |
@@ -64,28 +65,35 @@ jobs:
6465 CFG=(--config="${CONFIG_FILE}")
6566 fi
6667
67- # Run once, produce JSON, and capture log. Exit code is ignored intentionally.
68+ # PR: scan working tree only (no history) to keep it fast.
69+ # Main push: full history (because fetch-depth=0).
70+ EXTRA=()
71+ if [ "${{ github.event_name }}" = "pull_request" ]; then
72+ EXTRA=(--no-git)
73+ fi
74+
6875 gitleaks detect \
6976 --source="." \
7077 --redact \
7178 "${CFG[@]}" \
79+ "${EXTRA[@]}" \
7280 --report-format="json" \
7381 --report-path="${OUT_DIR}/${OUT_JSON}" \
7482 2>&1 | tee "${OUT_DIR}/${OUT_LOG}"
7583
76- # Create SARIF from JSON (single scan, dual outputs )
84+ # Convert JSON -> SARIF (no re- scan)
7785 python3 - << 'PY'
7886 import json, os, sys
7987 out_dir = os.environ["OUT_DIR"]
8088 json_path = os.path.join(out_dir, os.environ["OUT_JSON"])
8189 sarif_path = os.path.join(out_dir, os.environ["OUT_SARIF"])
90+ ver = os.environ.get("GITLEAKS_VERSION","0")
8291
83- # Baseline SARIF skeleton
8492 sarif = {
8593 "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
8694 "version": "2.1.0",
8795 "runs": [{
88- "tool": {"driver": {"name": "gitleaks", "version": os.environ.get("GITLEAKS_VERSION","0") }},
96+ "tool": {"driver": {"name": "gitleaks", "version": ver }},
8997 "results": []
9098 }]
9199 }
@@ -94,34 +102,34 @@ jobs:
94102 with open(json_path, "r", encoding="utf-8") as f:
95103 data = json.load(f)
96104 except Exception:
97- # If JSON missing or invalid, still write baseline SARIF
98105 with open(sarif_path, "w", encoding="utf-8") as f:
99106 json.dump(sarif, f, ensure_ascii=False, indent=2)
100107 sys.exit(0)
101108
102- # Gitleaks JSON is typically a list of findings
103109 if isinstance(data, list):
104110 for item in data:
105111 file_path = item.get("File") or item.get("file") or item.get("Path") or ""
106112 start_line = item.get("StartLine") or item.get("startLine") or item.get("Line") or item.get("line") or 1
107113 rule_id = item.get("RuleID") or item.get("ruleID") or item.get("Rule") or "gitleaks"
108114 desc = item.get("Description") or item.get("description") or "Potential secret detected"
109- secret = item.get("Secret") or item.get("secret") or ""
110- # Keep message minimal (avoid reproducing secrets)
111115 msg = f"{desc} (rule: {rule_id})"
112116
113- res = {
117+ try:
118+ start_line = int(start_line)
119+ except Exception:
120+ start_line = 1
121+
122+ sarif["runs"][0]["results"].append({
114123 "ruleId": str(rule_id),
115124 "level": "error",
116125 "message": {"text": msg},
117126 "locations": [{
118127 "physicalLocation": {
119128 "artifactLocation": {"uri": file_path},
120- "region": {"startLine": int( start_line) if str(start_line).isdigit() else 1 }
129+ "region": {"startLine": start_line}
121130 }
122131 }]
123- }
124- sarif["runs"][0]["results"].append(res)
132+ })
125133
126134 with open(sarif_path, "w", encoding="utf-8") as f:
127135 json.dump(sarif, f, ensure_ascii=False, indent=2)
0 commit comments