mirror of
https://github.com/katanemo/plano.git
synced 2026-06-20 15:28:07 +02:00
fix Tera template compat, remove Python from CI entirely
This commit is contained in:
parent
b7fd7771cd
commit
cc896bf20f
3 changed files with 54 additions and 29 deletions
44
.github/workflows/ci.yml
vendored
44
.github/workflows/ci.yml
vendored
|
|
@ -52,37 +52,33 @@ jobs:
|
||||||
# Native mode smoke test — build from source & start natively
|
# Native mode smoke test — build from source & start natively
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
native-smoke-test:
|
native-smoke-test:
|
||||||
|
needs: plano-cli-tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.12"
|
|
||||||
|
|
||||||
- name: Install uv
|
|
||||||
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
targets: wasm32-wasip1
|
targets: wasm32-wasip1
|
||||||
|
|
||||||
- name: Install planoai CLI
|
- name: Download planoai binary
|
||||||
working-directory: ./cli
|
uses: actions/download-artifact@v6
|
||||||
run: |
|
with:
|
||||||
uv sync
|
name: planoai-binary
|
||||||
uv tool install .
|
path: crates/target/release/
|
||||||
|
|
||||||
|
- name: Make binary executable
|
||||||
|
run: chmod +x crates/target/release/planoai
|
||||||
|
|
||||||
- name: Build native binaries
|
- name: Build native binaries
|
||||||
run: planoai build
|
run: crates/target/release/planoai build
|
||||||
|
|
||||||
- name: Start plano natively
|
- name: Start plano natively
|
||||||
env:
|
env:
|
||||||
OPENAI_API_KEY: test-key-not-used
|
OPENAI_API_KEY: test-key-not-used
|
||||||
run: planoai up tests/e2e/config_native_smoke.yaml
|
run: crates/target/release/planoai up tests/e2e/config_native_smoke.yaml
|
||||||
|
|
||||||
- name: Health check
|
- name: Health check
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -100,7 +96,7 @@ jobs:
|
||||||
|
|
||||||
- name: Stop plano
|
- name: Stop plano
|
||||||
if: always()
|
if: always()
|
||||||
run: planoai down || true
|
run: crates/target/release/planoai down || true
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
# Single Docker build — shared by all downstream jobs
|
# Single Docker build — shared by all downstream jobs
|
||||||
|
|
@ -147,21 +143,25 @@ jobs:
|
||||||
# Validate plano config
|
# Validate plano config
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
validate-config:
|
validate-config:
|
||||||
|
needs: plano-cli-tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Download planoai binary
|
||||||
uses: actions/setup-python@v6
|
uses: actions/download-artifact@v6
|
||||||
with:
|
with:
|
||||||
python-version: "3.14"
|
name: planoai-binary
|
||||||
|
path: crates/target/release/
|
||||||
|
|
||||||
- name: Install planoai
|
- name: Make binary executable
|
||||||
run: pip install -e ./cli
|
run: chmod +x crates/target/release/planoai
|
||||||
|
|
||||||
- name: Validate plano config
|
- name: Validate plano config
|
||||||
run: bash config/validate_plano_config.sh
|
run: |
|
||||||
|
export PATH="$PWD/crates/target/release:$PATH"
|
||||||
|
bash config/validate_plano_config.sh
|
||||||
|
|
||||||
# ──────────────────────────────────────────────
|
# ──────────────────────────────────────────────
|
||||||
# Docker security scan (Trivy)
|
# Docker security scan (Trivy)
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,7 @@ for file in $(find . -name config.yaml -o -name plano_config_full_reference.yaml
|
||||||
rendered_file="$(pwd)/${file}_rendered"
|
rendered_file="$(pwd)/${file}_rendered"
|
||||||
touch "$rendered_file"
|
touch "$rendered_file"
|
||||||
|
|
||||||
PLANO_CONFIG_FILE="$(pwd)/${file}" \
|
planoai validate "$(pwd)/${file}" 2>&1 > /dev/null
|
||||||
PLANO_CONFIG_SCHEMA_FILE="${SCRIPT_DIR}/plano_config_schema.yaml" \
|
|
||||||
TEMPLATE_ROOT="${SCRIPT_DIR}" \
|
|
||||||
ENVOY_CONFIG_TEMPLATE_FILE="envoy.template.yaml" \
|
|
||||||
PLANO_CONFIG_FILE_RENDERED="$rendered_file" \
|
|
||||||
ENVOY_CONFIG_FILE_RENDERED="/dev/null" \
|
|
||||||
python -m planoai.config_generator 2>&1 > /dev/null
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Validation failed for $file"
|
echo "Validation failed for $file"
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,10 @@ pub fn validate_and_render(
|
||||||
// Override inferred clusters with endpoints
|
// Override inferred clusters with endpoints
|
||||||
for (name, details) in &endpoints {
|
for (name, details) in &endpoints {
|
||||||
let mut cluster = details.clone();
|
let mut cluster = details.clone();
|
||||||
|
// Ensure protocol is always set
|
||||||
|
if cluster.get("protocol").is_none() {
|
||||||
|
cluster["protocol"] = json!("https");
|
||||||
|
}
|
||||||
if cluster.get("port").is_none() {
|
if cluster.get("port").is_none() {
|
||||||
let ep = cluster
|
let ep = cluster
|
||||||
.get("endpoint")
|
.get("endpoint")
|
||||||
|
|
@ -279,6 +283,10 @@ pub fn validate_and_render(
|
||||||
cluster["endpoint"] = json!(endpoint);
|
cluster["endpoint"] = json!(endpoint);
|
||||||
cluster["port"] = json!(port);
|
cluster["port"] = json!(port);
|
||||||
}
|
}
|
||||||
|
// Ensure connect_timeout is set
|
||||||
|
if cluster.get("connect_timeout").is_none() {
|
||||||
|
cluster["connect_timeout"] = json!("5s");
|
||||||
|
}
|
||||||
inferred_clusters.insert(name.clone(), cluster);
|
inferred_clusters.insert(name.clone(), cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -702,6 +710,29 @@ pub fn validate_and_render(
|
||||||
|
|
||||||
let mut tera = tera::Tera::default();
|
let mut tera = tera::Tera::default();
|
||||||
let template_content = std::fs::read_to_string(template_path)?;
|
let template_content = std::fs::read_to_string(template_path)?;
|
||||||
|
// Convert Jinja2 syntax to Tera syntax
|
||||||
|
// indent(N) → indent(width=N)
|
||||||
|
let template_content = regex::Regex::new(r"indent\((\d+)\)")
|
||||||
|
.unwrap()
|
||||||
|
.replace_all(&template_content, "indent(width=$1)")
|
||||||
|
.to_string();
|
||||||
|
// var.split(":") | first → var | split(pat=":") | first
|
||||||
|
let template_content = regex::Regex::new(r#"(\w+)\.split\("([^"]+)"\)"#)
|
||||||
|
.unwrap()
|
||||||
|
.replace_all(&template_content, r#"$1 | split(pat="$2")"#)
|
||||||
|
.to_string();
|
||||||
|
// default('value') → default(value='value')
|
||||||
|
let template_content = regex::Regex::new(r"default\('([^']+)'\)")
|
||||||
|
.unwrap()
|
||||||
|
.replace_all(&template_content, "default(value='$1')")
|
||||||
|
.to_string();
|
||||||
|
// replace(" ", "_") → replace(from=" ", to="_")
|
||||||
|
let template_content = regex::Regex::new(r#"replace\("([^"]*)",\s*"([^"]*)"\)"#)
|
||||||
|
.unwrap()
|
||||||
|
.replace_all(&template_content, r#"replace(from="$1", to="$2")"#)
|
||||||
|
.to_string();
|
||||||
|
// dict.items() → dict (Tera iterates dicts directly)
|
||||||
|
let template_content = template_content.replace(".items()", "");
|
||||||
tera.add_raw_template(template_filename, &template_content)?;
|
tera.add_raw_template(template_filename, &template_content)?;
|
||||||
|
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue