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
16 changes: 16 additions & 0 deletions .github/workflows/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4334,6 +4334,7 @@ jobs:
if ! gh api -X GET "repos/${GH_REPOSITORY}/actions/workflows/strix.yml" \
--jq '.id' >/dev/null 2>"$workflow_lookup_err"; then
if grep -Fq "HTTP 404" "$workflow_lookup_err"; then
printf 'Strix workflow is not installed on %s; skipping optional current-head Strix workflow-run lookup.\n' "$GH_REPOSITORY" >&2
: >"$output_file"
rm -f "$runs_json" "$workflow_lookup_err"
return 0
Expand Down Expand Up @@ -4540,7 +4541,22 @@ jobs:

latest_current_head_manual_strix_run() {
local runs_json
local workflow_lookup_err
runs_json="$(mktemp)"
workflow_lookup_err="$(mktemp)"

if ! gh api -X GET "repos/${GH_REPOSITORY}/actions/workflows/strix.yml" \
--jq '.id' >/dev/null 2>"$workflow_lookup_err"; then
if grep -Fq "HTTP 404" "$workflow_lookup_err"; then
printf 'Strix workflow is not installed on %s; skipping optional manual Strix run lookup.\n' "$GH_REPOSITORY" >&2
rm -f "$runs_json" "$workflow_lookup_err"
return 0
fi
cat "$workflow_lookup_err" >&2
rm -f "$runs_json" "$workflow_lookup_err"
return 1
fi
rm -f "$workflow_lookup_err"

if ! gh run list \
--repo "$GH_REPOSITORY" \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ jobs:

def iter_findings(path):
data = json.loads(Path(path).read_text(encoding="utf-8"))
for result in data.get("results", []):
for result in data.get("results") or []:
source = result.get("source", {})
source_name = source.get("path") or source.get("name") or "unknown"
for package in result.get("packages", []):
Expand Down
63 changes: 43 additions & 20 deletions scripts/ci/collect_failed_check_evidence.sh
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,27 @@ cleanup() {
}
trap cleanup EXIT

target_workflow_available() {
local workflow_file="$1"
local workflow_lookup_err

workflow_lookup_err="$(mktemp)"
tmp_files+=("$workflow_lookup_err")

if gh api -X GET "repos/${GH_REPOSITORY}/actions/workflows/${workflow_file}" \
--jq '.id' >/dev/null 2>"$workflow_lookup_err"; then
return 0
fi

if grep -Fq "HTTP 404" "$workflow_lookup_err"; then
printf 'Optional workflow %s is not installed on %s; skipping current-head workflow-run lookup.\n' "$workflow_file" "$GH_REPOSITORY" >&2
return 1
fi

cat "$workflow_lookup_err" >&2
return 1
}

manual_success_for_label() {
local label="$1"
local failed_run_id="${2:-}"
Expand Down Expand Up @@ -580,26 +601,28 @@ gh api graphql \
| @tsv
' >"$manual_success_check_runs"

env HEAD_SHA="$HEAD_SHA" gh run list \
--repo "$GH_REPOSITORY" \
--workflow strix.yml \
--commit "$HEAD_SHA" \
--limit 200 \
--json databaseId,workflowName,status,conclusion,url,event,headSha \
--jq '
.[]
| select((.event // "") == "workflow_dispatch")
| select((.headSha // "") == env.HEAD_SHA)
| select((.workflowName // "") == "Strix Security Scan" or (.workflowName // "") == "Strix")
| select((.status // "") == "completed")
| select((.conclusion // "" | ascii_downcase) == "success")
| [
"strix",
(.url // ""),
"Manual workflow_dispatch Strix evidence passed"
]
| @tsv
' >>"$manual_success_check_runs" || true
if target_workflow_available "strix.yml"; then
env HEAD_SHA="$HEAD_SHA" gh run list \
--repo "$GH_REPOSITORY" \
--workflow strix.yml \
--commit "$HEAD_SHA" \
--limit 200 \
--json databaseId,workflowName,status,conclusion,url,event,headSha \
--jq '
.[]
| select((.event // "") == "workflow_dispatch")
| select((.headSha // "") == env.HEAD_SHA)
| select((.workflowName // "") == "Strix Security Scan" or (.workflowName // "") == "Strix")
| select((.status // "") == "completed")
| select((.conclusion // "" | ascii_downcase) == "success")
| [
"strix",
(.url // ""),
"Manual workflow_dispatch Strix evidence passed"
]
| @tsv
' >>"$manual_success_check_runs" || true
fi

env HEAD_SHA="$HEAD_SHA" gh run list \
--repo "$GH_REPOSITORY" \
Expand Down
38 changes: 38 additions & 0 deletions tests/test_required_workflow_queue_contract.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import subprocess
import sys
import textwrap
from pathlib import Path


Expand Down Expand Up @@ -128,6 +129,43 @@ def test_osv_scan_logs_and_retries_without_transitive_resolution_on_resolver_fai
assert "OSV {label} scan produced {len(findings)} finding(s)" in workflow


def test_osv_findings_log_accepts_null_results_for_manifestless_repos(tmp_path: Path) -> None:
workflow = workflow_text("security-scan.yml")
step = " - name: Print OSV findings being compared\n"
start = workflow.index(step)
run_start = workflow.index(" run: |\n", start) + len(" run: |\n")
run_end = workflow.index("\n - name:", run_start)
script = textwrap.dedent(
"\n".join(line[10:] for line in workflow[run_start:run_end].splitlines())
)

for filename in ("old-results.json", "new-results.json"):
(tmp_path / filename).write_text('{"results": null}\n', encoding="utf-8")

result = subprocess.run(
[sys.executable, "-c", script],
cwd=tmp_path,
check=True,
capture_output=True,
text=True,
)

assert "OSV base scan produced 0 finding(s) in old-results.json." in result.stdout
assert "OSV head scan produced 0 finding(s) in new-results.json." in result.stdout


def test_optional_strix_workflow_absence_is_logged_without_failing_lookup() -> None:
workflow = workflow_text("opencode-review.yml")
failed_check_evidence = (REPO_ROOT / "scripts/ci/collect_failed_check_evidence.sh").read_text(
encoding="utf-8"
)

assert "skipping optional current-head Strix workflow-run lookup" in workflow
assert "skipping optional manual Strix run lookup" in workflow
assert "Optional workflow %s is not installed" in failed_check_evidence
assert 'if target_workflow_available "strix.yml"; then' in failed_check_evidence


def test_pr_scorecard_sarif_delegates_sast_and_vulnerability_posture_to_hard_gates() -> None:
"""PR Scorecard SARIF should not duplicate CodeQL/OSV/Trivy hard gates."""
for filename in ("scorecard-pr.yml", "security-scan.yml"):
Expand Down
Loading