Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
matrix:
os:
- ubuntu-latest
- windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -48,9 +47,8 @@ jobs:
matrix:
os:
- ubuntu-latest
- windows-latest
env:
V8TR_CI_TARGET_OS: ${{ runner.os }}
V8TR_CI_TARGET_OS: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand All @@ -73,6 +71,11 @@ jobs:
ACTOR: ${{ github.actor }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
REPOSITORY: ${{ github.repository }}
MATRIX_OS: ${{ matrix.os }}
V8TR_PLATFORM_BUNDLE_URL_LINUX: ${{ secrets.V8TR_PLATFORM_BUNDLE_URL_LINUX }}
V8TR_PLATFORM_BUNDLE_SHA256_LINUX: ${{ secrets.V8TR_PLATFORM_BUNDLE_SHA256_LINUX }}
V8TR_PLATFORM_BUNDLE_URL_WINDOWS: ${{ secrets.V8TR_PLATFORM_BUNDLE_URL_WINDOWS }}
V8TR_PLATFORM_BUNDLE_SHA256_WINDOWS: ${{ secrets.V8TR_PLATFORM_BUNDLE_SHA256_WINDOWS }}
run: |
trusted="true"

Expand All @@ -82,6 +85,26 @@ jobs:
trusted="false"
fi

case "$MATRIX_OS" in
ubuntu-latest)
bundle_url="$V8TR_PLATFORM_BUNDLE_URL_LINUX"
bundle_sha256="$V8TR_PLATFORM_BUNDLE_SHA256_LINUX"
;;
windows-latest)
bundle_url="$V8TR_PLATFORM_BUNDLE_URL_WINDOWS"
bundle_sha256="$V8TR_PLATFORM_BUNDLE_SHA256_WINDOWS"
;;
*)
echo "Unsupported matrix.os: $MATRIX_OS" >&2
exit 2
;;
esac

if [[ -z "$bundle_url" || -z "$bundle_sha256" ]]; then
trusted="false"
echo "V8TR_DESIGNER_ALLOW_MISSING_CONFIG=1" >> "$GITHUB_ENV"
fi

echo "trusted=$trusted" >> "$GITHUB_OUTPUT"

if [[ "$trusted" != "true" ]]; then
Expand Down
2 changes: 1 addition & 1 deletion SKILL/references/project-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ v8-runner launch thick
v8-runner launch ordinary
```

Launch onec-client-mcp-devkit through the supported `launch mcp` surface instead of manually assembling `/C"runMcp..."`:
Launch onec-client-mcp-devkit through the supported `launch mcp` surface instead of manually assembling `/C runMcp...`:

```bash
v8-runner launch mcp
Expand Down
7 changes: 7 additions & 0 deletions SKILL/references/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,15 @@ EDT syntax:

```bash
v8-runner syntax edt
v8-runner syntax edt --project <SOURCE_SET>
v8-runner syntax edt --project <SOURCE_SET> --exception-file tools/syntax-check-exception-file.txt
```

Use `--project <SOURCE_SET>` to check one configured EDT source-set by `source-set[].name`
from `v8project.yaml`; it is not the EDT `.project` display name.
Use `--exception-file <PATH>` when a project keeps a legacy syntax exception list; each
non-empty line is matched against parsed EDT issues after normalization.

## Artifacts

Preserve failed test artifacts under:
Expand Down
16 changes: 9 additions & 7 deletions docs/CAPABILITIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ v8-runner test va --feature login --filter-tag @smoke
```bash
v8-runner syntax designer-config [FLAGS]
v8-runner syntax designer-modules [FLAGS]
v8-runner syntax edt [--project <PROJECT>...]
v8-runner syntax edt [--project <SOURCE_SET>...] [--exception-file <PATH>]
```

`designer-config`:
Expand All @@ -202,8 +202,10 @@ v8-runner syntax edt [--project <PROJECT>...]
`edt`:

- Только `builder=DESIGNER`, `format=EDT`.
- Повторяемый `--project`.
- Без `--project` использует дефолтный набор EDT-проектов из конфига.
- Повторяемый `--project`; значение выбирается из `source-set[].name` в `v8project.yaml`.
- Без `--project` использует все EDT source-set из конфига.
- `--exception-file` читает legacy-файл исключений: каждая непустая строка исключает
совпавшую EDT issue после нормализации регистра, пробелов и пунктуации.

## Файлы и артефакты

