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
85 changes: 76 additions & 9 deletions .github/workflows/strix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,91 @@ jobs:
with:
python-version: "3.13"

- name: Materialize trusted workspace
- name: Resolve trusted Strix source ref
id: trusted_source
env:
JOB_CONTEXT_JSON: ${{ toJSON(job) }}
GITHUB_CONTEXT_JSON: ${{ toJSON(github) }}
run: |
set -euo pipefail
python3 <<'PY' >>"$GITHUB_OUTPUT"
import json
import os
import re
import sys

try:
job_context = json.loads(os.environ.get("JOB_CONTEXT_JSON") or "{}")
github_context = json.loads(os.environ.get("GITHUB_CONTEXT_JSON") or "{}")
except json.JSONDecodeError as exc:
print(f"::error::Could not parse GitHub workflow context JSON: {exc}", file=sys.stderr)
raise SystemExit(1)

trusted_repository = str(
job_context.get("workflow_repository") or "ContextualWisdomLab/.github"
).strip()
trusted_ref = str(
job_context.get("workflow_sha") or github_context.get("workflow_sha") or ""
).strip()
workflow_ref = str(
job_context.get("workflow_ref") or github_context.get("workflow_ref") or ""
).strip()

if not trusted_ref:
trusted_ref = "main"
prefix = "ContextualWisdomLab/.github/.github/workflows/strix.yml@"
if workflow_ref.startswith(prefix):
trusted_ref = workflow_ref.split("@", 1)[1]

if not re.fullmatch(r"[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+", trusted_repository):
print("::error::Trusted workflow repository resolved to an invalid name.", file=sys.stderr)
raise SystemExit(1)
if not re.fullmatch(r"[0-9a-fA-F]{40}|refs/[^\s]+|[A-Za-z0-9._/-]+", trusted_ref):
print("::error::Trusted workflow ref resolved to an invalid value.", file=sys.stderr)
raise SystemExit(1)

print(f"repository={trusted_repository}")
print(f"ref={trusted_ref}")
PY

- name: Checkout trusted Strix source
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ steps.trusted_source.outputs.repository }}
fetch-depth: 1
persist-credentials: false
ref: ${{ steps.trusted_source.outputs.ref }}
Comment thread
seonghobae marked this conversation as resolved.
path: trusted-strix-source

- name: Export trusted Strix source paths
run: |
set -euo pipefail
trusted_strix_source="$GITHUB_WORKSPACE/trusted-strix-source"
test -f "$trusted_strix_source/scripts/ci/strix_quick_gate.sh"
test -f "$trusted_strix_source/scripts/ci/test_strix_quick_gate.sh"
{
echo "TRUSTED_STRIX_SOURCE=$trusted_strix_source"
echo "TRUSTED_STRIX_GATE=$trusted_strix_source/scripts/ci/strix_quick_gate.sh"
echo "TRUSTED_STRIX_GATE_TEST=$trusted_strix_source/scripts/ci/test_strix_quick_gate.sh"
} >> "$GITHUB_ENV"

- name: Materialize target workspace
env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
TRUSTED_WORKSPACE_SHA: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha }}
TARGET_WORKSPACE_SHA: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.sha || github.sha }}
run: |
set -euo pipefail
trusted_workspace="$RUNNER_TEMP/trusted-workspace"
mkdir -p "$trusted_workspace"
git init -q "$trusted_workspace"
gh auth setup-git
git -C "$trusted_workspace" remote add origin "$GITHUB_SERVER_URL/$REPOSITORY.git"
git -C "$trusted_workspace" fetch --no-tags --depth=1 origin "$TRUSTED_WORKSPACE_SHA"
git -C "$trusted_workspace" checkout --detach --quiet "$TRUSTED_WORKSPACE_SHA"
git -C "$trusted_workspace" cat-file -e "$TRUSTED_WORKSPACE_SHA^{commit}"
git -C "$trusted_workspace" fetch --no-tags --depth=1 origin "$TARGET_WORKSPACE_SHA"
git -C "$trusted_workspace" checkout --detach --quiet "$TARGET_WORKSPACE_SHA"
git -C "$trusted_workspace" cat-file -e "$TARGET_WORKSPACE_SHA^{commit}"
{
echo "TRUSTED_WORKSPACE=$trusted_workspace"
echo "TRUSTED_STRIX_GATE=$trusted_workspace/scripts/ci/strix_quick_gate.sh"
echo "TRUSTED_STRIX_GATE_TEST=$trusted_workspace/scripts/ci/test_strix_quick_gate.sh"
} >> "$GITHUB_ENV"

