Skip to content

[CI] adapt .github/workflows/*.yml for MetaxGPU new #63

[CI] adapt .github/workflows/*.yml for MetaxGPU new

[CI] adapt .github/workflows/*.yml for MetaxGPU new #63

Workflow file for this run

name: Preflight Checks
permissions:
contents: read
checks: read
pull-requests: read
on:
push:
branches: [dev, main, testbed]
tags: ["v*"]
pull_request:
branches: [dev, main, testbed]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
validate-pr-title:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: .claude/conventions
sparse-checkout-cone-mode: false
- name: Validate PR title format
env:
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" != "pull_request" ]]; then
echo "Not a pull request event; skipping PR title validation."
exit 0
fi
source .claude/conventions/types.sh
if [[ ! "$PR_TITLE" =~ $COMMIT_MSG_PATTERN ]]; then
echo "::error::PR title does not follow TileOPs format."
echo "Expected: [Type] description or [Type][Scope] description"
echo "Types: $COMMIT_PR_TYPES"
echo "Got: $PR_TITLE"
exit 1
fi
echo "PR title is valid: $PR_TITLE"
detect-changes:
runs-on: ubuntu-latest
outputs:
manifest: ${{ steps.filter.outputs.manifest }}
benchmark: ${{ steps.filter.outputs.benchmark }}
steps:
- name: Detect relevant changed paths
id: filter
env:
GH_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
REPO: ${{ github.repository }}
WORKFLOW_PATH: .github/workflows/preflight.yml
run: |
set -euo pipefail
# Non-PR events (push to main, tags, manual dispatch) always run
# both gated jobs — no base ref to diff against.
if [[ "$EVENT_NAME" != "pull_request" ]]; then
echo "manifest=true" >> "$GITHUB_OUTPUT"
echo "benchmark=true" >> "$GITHUB_OUTPUT"
exit 0
fi
# Fail-open: if the API call errors out or returns nothing, run
# everything. The optimization must never reduce CI reliability.
if ! FILES=$(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/files" --jq '.[].filename' 2>&1); then
echo "::warning::gh api failed; defaulting to run all gated jobs"
echo "$FILES"
echo "manifest=true" >> "$GITHUB_OUTPUT"
echo "benchmark=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ -z "$FILES" ]]; then
echo "::warning::no files returned; defaulting to run all gated jobs"
echo "manifest=true" >> "$GITHUB_OUTPUT"
echo "benchmark=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Changed files in PR #$PR_NUMBER:"
echo "$FILES"
manifest=false
benchmark=false
while IFS= read -r f; do
[[ -z "$f" ]] && continue
case "$f" in
tileops/manifest/*.yaml|tileops/manifest/__init__.py|scripts/validate_manifest.py|"$WORKFLOW_PATH")
manifest=true
;;
esac
# `benchmark-contract-tests` runs `pytest benchmarks/tests`, which
# imports `workloads.workload_base`, `tileops.manifest`, and reads
# the per-family files under `tileops/manifest/*.yaml` via
# `load_workloads()` / `workloads_to_params()`. Any of those layers
# can break the contract tests, so include them all.
case "$f" in
benchmarks/*|workloads/*|tileops/manifest/*.yaml|tileops/manifest/__init__.py|"$WORKFLOW_PATH")
benchmark=true
;;
esac
done <<< "$FILES"
echo "manifest=$manifest"
echo "benchmark=$benchmark"
echo "manifest=$manifest" >> "$GITHUB_OUTPUT"
echo "benchmark=$benchmark" >> "$GITHUB_OUTPUT"
ci-gate:
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
steps:
- name: Check existing CI results for this SHA
id: check
env:
GH_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
EVENT_ACTION: ${{ github.event.action || '' }}
TARGET_BRANCH: ${{ github.base_ref || '' }}
IS_DRAFT: ${{ github.event.pull_request.draft || false }}
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" != "pull_request" ]]; then
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ "$IS_DRAFT" == "true" ]]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
case "$TARGET_BRANCH" in
dev|main|testbed) ;;
*) echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0 ;;
esac
if [[ "$EVENT_ACTION" != "ready_for_review" ]]; then
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# `benchmark-contract-tests` is intentionally skipped on PRs that
# don't touch its inputs (see detect-changes). Keep that job
# skippable, but still require the core preflight checks to be
# successful so `ready_for_review` re-runs them and unblocks
# gpu-smoke.
CHECKS=$(gh api "repos/${{ github.repository }}/commits/$HEAD_SHA/check-runs" --jq '
[
.check_runs
| group_by(.name)
| map(max_by(.id))[]
| select(.name == "pre-commit" or .name == "gitleaks" or .name == "actionlint" or .name == "benchmark-contract-tests")
| {name: .name, conclusion: .conclusion}
]
')
ALL_OK=$(echo "$CHECKS" | jq '
all(
if .name == "benchmark-contract-tests"
then (.conclusion == "success" or .conclusion == "skipped")
else (.conclusion == "success")
end
)
')
COUNT=$(echo "$CHECKS" | jq 'length')
if [[ "$ALL_OK" == "true" && "$COUNT" -ge 4 ]]; then
echo "CI already passed for SHA $HEAD_SHA; skipping"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
pre-commit:
needs: [validate-pr-title, ci-gate]
if: ${{ github.repository == 'MetaX-MACA/TileOPs-Metax' && needs.ci-gate.outputs.skip != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Run pre-commit
uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files --show-diff-on-failure
gitleaks:
needs: [validate-pr-title, ci-gate]
if: ${{ github.repository == 'MetaX-MACA/TileOPs-Metax' && needs.ci-gate.outputs.skip != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install gitleaks
env:
GITLEAKS_VERSION: "8.30.0"
run: |
set -euo pipefail
install_dir="${RUNNER_TEMP}/bin"
archive="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
mkdir -p "$install_dir"
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${archive}" \
-o "${RUNNER_TEMP}/${archive}"
tar -xzf "${RUNNER_TEMP}/${archive}" -C "$install_dir" gitleaks
echo "$install_dir" >> "$GITHUB_PATH"
- name: Run gitleaks
run: gitleaks dir . --redact --no-banner
validate-manifest:
needs: [validate-pr-title, ci-gate, detect-changes]
if: ${{ github.repository == 'tile-ai/TileOPs' && needs.ci-gate.outputs.skip != 'true' && needs.detect-changes.outputs.manifest == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install TileOPs and validator dependencies
run: pip install -e .
- name: Validate ops manifest
run: python scripts/validate_manifest.py --levels schema,shape,dtype,bench
actionlint:
needs: [validate-pr-title, ci-gate]
if: ${{ github.repository == 'MetaX-MACA/TileOPs-Metax' && needs.ci-gate.outputs.skip != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install actionlint
env:
ACTIONLINT_VERSION: "1.7.11"
run: |
set -euo pipefail
install_dir="${RUNNER_TEMP}/bin"
mkdir -p "$install_dir"
curl -sSfL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash \
| bash -s -- "$ACTIONLINT_VERSION" "$install_dir"
echo "$install_dir" >> "$GITHUB_PATH"
- name: Run actionlint
run: actionlint -color
benchmark-contract-tests:
# CPU-only contract tests for benchmark workload protocols.
# Scoped to `benchmarks/tests/` so the GPU-bound `benchmarks/ops/`
# suites (nightly-only) are NOT collected on PR CI.
needs: [validate-pr-title, ci-gate, detect-changes]
if: ${{ github.repository == 'tile-ai/TileOPs' && needs.ci-gate.outputs.skip != 'true' && needs.detect-changes.outputs.benchmark == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install TileOPs (with dev extras)
run: pip install -e ".[dev]"
- name: Run benchmark contract tests
run: python -m pytest -q benchmarks/tests