Expand Down Expand Up @@ -271,16 +273,16 @@ v8-runner launch mcp [va] [--mode <thin|thick|ordinary>] [FLAGS]
- `designer` использует `1cv8`.
- `thin` использует `1cv8c`.
- `thick` и `ordinary` используют `1cv8`.
- `mcp` запускает клиентский MCP-сервер onec-client-mcp-devkit через `/C"runMcp"`.
- `mcp` запускает клиентский MCP-сервер onec-client-mcp-devkit через `/C runMcp`.
- `launch mcp` по умолчанию использует `--mode thin` и `1cv8c`.
- `launch mcp --mode thick` использует `1cv8`; `launch mcp --mode ordinary` использует `1cv8`
и добавляет `/RunModeOrdinaryApplication`.
- `launch mcp va` дополнительно запускает Vanessa Automation из `tools.va` через `/Execute <epf>`
и передаёт `VAParams=<runtime params>` без `StartFeaturePlayer`.
- Любой управляемый runner payload для ключа `/C` передаётся как один аргумент
`/C"<payload>"`: это касается `launch --c`, `launch mcp`, `test yaxunit` и `test va`.
- Любой управляемый runner payload для ключа `/C` передаётся отдельным аргументом
после `/C`: это касается `launch --c`, `launch mcp`, `test yaxunit` и `test va`.
- Для `mcp` доступны typed flags `--mcp-config <FILE>` и `--mcp-port <PORT>`;
итоговый payload: `/C"runMcp[=<FILE>][;mcpPort=<PORT>]"`.
итоговый payload: `/C runMcp[=<FILE>][;mcpPort=<PORT>]`.
- Если `--mcp-port` не указан, используется `tools.client_mcp.port` из `v8project.yaml`.
- Если настроено `tools.client_mcp.extension`, `launch mcp` не устанавливает и не обновляет его;
подготовка выполняется командой `v8-runner build`.
Expand Down
2 changes: 1 addition & 1 deletion docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ runtime identity и не добавляет отдельное поле конф
- `port`, опциональный порт клиентского MCP-сервера onec-client-mcp-devkit.
- `extension`, опциональное tool extension для клиентского MCP-сервера.

`launch mcp` передаёт это значение как `mcpPort` внутри `/C"runMcp..."`
`launch mcp` передаёт это значение как `mcpPort` внутри payload после `/C`
если CLI не указал `--mcp-port`.

`extension` поддерживает:
Expand Down
4 changes: 4 additions & 0 deletions scripts/test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ live-mcp-http.py
bash scripts/test/ci-rust.sh
```

GitHub Actions currently runs this blocking contract on `ubuntu-latest`.
Re-enabling Windows as blocking requires hardening the existing Unix-assumptive
unit/helper tests first.

### Happy-path CI helper

```bash
Expand Down
25 changes: 13 additions & 12 deletions spec/acceptance/real-environment-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Цель

Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../.github/workflows/ci.yml) с matrix на `ubuntu-latest` и `windows-latest`, а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.
Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../.github/workflows/ci.yml), а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Исправьте относительную ссылку на workflow.

На Line 5 путь ../.github/workflows/ci.yml выглядит битым для файла в spec/acceptance; нужен переход на два уровня вверх.

Предлагаемое исправление
-Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../.github/workflows/ci.yml), а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.
+Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../../.github/workflows/ci.yml), а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../.github/workflows/ci.yml), а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.
Начиная с `2026-04-22`, source of truth для real-env happy-path является GitHub Actions workflow [`ci.yml`](../../.github/workflows/ci.yml), а локальные скрипты в `scripts/test/*` остаются helper/entrypoint-слоем для этого workflow.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spec/acceptance/real-environment-validation.md` at line 5, Update the broken
relative link string "../.github/workflows/ci.yml" in the sentence that starts
with "Начиная с `2026-04-22`, source of truth..." to use two-levels-up path
"../../.github/workflows/ci.yml" so the link from
spec/acceptance/real-environment-validation.md correctly points to the workflow
file.


Обязательный smoke-контур для обеих ОС один и тот же:
Обязательный smoke-контур:

1. `build`
2. `syntax/check`
Expand Down Expand Up @@ -47,9 +47,9 @@ bash scripts/test/ci-rust.sh
- `V8_RUNNER_CI_SCOPE=runtime-locks` запускает только lock-focused regression subset
- `V8_RUNNER_CI_SCOPE=happy-path` запускает обязательную цепочку `build -> syntax/check -> test -> package -> deploy-ready artifacts`

### 2. Mandatory Linux/Windows happy-path
### 2. Mandatory happy-path

Назначение: одинаково обязательный smoke для `Linux` и `Windows` на trusted контексте.
Назначение: обязательный smoke на trusted контексте. Blocking GitHub Actions runner сейчас `ubuntu-latest`; Windows full-test/live path остается TODO до hardening существующих Unix-assumptive тестов и helper-фикстур.

Canonical entrypoint:

Expand All @@ -64,7 +64,7 @@ V8_RUNNER_CI_SCOPE=happy-path bash scripts/test/ci-rust.sh
3. `cargo test --locked`
4. `bash scripts/test/live-cli-fixture.sh`

`scripts/test/live-cli-fixture.sh` в mandatory профиле обязан выполнить одинаковые стадии для обеих ОС:
`scripts/test/live-cli-fixture.sh` в mandatory профиле обязан выполнить стадии:

1. `init/setup infobase`
2. `build --full-rebuild`
Expand Down Expand Up @@ -158,19 +158,19 @@ python3 scripts/test/live-mcp-http.py
bash scripts/test/live-cli-ibcmd.sh
```

