Skip to content

Required Noema Review ContextualWisdomLab/ContextualWisdomLab.github.io#119@a70e02cdc72462b4a3216fac4a62ab97d807aae7 #13

Required Noema Review ContextualWisdomLab/ContextualWisdomLab.github.io#119@a70e02cdc72462b4a3216fac4a62ab97d807aae7

Required Noema Review ContextualWisdomLab/ContextualWisdomLab.github.io#119@a70e02cdc72462b4a3216fac4a62ab97d807aae7 #13

name: Required Noema Review
run-name: >-
Required Noema Review ${{ github.event.client_payload.target_repository ||
github.event.pull_request.base.repo.full_name || github.repository }}#${{
github.event.client_payload.pr_number || github.event.pull_request.number ||
github.event.workflow_run.pull_requests[0].number || 'event' }}@${{
github.event.client_payload.pr_head_sha || github.event.pull_request.head.sha ||
github.event.workflow_run.head_sha || github.sha }}
on:
pull_request_target:
types: [opened, synchronize, reopened, ready_for_review, closed]
workflow_run:
workflows: ["Required OpenCode Review", "Strix Security Scan"]
types: [completed]
# Default-branch-only retry entrypoint; no caller-selected workflow ref.
repository_dispatch:
types: [noema-review]
concurrency:
group: >-
noema-review-${{
github.event_name == 'pull_request_target' && github.event.pull_request.base.repo.full_name ||
github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository ||
github.repository }}-${{ github.event_name }}-${{
github.event_name == 'pull_request_target' && format('pr-{0}', github.event.pull_request.number) ||
github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].number && format('pr-{0}', github.event.workflow_run.pull_requests[0].number) ||
github.event_name == 'repository_dispatch' && github.event.client_payload.pr_number ||
github.run_id }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: read
checks: read
id-token: write
jobs:
cancel-closed-pr-runs:
if: github.event_name == 'pull_request_target' && github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- run: echo "PR closed; this run only cancels older runs through workflow concurrency."
noema-review:
name: noema-review
runs-on: ubuntu-latest
if: >-
github.event_name == 'repository_dispatch'
|| (
github.event_name == 'workflow_run'
&& github.event.workflow_run.conclusion != 'cancelled'
)
|| (
github.event_name == 'pull_request_target'
&& github.event.action != 'closed'
&& github.event.pull_request.head.repo.full_name == github.repository
)
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
TARGET_REPOSITORY: ${{ github.event.pull_request.base.repo.full_name || github.event.client_payload.target_repository || github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number || github.event.workflow_run.pull_requests[0].number || github.event.client_payload.pr_number || '' }}
steps:
- name: Skip events without pull request context
if: env.PR_NUMBER == ''
run: |
echo "::notice::Noema review skipped: no pull request number is associated with this event."
- name: Resolve trusted Noema review source ref
if: env.PR_NUMBER != ''
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/noema-review.yml@"
if workflow_ref.startswith(prefix):
trusted_ref = workflow_ref.split("@", 1)[1]
if trusted_repository != "ContextualWisdomLab/.github":
print("::error::Trusted Noema workflow repository resolved outside ContextualWisdomLab/.github.", 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 Noema 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: Materialize trusted Noema review gate
if: env.PR_NUMBER != ''
env:
GH_TOKEN: ${{ github.token }}
TRUSTED_SOURCE_REF: ${{ steps.trusted_source.outputs.ref }}
run: |
set -euo pipefail
if [[ ! "$TRUSTED_SOURCE_REF" =~ ^[0-9a-fA-F]{40}$ ]]; then
echo "::error::Trusted Noema source ref must resolve to the immutable workflow commit SHA before archive materialization."
exit 1
fi
trusted_archive="${RUNNER_TEMP}/trusted-noema-source.tar.gz"
api_url="${GITHUB_API_URL:-https://api.github.com}"
curl -fsSL \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "Accept: application/vnd.github+json" \
-o "$trusted_archive" \
"${api_url}/repos/ContextualWisdomLab/.github/tarball/${TRUSTED_SOURCE_REF}"
tar -xzf "$trusted_archive" -C "$GITHUB_WORKSPACE" --strip-components=1
test -f scripts/ci/noema_review_gate.py
- name: Select fail-closed Noema reviewer credential
if: env.PR_NUMBER != ''
id: noema_credential
env:
NOEMA_GITHUB_APP_CLIENT_ID: ${{ vars.NOEMA_GITHUB_APP_CLIENT_ID || '' }}
NOEMA_GITHUB_APP_PRIVATE_KEY: ${{ secrets.NOEMA_GITHUB_APP_PRIVATE_KEY || '' }}
TOKEN_EXCHANGE_URL: ${{ vars.NOEMA_TOKEN_EXCHANGE_URL || vars.NOEMA_EXCHANGE_URL || '' }}
NOEMA_REVIEW_TOKEN: ${{ secrets.NOEMA_REVIEW_TOKEN }}
run: |
set -euo pipefail
if [[ ! "$TARGET_REPOSITORY" =~ ^ContextualWisdomLab/[A-Za-z0-9_.-]+$ ]]; then
echo "::error::Noema target repository must belong to ContextualWisdomLab; observed ${TARGET_REPOSITORY:-<empty>}."
exit 1
fi
repository_name="${TARGET_REPOSITORY#*/}"
echo "repository=$repository_name" >>"$GITHUB_OUTPUT"
if [ -n "${NOEMA_REVIEW_TOKEN:-}" ]; then
echo "source=pat" >>"$GITHUB_OUTPUT"
echo "::notice::Noema reviewer using the NOEMA_REVIEW_TOKEN secret fallback identity."
exit 0
fi
if [ -n "${NOEMA_GITHUB_APP_CLIENT_ID:-}" ] && [ -n "${NOEMA_GITHUB_APP_PRIVATE_KEY:-}" ]; then
echo "source=github-app" >>"$GITHUB_OUTPUT"
echo "::notice::Noema reviewer will mint a repository-scoped cwl-noema-review installation token."
exit 0
fi
if [ -n "${TOKEN_EXCHANGE_URL:-}" ]; then
echo "source=oidc" >>"$GITHUB_OUTPUT"
echo "::notice::Noema reviewer will use the configured OIDC app-token exchange."
exit 0
fi
echo "::error::Noema reviewer credential is unconfigured: set NOEMA_GITHUB_APP_CLIENT_ID with NOEMA_GITHUB_APP_PRIVATE_KEY, NOEMA_REVIEW_TOKEN, or NOEMA_TOKEN_EXCHANGE_URL. Review cannot be skipped."
exit 1
- name: Mint repository-scoped Noema GitHub App token
if: env.PR_NUMBER != '' && steps.noema_credential.outputs.source == 'github-app'
id: noema_github_app_token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.NOEMA_GITHUB_APP_CLIENT_ID }}
private-key: ${{ secrets.NOEMA_GITHUB_APP_PRIVATE_KEY }}
owner: ContextualWisdomLab
repositories: ${{ steps.noema_credential.outputs.repository }}
permission-actions: read
permission-checks: read
permission-contents: read
permission-metadata: read
permission-pull-requests: write
permission-security-events: read
permission-statuses: read
permission-vulnerability-alerts: read
- name: Exchange Noema app token through OIDC
if: env.PR_NUMBER != '' && steps.noema_credential.outputs.source == 'oidc'
id: noema_oidc_token
env:
OIDC_AUDIENCE: ${{ vars.NOEMA_OIDC_AUDIENCE || 'cwl-noema-review' }}
TOKEN_EXCHANGE_URL: ${{ vars.NOEMA_TOKEN_EXCHANGE_URL || vars.NOEMA_EXCHANGE_URL || '' }}
run: |
set -euo pipefail
fail_unavailable() {
local message="$1"
echo "::error::$message"
exit 1
}
if [ -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" ] || [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]; then
fail_unavailable "Noema app token exchange unavailable: OIDC request environment is missing."
fi
request_url="${ACTIONS_ID_TOKEN_REQUEST_URL}"
separator="&"
case "$request_url" in
*\?*) ;;
*) separator="?" ;;
esac
if ! oidc_response="$(
curl -fsS \
-H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
"${request_url}${separator}audience=${OIDC_AUDIENCE}"
)"; then
fail_unavailable "Noema app token exchange unavailable: OIDC token request did not complete."
fi
oidc_token="$(jq -r '.value // empty' <<<"$oidc_response")"
if [ -z "$oidc_token" ]; then
fail_unavailable "Noema app token exchange unavailable: OIDC token response was empty."
fi
if ! token_response="$(
curl -fsS \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${oidc_token}" \
--data "$(jq -cn --arg target_repository "$TARGET_REPOSITORY" '{target_repository:$target_repository}')" \
"${TOKEN_EXCHANGE_URL}"
)"; then
fail_unavailable "Noema app token exchange unavailable: app token request did not complete."
fi
app_token="$(jq -r '.token // empty' <<<"$token_response")"
if [ -z "$app_token" ]; then
fail_unavailable "Noema app token exchange unavailable: app token response was empty."
fi
echo "::add-mask::$app_token"
echo "token=$app_token" >>"$GITHUB_OUTPUT"
- name: Run Noema LLM review and submit verdict
if: env.PR_NUMBER != ''
env:
GH_TOKEN: ${{ secrets.NOEMA_REVIEW_TOKEN || steps.noema_github_app_token.outputs.token || steps.noema_oidc_token.outputs.token }}
NOEMA_REVIEW_TOKEN_SOURCE: ${{ steps.noema_credential.outputs.source == 'pat' && 'noema-review-pat' || steps.noema_credential.outputs.source == 'github-app' && 'noema-review-github-app' || 'noema-review-app-oidc' }}
NOEMA_LLM_API_URL: ${{ vars.NOEMA_LLM_API_URL || '' }}
NOEMA_LLM_MODEL: ${{ vars.NOEMA_LLM_MODEL || '' }}
NOEMA_LLM_API_KEY: ${{ secrets.NOEMA_LLM_API_KEY || secrets.OPENAI_API_KEY || '' }}
run: |
set -euo pipefail
if [ -z "${PR_NUMBER:-}" ]; then
echo "No pull request number was available for this event; skipping."
exit 0
fi
if [ -z "${GH_TOKEN:-}" ]; then
echo "::error::Noema reviewer credential selection succeeded but no token was minted; review cannot submit a verdict."
exit 1
fi
if [ -z "${NOEMA_LLM_API_URL:-}" ] || [ -z "${NOEMA_LLM_MODEL:-}" ] || [ -z "${NOEMA_LLM_API_KEY:-}" ]; then
echo "::error::Noema LLM is unconfigured: NOEMA_LLM_API_URL, NOEMA_LLM_MODEL, and NOEMA_LLM_API_KEY (or OPENAI_API_KEY) are required."
exit 1
fi
python3 scripts/ci/noema_review_gate.py \
--repo "$TARGET_REPOSITORY" \
--pr-number "$PR_NUMBER"