Skip to content

Commit 1ddefbc

Browse files
committed
changes
1 parent 62433df commit 1ddefbc

File tree

3 files changed

+196
-16
lines changed

3 files changed

+196
-16
lines changed
Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
name: Validate SumoLogic Queries
22
on:
3+
push:
4+
paths:
5+
- '**/*.md'
36
pull_request:
47
paths:
58
- '**/*.md'
6-
types:
7-
- review_requested
89

910
jobs:
1011
validate-queries:
@@ -14,30 +15,66 @@ jobs:
1415
with:
1516
fetch-depth: 0 # Required for git diff detection
1617

17-
- name: Fetch pull request branch
18-
run: git fetch origin ${{ github.event.pull_request.head.ref }}:${{ github.event.pull_request.head.ref }}
19-
20-
- name: Checkout PR branch
21-
run: git checkout ${{ github.event.pull_request.head.ref }}
22-
23-
- name: Debug Git Log
24-
run: git log --oneline -n 10
25-
git diff --name-only --diff-filter=AM origin/main...HEAD -- 'docs/**/*.md' > changed_files.txt
26-
echo "Files to validate:"
18+
- name: Check for SQL changes
19+
id: check-sql
20+
run: |
21+
# Get the base commit for comparison
22+
if [ "${{ github.event_name }}" = "pull_request" ]; then
23+
BASE_COMMIT="${{ github.event.pull_request.base.sha }}"
24+
else
25+
# For push events, compare with previous commit
26+
BASE_COMMIT="${{ github.event.before }}"
27+
fi
28+
29+
echo "Base commit: $BASE_COMMIT"
30+
echo "Current commit: ${{ github.sha }}"
31+
32+
# Get changed markdown files
33+
git diff --name-only --diff-filter=AM $BASE_COMMIT...${{ github.sha }} -- '**/*.md' > changed_files.txt
34+
35+
if [ ! -s changed_files.txt ]; then
36+
echo "No markdown files changed"
37+
echo "sql_changed=false" >> $GITHUB_OUTPUT
38+
exit 0
39+
fi
40+
41+
echo "Changed markdown files:"
2742
cat changed_files.txt
43+
44+
# Check if any of the changed files have SQL code block modifications
45+
SQL_CHANGED=false
46+
while IFS= read -r file; do
47+
if [ -f "$file" ]; then
48+
# Check if the diff contains changes to SQL code blocks
49+
if git diff $BASE_COMMIT...${{ github.sha }} -- "$file" | grep -E "^[+-].*\`\`\`(sql|sumo)" > /dev/null; then
50+
echo "SQL code block changes detected in: $file"
51+
SQL_CHANGED=true
52+
fi
53+
fi
54+
done < changed_files.txt
55+
56+
echo "sql_changed=$SQL_CHANGED" >> $GITHUB_OUTPUT
57+
echo "SQL changes detected: $SQL_CHANGED"
2858
2959
- name: Set up Python
60+
if: steps.check-sql.outputs.sql_changed == 'true'
3061
uses: actions/setup-python@v4
3162
with:
3263
python-version: "3.10"
3364

3465
- name: Install dependencies
66+
if: steps.check-sql.outputs.sql_changed == 'true'
3567
run: pip install requests python-dotenv
3668

3769
- name: Validate queries
70+
if: steps.check-sql.outputs.sql_changed == 'true'
3871
working-directory: ./scripts
3972
env:
4073
SUMO_LOGIC_ACCESS_ID: ${{ secrets.SUMO_LOGIC_ACCESS_ID }}
4174
SUMO_LOGIC_ACCESS_KEY: ${{ secrets.SUMO_LOGIC_ACCESS_KEY }}
4275
run: |
4376
python validate_queries.py
77+
78+
- name: Skip validation
79+
if: steps.check-sql.outputs.sql_changed == 'false'
80+
run: echo "No SQL code block changes detected, skipping validation"

β€Ždocs/metrics/metrics-operators/where.mdβ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ You can use the `where` operator to filter out either entire time series, or ind
1212
```sql
1313
where [VALUE BOOLEAN EXPRESSION | REDUCER BOOLEAN EXPRESSION]
1414
```
15-
15+
## Checking my PR:
16+
```sql
17+
_collector="ABC2" | where type="web"
18+
```
1619
Where:
1720

1821
* `[VALUE BOOLEAN EXPRESSION]` is a value expression that operates on individual data points of a time series. For example,

β€Žscripts/validate_queries.pyβ€Ž

Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,19 @@ def debug_environment():
2929

3030
def get_changed_files(repo_root):
3131
"""Find Markdown files to validate"""
32-
# Try GitHub PR context first
32+
# First try to read from changed_files.txt if it exists (from GitHub workflow)
33+
changed_files_path = repo_root / "changed_files.txt"
34+
if changed_files_path.exists():
35+
try:
36+
with open(changed_files_path) as f:
37+
files = [line.strip() for line in f if line.strip()]
38+
if files:
39+
print(f"πŸ“¦ Found {len(files)} changed Markdown files from workflow")
40+
return [str(repo_root / f) for f in files]
41+
except Exception as e:
42+
print(f"::warning::Couldn't read changed_files.txt: {e}")
43+
44+
# Try GitHub PR context
3345
if "GITHUB_EVENT_PATH" in os.environ:
3446
try:
3547
with open(os.environ["GITHUB_EVENT_PATH"]) as f:
@@ -54,6 +66,96 @@ def get_changed_files(repo_root):
5466
print("::error::No Markdown files found in docs/ directory")
5567
return []
5668