### GitHub Actions matrix
### GitHub Actions

Для `ubuntu-latest` и `windows-latest` blocking использует один и тот же entrypoint:
Blocking path использует entrypoint:

```bash
V8_RUNNER_CI_SCOPE=happy-path bash scripts/test/ci-rust.sh
```

Текущая реализация workflow wiring:

- `.github/workflows/ci.yml` публикует два matrix job: `contract` и `happy-path`
- `contract` всегда запускает `bash scripts/test/ci-rust.sh` с `V8_RUNNER_CI_SCOPE=contract`
- `happy-path` всегда запускает `V8_RUNNER_CI_SCOPE=happy-path bash scripts/test/ci-rust.sh`
- `.github/workflows/ci.yml` публикует два job: `contract` и `happy-path`
- `contract` запускает `bash scripts/test/ci-rust.sh` с `V8_RUNNER_CI_SCOPE=contract`
- `happy-path` запускает `V8_RUNNER_CI_SCOPE=happy-path bash scripts/test/ci-rust.sh`; без platform bundle secrets workflow передает `V8TR_DESIGNER_ALLOW_MISSING_CONFIG=1`, поэтому Rust build/check/test остаются blocking, а live fixture завершается soft-skip
- trusted path использует `scripts/test/ci-platform-install.sh`, `scripts/test/ci-designer-config.sh` и `scripts/test/ci-ibsrv.sh`
- upload deploy-ready артефактов делает только trusted happy-path после успешной non-empty validation в `live-cli-fixture.sh`

Expand All @@ -194,8 +194,8 @@ Windows runner contract for this helper layer is explicit:

| Контур | Linux | Windows | Blocking | Build | Syntax/check | Test | Package | Deploy-ready artifacts |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `ci-rust contract` | yes | yes | yes | Rust | Rust | Rust | no | no |
| `ci-rust happy-path` | yes | yes | yes on trusted | Rust + real 1C | real | Rust by default; real 1C opt-in | real | real |
| `ci-rust contract` | yes | planned | yes | Rust | Rust | Rust | no | no |
| `ci-rust happy-path` | yes | planned | yes on trusted | Rust + real 1C | real | Rust by default; real 1C opt-in | real | real |
| `live-mcp-http` | optional | optional | no | real via MCP | real via MCP | real via MCP | n/a | n/a |
| `live-cli-ibcmd` | optional | optional | no | real (`IBCMD`) | n/a | n/a | diagnostic dump/export only | n/a |
| `live-cli-designer` | optional | optional | no | real (`DESIGNER`) | real | real opt-in | real | real |
Expand All @@ -207,3 +207,4 @@ Windows runner contract for this helper layer is explicit:
- `live-cli-fixture` по умолчанию не запускает 1С test-stage; `va`, `yaxunit-all` и `module` остаются opt-in режимами для стендов, где установлен и проверен соответствующий headless runner.
- `live-mcp-http` и `live-cli-ibcmd` остаются отдельными non-blocking контурами.
- Mandatory designer smoke requires `V8TR_DESIGNER_REAL_CONFIG`; `V8TR_DESIGNER_ALLOW_MISSING_CONFIG=1` is reserved for fork/non-blocking soft-skip contexts.
- Windows GitHub Actions full-test/live path is intentionally not blocking yet; current TODO is to remove Unix-only path and fake-executable assumptions from tests before re-enabling Windows as blocking.
10 changes: 7 additions & 3 deletions src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,13 @@ pub enum SyntaxTarget {
DesignerModules(DesignerModulesSyntaxArgs),
/// Check via EDT validate
Edt {
/// EDT project names
/// EDT source-set names from v8project.yaml
#[arg(long = "project")]
projects: Vec<String>,

/// File with syntax issue exception lines
#[arg(long = "exception-file")]
exception_file: Option<std::path::PathBuf>,
},
}

