Skip to content

Commit 34a0f87

Browse files
authored
ci: Add security checks and code quality tools (#14)
* ci: Add security checks and code quality tools - Add security scanning workflows - Configure SonarQube for code analysis - Add pre-commit hooks configuration - Add pylint configuration - Include security documentation - Update project dependencies * ci: Add security checks and code quality tools - Add security scanning workflows - Configure SonarQube for code analysis - Add pre-commit hooks configuration - Add pylint configuration - Include security documentation - Update project dependencies * SonarQube Key * Security workflows * Security workflows
1 parent 8d162c4 commit 34a0f87

File tree

8 files changed

+467
-1
lines changed

8 files changed

+467
-1
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: Security Checks
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
schedule:
9+
- cron: '0 0 * * 0' # Run weekly on Sunday at midnight
10+
workflow_dispatch:
11+
12+
jobs:
13+
security-scans:
14+
name: Security Scans
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v3
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Set up Python
22+
uses: actions/setup-python@v4
23+
with:
24+
python-version: '3.11'
25+
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install -e ".[dev]"
30+
pip install bandit pylint safety
31+
32+
- name: Run Bandit
33+
run: bandit -r src/ -f json -o bandit-results.json
34+
continue-on-error: true
35+
36+
- name: Run Pylint
37+
run: pylint --disable=C0111,C0103 --generate-rcfile > .pylintrc && pylint src/ --output-format=json:pylint-results.json
38+
continue-on-error: true
39+
40+
- name: Run Safety dependency check
41+
run: safety check --full-report --output json > safety-results.json
42+
continue-on-error: true
43+
44+
- name: Upload Security Results
45+
uses: actions/upload-artifact@v4
46+
with:
47+
name: security-results
48+
path: |
49+
bandit-results.json
50+
pylint-results.json
51+
safety-results.json
52+
53+
- name: Run test coverage
54+
run: |
55+
pip install coverage pytest
56+
coverage run -m pytest tests/
57+
coverage xml -o coverage.xml
58+
continue-on-error: true
59+
60+
- name: SonarCloud Scan
61+
uses: SonarSource/sonarqube-scan-action@master
62+
env:
63+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
65+
with:
66+
args: >
67+
-Dsonar.projectKey=teabranch_openai-responses-server
68+
-Dsonar.organization=${{ github.repository_owner }}
69+
-Dsonar.python.coverage.reportPaths=coverage.xml
70+
-Dsonar.python.bandit.reportPaths=bandit-results.json
71+
-Dsonar.python.pylint.reportPaths=pylint-results.json
72+
73+
dependency-review:
74+
name: Dependency Review
75+
runs-on: ubuntu-latest
76+
steps:
77+
- name: Checkout
78+
uses: actions/checkout@v3
79+
80+
- name: Dependency Review
81+
uses: actions/dependency-review-action@v3
82+
with:
83+
fail-on-severity: high
84+
85+
codeql-analysis:
86+
name: CodeQL Analysis
87+
runs-on: ubuntu-latest
88+
permissions:
89+
security-events: write
90+
steps:
91+
- name: Checkout repository
92+
uses: actions/checkout@v3
93+
94+
- name: Initialize CodeQL
95+
uses: github/codeql-action/init@v2
96+
with:
97+
languages: python
98+
99+
- name: Perform CodeQL Analysis
100+
uses: github/codeql-action/analyze@v2
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Security Scan
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
bandit:
12+
name: Bandit Security Scan
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: '3.11'
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install bandit
26+
pip install -e ".[dev]"
27+
28+
- name: Run Bandit
29+
run: bandit -r src/ -f json -o bandit-results.json
30+
continue-on-error: true
31+
32+
- name: Upload Bandit results
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: bandit-results
36+
path: bandit-results.json
37+
38+
pylint:
39+
name: Pylint
40+
runs-on: ubuntu-latest
41+
steps:
42+
- uses: actions/checkout@v3
43+
44+
- name: Set up Python
45+
uses: actions/setup-python@v4
46+
with:
47+
python-version: '3.11'
48+
49+
- name: Install dependencies
50+
run: |
51+
python -m pip install --upgrade pip
52+
pip install pylint
53+
pip install -e ".[dev]"
54+
55+
- name: Run pylint
56+
run: pylint --disable=C0111,C0103 --generate-rcfile > .pylintrc && pylint src/ --output-format=json:pylint-results.json
57+
continue-on-error: true
58+
59+
- name: Upload Pylint results
60+
uses: actions/upload-artifact@v4
61+
with:
62+
name: pylint-results
63+
path: pylint-results.json

.github/workflows/sonarqube.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: SonarQube Analysis
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
sonarqube:
12+
name: SonarQube Scan
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: '3.11'
23+
24+
- name: Install dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install -e ".[dev]"
28+
pip install coverage
29+
30+
- name: Run tests with coverage
31+
run: |
32+
coverage run -m pytest tests/
33+
coverage xml -o coverage.xml
34+
continue-on-error: true
35+
36+
- name: SonarCloud Scan
37+
uses: SonarSource/sonarqube-scan-action@master
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
41+
with:
42+
args: >
43+
-Dsonar.projectKey=teabranch_openai-responses-server
44+
-Dsonar.organization=${{ github.repository_owner }}
45+
-Dsonar.python.coverage.reportPaths=coverage.xml
46+
-Dsonar.sources=src/
47+
-Dsonar.tests=tests/

.pre-commit-config.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
repos:
2+
- repo: https://github.com/pycqa/flake8
3+
rev: 6.1.0
4+
hooks:
5+
- id: flake8
6+
additional_dependencies: [flake8-bandit, flake8-bugbear]
7+
8+
- repo: https://github.com/pycqa/isort
9+
rev: 5.12.0
10+
hooks:
11+
- id: isort
12+
13+
- repo: https://github.com/psf/black
14+
rev: 23.7.0
15+
hooks:
16+
- id: black
17+
language_version: python3
18+
19+
- repo: https://github.com/PyCQA/bandit
20+
rev: 1.7.5
21+
hooks:
22+
- id: bandit
23+
args: ["-r", "src"]
24+
25+
- repo: https://github.com/pycqa/pylint
26+
rev: v2.17.5
27+
hooks:
28+
- id: pylint
29+
additional_dependencies: [pylint-django]
30+
args: ["--disable=C0111,C0103", "--rcfile=.pylintrc"]
31+
32+
- repo: https://github.com/pre-commit/pre-commit-hooks
33+
rev: v4.4.0
34+
hooks:
35+
- id: trailing-whitespace
36+
- id: end-of-file-fixer
37+
- id: check-yaml
38+
- id: check-added-large-files
39+
- id: check-ast
40+
- id: detect-private-key

.pylintrc

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
[MASTER]
2+
ignore=CVS
3+
ignore-patterns=
4+
persistent=yes
5+
load-plugins=
6+
7+
[MESSAGES CONTROL]
8+
disable=
9+
C0111, # missing-docstring
10+
C0103, # invalid-name
11+
C0303, # trailing-whitespace
12+
C0330, # bad-continuation
13+
C1801, # len-as-condition
14+
R0903, # too-few-public-methods
15+
R0913, # too-many-arguments
16+
W0511, # fixme
17+
W1202, # logging-format-interpolation
18+
W1203, # logging-fstring-interpolation
19+
20+
[REPORTS]
21+
output-format=text
22+
files-output=no
23+
reports=yes
24+
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
25+
26+
[VARIABLES]
27+
init-import=no
28+
dummy-variables-rgx=_$|dummy
29+
additional-builtins=
30+
31+
[FORMAT]
32+
max-line-length=100
33+
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
34+
single-line-if-stmt=no
35+
no-space-check=trailing-comma,dict-separator
36+
max-module-lines=1000
37+
indent-string=' '
38+
39+
[SIMILARITIES]
40+
min-similarity-lines=4
41+
ignore-comments=yes
42+
ignore-docstrings=yes
43+
ignore-imports=no
44+
45+
[BASIC]
46+
good-names=i,j,k,ex,Run,_
47+
bad-names=foo,bar,baz,toto,tutu,tata
48+
name-group=
49+
include-naming-hint=no
50+
function-rgx=[a-z_][a-z0-9_]{2,30}$
51+
function-name-hint=[a-z_][a-z0-9_]{2,30}$
52+
variable-rgx=[a-z_][a-z0-9_]{2,30}$
53+
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
54+
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
55+
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
56+
attr-rgx=[a-z_][a-z0-9_]{2,30}$
57+
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
58+
argument-rgx=[a-z_][a-z0-9_]{2,30}$
59+
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
60+
class-rgx=[A-Z_][a-zA-Z0-9]+$
61+
class-name-hint=[A-Z_][a-zA-Z0-9]+$
62+
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
63+
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
64+
no-docstring-rgx=^_
65+
docstring-min-length=-1
66+
67+
[DESIGN]
68+
max-args=5
69+
ignored-argument-names=_.*
70+
max-locals=15
71+
max-returns=6
72+
max-branches=12
73+
max-statements=50
74+
max-parents=7
75+
max-attributes=7
76+
min-public-methods=2
77+
max-public-methods=20
78+
79+
[CLASSES]
80+
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
81+
defining-attr-methods=__init__,__new__,setUp
82+
valid-classmethod-first-arg=cls
83+
valid-metaclass-classmethod-first-arg=mcs
84+
85+
[IMPORTS]
86+
deprecated-modules=regsub,TERMIOS,Bastion,rexec
87+
import-graph=
88+
ext-import-graph=
89+
int-import-graph=
90+
91+
[EXCEPTIONS]
92+
overgeneral-exceptions=Exception

0 commit comments

Comments
 (0)