ci: add conditional environment test gates

This commit is contained in:
Joseph Magly
2026-08-14 14:29:14 -04:00
parent d54d2dbc90
commit c1a1275291
23 changed files with 1449 additions and 11 deletions
+368
View File
@@ -0,0 +1,368 @@
name: Conditional tests
on:
workflow_dispatch:
inputs:
run_model:
description: Run pinned tiny-model download and evaluation gates
type: boolean
default: true
run_network:
description: Run disposable network-service boundary gate
type: boolean
default: true
run_ui:
description: Construct the optional operator UI without a listener
type: boolean
default: true
run_cuda:
description: Run CUDA and bitsandbytes on the labeled self-hosted runner
type: boolean
default: false
run_mps:
description: Run MPS on the labeled Apple Silicon runner
type: boolean
default: false
run_mlx:
description: Run MLX on the labeled Apple Silicon runner
type: boolean
default: false
run_remote:
description: Run the least-privileged SSH provider gate
type: boolean
default: false
schedule:
- cron: "17 6 * * 0"
release:
types: [published]
permissions:
contents: read
concurrency:
group: conditional-tests-${{ github.ref }}
cancel-in-progress: false
env:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_NO_INPUT: "1"
UV_VERSION: "0.12.4"
jobs:
policy:
name: Conditional policy
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Validate gate mappings and evidence policy
run: python3 scripts/check_conditional_policy.py
model_runtime:
name: Pinned model runtime and evaluation
needs: policy
if: github.event_name != 'workflow_dispatch' || inputs.run_model
runs-on: ubuntu-latest
timeout-minutes: 25
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-model
HF_HOME: /tmp/obliteratus-hf-cache
HF_HUB_DISABLE_TELEMETRY: "1"
TOKENIZERS_PARALLELISM: "false"
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Restore pinned model cache
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.0.3
with:
path: /tmp/obliteratus-hf-cache
key: hf-tiny-random-gpt2-71034c5-py3.12-${{ runner.os }}
- name: Install locked runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --no-editable
- name: Run model download and cache replay
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py
model-download-runtime
- name: Run external evaluation adapter
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py
external-evaluation
- name: Upload model-runtime evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-model-runtime-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
network_services:
name: Network service boundary
needs: policy
if: github.event_name != 'workflow_dispatch' || inputs.run_network
runs-on: ubuntu-latest
timeout-minutes: 10
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-network
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --no-editable
- name: Run disposable service probe
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py
network-services
- name: Upload network evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-network-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
operator_ui:
name: Operator UI construction
needs: policy
if: github.event_name != 'workflow_dispatch' || inputs.run_ui
runs-on: ubuntu-latest
timeout-minutes: 15
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-ui
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked UI runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --all-extras --no-default-groups --no-editable
- name: Construct UI without opening a listener
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py
operator-ui
- name: Upload UI evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-operator-ui-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
cuda:
name: CUDA and bitsandbytes runtime
needs: policy
if: >-
(github.event_name == 'workflow_dispatch' && inputs.run_cuda) ||
(github.event_name != 'workflow_dispatch' && vars.ENABLE_CUDA_GATE == 'true')
runs-on: [self-hosted, linux, x64, cuda]
timeout-minutes: 20
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-cuda
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked CUDA runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --no-editable
- name: Run CUDA placement and operation probe
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py cuda-runtime
- name: Run bitsandbytes quantization probe
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py bitsandbytes-runtime
- name: Upload CUDA evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-cuda-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
mps:
name: Apple MPS runtime
needs: policy
if: >-
(github.event_name == 'workflow_dispatch' && inputs.run_mps) ||
(github.event_name != 'workflow_dispatch' && vars.ENABLE_MPS_GATE == 'true')
runs-on: [self-hosted, macOS, ARM64, mps]
timeout-minutes: 15
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-mps
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked MPS runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --no-editable
- name: Run MPS selection and operation probe
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py mps-runtime
- name: Upload MPS evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-mps-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
mlx:
name: Apple MLX runtime
needs: policy
if: >-
(github.event_name == 'workflow_dispatch' && inputs.run_mlx) ||
(github.event_name != 'workflow_dispatch' && vars.ENABLE_MLX_GATE == 'true')
runs-on: [self-hosted, macOS, ARM64, mlx]
timeout-minutes: 20
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-mlx
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked MLX runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --group mlx --no-editable
- name: Run MLX placement and operation probe
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py mlx-runtime
- name: Upload MLX evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-mlx-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: error
retention-days: 30
remote:
name: Least-privileged remote provider
needs: policy
if: >-
(github.event_name == 'workflow_dispatch' && inputs.run_remote) ||
(github.event_name != 'workflow_dispatch' && vars.ENABLE_REMOTE_GATE == 'true')
runs-on: ubuntu-latest
timeout-minutes: 10
env:
CONDITIONAL_ENV: /tmp/obliteratus-conditional-remote
OBLITERATUS_REMOTE_HOST: ${{ vars.OBLITERATUS_REMOTE_HOST }}
OBLITERATUS_REMOTE_USER: ${{ vars.OBLITERATUS_REMOTE_USER }}
OBLITERATUS_REMOTE_PORT: ${{ vars.OBLITERATUS_REMOTE_PORT }}
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
- name: Install locked runtime
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$CONDITIONAL_ENV" \
uv sync --locked --no-default-groups --extra dev --no-editable
- name: Materialize protected SSH prerequisites
env:
REMOTE_KEY_CONTENT: ${{ secrets.OBLITERATUS_REMOTE_KEY }}
REMOTE_KNOWN_HOSTS_CONTENT: ${{ secrets.OBLITERATUS_REMOTE_KNOWN_HOSTS }}
run: |
if [ -z "$OBLITERATUS_REMOTE_HOST" ] || [ -z "$OBLITERATUS_REMOTE_USER" ]; then
echo "remote gate selected: configure non-root OBLITERATUS_REMOTE_HOST and OBLITERATUS_REMOTE_USER variables"
exit 1
fi
if [ -z "$REMOTE_KEY_CONTENT" ] || [ -z "$REMOTE_KNOWN_HOSTS_CONTENT" ]; then
echo "remote gate selected: configure OBLITERATUS_REMOTE_KEY and pinned OBLITERATUS_REMOTE_KNOWN_HOSTS secrets"
exit 1
fi
install -m 700 -d "$RUNNER_TEMP/obliteratus-ssh"
install -m 600 /dev/null "$RUNNER_TEMP/obliteratus-ssh/key"
install -m 600 /dev/null "$RUNNER_TEMP/obliteratus-ssh/known_hosts"
printf '%s\n' "$REMOTE_KEY_CONTENT" > "$RUNNER_TEMP/obliteratus-ssh/key"
printf '%s\n' "$REMOTE_KNOWN_HOSTS_CONTENT" > "$RUNNER_TEMP/obliteratus-ssh/known_hosts"
- name: Run remote provider probe
env:
OBLITERATUS_REMOTE_KEY: ${{ runner.temp }}/obliteratus-ssh/key
OBLITERATUS_REMOTE_KNOWN_HOSTS: ${{ runner.temp }}/obliteratus-ssh/known_hosts
run: >-
"$CONDITIONAL_ENV/bin/python" scripts/run_conditional_gate.py remote-execution
- name: Upload remote evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-remote-${{ github.run_attempt }}
path: conditional-evidence/
if-no-files-found: warn
retention-days: 30
summary:
name: Conditional result and freshness summary
if: always()
needs: [policy, model_runtime, network_services, operator_ui, cuda, mps, mlx, remote]
runs-on: ubuntu-latest
timeout-minutes: 5
env:
CONDITIONAL_RESULTS: >-
{"policy":"${{ needs.policy.result }}","model_runtime":"${{ needs.model_runtime.result }}",
"network_services":"${{ needs.network_services.result }}","operator_ui":"${{ needs.operator_ui.result }}",
"cuda":"${{ needs.cuda.result }}","mps":"${{ needs.mps.result }}","mlx":"${{ needs.mlx.result }}",
"remote":"${{ needs.remote.result }}"}
CONDITIONAL_SELECTED: >-
{"model_runtime":${{ github.event_name != 'workflow_dispatch' || inputs.run_model }},
"network_services":${{ github.event_name != 'workflow_dispatch' || inputs.run_network }},
"operator_ui":${{ github.event_name != 'workflow_dispatch' || inputs.run_ui }},
"cuda":${{ (github.event_name == 'workflow_dispatch' && inputs.run_cuda) || (github.event_name != 'workflow_dispatch' && vars.ENABLE_CUDA_GATE == 'true') }},
"mps":${{ (github.event_name == 'workflow_dispatch' && inputs.run_mps) || (github.event_name != 'workflow_dispatch' && vars.ENABLE_MPS_GATE == 'true') }},
"mlx":${{ (github.event_name == 'workflow_dispatch' && inputs.run_mlx) || (github.event_name != 'workflow_dispatch' && vars.ENABLE_MLX_GATE == 'true') }},
"remote":${{ (github.event_name == 'workflow_dispatch' && inputs.run_remote) || (github.event_name != 'workflow_dispatch' && vars.ENABLE_REMOTE_GATE == 'true') }}}
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Enforce selected job results and publish freshness summary
run: python3 scripts/conditional_gate_summary.py
- name: Upload conditional summary
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: conditional-summary-${{ github.run_attempt }}
path: conditional-evidence/summary.json
if-no-files-found: error
retention-days: 30