Skip to content

Commit fc32bb1

Browse files
authored
New scan workflow + sonar project config file to enable sonarqube scans (#1935)
2 parents 4f3bbde + f93f31f commit fc32bb1

4 files changed

Lines changed: 203 additions & 24 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pycache__/
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env python3
2+
"""Temporarily repair SARIF generated by nasa-scrub 3.0.
3+
4+
Remove this script once https://github.com/nasa/scrub/issues/118 is fixed and
5+
the workflow no longer pins an affected nasa-scrub version.
6+
"""
7+
8+
import argparse
9+
import json
10+
from pathlib import Path
11+
12+
13+
SARIF_SCHEMA_2_1_0 = "https://json.schemastore.org/sarif-2.1.0.json"
14+
15+
16+
def repair_sarif_file(sarif_file: Path) -> bool:
17+
with sarif_file.open() as file:
18+
sarif = json.load(file)
19+
20+
changed = False
21+
if sarif.get("$schema") != SARIF_SCHEMA_2_1_0:
22+
sarif["$schema"] = SARIF_SCHEMA_2_1_0
23+
changed = True
24+
25+
for run in sarif.get("runs", []):
26+
tool = run.get("tool")
27+
if not isinstance(tool, dict) or "rules" not in tool:
28+
continue
29+
30+
driver = tool.setdefault("driver", {})
31+
if "rules" not in driver:
32+
driver["rules"] = tool["rules"]
33+
elif isinstance(driver["rules"], list) and isinstance(tool["rules"], list):
34+
driver["rules"].extend(tool["rules"])
35+
36+
del tool["rules"]
37+
changed = True
38+
39+
if changed:
40+
with sarif_file.open("w") as file:
41+
json.dump(sarif, file, indent=2)
42+
file.write("\n")
43+
44+
return changed
45+
46+
47+
def main() -> None:
48+
parser = argparse.ArgumentParser(description="Repair nasa-scrub SARIF output for SonarQube import.")
49+
parser.add_argument("results_dir", type=Path)
50+
args = parser.parse_args()
51+
52+
for sarif_file in args.results_dir.glob("*_stripped.sarif"):
53+
if repair_sarif_file(sarif_file):
54+
print(f"Repaired {sarif_file}")
55+
56+
57+
if __name__ == "__main__":
58+
main()
Lines changed: 130 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,155 @@
1-
name: Security Scan
1+
# AMMOS OSS Security Scan
2+
# (internal) docs - https://wiki.jpl.nasa.gov/pages/viewpage.action?spaceKey=AmmosArch&title=Code+Vulnerability+Scanning+Set+Up+for+AMMOS+Open+Source+Software
3+
name: 'Security Scan'
24

35
on:
4-
pull_request:
5-
branches:
6-
- develop
7-
- dev-[0-9]+.[0-9]+.[0-9]+
86
push:
97
branches:
108
- develop
119
tags:
12-
- v*
10+
- 'v*'
11+
pull_request:
12+
branches:
13+
- develop
14+
- 'dev-[0-9]+.[0-9]+.[0-9]+'
15+
schedule:
16+
- cron: '42 2 * * 0' # weekly cron scan
1317
workflow_dispatch:
1418

1519
jobs:
1620
analyze:
17-
name: Analyze
18-
runs-on: ubuntu-latest
21+
name: Analyze (${{ matrix.language }})
22+
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
1923
permissions:
24+
# required for all workflows
25+
security-events: write
26+
# required to fetch internal or private CodeQL packs
27+
packages: read
28+
# only required for workflows in private repositories
2029
actions: read
2130
contents: read
22-
security-events: write
2331

2432
strategy:
2533
fail-fast: false
2634
matrix:
27-
language: ['javascript']
28-
35+
include:
36+
- language: actions
37+
build-mode: none
38+
- language: javascript-typescript
39+
build-mode: none
40+
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
2941
steps:
3042
- name: Checkout repository
31-
uses: actions/checkout@v4
43+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4.3.1
44+
with:
45+
fetch-depth: 0
46+
47+
# Add any setup steps before running the `github/codeql-action/init` action.
48+
# This includes steps like installing compilers or runtimes (`actions/setup-node`
49+
# or others). This is typically only required for manual builds.
50+
# - name: Setup runtime (example)
51+
# uses: actions/setup-example@v1
52+
53+
# Initializes the CodeQL tools for scanning.
3254
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@v3
55+
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba #4.35.5
3456
with:
3557
languages: ${{ matrix.language }}
36-
- name: Autobuild
37-
uses: github/codeql-action/autobuild@v3
58+
build-mode: ${{ matrix.build-mode }}
59+
# If you wish to specify custom queries, you can do so here or in a config file.
60+
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
61+
# queries: security-extended,security-and-quality
62+
63+
# If the analyze step fails for one of the languages you are analyzing with
64+
# "We were unable to automatically build your code", modify the matrix above
65+
# to set the build mode to "manual" for that language. Then modify this step
66+
# to build your code.
67+
# ℹ️ Command-line programs to run using the OS shell.
68+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
69+
- name: Run manual build steps
70+
if: matrix.build-mode == 'manual'
71+
shell: bash
72+
run: |
73+
echo 'If you are using a "manual" build mode for one or more of the' \
74+
'languages you are analyzing, replace this with the commands to build' \
75+
'your code, for example:'
76+
echo ' make bootstrap'
77+
echo ' make release'
78+
exit 1
79+
3880
- name: Perform CodeQL Analysis
39-
uses: github/codeql-action/analyze@v3
40-
- name: NASA Scrub
81+
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba #4.35.5
82+
with:
83+
category: '/language:${{matrix.language}}'
84+
output: ../results
85+
86+
# This step is required by AMMOS to remove malformed data from the CodeQL output
87+
# It may be possible to remove in future iterations
88+
- name: Post-Process Output
4189
run: |
42-
pip install nasa-scrub
43-
python3 -m scrub.tools.parsers.translate_results ${{ runner.workspace }}/results/*.sarif ${{ runner.workspace }}/results/codeql.scrub ${{ github.workspace }} scrub
44-
python3 -m scrub.tools.parsers.csv_parser ${{ runner.workspace }}/results
45-
- name: Upload Security Scan Results
46-
uses: actions/upload-artifact@v4
90+
python3 -m pip install nasa-scrub==3.0
91+
92+
results_dir=`realpath ${{ github.workspace }}/../results`
93+
sarif_files=`find $results_dir -name '*.sarif'`
94+
95+
for sarif_file in $sarif_files
96+
do
97+
output_file="$results_dir/$(basename $sarif_file .sarif)_stripped.sarif"
98+
99+
python3 -m scrub.tools.parsers.translate_results $sarif_file $output_file ${{ github.workspace }} sarifv2.1.0
100+
done
101+
102+
# TEMPORARY WORKAROUND: remove this once nasa-scrub emits valid SARIF 2.1.0.
103+
# https://github.com/nasa/scrub/issues/118
104+
python3 .github/workflows/scripts/repair-scrub-sarif.py "$results_dir"
105+
# END TEMPORARY WORKAROUND
106+
107+
echo "RESULTS_DIR=$results_dir" >> $GITHUB_ENV
108+
109+
# This step makes the analysis artifacts available for download
110+
# This can be helpful for debugging and archive purposes
111+
- name: Upload Artifacts
112+
uses: actions/upload-artifact@v4.3.1
113+
with:
114+
name: codeql-artifacts-${{ matrix.language }}
115+
path: ${{ env.RESULTS_DIR }}
116+
117+
sonar:
118+
name: SonarQube Scan
119+
needs: analyze
120+
runs-on: ubuntu-latest
121+
# PRs for forks can't use secrets, can't upload to Sonar
122+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
123+
permissions:
124+
actions: read
125+
contents: read
126+
steps:
127+
- name: Checkout repository
128+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 #v4.3.1
129+
with:
130+
fetch-depth: 0
131+
132+
- name: Download CodeQL Artifacts
133+
uses: actions/download-artifact@v4
134+
with:
135+
pattern: codeql-artifacts-*
136+
path: codeql-results
137+
138+
- name: collect stripped .sarif file paths
139+
shell: bash
140+
run: |
141+
echo "downloaded CodeQL artifact files:"
142+
find "${{ github.workspace }}/codeql-results" -type f | sort
143+
144+
sarif_paths="$(find "${{ github.workspace }}/codeql-results" -name '*_stripped.sarif' -type f | paste -sd, -)"
145+
echo "sarif paths: $sarif_paths"
146+
test -n "$sarif_paths"
147+
echo "SARIF_REPORT_PATHS=$sarif_paths" >> "$GITHUB_ENV"
148+
149+
- name: SonarQube Scan
150+
uses: SonarSource/sonarqube-scan-action@7006c4492b2e0ee0f816d36501671557c97f5995 # v8.1.0
151+
env:
152+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
47153
with:
48-
name: Security Scan Results
49-
path: ${{ runner.workspace }}/results/*
154+
args: >
155+
-Dsonar.sarifReportPaths=${{ env.SARIF_REPORT_PATHS }}

sonar-project.properties

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Project config file for SonarQube scans (run via GH actions)
2+
3+
sonar.projectKey=NASA-AMMOS_aerie-ui
4+
sonar.organization=nasa-ammos
5+
6+
# name and version displayed in the SonarCloud UI.
7+
sonar.projectName=plandev-ui
8+
sonar.projectVersion=4.2.1
9+
10+
# Path of sources to analyze relative to the sonar-project.properties file
11+
#sonar.sources=.
12+
13+
# Encoding of the source code. Default is default system encoding
14+
#sonar.sourceEncoding=UTF-8

0 commit comments

Comments
 (0)