- name: Fetch pull request head for trusted scan
Expand Down Expand Up @@ -145,7 +211,7 @@ jobs:

- name: Self-test Strix gate script
timeout-minutes: 10
working-directory: ${{ runner.temp }}/trusted-workspace
working-directory: trusted-strix-source
run: |
set -euo pipefail
printf 'Running Strix gate self-test with a 10-minute step timeout.\n'
Expand Down Expand Up @@ -214,7 +280,7 @@ jobs:

- name: Install Strix
if: steps.gate.outputs.enabled == 'true'
working-directory: ${{ runner.temp }}/trusted-workspace
working-directory: trusted-strix-source
run: |
python3 -m pip install --disable-pip-version-check --no-cache-dir --require-hashes -r requirements-strix-ci-hashes.txt

Expand Down Expand Up @@ -363,6 +429,7 @@ jobs:
working-directory: ${{ runner.temp }}/trusted-workspace
env:
STRIX_LLM_FILE: ${{ env.STRIX_LLM_FILE }}
STRIX_REPO_ROOT: ${{ runner.temp }}/trusted-workspace
LLM_API_BASE_FILE: ${{ env.LLM_API_BASE_FILE }}
STRIX_LLM_DEFAULT_PROVIDER: ${{ steps.gate.outputs.provider_mode == 'vertex_ai' && 'vertex_ai' || 'openai' }}
LLM_API_KEY_FILE: ${{ env.LLM_API_KEY_FILE }}
Expand Down
8 changes: 7 additions & 1 deletion scripts/ci/strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
set -euo pipefail