Expand All @@ -357,11 +361,11 @@ pub struct LaunchArgs {
#[command(flatten)]
pub launch: LaunchOptionsArgs,

/// JSON config path for onec-client-mcp-devkit `/C"runMcp=<FILE>"`
/// JSON config path for onec-client-mcp-devkit `/C runMcp=<FILE>`
#[arg(long = "mcp-config")]
pub mcp_config: Option<String>,

/// Port override for onec-client-mcp-devkit `/C"...;mcpPort=<PORT>"`
/// Port override for onec-client-mcp-devkit `/C` payload.
#[arg(long = "mcp-port")]
pub mcp_port: Option<u16>,
}
Expand Down
6 changes: 5 additions & 1 deletion src/cli/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1185,8 +1185,12 @@ fn map_syntax_request(args: &SyntaxArgs) -> Result<SyntaxRequest, UseCaseError>
SyntaxTarget::DesignerModules(modules) => {
SyntaxTargetRequest::DesignerModules(map_designer_modules_request(modules)?)
}
SyntaxTarget::Edt { projects } => SyntaxTargetRequest::Edt {
SyntaxTarget::Edt {
projects,
exception_file,
} => SyntaxTargetRequest::Edt {
projects: projects.clone(),
exception_file: exception_file.clone(),
},
},
})
Expand Down
2 changes: 1 addition & 1 deletion src/config/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ impl Default for McpConfig {
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
#[serde(default, rename_all = "snake_case")]
pub struct ClientMcpToolConfig {
/// Default port passed to onec-client-mcp-devkit via `/C"...;mcpPort=<PORT>"`.
/// Default port passed to onec-client-mcp-devkit via `/C` payload.
pub port: Option<u16>,

/// Optional tool extension prepared by `build` for client MCP launches.
Expand Down
4 changes: 2 additions & 2 deletions src/mcp/edt_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub async fn execute(
) -> Result<UseCaseResult<SyntaxCheckResult>, EdtSyntaxTransportError> {
let started = Instant::now();
let projects = match &request.target {
SyntaxTargetRequest::Edt { projects } => projects,
SyntaxTargetRequest::Edt { projects, .. } => projects,
_ => {
let error = AppError::Validation(
"shared EDT syntax executor requires an EDT syntax target".to_owned(),
Expand Down Expand Up @@ -328,7 +328,7 @@ fn resolve_edt_source_sets<'a>(

if !unknown.is_empty() {
return Err(AppError::Validation(format!(
"unknown EDT project(s): {}",
"unknown EDT source-set(s): {}",
unknown.join(", ")
)));
}
Expand Down
6 changes: 5 additions & 1 deletion src/mcp/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ pub(crate) fn normalize_check_syntax_edt_request(
SyntaxRequest {
target: SyntaxTargetRequest::Edt {
projects: normalize_edt_projects(request.project_name.as_deref()),
exception_file: None,
},
}
}
Expand Down Expand Up @@ -1470,7 +1471,10 @@ mod tests {
let requests = service.port.syntax_requests.borrow();
assert_eq!(
requests[0].1.target,
SyntaxTargetRequest::Edt { projects: vec![] }
SyntaxTargetRequest::Edt {
projects: vec![],
exception_file: None
}
);
}

Expand Down
21 changes: 9 additions & 12 deletions src/platform/enterprise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ pub fn build_launch_args(
args.push(execute.clone());
}
if let Some(c) = &launch.c {
args.push(quoted_c_arg(c));
args.push("/C".to_owned());
args.push(c.clone());
}

let mut extra_args = Vec::new();
Expand All @@ -182,10 +183,6 @@ fn effective_out_path(launch: &LaunchOptions) -> Option<&str> {
launch.internal_out.as_deref().or(launch.out.as_deref())
}

fn quoted_c_arg(payload: &str) -> String {
format!("/C\"{payload}\"")
}

fn filtered_raw_launch_args(args: &[String]) -> Vec<String> {
let mut filtered = Vec::new();
let mut skip_value = false;
Expand Down Expand Up @@ -262,9 +259,8 @@ mod tests {
assert_eq!(args[1], "/DisableStartupDialogs");
assert!(args.iter().any(|arg| arg == "/TESTMANAGER"));
assert!(args
.iter()
.any(|arg| arg == "/C\"RunUnitTests=/tmp/path with space/тест config.json\""));
assert!(!args.iter().any(|arg| arg == "/C"));
.windows(2)
.any(|pair| pair == ["/C", "RunUnitTests=/tmp/path with space/тест config.json"]));
assert!(args.iter().any(|arg| arg == "/Out"));
}

Expand All @@ -288,10 +284,11 @@ mod tests {
.iter()
.any(|arg| arg == "/tmp/va/vanessa automation.epf"));
assert!(args.iter().any(|arg| arg == "/TESTMANAGER"));
assert!(args
.iter()
.any(|arg| arg == "/C\"StartFeaturePlayer;VAParams=/tmp/va/va-params.json\""));
assert!(!args.iter().any(|arg| arg == "/C"));
assert!(args.windows(2).any(|pair| pair
== [
"/C",
"StartFeaturePlayer;VAParams=/tmp/va/va-params.json"
]));
}

#[test]
Expand Down
Loading