Standardise PR workflow on ci.yml and drop scheduled SBOM scan
This commit is contained in:
4 files changed
+21
-113
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
name: Lint & Security
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -12,7 +12,7 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
precommit-and-security:
|
lint-and-security:
|
||||||
name: lint-and-security
|
name: lint-and-security
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
@@ -70,8 +70,9 @@ jobs:
|
|||||||
| "\($d.name)@\($d.version) -> \(.id) [fix: \(if (.fix_versions | length) > 0 then (.fix_versions | join(", ")) else "none" end)]"
|
| "\($d.name)@\($d.version) -> \(.id) [fix: \(if (.fix_versions | length) > 0 then (.fix_versions | join(", ")) else "none" end)]"
|
||||||
' pip-audit.json
|
' pip-audit.json
|
||||||
|
|
||||||
# Fail only on fixable findings (mirrors the Grype policy in security-scan.yml).
|
# Fail only on fixable findings. The type guard ensures a crashed or empty
|
||||||
# The type guard ensures a crashed/empty report fails rather than silently passing.
|
# report fails rather than silently passing. Dependency security updates
|
||||||
|
# are handled by the central Renovate job.
|
||||||
jq -e '
|
jq -e '
|
||||||
(.dependencies | type) == "array"
|
(.dependencies | type) == "array"
|
||||||
and
|
and
|
||||||
@@ -82,6 +83,10 @@ jobs:
|
|||||||
name: tests
|
name: tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
python-version: ["3.11", "3.13"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -92,7 +97,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.13"
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
- name: Install Poetry
|
- name: Install Poetry
|
||||||
run: pip install "poetry>=2,<3"
|
run: pip install "poetry>=2,<3"
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
name: Security Scan
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: 27 8 * * *
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
security-scan:
|
|
||||||
runs-on: running-man
|
|
||||||
|
|
||||||
env:
|
|
||||||
TARGET_DIR: .
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# Tool versions are centralised in the shared actions; bump them there and
|
|
||||||
# re-tag rather than editing every repository.
|
|
||||||
- name: Install Grype
|
|
||||||
uses: https://git.sysmd.uk/mdaleo404/actions/install-grype@v1
|
|
||||||
|
|
||||||
- name: Install Syft
|
|
||||||
uses: https://git.sysmd.uk/mdaleo404/actions/install-syft@v1
|
|
||||||
|
|
||||||
- name: Generate SBOM
|
|
||||||
working-directory: ${{ env.TARGET_DIR }}
|
|
||||||
run: |
|
|
||||||
syft dir:. -o json > sbom.json
|
|
||||||
|
|
||||||
- name: Show SBOM contents
|
|
||||||
working-directory: ${{ env.TARGET_DIR }}
|
|
||||||
run: |
|
|
||||||
echo "Packages discovered by Syft:"
|
|
||||||
jq -r '.artifacts[] | "\(.name)@\(.version) [\(.type)]"' sbom.json | sort
|
|
||||||
|
|
||||||
# Composite actions run from the workspace root, so pass the target and
|
|
||||||
# report relative to it (TARGET_DIR is "." for most repositories).
|
|
||||||
- name: Scan SBOM with Grype
|
|
||||||
id: audit
|
|
||||||
continue-on-error: true
|
|
||||||
uses: https://git.sysmd.uk/mdaleo404/actions/scan-image@v1
|
|
||||||
with:
|
|
||||||
target: sbom:${{ env.TARGET_DIR }}/sbom.json
|
|
||||||
severities: Medium,High,Critical
|
|
||||||
report-path: ${{ env.TARGET_DIR }}/grype.json
|
|
||||||
|
|
||||||
- name: Show full Grype table
|
|
||||||
working-directory: ${{ env.TARGET_DIR }}
|
|
||||||
run: |
|
|
||||||
echo "Full Grype report:"
|
|
||||||
grype sbom:sbom.json -o table
|
|
||||||
|
|
||||||
- name: Notify Node-RED on vulnerabilities
|
|
||||||
if: steps.audit.outcome == 'failure'
|
|
||||||
working-directory: ${{ env.TARGET_DIR }}
|
|
||||||
run: |
|
|
||||||
jq '
|
|
||||||
{
|
|
||||||
repo: "guardutils/filedust",
|
|
||||||
summary: (
|
|
||||||
"Total: " +
|
|
||||||
(
|
|
||||||
[
|
|
||||||
.matches[]
|
|
||||||
| select((.vulnerability.fix.versions | length) > 0)
|
|
||||||
] | length | tostring
|
|
||||||
)
|
|
||||||
),
|
|
||||||
vulnerabilities: [
|
|
||||||
.matches[]
|
|
||||||
| select((.vulnerability.fix.versions | length) > 0)
|
|
||||||
| {
|
|
||||||
library: .artifact.name,
|
|
||||||
cve: .vulnerability.id,
|
|
||||||
severity: .vulnerability.severity,
|
|
||||||
installed: .artifact.version,
|
|
||||||
fixed: (.vulnerability.fix.versions[0]),
|
|
||||||
title: .vulnerability.description,
|
|
||||||
url: .vulnerability.dataSource
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
' grype.json \
|
|
||||||
| curl -s -X POST https://nodered.sysmd.uk/vulns-alert \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
--data-binary @-
|
|
||||||
|
|
||||||
- name: Fail workflow if vulnerabilities found
|
|
||||||
if: steps.audit.outcome == 'failure'
|
|
||||||
run: exit 1
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Lint & Security
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -12,7 +12,7 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
precommit-and-security:
|
lint-and-security:
|
||||||
name: lint-and-security
|
name: lint-and-security
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
@@ -70,8 +70,9 @@ jobs:
|
|||||||
| "\($d.name)@\($d.version) -> \(.id) [fix: \(if (.fix_versions | length) > 0 then (.fix_versions | join(", ")) else "none" end)]"
|
| "\($d.name)@\($d.version) -> \(.id) [fix: \(if (.fix_versions | length) > 0 then (.fix_versions | join(", ")) else "none" end)]"
|
||||||
' pip-audit.json
|
' pip-audit.json
|
||||||
|
|
||||||
# Fail only on fixable findings (mirrors the Grype policy in security-scan.yml).
|
# Fail only on fixable findings. The type guard ensures a crashed or empty
|
||||||
# The type guard ensures a crashed/empty report fails rather than silently passing.
|
# report fails rather than silently passing. Dependency security updates
|
||||||
|
# are handled by the central Renovate job.
|
||||||
jq -e '
|
jq -e '
|
||||||
(.dependencies | type) == "array"
|
(.dependencies | type) == "array"
|
||||||
and
|
and
|
||||||
@@ -82,6 +83,10 @@ jobs:
|
|||||||
name: tests
|
name: tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
python-version: ["3.11", "3.13"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -92,7 +97,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.13"
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
- name: Install Poetry
|
- name: Install Poetry
|
||||||
run: pip install "poetry>=2,<3"
|
run: pip install "poetry>=2,<3"
|
||||||
+1
-12
@@ -63,7 +63,7 @@ poetry.lock locked dependency graph
|
|||||||
README.md user-facing documentation
|
README.md user-facing documentation
|
||||||
.filedust.conf.example example user include/exclude configuration
|
.filedust.conf.example example user include/exclude configuration
|
||||||
.pre-commit-config.yaml Bandit, Black, and generic pre-commit hooks
|
.pre-commit-config.yaml Bandit, Black, and generic pre-commit hooks
|
||||||
.gitea/workflows/ lint, dependency audit, SBOM, and Grype workflows
|
.gitea/workflows/ lint and dependency-audit workflows
|
||||||
dist/ built release artifacts, not source
|
dist/ built release artifacts, not source
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -428,17 +428,6 @@ Gitea pull request workflow:
|
|||||||
-> pip-audit dependency audit
|
-> pip-audit dependency audit
|
||||||
```
|
```
|
||||||
|
|
||||||
Scheduled/manual security workflow:
|
|
||||||
|
|
||||||
```text
|
|
||||||
.gitea/workflows/security-scan.yml
|
|
||||||
-> install verified Cosign, Syft, and Grype
|
|
||||||
-> generate SBOM
|
|
||||||
-> scan for vulnerabilities
|
|
||||||
-> notify Node-RED on fixable vulnerabilities
|
|
||||||
-> fail workflow on fixable Medium, High, or Critical vulnerabilities
|
|
||||||
```
|
|
||||||
|
|
||||||
Pre-commit currently includes Bandit, Black, trailing whitespace, EOF, YAML, and TOML checks.
|
Pre-commit currently includes Bandit, Black, trailing whitespace, EOF, YAML, and TOML checks.
|
||||||
|
|
||||||
Bandit is configured for `src/filedust/` and skips `B110` and `B112`, which reflects the codebase's deliberate best-effort exception handling in filesystem traversal.
|
Bandit is configured for `src/filedust/` and skips `B110` and `B112`, which reflects the codebase's deliberate best-effort exception handling in filesystem traversal.
|
||||||
|
|||||||
Reference in new issue
Block a user