haochengsama's picture
Add files using upload-large-folder tool
a2ec7b6 verified
Raw
History Blame Contribute Delete
3.73 kB
import base64
import os
import sys
from typing import List, Optional
import requests
from dotenv import load_dotenv
REPO_NAME = "mcpmark-cicd"
WORKFLOW_PATH = ".github/workflows/basic-ci.yml"
BRANCH = "main"
def _download_file(org: str, token: str, path: str) -> Optional[str]:
url = f"https://api.github.com/repos/{org}/{REPO_NAME}/contents/{path}?ref={BRANCH}"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/vnd.github+json",
}
try:
response = requests.get(url, headers=headers, timeout=30)
except Exception as exc: # pragma: no cover - network failure
print(f"Request error for {path}: {exc}", file=sys.stderr)
return None
if response.status_code != 200:
print(
f"GitHub API returned {response.status_code} when fetching {path}",
file=sys.stderr,
)
return None
data = response.json()
try:
content = base64.b64decode(data.get("content", "")).decode("utf-8")
except Exception as exc:
print(f"Unable to decode {path}: {exc}", file=sys.stderr)
return None
return content
def _line_index(lines: List[str], needle: str) -> int:
for idx, line in enumerate(lines):
if needle in line:
return idx
return -1
def verify() -> bool:
load_dotenv(".mcp_env")
token = os.environ.get("MCP_GITHUB_TOKEN")
org = os.environ.get("GITHUB_EVAL_ORG")
if not token:
print("MCP_GITHUB_TOKEN is missing", file=sys.stderr)
return False
if not org:
print("GITHUB_EVAL_ORG is missing", file=sys.stderr)
return False
content = _download_file(org, token, WORKFLOW_PATH)
if content is None:
print(
"Workflow file .github/workflows/basic-ci.yml was not found on main",
file=sys.stderr,
)
return False
normalized = content.lower()
normalized_lines = [line.strip().lower() for line in content.splitlines()]
errors = []
required_snippets = {
"workflow name": "name: basic ci checks",
"job name": "quality-checks",
"checkout step": "actions/checkout",
"setup-node step": "actions/setup-node",
"node version": "node-version: 18",
"ubuntu runner": "runs-on: ubuntu-latest",
"push trigger": "push:",
"pull_request trigger": "pull_request:",
}
for label, snippet in required_snippets.items():
if snippet not in normalized:
errors.append(f"Missing {label} ({snippet}) in workflow")
branch_limited = "- main" in normalized or "[main]" in normalized
if not branch_limited:
errors.append("Workflow triggers must be limited to the main branch")
for command in ["npm ci", "npm run lint", "npm test"]:
if command not in normalized:
errors.append(f"Missing '{command}' step")
# Ensure npm commands happen in the expected order
ci_index = _line_index(normalized_lines, "npm ci")
lint_index = _line_index(normalized_lines, "npm run lint")
test_index = _line_index(normalized_lines, "npm test")
if ci_index == -1 or lint_index == -1 or test_index == -1:
errors.append("Could not find all npm commands to validate ordering")
else:
if not (ci_index < lint_index < test_index):
errors.append("npm commands must run in order: ci -> lint -> test")
if errors:
print("Verification failed:")
for err in errors:
print(f" - {err}", file=sys.stderr)
return False
print("✅ basic-ci workflow found with required steps and triggers")
return True
if __name__ == "__main__":
sys.exit(0 if verify() else 1)