SCRIPT_DIR="$({ CDPATH='' && cd -P -- "$(dirname -- "$0")" && pwd -P; })"
REPO_ROOT="$({ CDPATH='' && cd -P -- "$SCRIPT_DIR/../.." && pwd -P; })"
DEFAULT_REPO_ROOT="$({ CDPATH='' && cd -P -- "$SCRIPT_DIR/../.." && pwd -P; })"
RAW_REPO_ROOT="${STRIX_REPO_ROOT:-$DEFAULT_REPO_ROOT}"
if [ -z "$RAW_REPO_ROOT" ] || [ ! -d "$RAW_REPO_ROOT" ] || [ -L "$RAW_REPO_ROOT" ]; then
echo "ERROR: STRIX_REPO_ROOT must reference a regular directory when provided." >&2
exit 2
fi
REPO_ROOT="$({ CDPATH='' && cd -P -- "$RAW_REPO_ROOT" && pwd -P; })"
RAW_TARGET_PATH="${STRIX_TARGET_PATH:-./}"
TARGET_PATH=""
PR_SCOPE_TARGET_SENTINEL="__PR_SCOPE__"
Expand Down
20 changes: 17 additions & 3 deletions scripts/ci/test_strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,30 @@ assert_strix_workflow_pr_trigger_hardened() {
assert_file_contains "$workflow_file" "models: read" "strix workflow grants only the GitHub Models read permission needed for Strix"
assert_file_contains "$workflow_file" "actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6" "strix workflow pins actions/setup-python"
assert_file_contains "$workflow_file" 'python-version: "3.13"' "strix workflow runs Python steps on Python 3.13"
assert_file_contains "$workflow_file" "Materialize trusted workspace" "strix workflow materializes trusted workspace"
assert_file_contains "$workflow_file" "TRUSTED_WORKSPACE_SHA" "strix workflow pins trusted workspace SHA"
assert_file_contains "$workflow_file" "Resolve trusted Strix source ref" "strix workflow resolves the central trusted Strix source ref"
assert_file_contains "$workflow_file" "toJSON(job)" "strix workflow derives the trusted source from the job workflow context"
assert_file_contains "$workflow_file" "workflow_repository" "strix workflow derives the trusted source repository from the job workflow identity"
assert_file_contains "$workflow_file" "workflow_sha" "strix workflow pins trusted source checkout to the job workflow commit SHA when available"
assert_file_contains "$workflow_file" "workflow_ref" "strix workflow falls back to the required-workflow source ref when the SHA is unavailable"
assert_file_contains "$workflow_file" "Checkout trusted Strix source" "strix workflow checks out the central Strix source"
assert_file_contains "$workflow_file" 'repository: ${{ steps.trusted_source.outputs.repository }}' "strix workflow checks out central Strix scripts instead of target-repo copies"
assert_file_contains "$workflow_file" 'ref: ${{ steps.trusted_source.outputs.ref }}' "strix workflow checks out the exact trusted Strix source ref"
assert_file_contains "$workflow_file" 'TRUSTED_STRIX_SOURCE=$trusted_strix_source' "strix workflow exports the central Strix source path"
assert_file_contains "$workflow_file" 'TRUSTED_STRIX_GATE=$trusted_strix_source/scripts/ci/strix_quick_gate.sh' "strix workflow executes the central Strix gate script"
assert_file_contains "$workflow_file" "Materialize target workspace" "strix workflow materializes target repository data separately from trusted scripts"
assert_file_contains "$workflow_file" "TARGET_WORKSPACE_SHA" "strix workflow pins target workspace SHA"
assert_file_contains "$workflow_file" "TRUSTED_WORKSPACE=\$trusted_workspace" "strix workflow exports a trusted workspace path"
assert_file_contains "$workflow_file" "git -C \"\$TRUSTED_WORKSPACE\"" "strix workflow runs git only inside trusted workspace"
assert_file_contains "$workflow_file" 'working-directory: ${{ runner.temp }}/trusted-workspace' "strix workflow executes privileged steps from the trusted workspace"
assert_file_contains "$workflow_file" "STRIX_REPO_ROOT:" "strix workflow passes target repository root to the central Strix gate"
assert_file_contains "$workflow_file" "bash \"\$TRUSTED_STRIX_GATE_TEST\"" "strix workflow self-test executes trusted temp script"
assert_file_contains "$workflow_file" "bash \"\$TRUSTED_STRIX_GATE\"" "strix workflow executes trusted temp gate script"
assert_file_contains "$workflow_file" "Collect Strix reports for artifact upload" "strix workflow preserves reports from trusted workspace"
assert_file_contains "$workflow_file" "scan-summary.txt" "strix workflow creates a fallback artifact when Strix emits no report files"
assert_file_not_contains "$workflow_file" "actions/checkout" "strix workflow avoids checkout in privileged context"
local checkout_count
checkout_count="$(grep -Fc "uses: actions/checkout@" "$workflow_file")"
assert_equals "1" "$checkout_count" "strix workflow uses actions/checkout exactly once for the central trusted source"
assert_file_not_contains "$workflow_file" 'repository: ${{ github.repository }}' "strix workflow must not checkout target repository code with actions/checkout in privileged context"
assert_file_not_contains "$workflow_file" "run: bash ./scripts/ci/test_strix_quick_gate.sh" "strix workflow avoids direct repo self-test execution on privileged trigger"
assert_file_not_contains "$workflow_file" "run: bash ./scripts/ci/strix_quick_gate.sh" "strix workflow avoids direct repo gate execution on privileged trigger"
assert_file_contains "$workflow_file" "Fetch pull request head for trusted scan" "strix workflow fetches PR head without checkout"
Expand Down