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
1 change: 1 addition & 0 deletions .github/workflows/AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ concrete reason, verified against the actual repository tree.
| `deploy.yml` | **DELETE** | References a non-existent `deployments/` tree (manifests/terraform); actual infra is `infrastructure/`. The validate job hard-`exit 1`s on missing manifests. Generic multi-cloud (AWS+Azure+Slack) scaffold that duplicates `deploy-cloud-run.yml`. |
| `e2e-tests.yml` | **FIX** | Resolve the PR's Vercel preview deployment via the GitHub Deployments API before E2E runs, and skip the PR-comment step for forked `pull_request` runs where `GITHUB_TOKEN` is read-only (`Resource not accessible by integration`). Same-repo PRs still get comments. |
| `emergency-stop.yml` | KEEP | Manual operational kill-switch with typed confirmation. |
| `eventrelay-ci-investigator.md` / `.lock.yml` | **FIX** | Require a dedicated `CODEX_API_KEY` credential in pre-agent steps so Codex-specific runs fail fast with an explicit key-missing error instead of ambiguous fallback behavior. |
| `issue-triage.yml` | KEEP | Keyword auto-labeling + triage comment on new issues. |
| `mcp-optimization.yml` | **DELETE** | Entire workflow targets `mcp-servers/mcp-profiling/` (requirements.txt, investigator_client.py, profiling_server.py) which does not exist — every run fails. |
| `phase-goal-tracker.yml` | KEEP | Tracks markdown checklists on phase issues, keeps a single status comment updated, and auto-closes the issue when all checklist goals are complete. |
Expand Down
22 changes: 21 additions & 1 deletion .github/workflows/eventrelay-ci-investigator.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .github/workflows/eventrelay-ci-investigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ on:
branches:
- main
workflow_dispatch:
steps:
- name: Require dedicated Codex credential
id: require_codex_credential
env:
CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }}
run: |
if [ -z "${CODEX_API_KEY}" ]; then
echo "::error::Dedicated CODEX_API_KEY is required"
exit 1
fi

permissions:
actions: read
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/test_gh_aw_workflow_governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,45 @@ def test_focused_coverage_controller_can_read_authoritative_runs() -> None:
assert "requires a separate approved GitHub App canary" in source


def test_ci_investigator_requires_dedicated_codex_credential() -> None:
workflow = _load_frontmatter(
ROOT / ".github/workflows/eventrelay-ci-investigator.md"
)
triggers = workflow.get("on", workflow.get(True))
assert triggers is not None
credential_gate = next(
step
for step in triggers["steps"]
if step.get("name") == "Require dedicated Codex credential"
)

assert credential_gate["id"] == "require_codex_credential"
assert credential_gate["env"]["CODEX_API_KEY"] == "${{ secrets.CODEX_API_KEY }}"
assert "Dedicated CODEX_API_KEY is required" in credential_gate["run"]
assert "OPENAI_API_KEY" not in credential_gate["run"]
Comment thread
groupthinking marked this conversation as resolved.

compiled = _load_yaml(
ROOT / ".github/workflows/eventrelay-ci-investigator.lock.yml"
)
pre_activation_steps = compiled["jobs"]["pre_activation"]["steps"]
activation = compiled["jobs"]["activation"]
agent_steps = compiled["jobs"]["agent"]["steps"]

compiled_gate = next(
step
for step in pre_activation_steps
if step.get("id") == "require_codex_credential"
)
assert compiled_gate["name"] == "Require dedicated Codex credential"
assert compiled_gate["env"]["CODEX_API_KEY"] == "${{ secrets.CODEX_API_KEY }}"
assert activation["needs"] == "pre_activation"
assert any(step.get("id") == "validate-secret" for step in activation["steps"])
assert not any(
step.get("name") == "Require dedicated Codex credential"
for step in agent_steps
)


def test_live_smoke_modules_are_excluded_before_import(monkeypatch) -> None:
monkeypatch.delenv("RUN_LIVE_E2E", raising=False)
monkeypatch.delenv("RUN_LIVE_DEPLOY", raising=False)
Expand Down
Loading