Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,54 @@ jobs:

- name: Run tests
run: python -m pytest -q

static-analysis:
name: Static analysis
needs: test
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: pyproject.toml

- name: Install development dependencies
run: python -m pip install -e ".[dev]"

- name: Analyze project tools
run: |
mkdir -p reports/ci
securecode-analyzer src --format json \
> reports/ci/static-analysis-src.json
securecode-analyzer tools --format json \
> reports/ci/static-analysis-tools.json

- name: Analyze controlled demo
shell: bash
run: |
set +e
securecode-analyzer sample_app --format json \
> reports/ci/static-analysis-sample-app.json
status=$?
set -e

if [ "$status" -ne 1 ]; then
echo "Expected demo scan exit code 1, received $status."
exit 1
fi

- name: Validate controlled demo findings
run: |
cmp \
reports/ci/static-analysis-sample-app.json \
reports/sample-app/static-analysis.json
python -m pytest tests/test_sample_app_security_demo.py -q
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ __pycache__/
.coverage
.coverage.*
htmlcov/
reports/ci/

# Packaging artifacts
build/
Expand Down
84 changes: 64 additions & 20 deletions docs/ci.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# GitHub Actions CI

Bu doküman Backlog 5.1 kapsamındaki temel test pipeline'ının gereksinimlerini,
güvenlik sınırlarını ve çalışma sırasını açıklar.
Bu doküman Backlog 5.1 ve 5.2 kapsamındaki test ve statik analiz pipeline'ının
gereksinimlerini, güvenlik sınırlarını ve çalışma sırasını açıklar.

## Mevcut Durum

Temel GitHub Actions workflow'u tamamlanmıştır:
GitHub Actions test ve statik analiz workflow'u tamamlanmıştır:

```text
.github/workflows/ci.yml
```

Workflow Pull Request değişikliklerinde ve `main` branch push olaylarında
Python 3.11 test paketini çalıştırır. Sıradaki aşama static analyzer,
dependency scanner ve report artifact adımlarının ayrı CI job'ları olarak
eklenmesidir.
Python 3.11 test paketini çalıştırır. Test gate'i geçtikten sonra proje
kaynaklarını ve kontrollü demo uygulamasını ayrı bir static-analysis job'unda
tarar. Sıradaki aşama dependency scanner ve report artifact job'larıdır.

## Trigger Sözleşmesi

Expand All @@ -35,12 +35,12 @@ permissions:
contents: read
```

Checkout sonrasında credential persistence kapalıdır. Test job'u
`ubuntu-latest` runner üzerinde en fazla 10 dakika çalışır. Aynı workflow ve
Git ref için yeni bir run başladığında önceki run iptal edilir.
Checkout sonrasında credential persistence kapalıdır. Test ve statik analiz
job'ları `ubuntu-latest` runner üzerinde en fazla 10 dakika çalışır. Aynı
workflow ve Git ref için yeni bir run başladığında önceki run iptal edilir.

Bu foundation job secret, write permission, deployment environment veya
external service credential kullanmaz.
Bu job'lar secret, write permission, deployment environment veya external
service credential kullanmaz.

## Action Pinleri

Expand Down Expand Up @@ -74,6 +74,34 @@ Job sırası:
Install veya test komutlarından herhangi biri non-zero exit code üretirse job
ve workflow başarısız olur.

## Statik Analiz Job Akışı

`static-analysis` job'u test job'una `needs: test` ile bağlıdır. Başarılı test
sonrasında aynı sabit action SHA değerleri ve Python 3.11 ortamıyla çalışır.

Job aşağıdaki raporları üretir:

```text
reports/ci/static-analysis-src.json
reports/ci/static-analysis-tools.json
reports/ci/static-analysis-sample-app.json
```

`src` ve `tools` taramalarında herhangi bir bulgu CLI exit code `1` ürettiği
için job başarısız olur. Bu sıfır-bulgu politikası, proje planındaki yalnızca
yüksek önem seviyelerinde durma gereksiniminden daha katıdır. Statik analiz
modeli `INFO`, `WARNING` ve `ERROR` seviyelerini kullandığından `HIGH` ve
`CRITICAL` adları bu bileşene uygulanmaz.

`sample_app` bilerek eklenmiş beş bulgu içerir. Bu taramanın exit code `1`
üretmesi beklenir ve hata olarak değerlendirilmez. Üretilen JSON, checked-in
`reports/sample-app/static-analysis.json` baseline'ı ile byte düzeyinde
karşılaştırılır; ardından kontrollü demo entegrasyon testleri çalıştırılır.
Exit code veya baseline değişirse job başarısız olur.

Bu aşamada `reports/ci` yalnızca job workspace'inde tutulur. Artifact upload
Backlog 5.4 kapsamında eklenecektir.

## Yerel Eşdeğer

CI test adımını yerelde doğrulamak için:
Expand All @@ -84,6 +112,22 @@ python -m pip install -e ".[dev]"
python -m pytest -q
```

Statik analiz adımlarını yerelde doğrulamak için:

