Делаем простую систему непрерывной интеграции (CI) c OneSсript, xUnitFor1C и v8LogScanner
1C-admin
15.01.2018
Практика программирования, Разработка
включает, всеми, данном, для, и, каталога, момент, на, написания, подготовленного, пример, Рабочий, скрипта, скриптом, со, утилитами
Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.
В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "///// echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1.
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.
Собственно сам скрипт:
<?php // Полная загрузка сервисных книжек, создан 2024-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='\
Здорово, спасибо, что пользуетесь. 2 вопроса:
1. Почему руками прописываем путь в переменную PATH? Инсталлятор делает это автоматически
2. Не увидел, как человек получит к себе на машину «деплойку»? Деплойка также ставится через opm.
(1) насколько я понял, деплойка тут и не используется.
(2) Аа, действительно. Она лишь в начале, как совет. Ок.
(1)
У меня не прописалась. Возможно она не прописывается под неполными правами?
(4) А зачем вообще в PATH прописывать? Все равно в шаге 9 полный путь к exe. Так же можно написать в шаге 8. Даже лучше, чтоб строки совпадали. А то oscript и C:Program…oscript.exe могут быть разными, что может принести сюрприз при отладке.
(0) Каким образом получаете/генерируете отчет в почту?
Делаете анализ отчет xUnitFor1C, разборку его и т.п.?
PS Спасибо за использование нашего продукта xUnitFor1C 🙂
Да, использую ГенераторОтчетаJUnitXML
Я что-то упустил в этой жизни или Обновление базы скриптом и автотесты теперь называют непрерывной интеграцией?
Не говоря уже о том что с хранилищем 1С она особенно актуальна! А то мы так страдаем когда мёрджим различные ветки хранилища :))))))))))
(8) А причем здесь мерж? здесь главное от CI — непрерывная/периодическая проверка/тестирование изменений разработчиков
(8)
Не просто обновление базы скриптом и автотесты, а ежедневное обновление базы скриптом + автотесты по итогам мерджей + интегральная оценка качества. Вроде, про это же речь в статье.
Вы удивитесь, но довольно много косяков вылезает просто по итогам слияния веток.
(9)
Интересно что значит слово «Интеграция» в словосочетании «Непрерывная интеграция»? :)))
на xUnitFor1C много тестов написано для ваших конфигураций?
Сами тесты можно поДсмотреть где-нибудь ?
(11) десять команд пилят сорок компонент, потом все это из разных веток хаотично вливается в ствол релиза. Работает оно?
А пес его знает…
Поэтому вся эта мешанина автоматически собирается и тестируется в комплексе. Т.е. «интегрируется» между собой.
Применительно к 1С: — 1С-ники пишут что-то в хранилище, ни в жизнь не тестируют перед коммитом, «я всего одну строчку исправил». Потом в течении 10-15 минут после коммита автор получает в почту отчет со словами «ААА, фсе сломал, гаденыш!» И результаты прогона тестов.
У нас на 2 базах используются тесты. Сейчас это 3 теста.
Первый тест тестирует функцию печати различных печатных форм, второй — выборочное проведение документов из журнала «Реестр торговых документов» и отражения их в БУ (с отменой транзакции), третий — то же, что и второй только по производственным документам.
Этого маловато конечно, но главное, что работает система, а добавление новых тестов — это дело времени.
Скм код тестов не тайна. Я приложил их к сообщению.
(10)
нет в 1с меджей… без EDT нет.
(10)
и непрерывное — это по-моему несколько разные вещи…
(13)
это автоматизированное тестирование всё-таки а не непрерывная интеграция.
в статье нет привязки к коммиту.
CI всё-таки подразумевает наличие ветвлений… Без веток оно не так и нужно… Не говоря уже о другой проблеме — 100% покрытия тестами в 1С не достигнешь да и не нужно оно…
(14)
Их прогон дело времени… Добавление то фигня. И вот тут возникает вопрос…
(17) что за лютое сопротивление Олег. CI нет, интеграция тебе не интеграция. Тестов нет вообще и не нужны. Ты чего это ? Тебя на работе заставляют все таки сервер сборок запускать ? И ты готовишь аргументы против ?
P.S. И merge в 1С есть, просто ты не в курсе (без EDT)
(15) И самого 1С нет — его не существует. И Владислава тоже нет — он всего лишь наша выдумка.
(15)
Ещё как есть: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
(16) если есть CI-сервер, значит в каком-то виде есть и CI. Понятно, что терминология в данном случае не будет 100% верной, но это больше буквоедство, нежели существенная проблема. 1С, например, судя по их статье на Хабре запросто даже мержит ветки-хранилища ERP в общий ствол с помощью СППР. Я слабо себе представляю как это можно делать, не сойдя с ума, но наверное можно. Уже много лет у них этот процесс. Так что и CI им пригодится.
(20) Олег, практически нигде не говорится про ветки и CI. Главное — помещать свои изменения в рабочий ствол и интегрироваться с другими разрабами, системами и прочее.
например, Википедию почитать, первый же абзац
Непрерывная интеграция является одним из основных приёмов экстремального программирования.
(20) если процесс подразумевает мердж раз в день и действие данного правила непрерывается, то значит оно непрерывно.
(18) Выше ссылка на ИТС и было на Хабре. В 1С есть merge без EDT. Но в мою голову он не помещается, к сожалению. Хотя ERP разрабатывается много лет и успешно в таком виде. Значит оно работает.
Ну и я накину, разве в EDT есть merge работающий? В документации он конечно есть, в пунктах меню тоже, но вот что-б он работал такого нет.
я не про извращения писал… я про ветвления….
хм. ну да по классике видимо так :). Но я думаю ребята «не из мира 1С» очень сильно этому удивились бы
(22)
я даже как-то не знаю…. :)))
(18)
Нуу… так скажем я очень хотел CI. Посвятил этому достаточно много времени….
Потом пытался понять почему «успешно зашло web-ерам» и «нихрена не зашло 1С-никам».
Тут дело не в том что мы 1С-ники.
CI спасает от веток и постоянных Merge-ей. У нас ветка одна.
CI спасает когда весь код покрыт тестами. Удачи вам в покрытии всего кода ERP.
Прочитал у SAP-ёров почему не зашло с тестами. Понял что в 1С у нас… до EDT по крайней мере CI не прокатит :(.
Ну по крайней мере я нормального решения не нашел. То, что описал коллега выше — профанация и определённый род извращений.
Вцелом наверное полезный, но не CI.
(24) Мне коллеги из CarMoney рассказывали про этот «Merge». Они его юзают и с СППР.
Это не совсем то, что я видел у Web-еров… Временные затраты настолько чудовищны, что CI назвать язык не поворачивается.
Но да — позволяет редактировать один объект 2-м разработчикам (в теории) и систематизирует процесс выпуска фич.
(25) Нуу… он же должен когда то появиться…. иначе на кой…. (цензура) EDT нужен?
Я так понял EDT = здравствуй GitFlow и здравствуй CI/CD (хотя тоже не уверен).
(18) Автотесты то у меня конечно есть… Сервер сборок тоже будет, только не у 1С части. Уже в очередной раз не у 1С части….
(28)
а оно вообще пыталось заходить?
Вон только с десяток-другой энтузиастов делают тесты и фрейморки к ним в 1С. И все заходит вроде бы.
Т.е. основная масса одинэсников вообще не знает что такое тесты и с чем его едят, а ты про какое-то «незашло»
Так и не понял при чем тут CI и ветки. Почему CI не может быть с одной веткой?
(32)
CI придумали чтобы решить проблему слияния веток… и внедряют для решения этой проблемы главным образом.
(33) а мне казалось, что важнее было решить проблемы интеграции всех наработок в одну кучу и оценки ее качества и работоспособности. С одной веткой таких проблем тоже хватает.
(33)CI придумали для того, чтобы максимально быстро узнавать о том, что новый код сломал старый…. А как там слияние проходит, особенно в 1с, вопрос десятый… Если так коробит от сочетания CI и 1с можно назвать это как нить еще. Ну и уже привыкли что в 1с все «особенное». И mrg в EDT будет «особенный» и git-flow будет EDT-flow.
(26)
чему «этому» бы они удивились?
(33) Чот не пойму, как CI решает проблему конфликтов при слияния? Какая еще проблема слияния веток?
(34) С одной веткой «коммит» не «испортит билд». А у ребят с gitflow это сплош и рядом
(35)
Так в том то и вопрос что никак не проходит… нет его в 1С… что бы там не говорили выше
(40) причем тут 1с? я спросил про гит
Спасибо за упоминание InternetMail. Уже про него слышала, на как-то руки не доходили.
Посмотрела и перешла наконец на него с самодельного VBS скрипта. Действительно, удобнее.
(41) эээ.. ну это можно в книжках прочитать конечно. Но общий смысл в том что master у вас всегда в актуальном состоянии.
(38) мы, наверное, про что-то разное говорим )
Правки одного разраба могут легко сломать что-то в другом месте, о котором о и не думал
Достаточно много действий. Можно же было создать обработку мастер установки развертывания CI с помощью этих утилит.
Вижу концепт: открыл обработку мастер, жмешь далее, вводишь требуемые данные, ожидаешь процедуру скачивания файлов/применения настроек…. и в завершении получаешь профит)
EDT пока сыроват и выполнять в нем полноценную работу в связке с GIT невозможно, ждем версию 1.8, в которой обещали поправить существующие явные «баги».
Доброго всем!
https://github.com/dmpas/oscript-mail/issues/16
Может кто подскажет, как быть с internetmail?
Пробовал настройку с несколькими серверами
Родной exchange позволяет подключиться, но не позволяет отсылать. Как понимаю проблема в методе аутентификации SMTP «Безаутентификации».
Отметил проблему в репозитории разработчика
Затем пробовал с mail.ru, снова фиаско
https://e.mail.ru/login?email=.. .
{Модуль C:Scripts est.os / Ошибка в строке: 40 / Внешнее исключение (MailKit.S
ecurity.AuthenticationException): AuthenticationInvalidCredentials: Authenticati
on failed. Please verify your account by going to
С google удается приконнектиться по POP3 (и то после включения двухфакторной аутентификации и генерации отдельного пароля для приложения)
Но при попытке отправки он шлет куда подальше с
«gmail the smtp server has unexpectedly disconnected»
Была надежда, что автор поправил пакет в версии 1.05. Она недоступна для получения из репозитория, но легко качается с github и устанавливается из пакета.
Но нет, 1.05 вообще отказалась работать.
Были ли примеры успешной настройки и отправки через internetmail? С oneScript только знакомлюсь, может что не так делаю
PS завел через пакет tmail, лучше чем ничего.
Но все же интересен пакет internetmail
И сразу еще один вопрос.
Если хранилище поднято по tcp у кого-то удалось подключиться?
Выдает ошибку
«Модуль C:ScriptsOneScriptlibv8runnersrcv8runner.os / Ошибка в строке: 1105 / Ошибка связывания с хранилищем конфигурации по адресу: tcp://S01-1C07:2042/erp_pm2 Соединение с хранилищем конфигурации не установлено Ошибка связывания с хранилищем конфигурации по адресу: tcp://S01-1C07:2042/erp_pm2 Соединение с хранилищем конфигурации не установлено Ошибка обновления конфигурации из хранилища } ВызватьИсключение ВыводКоманды();»