From 27c4db980ed85ade5338e7deebc201b3711a3f19 Mon Sep 17 00:00:00 2001 From: Forge Bot <3+renovate-bot@noreply.gitea.hellion-forge.cloud> Date: Mon, 11 May 2026 23:11:39 +0000 Subject: [PATCH] fix(scan): merge semgrep + trivy into one job to avoid act_runner race act_runner v0.6.1 fails when 2 jobs in the same task chown the shared workspace in parallel. Sequential steps inside one job sidestep the issue. Trivy step uses if: always() so both tools surface findings in a single run. --- .gitea/workflows/security-scan.yml | 41 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/.gitea/workflows/security-scan.yml b/.gitea/workflows/security-scan.yml index 8ef599b..221aa45 100644 --- a/.gitea/workflows/security-scan.yml +++ b/.gitea/workflows/security-scan.yml @@ -1,8 +1,13 @@ name: Security Scan (reusable) # Reusable workflow consumed by per-repo security.yml stubs across the -# Hellion stack. Runs Semgrep SAST and Trivy filesystem scan in parallel. -# Either job failing fails the calling workflow. +# Hellion stack. Runs Semgrep SAST + Trivy filesystem scan sequentially +# inside a single job. Either tool failing fails the calling workflow. +# +# Why one job, not two parallel jobs: +# act_runner v0.6.1 has a race condition when two jobs in the same task +# share a workspace and chown it in parallel — one container never gets +# /var/run/act/ provisioned and silent-fails. Sequential steps avoid it. on: workflow_call: @@ -24,8 +29,8 @@ on: default: '' jobs: - semgrep: - name: Semgrep SAST + scan: + name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout @@ -39,9 +44,16 @@ jobs: - name: Install Semgrep run: pip install --no-cache-dir semgrep - - name: Run Semgrep scan + - name: Install Trivy + # Direct install via the official upstream script. The aquasecurity/ + # trivy-action wrapper does nested checkouts and auth-juggling that + # does not play well with Self-Hosted Gitea Actions, this is more + # robust and a smaller surface. + run: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin + + - name: Run Semgrep SAST # --config=auto pulls language-appropriate rule packs from semgrep.dev - # without requiring an account. --error makes the job fail when ERROR + # without requiring an account. --error makes the step fail when ERROR # findings exist. WARNING-level rules still run for visibility but do # not fail the build (they would dominate the noise). # Per-repo rule exclusion via the semgrep-exclude-rules input. @@ -57,22 +69,11 @@ jobs: echo "Running: semgrep scan $args" semgrep scan $args - trivy: - name: Trivy Vulnerability Scan - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Trivy - # Direct install via the official upstream script. The aquasecurity/ - # trivy-action wrapper does nested checkouts and auth-juggling that - # does not play well with Self-Hosted Gitea Actions, this is more - # robust and a smaller surface. - run: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin - - name: Run Trivy filesystem scan + # if: always() — surface Trivy findings even when Semgrep fails first, + # so a single run gives the full combined picture. # Scans dependency manifests (NuGet, npm, package-lock etc.) against # the NVD CVE database. --ignore-unfixed skips findings that have # no patched version available so we focus on actionable items. + if: always() run: trivy fs --severity ${{ inputs.severity }} --exit-code 1 --ignore-unfixed .