Делаем простую систему непрерывной интеграции (CI) c OneSсript, xUnitFor1C и v8LogScanner




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

46 Comments

  1. Evil Beaver

    Здорово, спасибо, что пользуетесь. 2 вопроса:

    1. Почему руками прописываем путь в переменную PATH? Инсталлятор делает это автоматически

    2. Не увидел, как человек получит к себе на машину «деплойку»? Деплойка также ставится через opm.

    Reply ↓
  2. baton_pk

    (1) насколько я понял, деплойка тут и не используется.

    Reply ↓
  3. Evil Beaver

    (2) Аа, действительно. Она лишь в начале, как совет. Ок.

    Reply ↓
  4. ripreal1

    (1)

    У меня не прописалась. Возможно она не прописывается под неполными правами?

    Reply ↓
  5. Stepa86

    (4) А зачем вообще в PATH прописывать? Все равно в шаге 9 полный путь к exe. Так же можно написать в шаге 8. Даже лучше, чтоб строки совпадали. А то oscript и C:Program…oscript.exe могут быть разными, что может принести сюрприз при отладке.

    Reply ↓
  6. artbear

    (0) Каким образом получаете/генерируете отчет в почту?

    Делаете анализ отчет xUnitFor1C, разборку его и т.п.?

    PS Спасибо за использование нашего продукта xUnitFor1C 🙂

    Reply ↓
  7. ripreal1

    Да, использую ГенераторОтчетаJUnitXML

    Reply ↓
  8. comol

    Я что-то упустил в этой жизни или Обновление базы скриптом и автотесты теперь называют непрерывной интеграцией?

    Не говоря уже о том что с хранилищем 1С она особенно актуальна! А то мы так страдаем когда мёрджим различные ветки хранилища :))))))))))

    Reply ↓
  9. artbear

    (8) А причем здесь мерж? здесь главное от CI — непрерывная/периодическая проверка/тестирование изменений разработчиков

    Reply ↓
  10. vlad.frost

    (8)

    Я что-то упустил в этой жизни или Обновление базы скриптом и автотесты теперь называют непрерывной интеграцией?

    Не просто обновление базы скриптом и автотесты, а ежедневное обновление базы скриптом + автотесты по итогам мерджей + интегральная оценка качества. Вроде, про это же речь в статье.

    Вы удивитесь, но довольно много косяков вылезает просто по итогам слияния веток.

    Reply ↓
  11. comol

    (9)

    А причем здесь мерж?

    Интересно что значит слово «Интеграция» в словосочетании «Непрерывная интеграция»? :)))

    Reply ↓
  12. headMade

    на xUnitFor1C много тестов написано для ваших конфигураций?

    Сами тесты можно поДсмотреть где-нибудь ?

    Reply ↓
  13. Evil Beaver

    (11) десять команд пилят сорок компонент, потом все это из разных веток хаотично вливается в ствол релиза. Работает оно?

    А пес его знает…

    Поэтому вся эта мешанина автоматически собирается и тестируется в комплексе. Т.е. «интегрируется» между собой.

    Применительно к 1С: — 1С-ники пишут что-то в хранилище, ни в жизнь не тестируют перед коммитом, «я всего одну строчку исправил». Потом в течении 10-15 минут после коммита автор получает в почту отчет со словами «ААА, фсе сломал, гаденыш!» И результаты прогона тестов.

    Reply ↓
  14. ripreal1

    У нас на 2 базах используются тесты. Сейчас это 3 теста.

    Первый тест тестирует функцию печати различных печатных форм, второй — выборочное проведение документов из журнала «Реестр торговых документов» и отражения их в БУ (с отменой транзакции), третий — то же, что и второй только по производственным документам.

    Этого маловато конечно, но главное, что работает система, а добавление новых тестов — это дело времени.

    Скм код тестов не тайна. Я приложил их к сообщению.

    Reply ↓
  15. comol

    (10)

    итогам мерджей

    нет в 1с меджей… без EDT нет.

    (10)

    ежедневное

    и непрерывное — это по-моему несколько разные вещи…

    Reply ↓
  16. comol

    (13)

    результаты прогона тестов

    это автоматизированное тестирование всё-таки а не непрерывная интеграция.

    течении 10-15 минут после коммита

    в статье нет привязки к коммиту.

    CI всё-таки подразумевает наличие ветвлений… Без веток оно не так и нужно… Не говоря уже о другой проблеме — 100% покрытия тестами в 1С не достигнешь да и не нужно оно…

    Reply ↓
  17. comol

    (14)

    добавление новых тестов — это дело времени

    Их прогон дело времени… Добавление то фигня. И вот тут возникает вопрос…

    Reply ↓
  18. lustin

    (17) что за лютое сопротивление Олег. CI нет, интеграция тебе не интеграция. Тестов нет вообще и не нужны. Ты чего это ? Тебя на работе заставляют все таки сервер сборок запускать ? И ты готовишь аргументы против ?

    P.S. И merge в 1С есть, просто ты не в курсе (без EDT)

    Reply ↓
  19. lustin

    (15) И самого 1С нет — его не существует. И Владислава тоже нет — он всего лишь наша выдумка.

    Reply ↓
  20. vlad.frost

    (15)

    нет в 1с меджей… без EDT нет.

    Ещё как есть: https://its.1c.ru/db/v8std#content:2149184358:hdoc

    ежедневное

    и непрерывное — это по-моему несколько разные вещи…

    Да википедия нам говорит, чтобы называться «непрерывной», нужно несколько раз в день интегрироваться. Но, поскольку процесс прогона автотестов в 1С небыстрый, один прогон может почти на сутки растянуться 🙁

    И Мартин Фаулер говорит, что «usually each person integrates at least daily — leading to multiple integrations per day.», т.е. хотя бы раз в день, уже достаточно, чтобы называться «Непрерывной» https://martinfowler.com/articles/continuousIntegration.html

    Reply ↓
  21. Evil Beaver

    (16) если есть CI-сервер, значит в каком-то виде есть и CI. Понятно, что терминология в данном случае не будет 100% верной, но это больше буквоедство, нежели существенная проблема. 1С, например, судя по их статье на Хабре запросто даже мержит ветки-хранилища ERP в общий ствол с помощью СППР. Я слабо себе представляю как это можно делать, не сойдя с ума, но наверное можно. Уже много лет у них этот процесс. Так что и CI им пригодится.

    Reply ↓
  22. artbear

    (20) Олег, практически нигде не говорится про ветки и CI. Главное — помещать свои изменения в рабочий ствол и интегрироваться с другими разрабами, системами и прочее.

    например, Википедию почитать, первый же абзац

    Непрерывная интеграция (CI, англ. Continuous Integration) — это практика разработки программного обеспечения, которая заключается в слиянии рабочих копий в общую основную ветвь разработки несколько раз в день и выполнении частых автоматизированных сборок проекта для скорейшего выявления потенциальных дефектов и решения интеграционных проблем. В обычном проекте, где над разными частями системы разработчики трудятся независимо, стадия интеграции является заключительной. Она может непредсказуемо задержать окончание работ. Переход к непрерывной интеграции позволяет снизить трудоёмкость интеграции и сделать её более предсказуемой за счет наиболее раннего обнаружения и устранения ошибок и противоречий, но основным преимуществом является сокращение стоимости исправления дефекта, за счёт раннего его выявления. Непрерывная интеграция впервые названа и предложена Гради Бучем в 1991 г.[1]

    Непрерывная интеграция является одним из основных приёмов экстремального программирования.

    Reply ↓
  23. lustin

    (20) если процесс подразумевает мердж раз в день и действие данного правила непрерывается, то значит оно непрерывно.

    Reply ↓
  24. Evil Beaver

    (18) Выше ссылка на ИТС и было на Хабре. В 1С есть merge без EDT. Но в мою голову он не помещается, к сожалению. Хотя ERP разрабатывается много лет и успешно в таком виде. Значит оно работает.

    Reply ↓
  25. pumbaE

    Ну и я накину, разве в EDT есть merge работающий? В документации он конечно есть, в пунктах меню тоже, но вот что-б он работал такого нет.

    Reply ↓
  26. comol

    я не про извращения писал… я про ветвления….

    хотя бы раз в день, уже достаточно, чтобы называться «Непрерывной»

    хм. ну да по классике видимо так :). Но я думаю ребята «не из мира 1С» очень сильно этому удивились бы

    Reply ↓
  27. comol

    (22)

    которая заключается в слиянии рабочих копий в общую основную ветвь разработки

    я даже как-то не знаю…. :)))

    Reply ↓
  28. comol

    (18)

    что за лютое сопротивление Олег. CI нет, интеграция тебе не интеграция

    Нуу… так скажем я очень хотел CI. Посвятил этому достаточно много времени….

    Потом пытался понять почему «успешно зашло web-ерам» и «нихрена не зашло 1С-никам».

    Тут дело не в том что мы 1С-ники.

    CI спасает от веток и постоянных Merge-ей. У нас ветка одна.

    CI спасает когда весь код покрыт тестами. Удачи вам в покрытии всего кода ERP.

    Прочитал у SAP-ёров почему не зашло с тестами. Понял что в 1С у нас… до EDT по крайней мере CI не прокатит :(.

    Ну по крайней мере я нормального решения не нашел. То, что описал коллега выше — профанация и определённый род извращений.

    Вцелом наверное полезный, но не CI.

    Reply ↓
  29. comol

    (24) Мне коллеги из CarMoney рассказывали про этот «Merge». Они его юзают и с СППР.

    Это не совсем то, что я видел у Web-еров… Временные затраты настолько чудовищны, что CI назвать язык не поворачивается.

    Но да — позволяет редактировать один объект 2-м разработчикам (в теории) и систематизирует процесс выпуска фич.

    Reply ↓
  30. comol

    (25) Нуу… он же должен когда то появиться…. иначе на кой…. (цензура) EDT нужен?

    Я так понял EDT = здравствуй GitFlow и здравствуй CI/CD (хотя тоже не уверен).

    Reply ↓
  31. comol

    (18) Автотесты то у меня конечно есть… Сервер сборок тоже будет, только не у 1С части. Уже в очередной раз не у 1С части….

    Reply ↓
  32. JohnyDeath

    (28)

    Потом пытался понять почему «успешно зашло web-ерам» и «нихрена не зашло 1С-никам».

    а оно вообще пыталось заходить?

    Вон только с десяток-другой энтузиастов делают тесты и фрейморки к ним в 1С. И все заходит вроде бы.

    Т.е. основная масса одинэсников вообще не знает что такое тесты и с чем его едят, а ты про какое-то «незашло»

    Так и не понял при чем тут CI и ветки. Почему CI не может быть с одной веткой?

    Reply ↓
  33. comol

    (32)

    Почему CI не может быть с одной веткой?

    CI придумали чтобы решить проблему слияния веток… и внедряют для решения этой проблемы главным образом.

    Reply ↓
  34. JohnyDeath

    (33) а мне казалось, что важнее было решить проблемы интеграции всех наработок в одну кучу и оценки ее качества и работоспособности. С одной веткой таких проблем тоже хватает.

    Reply ↓
  35. Labotamy

    (33)CI придумали для того, чтобы максимально быстро узнавать о том, что новый код сломал старый…. А как там слияние проходит, особенно в 1с, вопрос десятый… Если так коробит от сочетания CI и 1с можно назвать это как нить еще. Ну и уже привыкли что в 1с все «особенное». И mrg в EDT будет «особенный» и git-flow будет EDT-flow.

    Reply ↓
  36. Evil Beaver

    (26)

    ребята «не из мира 1С» очень сильно этому удивились бы

    чему «этому» бы они удивились?

    Reply ↓
  37. Gureev

    (33) Чот не пойму, как CI решает проблему конфликтов при слияния? Какая еще проблема слияния веток?

    Reply ↓
  38. comol

    (34) С одной веткой «коммит» не «испортит билд». А у ребят с gitflow это сплош и рядом

    Reply ↓
  39. comol

    (35)

    как там слияние проходит, особенно в 1с, вопрос десятый

    Так в том то и вопрос что никак не проходит… нет его в 1С… что бы там не говорили выше

    Reply ↓
  40. Gureev

    (40) причем тут 1с? я спросил про гит

    Reply ↓
  41. ekaruk

    Спасибо за упоминание InternetMail. Уже про него слышала, на как-то руки не доходили.

    Посмотрела и перешла наконец на него с самодельного VBS скрипта. Действительно, удобнее.

    Reply ↓
  42. comol

    (41) эээ.. ну это можно в книжках прочитать конечно. Но общий смысл в том что master у вас всегда в актуальном состоянии.

    Reply ↓
  43. JohnyDeath

    (38) мы, наверное, про что-то разное говорим )

    Правки одного разраба могут легко сломать что-то в другом месте, о котором о и не думал

    Reply ↓
  44. ivanov660

    Достаточно много действий. Можно же было создать обработку мастер установки развертывания CI с помощью этих утилит.

    Вижу концепт: открыл обработку мастер, жмешь далее, вводишь требуемые данные, ожидаешь процедуру скачивания файлов/применения настроек…. и в завершении получаешь профит)

    EDT пока сыроват и выполнять в нем полноценную работу в связке с GIT невозможно, ждем версию 1.8, в которой обещали поправить существующие явные «баги».

    Reply ↓
  45. Pavel_Dv

    Доброго всем!

    Может кто подскажет, как быть с internetmail?

    Пробовал настройку с несколькими серверами

    Родной exchange позволяет подключиться, но не позволяет отсылать. Как понимаю проблема в методе аутентификации SMTP «Безаутентификации».

    Отметил проблему в репозитории разработчика

    https://github.com/dmpas/oscript-mail/issues/16

    Затем пробовал с mail.ru, снова фиаско

    {Модуль C:Scripts est.os / Ошибка в строке: 40 / Внешнее исключение (MailKit.S

    ecurity.AuthenticationException): AuthenticationInvalidCredentials: Authenticati

    on failed. Please verify your account by going to https://e.mail.ru/login?email=...

    С google удается приконнектиться по POP3 (и то после включения двухфакторной аутентификации и генерации отдельного пароля для приложения)

    Но при попытке отправки он шлет куда подальше с

    «gmail the smtp server has unexpectedly disconnected»

    Была надежда, что автор поправил пакет в версии 1.05. Она недоступна для получения из репозитория, но легко качается с github и устанавливается из пакета.

    Но нет, 1.05 вообще отказалась работать.

    Были ли примеры успешной настройки и отправки через internetmail? С oneScript только знакомлюсь, может что не так делаю

    PS завел через пакет tmail, лучше чем ничего.

    Но все же интересен пакет internetmail

    Reply ↓
  46. Pavel_Dv

    И сразу еще один вопрос.

    Если хранилище поднято по tcp у кого-то удалось подключиться?

    Выдает ошибку

    «Модуль C:ScriptsOneScriptlibv8runnersrcv8runner.os / Ошибка в строке: 1105 / Ошибка связывания с хранилищем конфигурации по адресу: tcp://S01-1C07:2042/erp_pm2 Соединение с хранилищем конфигурации не установлено Ошибка связывания с хранилищем конфигурации по адресу: tcp://S01-1C07:2042/erp_pm2 Соединение с хранилищем конфигурации не установлено Ошибка обновления конфигурации из хранилища } ВызватьИсключение ВыводКоманды();»

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *