# dsh-sentinel-scanner GitHub Action (root action, structure A) # # 在 PR / push 时对插件源码或仓库运行 dsh-sentinel 静态安全扫描, # 输出 SARIF(供 GitHub Code Scanning 展示)并依据 fail-on 决定 job 是否失败。 # # 用法(用户 workflow): # steps: # - uses: actions/checkout@v4 # - uses: Eligahyu/dsh-sentinel-scanner@v0.4 # with: # path: . # mode: source # fail-on: high # - name: Upload SARIF # if: always() && hashFiles('sentinel.sarif') != '' # uses: github/codeql-action/upload-sarif@v3 # with: # sarif_file: sentinel.sarif # # 自包含说明:AST 解析依赖 acorn;仓库内已 vendor 单文件副本 # (.github/actions/dsh-sentinel/vendor/acorn.mjs),引擎自动回退加载, # 因此 Action 无需 npm install,checkout 即用。 name: 'dsh-sentinel-scanner' description: 'Static security scan of DSH plugins/source with SARIF output (for GitHub Code Scanning)' author: 'Eligahyu' inputs: path: description: 'Scan target (directory or single file)' required: false default: '.' mode: description: 'Scan mode: source (default, skips dist/build) | package | profile' required: false default: 'source' fail-on: description: 'Fail the job when any finding >= this severity: critical | high | medium | low' required: false default: 'high' fail-on-incomplete: description: 'Exit 3 when the scan is incomplete (maxFiles / file size / plugin count limits)' required: false default: 'false' max-files: description: 'Max files to scan' required: false default: '3000' sarif-file: description: 'SARIF output filename (relative to workspace)' required: false default: 'sentinel.sarif' outputs: exit-code: description: 'dsh-sentinel exit code (0 ok / 1 threshold exceeded / 2 runtime error / 3 incomplete scan)' value: ${{ steps.run.outputs.exit-code }} sarif-path: description: 'Absolute path of the SARIF file' value: ${{ steps.run.outputs.sarif-path }} runs: using: composite steps: # 安全红线:绝不在被扫描项目执行 npm install/npm ci—— # 安装必须定向到 ${{ github.action_path }}(dsh-sentinel 自己的依赖), # 且强制 --ignore-scripts(最小执行面,防未来依赖出现 lifecycle 脚本)。 # 兜底:引擎自带 vendored acorn(.github/actions/dsh-sentinel/vendor/), # 即使安装失败/离线,扫描仍可运行。 - name: Install dsh-sentinel runtime dependencies shell: bash run: | if [ -f "${{ github.action_path }}/package-lock.json" ]; then npm ci \ --prefix "${{ github.action_path }}" \ --omit=dev \ --ignore-scripts \ --no-audit \ --no-fund fi - name: Run dsh-sentinel id: run shell: bash run: | set +e node "${{ github.action_path }}/bin/sentinel.mjs" "${{ inputs.path }}" \ --mode "${{ inputs.mode }}" \ --format sarif \ --out "${{ github.workspace }}/${{ inputs.sarif-file }}" \ --max-files "${{ inputs.max-files }}" \ --fail-on "${{ inputs.fail-on }}" \ ${{ inputs.fail-on-incomplete == 'true' && '--fail-on-incomplete' || '' }} code=$? echo "exit-code=$code" >> "$GITHUB_OUTPUT" echo "sarif-path=${{ github.workspace }}/${{ inputs.sarif-file }}" >> "$GITHUB_OUTPUT" echo "dsh-sentinel exit code: $code (0=ok 1=threshold-exceeded 2=runtime-error 3=incomplete-scan)" exit "$code"