69+
def extract_sql_queries(file_path):
70+
"""Extract SQL code blocks from markdown files"""
71+
try:
72+
with open(file_path, 'r', encoding='utf-8') as f:
73+
content = f.read()
74+
75+
# Find SQL code blocks using regex
76+
sql_pattern = r'```(?:sql|sumo)\s*(?:title="[^"]*")?\s*\n(.*?)```'
77+
sql_blocks = re.findall(sql_pattern, content, re.DOTALL | re.IGNORECASE)
78+
79+
queries = []
80+
for block in sql_blocks:
81+
# Clean up the query
82+
query = block.strip()
83+
if query and not query.startswith('#') and not query.startswith('//'):
84+
queries.append(query)
85+
86+
return queries
87+
except Exception as e:
88+
print(f"::error::Error reading file {file_path}: {e}")
89+
return []
90+
91+
def validate_query_syntax(query):
92+
"""Basic syntax validation for SumoLogic queries"""
93+
errors = []
94+
95+
# Check for basic syntax issues
96+
if '|' in query:
97+
# Split by pipes to check operators
98+
parts = [part.strip() for part in query.split('|')]
99+
for i, part in enumerate(parts):
100+
if not part:
101+
errors.append(f"Empty pipe section at position {i}")
102+
103+
# Check for common operator patterns
104+
if i > 0: # Skip the first part (search expression)
105+
if not any(op in part.lower() for op in [
106+
'where', 'parse', 'json', 'count', 'sum', 'avg', 'max', 'min',
107+
'timeslice', 'sort', 'top', 'bottom', 'fields', 'if', 'lookup',
108+
'join', 'extract', 'formatDate', 'toLowerCase', 'toUpperCase'
109+
]):
110+
# This might be a custom function or valid operator we don't know about
111+
pass
112+
113+
# Check for unmatched quotes
114+
single_quotes = query.count("'") - query.count("\\'")
115+
double_quotes = query.count('"') - query.count('\\"')
116+
117+
if single_quotes % 2 != 0:
118+
errors.append("Unmatched single quotes")
119+
if double_quotes % 2 != 0:
120+
errors.append("Unmatched double quotes")
121+
122+
# Check for unmatched parentheses
123+
paren_count = query.count('(') - query.count(')')
124+
if paren_count != 0:
125+
errors.append("Unmatched parentheses")
126+
127+
# Check for unmatched brackets
128+
bracket_count = query.count('[') - query.count(']')
129+
if bracket_count != 0:
130+
errors.append("Unmatched square brackets")
131+
132+
return errors
133+
134+
def validate_file(file_path):
135+
"""Validate all SQL queries in a markdown file"""
136+
print(f"πŸ” Validating: {file_path}")
137+
138+
queries = extract_sql_queries(file_path)
139+
if not queries:
140+
print(f" ℹ️ No SQL queries found")
141+
return True
142+
143+
print(f" πŸ“Š Found {len(queries)} SQL queries")
144+
145+
all_valid = True
146+
for i, query in enumerate(queries, 1):
147+
errors = validate_query_syntax(query)
148+
if errors:
149+
all_valid = False
150+
print(f" ❌ Query {i} has errors:")
151+
for error in errors:
152+
print(f" - {error}")
153+
print(f" Query preview: {query[:100]}...")
154+
else:
155+
print(f" βœ… Query {i} passed basic syntax validation")
156+
157+
return all_valid
158+
57159
def main():
58160
repo_root = debug_environment()
59161
changed_files = get_changed_files(repo_root)
@@ -62,8 +164,46 @@ def main():
62164
print("::warning::No Markdown files to validate")
63165
sys.exit(0)
64166

65-
print(f"Validating {len(changed_files)} files...")
66-
# Rest of your validation logic here
167+
print(f"πŸ“‹ Validating {len(changed_files)} files...")
168+
169+
validation_results = []
170+
total_queries = 0
171+
172+
for file_path in changed_files:
173+
if os.path.exists(file_path):
174+
result = validate_file(file_path)
175+
validation_results.append((file_path, result))
176+
177+
# Count queries for summary
178+
queries = extract_sql_queries(file_path)
179+
total_queries += len(queries)
180+
else:
181+
print(f"::warning::File not found: {file_path}")
182+
183+
# Summary
184+
print("\n" + "="*60)
185+
print("πŸ“Š VALIDATION SUMMARY")
186+
print("="*60)
187+
188+
passed_files = sum(1 for _, result in validation_results if result)
189+
failed_files = len(validation_results) - passed_files
190+
191+
print(f"πŸ“ Files processed: {len(validation_results)}")
192+
print(f"πŸ“Š Total SQL queries: {total_queries}")
193+
print(f"βœ… Files passed: {passed_files}")
194+
print(f"❌ Files failed: {failed_files}")
195+
196+
if failed_files > 0:
197+
print("\n❌ Files with validation errors:")
198+
for file_path, result in validation_results:
199+
if not result:
200+
print(f" - {file_path}")
201+
202+
print("\n::error::SQL query validation failed!")
203+
sys.exit(1)
204+
else:
205+
print("\nπŸŽ‰ All SQL queries passed validation!")
206+
sys.exit(0)
67207

68208
if __name__ == "__main__":
69209
main()

0 commit comments

Comments
Β (0)