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