shkit 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shkit-1.2.0/.github/workflows/build-wheel.yml +154 -0
- shkit-1.2.0/.github/workflows/ci.yml +23 -0
- shkit-1.2.0/.github/workflows/deploy-prod.yml +36 -0
- shkit-1.2.0/.github/workflows/incident-dispatch.yml +33 -0
- shkit-1.2.0/.github/workflows/publish-tenant.yml +70 -0
- shkit-1.2.0/.github/workflows/pull-antibodies.yml +68 -0
- shkit-1.2.0/.github/workflows/push-antibodies.yml +86 -0
- shkit-1.2.0/.github/workflows/release-pypi.yml +75 -0
- shkit-1.2.0/.gitignore +15 -0
- shkit-1.2.0/PKG-INFO +239 -0
- shkit-1.2.0/README.md +209 -0
- shkit-1.2.0/config/dev.yml +24 -0
- shkit-1.2.0/config/prod.yml +24 -0
- shkit-1.2.0/config/staging.yml +24 -0
- shkit-1.2.0/config/workspace.yml +26 -0
- shkit-1.2.0/databricks.yml +46 -0
- shkit-1.2.0/dbt_project/.user.yml +1 -0
- shkit-1.2.0/dbt_project/dbt_project.yml +17 -0
- shkit-1.2.0/dbt_project/models/ai_accuracy_metrics.sql +26 -0
- shkit-1.2.0/dbt_project/models/healing_audit_log.sql +33 -0
- shkit-1.2.0/dbt_project/models/healing_config.sql +12 -0
- shkit-1.2.0/dbt_project/models/healing_state.sql +30 -0
- shkit-1.2.0/dbt_project/models/resolution_cache.sql +27 -0
- shkit-1.2.0/dbt_project/models/schema.yml +60 -0
- shkit-1.2.0/dbt_project/models/token_budget.sql +24 -0
- shkit-1.2.0/dbt_project/profiles.yml +24 -0
- shkit-1.2.0/dbt_project/seeds/healing_config_defaults.csv +9 -0
- shkit-1.2.0/dbt_project/tests/assert_valid_action_ids.sql +7 -0
- shkit-1.2.0/dbt_project/tests/assert_valid_healing_modes.sql +5 -0
- shkit-1.2.0/deploy/init_scripts/iic_agent.sh +23 -0
- shkit-1.2.0/docs/ANTIBODIES.md +162 -0
- shkit-1.2.0/docs/ARCHITECTURE.md +743 -0
- shkit-1.2.0/docs/AUTOMATION.md +226 -0
- shkit-1.2.0/docs/INSTALL.md +81 -0
- shkit-1.2.0/docs/MIGRATION.md +64 -0
- shkit-1.2.0/docs/SELF_ARMING.md +73 -0
- shkit-1.2.0/docs/V4_ARCHITECTURE.md +139 -0
- shkit-1.2.0/docs/architecture.svg +368 -0
- shkit-1.2.0/iic_autoload.pth +1 -0
- shkit-1.2.0/notebooks/approval_handler.py +34 -0
- shkit-1.2.0/notebooks/audit_retention.py +33 -0
- shkit-1.2.0/notebooks/incident_engine.py +34 -0
- shkit-1.2.0/notebooks/weekly_accuracy_job.py +122 -0
- shkit-1.2.0/onboarding/__init__.py +1 -0
- shkit-1.2.0/onboarding/cli.py +168 -0
- shkit-1.2.0/onboarding/config_schema.py +62 -0
- shkit-1.2.0/onboarding/manifest.py +27 -0
- shkit-1.2.0/onboarding/preflight.py +129 -0
- shkit-1.2.0/onboarding/provisioner.py +573 -0
- shkit-1.2.0/onboarding/rollback.py +81 -0
- shkit-1.2.0/pyproject.toml +81 -0
- shkit-1.2.0/requirements.txt +7 -0
- shkit-1.2.0/resources/incident_workflows.yml +42 -0
- shkit-1.2.0/scripts/publish_tenant.py +200 -0
- shkit-1.2.0/scripts/smoke_databricks.md +87 -0
- shkit-1.2.0/scripts/smoke_local.py +97 -0
- shkit-1.2.0/scripts/sync_antibodies.py +322 -0
- shkit-1.2.0/setup.py +83 -0
- shkit-1.2.0/src/healing_kit/__init__.py +3 -0
- shkit-1.2.0/src/healing_kit/auth.py +79 -0
- shkit-1.2.0/src/healing_kit/clients/__init__.py +1 -0
- shkit-1.2.0/src/healing_kit/clients/databricks_client.py +183 -0
- shkit-1.2.0/src/healing_kit/clients/teams_client.py +128 -0
- shkit-1.2.0/src/healing_kit/models/__init__.py +1 -0
- shkit-1.2.0/src/healing_kit/models/diagnosis.py +45 -0
- shkit-1.2.0/src/healing_kit/models/events.py +30 -0
- shkit-1.2.0/src/healing_kit/models/evidence.py +83 -0
- shkit-1.2.0/src/healing_kit/runtime/__init__.py +6 -0
- shkit-1.2.0/src/healing_kit/runtime/approval.py +141 -0
- shkit-1.2.0/src/healing_kit/runtime/maintenance.py +52 -0
- shkit-1.2.0/src/healing_kit/services/__init__.py +1 -0
- shkit-1.2.0/src/healing_kit/services/cache_service.py +120 -0
- shkit-1.2.0/src/healing_kit/services/circuit_breaker.py +114 -0
- shkit-1.2.0/src/healing_kit/services/context_agent.py +127 -0
- shkit-1.2.0/src/healing_kit/services/dependency_graph.py +141 -0
- shkit-1.2.0/src/healing_kit/services/diagnosis_engine.py +165 -0
- shkit-1.2.0/src/healing_kit/services/identity.py +61 -0
- shkit-1.2.0/src/healing_kit/services/model_router.py +52 -0
- shkit-1.2.0/src/healing_kit/services/query_guard.py +168 -0
- shkit-1.2.0/src/healing_kit/services/resolution_verifier.py +100 -0
- shkit-1.2.0/src/healing_kit/services/token_budget.py +137 -0
- shkit-1.2.0/src/healing_kit/utils/__init__.py +1 -0
- shkit-1.2.0/src/healing_kit/utils/error_hash.py +15 -0
- shkit-1.2.0/src/healing_kit/utils/hmac_tokens.py +86 -0
- shkit-1.2.0/src/healing_kit/utils/sql_safety.py +84 -0
- shkit-1.2.0/src/iic/__init__.py +51 -0
- shkit-1.2.0/src/iic/__main__.py +18 -0
- shkit-1.2.0/src/iic/_console.py +235 -0
- shkit-1.2.0/src/iic/_doctor.py +143 -0
- shkit-1.2.0/src/iic/change/__init__.py +7 -0
- shkit-1.2.0/src/iic/change/change_detector.py +154 -0
- shkit-1.2.0/src/iic/context/__init__.py +7 -0
- shkit-1.2.0/src/iic/context/context_builder.py +117 -0
- shkit-1.2.0/src/iic/dependency/__init__.py +7 -0
- shkit-1.2.0/src/iic/dependency/dependency_analyzer.py +93 -0
- shkit-1.2.0/src/iic/diagnosis/__init__.py +7 -0
- shkit-1.2.0/src/iic/diagnosis/diagnosis_engine.py +183 -0
- shkit-1.2.0/src/iic/dna/__init__.py +7 -0
- shkit-1.2.0/src/iic/dna/dna_builder.py +184 -0
- shkit-1.2.0/src/iic/impact/__init__.py +7 -0
- shkit-1.2.0/src/iic/impact/impact_engine.py +102 -0
- shkit-1.2.0/src/iic/ingestion/__init__.py +14 -0
- shkit-1.2.0/src/iic/ingestion/base.py +21 -0
- shkit-1.2.0/src/iic/ingestion/databricks_source.py +98 -0
- shkit-1.2.0/src/iic/ingestion/static_source.py +23 -0
- shkit-1.2.0/src/iic/ingestion/webhook_source.py +39 -0
- shkit-1.2.0/src/iic/models/__init__.py +44 -0
- shkit-1.2.0/src/iic/models/change.py +77 -0
- shkit-1.2.0/src/iic/models/context.py +46 -0
- shkit-1.2.0/src/iic/models/diagnosis.py +37 -0
- shkit-1.2.0/src/iic/models/dna.py +77 -0
- shkit-1.2.0/src/iic/models/event.py +78 -0
- shkit-1.2.0/src/iic/models/impact.py +60 -0
- shkit-1.2.0/src/iic/models/report.py +88 -0
- shkit-1.2.0/src/iic/models/routing.py +41 -0
- shkit-1.2.0/src/iic/notify/__init__.py +7 -0
- shkit-1.2.0/src/iic/notify/teams_notifier.py +112 -0
- shkit-1.2.0/src/iic/report/__init__.py +7 -0
- shkit-1.2.0/src/iic/report/report_generator.py +67 -0
- shkit-1.2.0/src/iic/routing/__init__.py +7 -0
- shkit-1.2.0/src/iic/routing/router.py +42 -0
- shkit-1.2.0/src/iic/runtime/__init__.py +10 -0
- shkit-1.2.0/src/iic/runtime/_sql.py +11 -0
- shkit-1.2.0/src/iic/runtime/agent_config.py +48 -0
- shkit-1.2.0/src/iic/runtime/agent_runtime.py +70 -0
- shkit-1.2.0/src/iic/runtime/antibodies.py +100 -0
- shkit-1.2.0/src/iic/runtime/bootstrap.py +157 -0
- shkit-1.2.0/src/iic/runtime/constants.py +40 -0
- shkit-1.2.0/src/iic/runtime/context.py +46 -0
- shkit-1.2.0/src/iic/runtime/detective.py +72 -0
- shkit-1.2.0/src/iic/runtime/hooks.py +85 -0
- shkit-1.2.0/src/iic/runtime/incident_engine.py +207 -0
- shkit-1.2.0/src/iic/runtime/inprocess.py +350 -0
- shkit-1.2.0/src/iic/runtime/ledger.py +120 -0
- shkit-1.2.0/src/iic/runtime/monitor.py +155 -0
- shkit-1.2.0/src/iic/runtime/pattern_store.py +53 -0
- shkit-1.2.0/src/iic/runtime/reconciler.py +139 -0
- shkit-1.2.0/src/iic/runtime/scope_config.py +127 -0
- shkit-1.2.0/src/iic/runtime/store.py +150 -0
- shkit-1.2.0/src/iic/runtime/wrapper.py +28 -0
- shkit-1.2.0/tests/__init__.py +1 -0
- shkit-1.2.0/tests/integration/__init__.py +1 -0
- shkit-1.2.0/tests/integration/check_agent_run.py +44 -0
- shkit-1.2.0/tests/integration/check_job_params.py +18 -0
- shkit-1.2.0/tests/integration/check_task_output.py +27 -0
- shkit-1.2.0/tests/integration/deploy_consolidated_agent.py +57 -0
- shkit-1.2.0/tests/integration/fix_job_add_aggregator.py +82 -0
- shkit-1.2.0/tests/integration/test_v2_live_validation.py +189 -0
- shkit-1.2.0/tests/property/__init__.py +1 -0
- shkit-1.2.0/tests/unit/__init__.py +1 -0
- shkit-1.2.0/tests/unit/test_circuit_breaker.py +58 -0
- shkit-1.2.0/tests/unit/test_error_hash.py +43 -0
- shkit-1.2.0/tests/unit/test_identity.py +53 -0
- shkit-1.2.0/tests/unit/test_iic_change_detector.py +55 -0
- shkit-1.2.0/tests/unit/test_iic_context_builder.py +58 -0
- shkit-1.2.0/tests/unit/test_iic_dependency_analyzer.py +42 -0
- shkit-1.2.0/tests/unit/test_iic_diagnosis_engine.py +81 -0
- shkit-1.2.0/tests/unit/test_iic_dna_builder.py +79 -0
- shkit-1.2.0/tests/unit/test_iic_engine.py +97 -0
- shkit-1.2.0/tests/unit/test_iic_event.py +59 -0
- shkit-1.2.0/tests/unit/test_iic_impact_engine.py +63 -0
- shkit-1.2.0/tests/unit/test_iic_report_and_notify.py +71 -0
- shkit-1.2.0/tests/unit/test_iic_router.py +47 -0
- shkit-1.2.0/tests/unit/test_model_router.py +48 -0
- shkit-1.2.0/tests/unit/test_query_guard.py +74 -0
- shkit-1.2.0/tests/unit/test_resolution_verifier.py +72 -0
- shkit-1.2.0/tests/unit/test_sql_safety.py +72 -0
- shkit-1.2.0/tests/unit/test_v4_antibodies.py +288 -0
- shkit-1.2.0/tests/unit/test_v4_console_doctor.py +148 -0
- shkit-1.2.0/tests/unit/test_v4_context_cache.py +44 -0
- shkit-1.2.0/tests/unit/test_v4_detective.py +135 -0
- shkit-1.2.0/tests/unit/test_v4_monitor.py +109 -0
- shkit-1.2.0/tests/unit/test_v4_reconciler.py +78 -0
- shkit-1.2.0/tests/unit/test_v4_scope_config.py +145 -0
- shkit-1.2.0/tests/unit/test_v4_self_arming.py +201 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
name: Build & publish IIC wheel
|
|
2
|
+
|
|
3
|
+
# v4 distribution: on merge to main, build the wheel and upload it to DBFS as the
|
|
4
|
+
# "latest" agent artifact that clusters install via the init script.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
tags: ["v*"]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write # needed to attach the wheel to a GitHub Release on tags
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build-and-publish:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
# Job-level env IS available to a step's `if:` (step-level env is not — that was
|
|
17
|
+
# the bug). Empty strings when the secrets aren't configured → publish is skipped.
|
|
18
|
+
env:
|
|
19
|
+
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
|
|
20
|
+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
|
|
27
|
+
- name: Build wheel
|
|
28
|
+
run: |
|
|
29
|
+
pip install build
|
|
30
|
+
python -m build --wheel
|
|
31
|
+
ls -l dist/
|
|
32
|
+
|
|
33
|
+
- name: Verify self-arming packaging (.pth at wheel root + arms on install)
|
|
34
|
+
run: |
|
|
35
|
+
set -e
|
|
36
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
37
|
+
echo "Checking $WHEEL for iic_autoload.pth at archive root..."
|
|
38
|
+
python -m zipfile -l "$WHEEL" | awk '{print $1}' | grep -qxE 'iic_autoload\.pth' \
|
|
39
|
+
|| { echo "FAIL: iic_autoload.pth not at wheel root"; exit 1; }
|
|
40
|
+
echo "OK: .pth at wheel root"
|
|
41
|
+
python -m venv /tmp/iic_smoke_venv
|
|
42
|
+
/tmp/iic_smoke_venv/bin/pip install --quiet "$WHEEL"
|
|
43
|
+
echo "Confirming the .pth arms the tripwire at interpreter startup..."
|
|
44
|
+
/tmp/iic_smoke_venv/bin/python -c "import sys; assert 'iic.runtime.bootstrap' in sys.modules, 'bootstrap not auto-imported'; print('OK: tripwire armed at startup')"
|
|
45
|
+
|
|
46
|
+
- name: Self-arming integration smoke (failure → mock webhook gets one card)
|
|
47
|
+
run: |
|
|
48
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
49
|
+
python scripts/smoke_local.py "$WHEEL"
|
|
50
|
+
|
|
51
|
+
- name: Upload wheel artifact (always)
|
|
52
|
+
uses: actions/upload-artifact@v4
|
|
53
|
+
with:
|
|
54
|
+
name: iic-wheel
|
|
55
|
+
path: dist/*.whl
|
|
56
|
+
|
|
57
|
+
# On every push to main: refresh a rolling "latest" pre-release with the new
|
|
58
|
+
# wheel and emit the copyable install URL — auto-publish, no tag needed.
|
|
59
|
+
- name: Publish rolling "latest" release
|
|
60
|
+
if: github.ref == 'refs/heads/main'
|
|
61
|
+
uses: softprops/action-gh-release@v2
|
|
62
|
+
with:
|
|
63
|
+
tag_name: latest
|
|
64
|
+
name: "Latest (rolling — auto-published from main)"
|
|
65
|
+
prerelease: true
|
|
66
|
+
files: dist/*.whl
|
|
67
|
+
|
|
68
|
+
- name: Latest install URL → summary
|
|
69
|
+
if: github.ref == 'refs/heads/main'
|
|
70
|
+
run: |
|
|
71
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
72
|
+
NAME=$(basename "$WHEEL")
|
|
73
|
+
URL="https://github.com/${{ github.repository }}/releases/download/latest/${NAME}"
|
|
74
|
+
echo "==========================================="
|
|
75
|
+
echo "DATABRICKS INSTALL URL (latest, copy this):"
|
|
76
|
+
echo "$URL"
|
|
77
|
+
echo "==========================================="
|
|
78
|
+
{
|
|
79
|
+
echo "## 🚀 IIC SDK (latest) — auto-published from main"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "**Wheel:** \`${NAME}\`"
|
|
82
|
+
echo ""
|
|
83
|
+
echo "### Databricks install URL (copy this):"
|
|
84
|
+
echo '```'
|
|
85
|
+
echo "$URL"
|
|
86
|
+
echo '```'
|
|
87
|
+
echo ""
|
|
88
|
+
echo "_Always points at the most recent main build. Install via a cluster"
|
|
89
|
+
echo "init script \`pip install <url>\` or a notebook \`%pip install <url>\`._"
|
|
90
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
91
|
+
|
|
92
|
+
# On a version tag (e.g. v1.0.0): publish the wheel to a GitHub Release and
|
|
93
|
+
# emit a copyable Databricks install URL — no Databricks dependency, no secrets.
|
|
94
|
+
- name: Generate Databricks install URL
|
|
95
|
+
id: url
|
|
96
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
97
|
+
run: |
|
|
98
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
99
|
+
NAME=$(basename "$WHEEL")
|
|
100
|
+
URL="https://github.com/${{ github.repository }}/releases/download/${GITHUB_REF_NAME}/${NAME}"
|
|
101
|
+
{
|
|
102
|
+
echo "install_url=$URL"
|
|
103
|
+
echo "wheel_name=$NAME"
|
|
104
|
+
} >> "$GITHUB_OUTPUT"
|
|
105
|
+
echo "==========================================="
|
|
106
|
+
echo "DATABRICKS INSTALL URL (copy this):"
|
|
107
|
+
echo "$URL"
|
|
108
|
+
echo "==========================================="
|
|
109
|
+
|
|
110
|
+
- name: Publish to GitHub Release
|
|
111
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
112
|
+
uses: softprops/action-gh-release@v2
|
|
113
|
+
with:
|
|
114
|
+
files: dist/*.whl
|
|
115
|
+
body: |
|
|
116
|
+
## 🚀 IIC SDK ${{ github.ref_name }}
|
|
117
|
+
|
|
118
|
+
**Databricks install URL — copy this:**
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
${{ steps.url.outputs.install_url }}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Install on a cluster via a notebook `%pip install <url>` or a cluster
|
|
125
|
+
init script `pip install <url>`, then restart — the agent
|
|
126
|
+
auto-bootstraps on import. See `docs/V4_ARCHITECTURE.md`.
|
|
127
|
+
|
|
128
|
+
- name: Write job summary
|
|
129
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
130
|
+
run: |
|
|
131
|
+
{
|
|
132
|
+
echo "## 🚀 IIC SDK Published — ${GITHUB_REF_NAME}"
|
|
133
|
+
echo ""
|
|
134
|
+
echo "**Wheel:** \`${{ steps.url.outputs.wheel_name }}\`"
|
|
135
|
+
echo ""
|
|
136
|
+
echo "### Databricks install URL (copy this):"
|
|
137
|
+
echo '```'
|
|
138
|
+
echo "${{ steps.url.outputs.install_url }}"
|
|
139
|
+
echo '```'
|
|
140
|
+
} >> "$GITHUB_STEP_SUMMARY"
|
|
141
|
+
|
|
142
|
+
# Publish to DBFS only when Databricks credentials are configured as repo
|
|
143
|
+
# secrets. Skipped (not failed) otherwise, so forks/PRs still build cleanly.
|
|
144
|
+
- name: Set up Databricks CLI
|
|
145
|
+
if: ${{ env.DATABRICKS_HOST != '' && env.DATABRICKS_TOKEN != '' }}
|
|
146
|
+
uses: databricks/setup-cli@main
|
|
147
|
+
|
|
148
|
+
- name: Publish to DBFS as latest
|
|
149
|
+
if: ${{ env.DATABRICKS_HOST != '' && env.DATABRICKS_TOKEN != '' }}
|
|
150
|
+
run: |
|
|
151
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
152
|
+
echo "Uploading $WHEEL -> dbfs:/libs/iic/latest.whl"
|
|
153
|
+
databricks fs cp --overwrite "$WHEEL" dbfs:/libs/iic/latest.whl
|
|
154
|
+
databricks fs cp --overwrite "$WHEEL" "dbfs:/libs/iic/$(basename "$WHEEL")"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
branches: [main]
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint-and-test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.11"
|
|
16
|
+
- name: Install package
|
|
17
|
+
run: pip install -e ".[dev]"
|
|
18
|
+
- name: Lint source code
|
|
19
|
+
run: ruff check src/ onboarding/ --ignore E501
|
|
20
|
+
- name: Lint unit tests
|
|
21
|
+
run: ruff check tests/unit/ --ignore E501
|
|
22
|
+
- name: Run unit tests
|
|
23
|
+
run: pytest tests/unit/ -v --tb=short
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Deploy Production
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
inputs:
|
|
5
|
+
confirm:
|
|
6
|
+
description: 'Type "deploy-prod" to confirm'
|
|
7
|
+
required: true
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
deploy:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
if: github.event.inputs.confirm == 'deploy-prod'
|
|
13
|
+
environment: production
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: databricks/setup-cli@main
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.11"
|
|
20
|
+
|
|
21
|
+
- name: Install dbt
|
|
22
|
+
run: pip install dbt-databricks
|
|
23
|
+
|
|
24
|
+
- name: Run dbt build (create/update tables)
|
|
25
|
+
run: cd dbt_project && dbt build --target prod
|
|
26
|
+
env:
|
|
27
|
+
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST_PROD }}
|
|
28
|
+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN_PROD }}
|
|
29
|
+
DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH_PROD }}
|
|
30
|
+
DATABRICKS_CATALOG: prod_catalog
|
|
31
|
+
|
|
32
|
+
- name: Deploy bundle
|
|
33
|
+
run: databricks bundle deploy --target prod
|
|
34
|
+
env:
|
|
35
|
+
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST_PROD }}
|
|
36
|
+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN_PROD }}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: IIC incident detective
|
|
2
|
+
|
|
3
|
+
# Event-driven ONLY — fires when the in-process agent sends a repository_dispatch
|
|
4
|
+
# after a failure. No schedule, no polling. PAYLOAD-ONLY: the issue is rendered
|
|
5
|
+
# entirely from the self-contained client_payload — GitHub never touches the
|
|
6
|
+
# customer's Databricks workspace, so there are no tenant tokens here.
|
|
7
|
+
on:
|
|
8
|
+
repository_dispatch:
|
|
9
|
+
types: [iic_incident]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
issues: write # to archive the incident as an issue
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
investigate:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.11"
|
|
24
|
+
|
|
25
|
+
- name: Install IIC
|
|
26
|
+
run: pip install .
|
|
27
|
+
|
|
28
|
+
- name: Archive incident (from payload only)
|
|
29
|
+
env:
|
|
30
|
+
IIC_PAYLOAD: ${{ toJSON(github.event.client_payload) }}
|
|
31
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
32
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
33
|
+
run: python -m iic.runtime.detective
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: "[DEPRECATED] Publish IIC to tenant (manual)"
|
|
2
|
+
|
|
3
|
+
# ⚠️ DEPRECATED (product-model): distribution moved to PyPI (release-pypi.yml) and
|
|
4
|
+
# config moved to a Databricks secret scope (see docs/INSTALL.md + docs/MIGRATION.md).
|
|
5
|
+
# Kept functional for ONE release for migration; will be deleted. This is the only
|
|
6
|
+
# remaining workflow that references the DBX_TOKENS secret.
|
|
7
|
+
#
|
|
8
|
+
# MANUAL ONLY — never auto-runs. You pick a tenant from the dropdown and the wheel
|
|
9
|
+
# is published to THAT tenant's Databricks Volume only. Tenant config (host/volume)
|
|
10
|
+
# comes from the private Access-private repo; the Databricks token comes from the
|
|
11
|
+
# DBX_TOKENS secret (never from the config repo).
|
|
12
|
+
on:
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
tenant:
|
|
16
|
+
description: "Tenant to publish for"
|
|
17
|
+
type: choice
|
|
18
|
+
required: true
|
|
19
|
+
options:
|
|
20
|
+
- zeb
|
|
21
|
+
# add tenants here as you add folders under Access-private/tenants/
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
publish:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
# Optional: require an approval before publishing.
|
|
30
|
+
# environment: production
|
|
31
|
+
steps:
|
|
32
|
+
- name: Checkout code
|
|
33
|
+
uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Checkout tenant config (Access-private)
|
|
36
|
+
uses: actions/checkout@v4
|
|
37
|
+
with:
|
|
38
|
+
repository: yogasathyandrun/Access-private
|
|
39
|
+
path: _tenants
|
|
40
|
+
token: ${{ secrets.CONFIG_REPO_TOKEN }}
|
|
41
|
+
|
|
42
|
+
- uses: actions/setup-python@v5
|
|
43
|
+
with:
|
|
44
|
+
python-version: "3.11"
|
|
45
|
+
|
|
46
|
+
- name: Build wheel
|
|
47
|
+
run: |
|
|
48
|
+
pip install build databricks-sdk pyyaml
|
|
49
|
+
python -m build --wheel
|
|
50
|
+
ls -l dist/
|
|
51
|
+
|
|
52
|
+
- name: Publish to selected tenant
|
|
53
|
+
env:
|
|
54
|
+
TENANT: ${{ inputs.tenant }}
|
|
55
|
+
DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
|
|
56
|
+
run: python scripts/publish_tenant.py
|
|
57
|
+
|
|
58
|
+
- name: Summary
|
|
59
|
+
if: always()
|
|
60
|
+
run: |
|
|
61
|
+
echo "## 📦 IIC published to tenant: \`${{ inputs.tenant }}\`" >> "$GITHUB_STEP_SUMMARY"
|
|
62
|
+
echo "" >> "$GITHUB_STEP_SUMMARY"
|
|
63
|
+
echo "Uploaded: **wheel + base_environment.yml → Workspace** (base-env builder can't read Volumes)," >> "$GITHUB_STEP_SUMMARY"
|
|
64
|
+
echo "and **config.yaml → Volume** (read by the agent at runtime). See job log for exact paths." >> "$GITHUB_STEP_SUMMARY"
|
|
65
|
+
echo "" >> "$GITHUB_STEP_SUMMARY"
|
|
66
|
+
echo "➡️ One-time per workspace: **Admin Settings → Workspace base environments for serverless** →" >> "$GITHUB_STEP_SUMMARY"
|
|
67
|
+
echo "set **Base environment file path** to the uploaded \`/Workspace/.../base_environment.yml\`" >> "$GITHUB_STEP_SUMMARY"
|
|
68
|
+
echo "(✅ default for new notebooks). It references the Workspace wheel → new serverless" >> "$GITHUB_STEP_SUMMARY"
|
|
69
|
+
echo "notebooks self-arm automatically. See docs/SELF_ARMING.md. Mute via a \`DISABLED\` file" >> "$GITHUB_STEP_SUMMARY"
|
|
70
|
+
echo "next to config.yaml in the Volume." >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: "[DEPRECATED] Pull antibodies from tenant (manual)"
|
|
2
|
+
|
|
3
|
+
# ⚠️ DEPRECATED (product-model): the antibody ledger is now workspace-local and is
|
|
4
|
+
# folded by the in-workspace console notebook (iic.console()); there is no git
|
|
5
|
+
# mirror and no operator sync. Kept one release for migration; will be deleted.
|
|
6
|
+
#
|
|
7
|
+
# MANUAL ONLY. Downloads the tenant's Antibody Ledger + pending occurrence markers
|
|
8
|
+
# from its Databricks Volume, folds the occurrences into the git ledger
|
|
9
|
+
# (Access-private/tenants/<tenant>/antibodies.yaml), commits it, and uploads the
|
|
10
|
+
# merged ledger back to the Volume. A human then fills in `resolution:` values in
|
|
11
|
+
# the committed file via the GitHub web editor; push-antibodies.yml ships them back.
|
|
12
|
+
#
|
|
13
|
+
# NOTE: this commits to the PRIVATE Access-private repo, so CONFIG_REPO_TOKEN must
|
|
14
|
+
# have WRITE (contents) scope on that repo (publish-tenant.yml only needs read).
|
|
15
|
+
on:
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
inputs:
|
|
18
|
+
tenant:
|
|
19
|
+
description: "Tenant to pull antibodies from"
|
|
20
|
+
type: choice
|
|
21
|
+
required: true
|
|
22
|
+
options:
|
|
23
|
+
- zeb
|
|
24
|
+
# add tenants here as you add folders under Access-private/tenants/
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
pull:
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- name: Checkout code
|
|
34
|
+
uses: actions/checkout@v4
|
|
35
|
+
|
|
36
|
+
- name: Checkout tenant config (Access-private, write scope)
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
with:
|
|
39
|
+
repository: yogasathyandrun/Access-private
|
|
40
|
+
path: _tenants
|
|
41
|
+
token: ${{ secrets.CONFIG_REPO_TOKEN }}
|
|
42
|
+
|
|
43
|
+
- uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: "3.11"
|
|
46
|
+
|
|
47
|
+
- name: Install
|
|
48
|
+
run: pip install . databricks-sdk pyyaml
|
|
49
|
+
|
|
50
|
+
- name: Pull + fold pending occurrences
|
|
51
|
+
env:
|
|
52
|
+
TENANT: ${{ inputs.tenant }}
|
|
53
|
+
DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
|
|
54
|
+
CONFIG_DIR: _tenants
|
|
55
|
+
run: python scripts/sync_antibodies.py --mode pull
|
|
56
|
+
|
|
57
|
+
- name: Commit updated ledger to Access-private
|
|
58
|
+
run: |
|
|
59
|
+
cd _tenants
|
|
60
|
+
git config user.name "iic-antibodies-bot"
|
|
61
|
+
git config user.email "iic-antibodies-bot@users.noreply.github.com"
|
|
62
|
+
git add "tenants/${{ inputs.tenant }}/antibodies.yaml"
|
|
63
|
+
if git diff --cached --quiet; then
|
|
64
|
+
echo "No ledger changes to commit."
|
|
65
|
+
else
|
|
66
|
+
git commit -m "antibodies(${{ inputs.tenant }}): fold pending occurrence(s)"
|
|
67
|
+
git push
|
|
68
|
+
fi
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: "[DEPRECATED] Push antibodies to tenant"
|
|
2
|
+
|
|
3
|
+
# ⚠️ DEPRECATED (product-model): the antibody ledger is now workspace-local (edited
|
|
4
|
+
# in the workspace via iic.console()), with no git mirror and no operator sync.
|
|
5
|
+
# Kept one release for migration; will be deleted.
|
|
6
|
+
#
|
|
7
|
+
# Ships the human-edited Antibody Ledger from git back to the tenant's Databricks
|
|
8
|
+
# Volume. Runs the merge rule against the CURRENT Volume copy first (so counters
|
|
9
|
+
# that accumulated since the last pull are not clobbered — git only wins on
|
|
10
|
+
# `resolution`), then uploads the result to {volume}/antibodies.yaml.
|
|
11
|
+
#
|
|
12
|
+
# Triggers:
|
|
13
|
+
# * workflow_dispatch — manual, pick a tenant.
|
|
14
|
+
# * repository_dispatch — fired by a tiny companion workflow in the
|
|
15
|
+
# (type: antibodies_push) Access-private repo whenever someone edits
|
|
16
|
+
# tenants/<t>/antibodies.yaml. Cross-repo `push`
|
|
17
|
+
# path filters can't reach this repo directly, so
|
|
18
|
+
# the edit side sends a repository_dispatch.
|
|
19
|
+
#
|
|
20
|
+
# Companion workflow to paste into Access-private (.github/workflows/notify-antibodies.yml):
|
|
21
|
+
#
|
|
22
|
+
# on:
|
|
23
|
+
# push:
|
|
24
|
+
# paths: ["tenants/*/antibodies.yaml"]
|
|
25
|
+
# jobs:
|
|
26
|
+
# notify:
|
|
27
|
+
# runs-on: ubuntu-latest
|
|
28
|
+
# steps:
|
|
29
|
+
# - uses: actions/checkout@v4
|
|
30
|
+
# - name: Fire push for each changed tenant
|
|
31
|
+
# env:
|
|
32
|
+
# GH_TOKEN: ${{ secrets.KIT_DISPATCH_TOKEN }} # repo scope on Self-healing-kit
|
|
33
|
+
# run: |
|
|
34
|
+
# for f in $(git diff --name-only HEAD~1 HEAD | grep 'tenants/.*/antibodies.yaml'); do
|
|
35
|
+
# t=$(echo "$f" | cut -d/ -f2)
|
|
36
|
+
# gh api repos/yogasathyandrun/Self-healing-kit/dispatches \
|
|
37
|
+
# -f event_type=antibodies_push -F client_payload[tenant]="$t"
|
|
38
|
+
# done
|
|
39
|
+
|
|
40
|
+
on:
|
|
41
|
+
workflow_dispatch:
|
|
42
|
+
inputs:
|
|
43
|
+
tenant:
|
|
44
|
+
description: "Tenant to push antibodies to"
|
|
45
|
+
type: choice
|
|
46
|
+
required: true
|
|
47
|
+
options:
|
|
48
|
+
- zeb
|
|
49
|
+
# add tenants here as you add folders under Access-private/tenants/
|
|
50
|
+
repository_dispatch:
|
|
51
|
+
types: [antibodies_push]
|
|
52
|
+
|
|
53
|
+
permissions:
|
|
54
|
+
contents: read
|
|
55
|
+
|
|
56
|
+
jobs:
|
|
57
|
+
push:
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
steps:
|
|
60
|
+
- name: Resolve tenant
|
|
61
|
+
id: t
|
|
62
|
+
run: echo "tenant=${{ inputs.tenant || github.event.client_payload.tenant }}" >> "$GITHUB_OUTPUT"
|
|
63
|
+
|
|
64
|
+
- name: Checkout code
|
|
65
|
+
uses: actions/checkout@v4
|
|
66
|
+
|
|
67
|
+
- name: Checkout tenant config (Access-private)
|
|
68
|
+
uses: actions/checkout@v4
|
|
69
|
+
with:
|
|
70
|
+
repository: yogasathyandrun/Access-private
|
|
71
|
+
path: _tenants
|
|
72
|
+
token: ${{ secrets.CONFIG_REPO_TOKEN }}
|
|
73
|
+
|
|
74
|
+
- uses: actions/setup-python@v5
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.11"
|
|
77
|
+
|
|
78
|
+
- name: Install
|
|
79
|
+
run: pip install . databricks-sdk pyyaml
|
|
80
|
+
|
|
81
|
+
- name: Push ledger to the Volume
|
|
82
|
+
env:
|
|
83
|
+
TENANT: ${{ steps.t.outputs.tenant }}
|
|
84
|
+
DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
|
|
85
|
+
CONFIG_DIR: _tenants
|
|
86
|
+
run: python scripts/sync_antibodies.py --mode push
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
# On a version tag (v*): build sdist+wheel, run the FULL gate (lint + unit tests +
|
|
4
|
+
# the .pth-at-wheel-root assertion + the fresh-venv arms-on-install + the
|
|
5
|
+
# self-arming smoke), then publish to PyPI via TRUSTED PUBLISHING (OIDC). No PyPI
|
|
6
|
+
# API token is stored anywhere.
|
|
7
|
+
#
|
|
8
|
+
# ONE-TIME MAINTAINER SETUP (on PyPI, before the first release):
|
|
9
|
+
# 1. Claim the distribution name in pyproject.toml [project].name. `iic` may be
|
|
10
|
+
# taken — if so, change [project].name (the ONLY place the dist name lives;
|
|
11
|
+
# the import name stays `iic`) and re-run the grep check in docs/INSTALL.md.
|
|
12
|
+
# 2. Add a PyPI "Trusted Publisher": this repo, workflow `release-pypi.yml`,
|
|
13
|
+
# environment `pypi`. See https://docs.pypi.org/trusted-publishers/.
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
tags: ["v*"]
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
gate:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.11"
|
|
29
|
+
|
|
30
|
+
- name: Install + lint + unit tests
|
|
31
|
+
run: |
|
|
32
|
+
pip install -e ".[dev]"
|
|
33
|
+
ruff check src/ onboarding/ --ignore E501
|
|
34
|
+
pytest tests/unit/ -q
|
|
35
|
+
|
|
36
|
+
- name: Build sdist + wheel
|
|
37
|
+
run: |
|
|
38
|
+
pip install build
|
|
39
|
+
python -m build
|
|
40
|
+
ls -l dist/
|
|
41
|
+
|
|
42
|
+
- name: Gate — .pth at wheel root + arms on install
|
|
43
|
+
run: |
|
|
44
|
+
set -e
|
|
45
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
46
|
+
python -m zipfile -l "$WHEEL" | awk '{print $1}' | grep -qxE 'iic_autoload\.pth' \
|
|
47
|
+
|| { echo "FAIL: iic_autoload.pth not at wheel root"; exit 1; }
|
|
48
|
+
python -m venv /tmp/relvenv
|
|
49
|
+
/tmp/relvenv/bin/pip install --quiet "$WHEEL" 2>/dev/null || /tmp/relvenv/bin/pip install --quiet "$WHEEL"
|
|
50
|
+
/tmp/relvenv/bin/python -c "import sys; assert 'iic.runtime.bootstrap' in sys.modules, 'bootstrap not auto-imported'; print('OK: tripwire armed at startup')"
|
|
51
|
+
|
|
52
|
+
- name: Gate — self-arming smoke (failure → one card)
|
|
53
|
+
run: |
|
|
54
|
+
WHEEL=$(ls dist/*.whl | head -1)
|
|
55
|
+
python scripts/smoke_local.py "$WHEEL"
|
|
56
|
+
|
|
57
|
+
- name: Upload dist
|
|
58
|
+
uses: actions/upload-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: dist
|
|
61
|
+
path: dist/*
|
|
62
|
+
|
|
63
|
+
publish:
|
|
64
|
+
needs: gate
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
environment: pypi
|
|
67
|
+
permissions:
|
|
68
|
+
id-token: write # OIDC for PyPI Trusted Publishing — no API token stored
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist
|
|
73
|
+
path: dist
|
|
74
|
+
- name: Publish to PyPI (Trusted Publishing / OIDC)
|
|
75
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
shkit-1.2.0/.gitignore
ADDED