```powershell
New-Item -ItemType Directory -Force reports/ci
securecode-analyzer src --format json `
> reports/ci/static-analysis-src.json
securecode-analyzer tools --format json `
> reports/ci/static-analysis-tools.json
securecode-analyzer sample_app --format json `
> reports/ci/static-analysis-sample-app.json
python -m pytest tests/test_sample_app_security_demo.py -q
```

Demo komutunun beklenen exit code değeri `1` olmalıdır. Üretilen demo JSON'u
checked-in baseline ile birebir aynı olmalıdır.

Workflow sözleşmesi de normal test paketi içindedir:

```powershell
Expand All @@ -109,6 +153,9 @@ python -m pytest tests/test_python_compatibility.py -q
- Python 3.11 ve pip cache yapılandırması
- Pip upgrade, dev install ve pytest komut sırası
- Ubuntu runner ve 10 dakikalık timeout
- Test job'una bağlı statik analiz job'u
- `src`, `tools` ve `sample_app` JSON rapor yolları
- Kontrollü demo exit code ve baseline doğrulaması

`tests/test_python_compatibility.py`, `src`, `sample_app`, `tools` ve `tests`
altındaki bütün Python dosyalarını desteklenen en düşük sürüm olan Python
Expand All @@ -118,23 +165,20 @@ geçen Python 3.12+ söz dizimi değişiklikleri CI'a ulaşmadan tespit edilir.
Doğrulanan mevcut sonuç:

```text
CI workflow contract tests: 7 passed
CI workflow contract tests: 10 passed
Python 3.11 compatibility tests: 1 passed
Complete test suite: 985 passed
Complete test suite: 988 passed
Workflow YAML parse check: passed
```

## Sonraki Güvenlik Job'ları

Bu foundation PR yalnızca Backlog 5.1'i tamamlar. Sonraki aşamalar:
Backlog 5.1 ve 5.2 tamamlanmıştır. Sonraki aşamalar:

1. `src` ve `tools` için sıfır-bulgu static self-analysis gate'i
2. `sample_app` için beklenen beş bulguyu drift testiyle doğrulama
3. Offline OSV fixture-backed dependency scan gate'i
4. Static ve dependency JSON raporlarını workflow artifact olarak yükleme
1. Offline OSV fixture-backed dependency scan gate'i
2. Static ve dependency JSON raporlarını workflow artifact olarak yükleme

Bu ayrım temel test workflow'unun ilk gerçek GitHub run sonucunu bağımsız
olarak incelemeyi sağlar.
Bu ayrım her güvenlik gate'inin davranışını bağımsız olarak incelemeyi sağlar.

## Navigation

Expand Down
8 changes: 4 additions & 4 deletions docs/components/sample-web-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ Mevcut özellikler:
* Ayrı ve runtime dışı vulnerable dependency fixture'ı
* Portable static-analysis ve dependency-scan JSON baseline'ları
* Offline report generator ve drift check
* Pull Request ve `main` push için temel pytest CI workflow'u
* Pull Request ve `main` push için pytest ve statik analiz CI job'ları

Sıradaki aşama analyzer, dependency scanner ve report artifact CI job'larıdır.
Sıradaki aşama dependency scanner ve report artifact CI job'larıdır.

## Kurulum

Expand Down Expand Up @@ -547,10 +547,10 @@ New update/delete test cases: 54 passed
New frontend test cases: 18 passed
New security demo test cases: 4 passed
New integration report test cases: 6 passed
New CI workflow test cases: 7 passed
New CI workflow test cases: 10 passed
New Python 3.11 compatibility test cases: 1 passed
Sample app targeted suite: 149 passed
Complete test suite: 985 passed
Complete test suite: 988 passed
Compile check: passed
Sample app analysis: 5 expected findings
Analyzer source self-analysis: no findings
Expand Down
71 changes: 71 additions & 0 deletions tests/test_ci_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,74 @@ def test_test_job_has_bounded_ubuntu_execution() -> None:

assert "runs-on: ubuntu-latest" in workflow
assert "timeout-minutes: 10" in workflow


def test_static_analysis_job_waits_for_tests() -> None:
"""Security analysis should run only after the test gate passes."""

workflow = _workflow_text()

assert (
" static-analysis:\n"
" name: Static analysis\n"
" needs: test\n"
" runs-on: ubuntu-latest\n"
" timeout-minutes: 10\n"
) in workflow
assert workflow.count("persist-credentials: false") == 2
assert workflow.count('python-version: "3.11"') == 2
assert workflow.count("actions/checkout@") == 2
assert workflow.count("actions/setup-python@") == 2


def test_static_analysis_job_writes_project_json_reports() -> None:
"""Project sources should produce separate machine-readable reports."""

workflow = _workflow_text()

assert "mkdir -p reports/ci" in workflow
assert (
"securecode-analyzer src --format json"
in workflow
)
assert (
"> reports/ci/static-analysis-src.json"
in workflow
)
assert (
"securecode-analyzer tools --format json"
in workflow
)
assert (
"> reports/ci/static-analysis-tools.json"
in workflow
)


def test_static_analysis_job_validates_controlled_demo() -> None:
"""Known demo findings should be reported without breaking the gate."""

workflow = _workflow_text()

assert (
"securecode-analyzer sample_app --format json"
in workflow
)
assert (
"> reports/ci/static-analysis-sample-app.json"
in workflow
)
assert 'if [ "$status" -ne 1 ]; then' in workflow
assert (
"reports/ci/static-analysis-sample-app.json"
in workflow
)
assert (
"reports/sample-app/static-analysis.json"
in workflow
)
assert (
"python -m pytest "
"tests/test_sample_app_security_demo.py -q"
in workflow
)