Skip to content

Commit e57089a

Browse files
Initial CI/CD config to try
1 parent 5003e3c commit e57089a

2 files changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: "Validate Query Formatting"
2+
on:
3+
pull_request:
4+
branches:
5+
- main
6+
7+
env:
8+
XARGS_MAX_PROCS: 4
9+
10+
jobs:
11+
validate-query-formatting:
12+
runs-on: ubuntu-22.04
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
with:
17+
ref: ${{ inputs.ref }}
18+
19+
- name: Setup CodeQL
20+
id: install-codeql
21+
uses: ./.github/actions/install-codeql
22+
23+
- name: Validate query format
24+
env:
25+
LANGUAGE: ${{ matrix.language }}
26+
run: |
27+
codeql version
28+
find . \( -name \*.ql -or -name \*.qll \) -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql query format --in-place
29+
30+
git diff
31+
git diff --compact-summary
32+
git diff --quiet
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
name: Build CodeQL Packs
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
compile-and-test:
10+
runs-on: ubuntu-latest
11+
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
language: [ 'common', 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Setup CodeQL
21+
id: install-codeql
22+
uses: ./.github/actions/install-codeql
23+
24+
- name: Install CodeQL packs
25+
uses: ./.github/actions/install-codeql-packs
26+
with:
27+
cli_path: ${{ github.workspace }}/codeql_home/codeql
28+
29+
- name: Pre-Compile Queries
30+
id: pre-compile-queries
31+
run: |
32+
${{ github.workspace }}/codeql_home/codeql/codeql query compile --threads 0 ${{ matrix.language }}
33+
34+
- name: Test Queries
35+
if: steps.changes.outputs.src == 'true'
36+
env:
37+
RUNNER_TEMP: ${{ runner.temp }}
38+
shell: python
39+
run: |
40+
import os
41+
import sys
42+
import subprocess
43+
from pathlib import Path
44+
45+
def print_error(fmt, *args):
46+
print(f"::error::{fmt}", *args)
47+
48+
def print_error_and_fail(fmt, *args):
49+
print_error(fmt, args)
50+
sys.exit(1)
51+
52+
runner_temp = os.environ['RUNNER_TEMP']
53+
54+
if ${{ matrix.language }} == 'common':
55+
test_root = Path('${{ github.workspace }}', 'test')
56+
else:
57+
test_root = Path('${{ github.workspace }}', '${{ matrix.language }}', 'test')
58+
print(f"Executing tests found (recursively) in the directory '{test_root}'")
59+
files_to_close = []
60+
try:
61+
# Runners have 4 cores, so split the tests into 4 "slices", and run one per thread
62+
num_slices = 4
63+
procs = []
64+
65+
for slice in range(1, num_slices+1):
66+
test_report_path = os.path.join(runner_temp, "${{ matrix.language }}", f"test_report_slice_{slice}_of_{num_slices}.json")
67+
os.makedirs(os.path.dirname(test_report_path), exist_ok=True)
68+
test_report_file = open(test_report_path, 'w')
69+
files_to_close.append(test_report_file)
70+
procs.append(subprocess.Popen(["codeql", "test", "run", "--failing-exitcode=122", f"--slice={slice}/{num_slices}", "--ram=2048", "--format=json", test_root], stdout=test_report_file, stderr=subprocess.PIPE))
71+
72+
for p in procs:
73+
_, err = p.communicate()
74+
if p.returncode != 0:
75+
if p.returncode == 122:
76+
# Failed because a test case failed, so just print the regular output.
77+
# This will allow us to proceed to validate-test-results, which will fail if
78+
# any test cases failed
79+
print(f"{err.decode()}")
80+
else:
81+
# Some more serious problem occurred, so print and fail fast
82+
print_error_and_fail(f"Failed to run tests with return code {p.returncode}\n{err.decode()}")
83+
finally:
84+
for file in files_to_close:
85+
file.close()
86+
87+
- name: Upload test results
88+
if: steps.changes.outputs.src == 'true'
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: ${{ matrix.language }}-test-results
92+
path: |
93+
${{ runner.temp }}/${{ matrix.language }}/test_report_slice_*.json
94+
if-no-files-found: error
95+
96+
- name: Compile / Check Suites & Packs
97+
if: steps.changes.outputs.src == 'true'
98+
env:
99+
GITHUB_TOKEN: ${{ github.token }}
100+
run: |
101+
./.github/scripts/pr-suites-packs.sh ${{ github.event.number }} ${{ matrix.language }}
102+
103+
validate-test-results:
104+
name: Validate test results
105+
needs: compile-and-test
106+
runs-on: ubuntu-latest
107+
steps:
108+
- name: Check if compile-and-test job failed to complete, if so fail
109+
if: ${{ needs.compile-and-test.result == 'failure' }}
110+
uses: actions/github-script@v7
111+
with:
112+
script: |
113+
core.setFailed('Test run job failed')
114+
115+
- name: Collect test results
116+
uses: actions/download-artifact@v4
117+
118+
- name: Validate test results
119+
run: |
120+
if [[ ! -n "$(find . -name 'test_report_*' -print -quit)" ]]; then
121+
echo "No test results found"
122+
exit 0
123+
fi
124+
125+
for json_report in *-test-results/test_report_*
126+
do
127+
jq --raw-output '"PASS \(map(select(.pass == true)) | length)/\(length)'" $json_report\"" "$json_report"
128+
done
129+
FAILING_TESTS=$(jq --raw-output '.[] | select(.pass == false)' *-test-results/test_report_*.json)
130+
if [[ ! -z "$FAILING_TESTS" ]]; then
131+
echo "ERROR: The following tests failed:"
132+
echo $FAILING_TESTS | jq .
133+
exit 1
134+
fi
135+

0 commit comments

Comments
 (0)