Skip to content
Open
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
3 changes: 2 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Patterns
- Use private methods (`_method_name`) for internal class helpers
- ActionInputs class validates only, use `get_action_input()` from utils to get inputs elsewhere
- All info logs must start with "AquaSec Scan Results -" prefix
- Never disable pylint behaviour in the code

Testing
- Mirror src structure: `src/module.py` -> `tests/test_module.py`
Expand All @@ -36,7 +37,7 @@ Testing
- Use conftest.py fixtures for repeated mocking patterns across tests
- Comment sections: `# method_name` before tests
- Use `mocker.patch("module.dependency")` or `mocker.patch.object(Class, "method")`
- Use `monkeypatch.setenv("VAR", "value")` for environment variables
- Use `monkeypatch.setenv("VAR", "value")` for cleaning up environment variables
- Assert pattern: `assert expected == actual`
- Use `pytest.raises(Exception)` for exceptions

Expand Down
47 changes: 23 additions & 24 deletions .github/workflows/check_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,30 +127,29 @@ jobs:
id: check-format
run: black --check $(git ls-files '*.py')

# #TODO: Enable pytest checks once tests are available
# pytest-test:
# name: Pytest Unit Tests with Coverage
# needs: detect
# if: needs.detect.outputs.python_changed == 'true'
# runs-on: ubuntu-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
# with:
# persist-credentials: false
# fetch-depth: 0
#
# - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
# with:
# python-version: '3.14'
# cache: 'pip'
#
# - name: Install Python dependencies
# run: pip install -r requirements.txt
#
#
# - name: Check code coverage with Pytest
# run: pytest --cov=. -v tests/ --cov-fail-under=80
pytest-test:
name: Pytest Unit Tests with Coverage
needs: detect
if: needs.detect.outputs.python_changed == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
with:
persist-credentials: false
fetch-depth: 0

- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548
with:
python-version: '3.14'
cache: 'pip'

- name: Install Python dependencies
run: pip install -r requirements.txt


- name: Check code coverage with Pytest
run: pytest --cov=. -v tests/ --cov-fail-under=80

mypy-check:
name: Mypy Type Check
Expand Down
16 changes: 9 additions & 7 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ Add the shebang line at the top of the sh script file.
Set the configuration environment variables in the shell script following the structure below.

```shell
# Essential environment variables for GitHub Action functionality
# Environment variables for GitHub Action full functionality
export INPUT_AQUA_KEY="your-aquasec-api-key"
export INPUT_AQUA_SECRET="your-aquasec-api-secret"
export INPUT_REPOSITORY_ID="your-aquasec-repository-id"
export INPUT_VERBOSE_LOGGING="true" # Optional
```

### Running the script locally
Expand All @@ -61,10 +62,11 @@ The whole script should look like this example:
```shell
#!/bin/sh

# Essential environment variables for GitHub Action functionality
# Environment variables for GitHub Action full functionality
export INPUT_AQUA_KEY="your-aquasec-api-key"
export INPUT_AQUA_SECRET="your-aquasec-api-secret"
export INPUT_REPOSITORY_ID="your-aquasec-repository-id"
export INPUT_VERBOSE_LOGGING="true" # Optional

python3 main.py
```
Expand Down Expand Up @@ -108,7 +110,7 @@ To run Pylint on a specific file, follow the pattern `pylint <path_to_file>/<nam

Example:
```shell
pylint src/convertor.py
pylint src/model/authenticator.py
```

### Expected Output
Expand Down Expand Up @@ -148,7 +150,7 @@ To run Black on a specific file, follow the pattern `black <path_to_file>/<name_

Example:
```shell
black src/convertor.py
black src/model/sarif_convertor.py
```

### Expected Output
Expand Down Expand Up @@ -185,7 +187,7 @@ To run my[py] check on a specific file, follow the pattern `mypy <path_to_file>/

Example:
```shell
mypy src/convertor.py
mypy src/action_inputs.py
```

### Expected Output
Expand All @@ -207,12 +209,12 @@ pytest tests/

Run a single test file:
```shell
pytest tests/test_convertor.py -q
pytest tests/test_main.py -q
```

Run a single test function (node id):
```shell
pytest tests/test_convertor.py::test_load_the_sarif_schema.py -q
pytest tests/test_main.py::test_run_successful -q
```

---
Expand Down
6 changes: 3 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ inputs:
default: 'false'

outputs:
scan-findings:
description: 'JSON containing all AquaSec security scan findings'
value: ${{ steps.aquasec-scan-results.outputs.scan_findings }}
aquasec_sarif_file:
description: 'Path to the generated SARIF file'
value: ${{ steps.aquasec-scan-results.outputs.aquasec_sarif_file }}

runs:
using: 'composite'
Expand Down
22 changes: 19 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@

from src.action_inputs import ActionInputs
from src.model.authenticator import AquaSecAuthenticator
from src.model.sarif_convertor import SarifConvertor
from src.model.scan_fetcher import ScanFetcher
from src.utils.logging_config import setup_logging
from src.utils.utils import set_action_output
from src.utils.utils import get_sarif_output_filename, set_action_output


def run() -> None:
Expand All @@ -40,23 +41,38 @@ def run() -> None:

logger.info("AquaSec Scan Results - Starting.")

# Validate inputs
if not ActionInputs().validate():
logger.error("AquaSec Scan Results - Input validation failed.")
sys.exit(1)

# Authentication
try:
bearer_token = AquaSecAuthenticator().authenticate()
except (ValueError, RequestException) as e:
logger.exception("Authentication failed: %s", str(e))
sys.exit(1)

# Fetching scan results
try:
findings = ScanFetcher(bearer_token).fetch_findings()
findings_json = ScanFetcher(bearer_token).fetch_findings()
except (ValueError, RequestException) as e:
logger.exception("Fetching scan results failed: %s", str(e))
sys.exit(1)

set_action_output("scan_findings", json.dumps(findings))
# Converting findings to SARIF format
sarif_data = SarifConvertor(findings_json).convert_to_sarif()

try:
output_filename = get_sarif_output_filename()
with open(output_filename, "w", encoding="utf-8") as sarif_file:
json.dump(sarif_data, sarif_file, indent=2)
logger.info("AquaSec Scan Results - SARIF output file saved in `%s`.", output_filename)
except IOError as e:
logger.exception("Failed to convert and write SARIF file: %s", str(e))
sys.exit(1)

set_action_output("aquasec_sarif_file", output_filename)

logger.info("AquaSec Scan Results - Finished.")

Expand Down
Loading