diff --git a/ci/config_global.json b/ci/config_global.json index 17807ea7fe..0ed1e5b28c 100644 --- a/ci/config_global.json +++ b/ci/config_global.json @@ -24,7 +24,7 @@ }, "osPath": { "description": "OneScript exe path", - "value": "D:/OneScript/" + "value": "D:/OneScript" }, "ghcliPath": { "description": "GitHub CLI exe path", @@ -57,6 +57,10 @@ "releaseWorkspace": { "description": "Artifacts root folder", "value": "C:/Users/bayselonarrend/AppData/Local/Jenkins/.jenkins/workspace/OpiBuild/OpiRelease" + }, + "yadiskPath": { + "description": "Yandex Disk mount path", + "value": "D:/Yandex.Disk-bayselonarrend" } } }, diff --git a/ci/os/ReleasePublisher.os b/ci/os/ReleasePublisher.os index 11509c3e04..2400194905 100644 --- a/ci/os/ReleasePublisher.os +++ b/ci/os/ReleasePublisher.os @@ -110,15 +110,11 @@ OPI_ПреобразованиеТипов.ПолучитьСтроку(IDРелиза); КонецЕсли; - СтруктураЗапроса = Новый Структура; - СтруктураЗапроса.Вставить("publish", Ложь); - СозданиеДрафта = OPI_ЗапросыHTTP .НовыйЗапрос() - .Инициализировать(СтрШаблон("https://api.sourcecraft.tech/releases/id:%1", IDРелиза)) + .Инициализировать(СтрШаблон("https://api.sourcecraft.tech/releases/id:%1/publish", IDРелиза)) .ДобавитьBearerАвторизацию(Токен) - .УстановитьJsonТело(СтруктураЗапроса) - .ОбработатьЗапрос("PATCH") + .ОбработатьЗапрос("POST") .ВернутьОтветКакСтроку(); CommonTools.СообщитьПроцесс(СозданиеДрафта); diff --git a/ci/os/internal/Classes/JenkinsTestsMethods.os b/ci/os/internal/Classes/JenkinsTestsMethods.os index 8a2c5d8d63..6ea64bbef7 100644 --- a/ci/os/internal/Classes/JenkinsTestsMethods.os +++ b/ci/os/internal/Classes/JenkinsTestsMethods.os @@ -4,6 +4,8 @@ Перем Путь1с; Перем Сервер1с; +Перем КаталогOscript; + Перем КаталогКонфигурацииYaxUnit; Перем ШаблонКонфигурацииYaxUnit; @@ -47,6 +49,8 @@ Сервер1с = ДанныеПроекта.ПолучитьЗначениеНастройки("local.serverName"); ХостJenkins = ДанныеПроекта.ПолучитьЗначениеНастройки("local.jenkinsHost"); + КаталогOscript = ДанныеПроекта.ПолучитьЗначениеНастройки("local.osPath"); + ДанныеКонфигурацииТестов = ДанныеПроекта.ПолучитьЗначениеНастройки("tests.availability"); КаталогКонфигурацииYaxUnit = ДанныеПроекта.ПолучитьЗначениеНастройки("tests.yaxunitConf"); ПутьJenkinsFull = ДанныеПроекта.ПолучитьЗначениеНастройки("tests.jenkinsFull"); @@ -189,8 +193,8 @@ ТекстВыполненияCLI = ПолучитьТекстВыполненияOs(ТаблицаТестов, СписокБиблиотек, МодульТестовCLI, Язык); ТекстВыполнения1С = ПолучитьТекстВыполнения1c(ТаблицаТестов, СписокБиблиотек, МодульТестов, Язык); - ТекстJFCLI = СтрШаблон(ШаблонCliWindows, Язык, ТекстВыполненияCLI); - ТекстJFOS = СтрШаблон(ШаблонOsWindows, Язык, ТекстВыполненияOS); + ТекстJFCLI = СтрШаблон(ШаблонCliWindows, Язык, ТекстВыполненияCLI, КаталогOscript); + ТекстJFOS = СтрШаблон(ШаблонOsWindows, Язык, ТекстВыполненияOS, КаталогOscript); ТекстJFOSRPM = СтрШаблон(ШаблонOsLinux, Язык, ТекстВыполненияOS, "Rpm-Agent"); ТекстJFOSDEB = СтрШаблон(ШаблонOsLinux, Язык, ТекстВыполненияOS, "Deb-Agent"); diff --git a/ci/os/internal/Classes/ReleaseFactory.os b/ci/os/internal/Classes/ReleaseFactory.os index fa0aae28bf..2acb590d00 100644 --- a/ci/os/internal/Classes/ReleaseFactory.os +++ b/ci/os/internal/Classes/ReleaseFactory.os @@ -14,6 +14,7 @@ Перем ХешСумма; Перем НеобходимоеЧислоАртефактов; Перем ДанныеПроекта; +Перем КаталогЯндексДиск; Процедура ПриСозданииОбъекта(Знач ДанныеПроекта_ = Неопределено) @@ -39,6 +40,7 @@ ОСкрипт = ДанныеПроекта.ПолучитьЗначениеНастройки("local.osPath"); ПутьGHCLI = ДанныеПроекта.ПолучитьЗначениеНастройки("local.ghcliPath"); ПутьInnoSetup = ДанныеПроекта.ПолучитьЗначениеНастройки("local.innoPath"); + КаталогЯндексДиск = ДанныеПроекта.ПолучитьЗначениеНастройки("local.yadiskPath"); ПутьВыгрузки = СтрШаблон("./%1/", Версия); ХешСумма = ПолучитьСтрокуИзДвоичныхДанных(Новый ДвоичныеДанные("./service/last_build_hash.txt")); @@ -134,7 +136,7 @@ CommonTools.СообщитьПроцесс("Files uploading"); - КаталогПререлиза = "D:\Yandex.Disk-bayselonarrend\OpenIntegrations\prerelease"; // TODO: Добавить в conf + КаталогПререлиза = КаталогЯндексДиск + "/OpenIntegrations/prerelease"; Для Каждого ФайлРелиза Из ФайлыРелиза Цикл @@ -268,19 +270,19 @@ ИмяOSPX = СтрШаблон("%1-%2_%3.ospx", ИдентификаторOSPX, Версия, Префикс); КонечныйПутьOSPX = ПутьВыгрузки + ИмяOSPX; - СборкаOS = СтрШаблон("""%2bin/opm.bat"" b -o %1", ВременныКаталог, ОСкрипт); + СборкаOS = СтрШаблон("""%2/bin/opm.bat"" b -o %1", ВременныКаталог, ОСкрипт); CommonTools.ЗапуститьВнешнееПриложение(СборкаOS, ПутьСборки); ПереместитьФайл(ОбъединитьПути(ВременныКаталог, СтандартноеИмяOSPX), КонечныйПутьOSPX); - УдалитьФайлы(СтрШаблон("%1lib/%2", Оскрипт, ИдентификаторOSPX)); + УдалитьФайлы(СтрШаблон("%1/lib/%2", Оскрипт, ИдентификаторOSPX)); Приостановить(1000); СтрокаВызова = СтрШаблон("""%2bin/opm.bat"" install -f ""%1""", КонечныйПутьOSPX, ОСкрипт); CommonTools.ЗапуститьВнешнееПриложение(СтрокаВызова); Приостановить(1000); - НачальныйПуть = СтрШаблон("%1lib/%2", ОСкрипт, ИдентификаторOSPX); + НачальныйПуть = СтрШаблон("%1/lib/%2", ОСкрипт, ИдентификаторOSPX); КонечныйПуть = СтрШаблон("./ci/installer_set/share/oint/lib/%1", ИдентификаторOSPX); ФС.КопироватьСодержимоеКаталога(НачальныйПуть, КонечныйПуть); diff --git a/docs/en/md/Instructions/Start.md b/docs/en/md/Instructions/Start.md index 4de5489faa..8df019b05b 100644 --- a/docs/en/md/Instructions/Start.md +++ b/docs/en/md/Instructions/Start.md @@ -48,6 +48,7 @@ Fast navigation: + diff --git a/docs/ru/md/Instructions/Start.md b/docs/ru/md/Instructions/Start.md index b31753ade3..94b945d3a3 100644 --- a/docs/ru/md/Instructions/Start.md +++ b/docs/ru/md/Instructions/Start.md @@ -49,6 +49,7 @@ keywords: [1C, 1С, 1С:Предприятие, 1С:Предприятие 8.3, + diff --git a/media/Covers/RSS.png b/media/Covers/RSS.png index a2009c0ed7..5d8fd8d382 100644 Binary files a/media/Covers/RSS.png and b/media/Covers/RSS.png differ diff --git a/media/Covers/WebSocket.png b/media/Covers/WebSocket.png new file mode 100644 index 0000000000..d1b49c8a81 Binary files /dev/null and b/media/Covers/WebSocket.png differ diff --git a/service/releases.json b/service/releases.json index 18eaa37ef9..436dca417c 100644 --- a/service/releases.json +++ b/service/releases.json @@ -4,13 +4,19 @@ "title": "Version 1.35.0 - .04.2026", "summary_ru": "Методы работы с Websocket", "summary_en": "Methods of working with Websocket", - "image": "media/Covers/RSS.png", + "image": "media/Covers/WebSocket.png", "changes": [ { "lib": "WebSocket", "icon": "media/WebSocket.png", "description_ru": "Методы клиента (3 функции)", "description_en": "Client methods (3 functions)" + }, + { + "lib": "SQLite", + "icon": "media/SQLite.png", + "description_ru": "Исправлена работа с расширениями для новых версий платформы", + "description_en": "Fixed extension compatibility with new platform versions" } ] }, diff --git a/service/templates/jenkins/cli_test_windows.txt b/service/templates/jenkins/cli_test_windows.txt index 61364746e5..7a7f7e9719 100644 --- a/service/templates/jenkins/cli_test_windows.txt +++ b/service/templates/jenkins/cli_test_windows.txt @@ -33,7 +33,7 @@ pipeline { stage('Remove oint.bat if exists') { steps { powershell encoding: 'UTF-8', script: ''' - $batFile = "D:\\OneScript\\bin\\oint.bat" + $batFile = "%3/oint.bat" if (Test-Path $batFile) { Remove-Item -Path $batFile -Force Write-Host "Файл oint.bat удален." @@ -44,7 +44,7 @@ pipeline { // Проверяем, что файл действительно удален powershell encoding: 'UTF-8', script: ''' - $batFile = "D:\\OneScript\\bin\\oint.bat" + $batFile = "%3/oint.bat" if (Test-Path $batFile) { Write-Error "Ошибка: Файл oint.bat не удален!" exit 1 diff --git a/service/templates/jenkins/os_test_windows.txt b/service/templates/jenkins/os_test_windows.txt index 84fdae9d9f..d1fda3e2ba 100644 --- a/service/templates/jenkins/os_test_windows.txt +++ b/service/templates/jenkins/os_test_windows.txt @@ -27,7 +27,7 @@ pipeline { try { // Удаление каталога C:\Program Files\OneScript\lib\oint, если существует powershell encoding: 'UTF-8', script: ''' - $dirPath = "D:\\OneScript\\lib\\oint" + $dirPath = "%3/lib/oint" if (Test-Path $dirPath) { Write-Host "Каталог oint найден. Удаляем..." Remove-Item -Path $dirPath -Recurse -Force @@ -39,7 +39,7 @@ pipeline { // Проверяем, что каталог действительно удален powershell encoding: 'UTF-8', script: ''' - $dirPath = "D:\\OneScript\\lib\\oint" + $dirPath = "%3/lib/oint" if (Test-Path $dirPath) { Write-Error "Ошибка: Каталог oint всё ещё существует после попытки удаления!" exit 1 diff --git a/src/addins/commons/common-core/README.md b/src/addins/commons/common-core/README.md deleted file mode 100644 index efabe3a10a..0000000000 --- a/src/addins/commons/common-core/README.md +++ /dev/null @@ -1,184 +0,0 @@ -# common-core - -Общая библиотека для создания 1С Native API расширений с автоматической защитой от panic. - -## Возможности - -- ✅ **Trait ValueType** - универсальный trait для работы с типами 1С -- ✅ **Макрос impl_raw_addin!** - автоматическая генерация RawAddin impl -- ✅ **Защита от panic** - автоматический перехват panic и возврат ошибки в 1С -- ✅ **Логирование** - опциональное логирование всех panic -- ✅ **Нет boilerplate** - весь повторяющийся код генерируется макросом - -## Установка - -Добавь в `Cargo.toml`: - -```toml -[dependencies] -common-core = { path = "../commons/common-core" } -``` - -## Использование - -### Базовое использование - -**Было (старый способ):** - -```rust -// src/core/mod.rs -pub mod getset; - -use addin1c::{name, RawAddin, Variant}; -use crate::component::{METHODS, PROPS, get_params_amount, cal_func, AddIn}; - -impl RawAddin for AddIn { - fn register_extension_as(&mut self) -> &'static [u16] { - name!("Main") - } - // ... 20+ строк boilerplate кода ... - fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret_value: &mut Variant) -> bool { - cal_func(self, num, params).get_value(ret_value) - } -} - -impl std::ops::Index for AddIn { - // ... ещё код ... -} - -impl std::ops::IndexMut for AddIn { - // ... ещё код ... -} -``` - -**Стало (новый способ):** - -```rust -// src/core/mod.rs -pub use common_core::getset; - -use common_core::impl_raw_addin; -use crate::component::{AddIn, METHODS, PROPS, get_params_amount, cal_func}; - -impl_raw_addin!(AddIn, METHODS, PROPS, get_params_amount, cal_func); -``` - -Всё! Одна строка макроса заменяет весь boilerplate код. - -### С логированием panic - -Если хочешь логировать все panic в файл: - -```rust -use common_core::impl_raw_addin_with_logging; -use crate::component::{AddIn, METHODS, PROPS, get_params_amount, cal_func}; - -impl_raw_addin_with_logging!( - AddIn, - METHODS, - PROPS, - get_params_amount, - cal_func, - "D:\\my_addon_panic.log" -); -``` - -## Что генерирует макрос - -Макрос автоматически генерирует: - -1. **Полную реализацию RawAddin** - все 15+ методов -2. **Защиту от panic** - `catch_unwind` в `call_as_func` -3. **Index/IndexMut** - для доступа к полям через `self[index]` -4. **Обработку ошибок** - извлечение сообщения из `Any` panic -5. **Опциональное логирование** - запись всех panic в файл - -## Защита от panic - -Макрос автоматически оборачивает `call_as_func` в `catch_unwind`: - -```rust -fn call_as_func(&mut self, num: usize, params: &mut [Variant], ret_value: &mut Variant) -> bool { - let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - cal_func(self, num, params) - })); - - match result { - Ok(value) => value.get_value(ret_value), - Err(panic_info) => { - // Извлекаем сообщение из panic - let error_msg = if let Some(s) = panic_info.downcast_ref::<&str>() { - format!("Internal error (panic): {}", s) - } else if let Some(s) = panic_info.downcast_ref::() { - format!("Internal error (panic): {}", s) - } else { - "Internal error: unknown panic occurred".to_string() - }; - - // Возвращаем ошибку в 1С вместо краша - ret_value.set_str(&error_msg); - true - } - } -} -``` - -Это означает, что: -- ❌ **Нет краша 1С** - даже если происходит panic -- ✅ **Информативные ошибки** - пользователь видит, что произошло -- ✅ **Легко отлаживать** - можно включить логирование - -## Требования - -В `Cargo.toml` должно быть: - -```toml -[profile.release] -panic = "unwind" # НЕ "abort"! -``` - -Это необходимо для работы `catch_unwind`. - -## Миграция существующих проектов - -1. Добавь зависимость `common-core` -2. Замени содержимое `src/core/mod.rs` на одну строку макроса -3. Удали `src/core/getset.rs` (теперь используется из common-core) -4. Убедись, что `panic = "unwind"` в Cargo.toml - -## Пример полной структуры проекта - -``` -my-addon/ -├── Cargo.toml -├── src/ -│ ├── lib.rs -│ ├── core/ -│ │ └── mod.rs # Только макрос, 3 строки -│ └── component/ -│ ├── mod.rs # METHODS, PROPS, AddIn, cal_func, get_params_amount -│ └── ... -``` - -**src/core/mod.rs:** -```rust -pub use common_core::getset; -use common_core::impl_raw_addin; -use crate::component::{AddIn, METHODS, PROPS, get_params_amount, cal_func}; - -impl_raw_addin!(AddIn, METHODS, PROPS, get_params_amount, cal_func); -``` - -Готово! - -## Преимущества - -1. **Меньше кода** - 3 строки вместо 50+ -2. **Меньше ошибок** - нет дублирования кода между проектами -3. **Автоматическая защита** - все проекты автоматически защищены от panic -4. **Легко обновлять** - изменения в одном месте применяются ко всем проектам -5. **Единообразие** - все проекты используют одинаковую логику - -## Лицензия - -MIT diff --git a/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl index 7b1eba1a76..4e4da31548 100644 --- a/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_SQLite/Module.bsl @@ -69,7 +69,7 @@ OPI_ПреобразованиеТипов.ПолучитьСтроку(База); OPI_Инструменты.ВернутьУправляющиеПоследовательности(База); - Коннектор = OPI_Компоненты.ПолучитьКомпоненту("SQLite"); + Коннектор = OPI_Компоненты.ПолучитьКомпоненту("SQLite", , Истина); Коннектор.Database = База; diff --git a/src/ru/OPI/src/CommonModules/OPI_Компоненты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Компоненты/Module.bsl index 5c636f1dd8..191a1748e3 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Компоненты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Компоненты/Module.bsl @@ -48,7 +48,7 @@ #Область Основные -Функция ПолучитьКомпоненту(Знач ИмяКомпоненты, Знач Класс = "Main") Экспорт +Функция ПолучитьКомпоненту(Знач ИмяКомпоненты, Знач Класс = "Main", НеИзолированно = Ложь) Экспорт Компонента = Неопределено; Ошибка = ""; @@ -57,7 +57,7 @@ Если Не ИнициализироватьВнешнююКомпоненту(ИмяКомпоненты, Класс, Компонента) Тогда Ошибка = Неопределено; - Компонента = ПодключитьКомпонентуНаСервере(ИмяКомпоненты, Класс, Ошибка); + Компонента = ПодключитьКомпонентуНаСервере(ИмяКомпоненты, Класс, Ошибка, НеИзолированно); Если ЗначениеЗаполнено(Ошибка) Тогда СформироватьИсключениеКомпоненты(Ошибка); @@ -235,7 +235,7 @@ КонецФункции -Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс, Ошибка) +Функция ПодключитьКомпонентуНаСервере(Знач ИмяКомпоненты, Знач Класс, Ошибка, НеИзолированно) Если OPI_Инструменты.ЭтоOneScript() Тогда ИмяМакета = СтрШаблон("%1%2.zip" , КаталогКомпонентOS(), ИмяКомпоненты); @@ -244,7 +244,7 @@ КонецЕсли; Попытка - ПодключитьКомпонентуНеИзолированно(ИмяМакета, ИмяКомпоненты); + ПодключитьКомпонентуВРежиме(ИмяМакета, ИмяКомпоненты, НеИзолированно); Компонента = Новый(СтрШаблон("AddIn.%1.%2", ИмяКомпоненты, Класс)); Ошибка = Неопределено; Возврат Компонента; @@ -255,12 +255,14 @@ КонецФункции -Функция ПодключитьКомпонентуНеИзолированно(ИмяМакета, ИмяКомпоненты) +Функция ПодключитьКомпонентуВРежиме(ИмяМакета, ИмяКомпоненты, ПринудительноНеИзолированно) ЭтоOneScript = OPI_Инструменты.ЭтоOneScript(); - НеобходимТипПоСистеме = Не ЭтоOneScript И Не OPI_Инструменты.ЭтоWindows(); + + НеобходимТипПоVM = Не ЭтоOneScript; + НеобходимТипПоСистеме = Не OPI_Инструменты.ЭтоWindows(); - Если ЭтоOneScript Тогда + Если Не НеобходимТипПоVM Тогда НеобходимТипПоВерсии = Ложь; @@ -279,7 +281,7 @@ КонецЕсли; - НеобходимТип = НеобходимТипПоВерсии И НеобходимТипПоСистеме; + НеобходимТип = НеобходимТипПоVM И НеобходимТипПоВерсии И (НеобходимТипПоСистеме Или ПринудительноНеИзолированно); Если Не НеобходимТип Тогда diff --git a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index 6883fa7c85..428cd2557d 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -7869,6 +7869,8 @@ Данные = ПолучитьСтрокуИзДвоичныхДанных(Данные); ОжидаетЧто(Данные).Равно(Сообщение); + + Результат["message"] = "<ДвоичныеДанные>"; КонецЕсли; @@ -13617,9 +13619,12 @@ ОжидаетЧто(СтрНайти(Результат, " 0).Равно(Истина); ОжидаетЧто(СтрНайти(Результат, "") > 0).Равно(Истина); ОжидаетЧто(СтрНайти(Результат, "") > 0).Равно(Истина); + + ИВФ = ПолучитьИмяВременногоФайла("xml"); + ПолучитьДвоичныеДанныеИзСтроки(Результат).Записать(ИВФ); - ЗаписатьПараметр("RSS_FeedXML", Результат); - Параметры.Вставить("RSS_FeedXML", Результат); + ЗаписатьПараметр("RSS_FeedXML", ИВФ); + Параметры.Вставить("RSS_FeedXML", ИВФ); Возврат Результат; @@ -13671,9 +13676,12 @@ ОжидаетЧто(СтрНайти(Результат, " 0).Равно(Истина); ОжидаетЧто(СтрНайти(Результат, "xmlns=""http://www.w3.org/2005/Atom""") > 0).Равно(Истина); ОжидаетЧто(СтрНайти(Результат, "") > 0).Равно(Истина); + + ИВФ = ПолучитьИмяВременногоФайла("xml"); + ПолучитьДвоичныеДанныеИзСтроки(Результат).Записать(ИВФ); - ЗаписатьПараметр("RSS_AtomFeedXML", Результат); - Параметры.Вставить("RSS_AtomFeedXML", Результат); + ЗаписатьПараметр("RSS_AtomFeedXML", ИВФ); + Параметры.Вставить("RSS_AtomFeedXML", ИВФ); Возврат Результат; diff --git a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl index 8df66fad0c..3d47095c38 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -29631,6 +29631,8 @@ // END Обработать(Результат, "RSS", "РазобратьФидRSS"); + + OPI_Инструменты.УдалитьФайлВПопытке(ФидXML, "Не удалось удалить временный файл после теста!"); КонецПроцедуры @@ -29701,6 +29703,8 @@ // END Обработать(Результат, "RSS", "РазобратьФидAtom"); + + OPI_Инструменты.УдалитьФайлВПопытке(ФидXML, "Не удалось удалить временный файл после теста!"); КонецПроцедуры