Автоматизация обновления до последнего релиза

21.06.23

Разработка - DevOps и автоматизация разработки

Это механизм, который автоматически обновляет базы 1С до последнего релиза, при разработке в 1С:Enterprise Development Tools c использованием распределённой системы управления версиями GIT.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Автоматизация обновления до последнего релиза: Расширение с веб-сервисом
.cfe 9,07Kb
2
2 Скачать (1 SM) Купить за 1 850 руб.
Автоматизация обновления до последнего релиза: Файл скрипта на OneScript
.os 23,59Kb
1
1 Скачать (1 SM) Купить за 1 850 руб.

Введение.

Эта статья подойдет для тех, кто имеет по крайней мере базовые знания и навык работы с git. Она разработана для разработки с помощью модели ветвления Git Flow.

Формат версии конфигурации 1С это A.B.C.[h], где:

  • A – главный номер версии (major version number).
  • B – вспомогательный номер версии (minor version number).
  • C – номер сборки, номер логической итерации по работе над функционалом версии A.B (build number).
  • h – Немедленные изменения/исправления конфигурации (hotfix branches), при которых конфигурация обновляется вручную (незапланированно), и не приводят к автоматическому обновлению конфигурации.

Представленный механизм так же подойдет для интеграции в среду Jenkins, но выходит за пределы темы статьи и рассматриваться не будет.

Итак, начнем!

В конфигурацию нужно добавить http-сервис, с корневым url - api. Добавим ему шаблон "/v1/{action}/" с методом GET. Обработчик у метода будет следующий:

	Action = НРег(Запрос.ПараметрыURL["action"]);

	Если Action = "version" Тогда
		HTTPОтвет = Новый HTTPСервисОтвет(200);
		HTTPОтвет.УстановитьТелоИзСтроки(Метаданные.Версия);
		Возврат HTTPОтвет;
	ИначеЕсли Action = "telegram" И Не Запрос.Заголовки.Получить("Text") = Неопределено Тогда
		HTTPСоединение = Новый HTTPСоединение("api.telegram.org", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
		ПараметрыЗапроса = Новый Соответствие;
		Текст = Запрос.Заголовки.Получить("Text");
		ПараметрыЗапроса.Вставить("Content-type", "application/json");
		TelegramBotID = Константы.Update_TelegramBotID.Получить();
		TelegramChatID = Константы.Update_TelegramChatID.Получить();
		Если ЗначениеЗаполнено(TelegramBotID) И ЗначениеЗаполнено(TelegramChatID) Тогда
			МассивЧатов = СтрРазделить(TelegramChatID, ";");
			Для Каждого ЧатID Из МассивЧатов Цикл
				HTTPЗапрос = Новый HTTPЗапрос(TelegramBotID + "/sendMessage?chat_id=" + ЧатID
					+ "&parse_mode=html&text=" + Текст, ПараметрыЗапроса);
				HTTPСоединение.Получить(HTTPЗапрос);
			КонецЦикла;
		КонецЕсли;
		HTTPОтвет = Новый HTTPСервисОтвет(200);
		Возврат HTTPОтвет;
	ИначеЕсли Action = "disconnect" Тогда

		Port = Запрос.Заголовки.Получить("Port");
		MainPort = Запрос.Заголовки.Получить("MainPort");
		AgentSrv = Запрос.Заголовки.Получить("AgentSrv");
		BaseName = Запрос.Заголовки.Получить("BaseName");
		login = Запрос.Заголовки.Получить("login");
		password = Запрос.Заголовки.Получить("password");

		СистемнаяИнфо = Новый СистемнаяИнформация;
		ПодстрокиВерсии = СтрРазделить(СистемнаяИнфо.ВерсияПриложения, ".");
		COMСоединитель = Новый COMОбъект("v" + ПодстрокиВерсии[0] + ПодстрокиВерсии[1] + ".COMConnector");

		СтрокаСоединенияСАгентомСервера = "tcp://" + AgentSrv + ":" + Port;
		СоединениеСАгентомСервера = COMСоединитель.ConnectAgent(СтрокаСоединенияСАгентомСервера);

		ПеремКластер = Неопределено;
		Для Каждого Кластер Из СоединениеСАгентомСервера.GetClusters() Цикл
			Если Формат(Кластер.MainPort, "ЧГ=0;") = MainPort Тогда
				СоединениеСАгентомСервера.Authenticate(Кластер, login, password);
				ПеремКластер = Кластер;
				Прервать;
			КонецЕсли;
		КонецЦикла;

		Если ПеремКластер = Неопределено Тогда
			HTTPОтвет = Новый HTTPСервисОтвет(400);
			HTTPОтвет.УстановитьТелоИзСтроки("ERROR: Не удалось найти кластер");
			Возврат HTTPОтвет;
		КонецЕсли;

		ПеремОписаниеИнформационнойБазы = Неопределено;
		Для Каждого ОписаниеИнформационнойБазы Из СоединениеСАгентомСервера.GetInfoBases(ПеремКластер) Цикл
			Если НРег(ОписаниеИнформационнойБазы.Name) = НРег(BaseName) Тогда
				ПеремОписаниеИнформационнойБазы = ОписаниеИнформационнойБазы;
				Прервать;
			КонецЕсли;
		КонецЦикла;

		Если ПеремОписаниеИнформационнойБазы = Неопределено Тогда
			HTTPОтвет = Новый HTTPСервисОтвет(400);
			HTTPОтвет.УстановитьТелоИзСтроки("ERROR: Не удалось найти базу");
			Возврат HTTPОтвет;
		КонецЕсли;

		ВсеПользователи = Истина;
		Сеансы = СоединениеСАгентомСервера.GetInfoBaseSessions(ПеремКластер, ПеремОписаниеИнформационнойБазы);
		Для Каждого Сеанс Из Сеансы Цикл
			Попытка
				СоединениеСАгентомСервера.TerminateSession(ПеремКластер, Сеанс);
			Исключение
				ВсеПользователи = Ложь;
			КонецПопытки;
		КонецЦикла;
		Если Не ВсеПользователи Тогда
			HTTPОтвет = Новый HTTPСервисОтвет(400);
			HTTPОтвет.УстановитьТелоИзСтроки("ERROR: Не удалось отключить всех пользователей");
			Возврат HTTPОтвет;
		КонецЕсли;
		HTTPОтвет = Новый HTTPСервисОтвет(200);
		Возврат HTTPОтвет;
	ИначеЕсли Action = "check" Тогда
		HTTPОтвет = Новый HTTPСервисОтвет(?(Константы.Update_ЗапретАвтообновления1С.Получить(), 400, 200));
		Возврат HTTPОтвет;
	КонецЕсли;
	
	HTTPОтвет = Новый HTTPСервисОтвет(200);
	Возврат HTTPОтвет;

далее короткое описание для каждого Action в методе:

  1. version - Основной метод, возвращает текущую версию конфигурации
  2. telegram - метод, который оповещает о процессе обновления, с помощью bota. Можно заменить на оповещения по электронной почте, смс и тд.
  3. disconnect - метод, который завершает работу пользователей перед обновлением (позволяет отключать пользователей в конфигурациях без БСП)
  4. check - метод, в который можно добавить нужные проверки перед обновлением. Например, проверку создания backup обновляемой базы, дня недели, выполнение важных регламентных заданий при которых нельзя обновлять конфигурацию и тд

Следующим пунктом опишем скрипт, который выполняет обновление баз. Он запускается с помощью скриптового языка OneScript.

Файл update1C.os

#Использовать irac
#Использовать cmdline
#Использовать 1commands

Функция ПолучитьМассивБазДляОбновления()

	МассивНастроеек = Новый Массив();
		
	МассивБазДляОбновления = Новый Массив();
	СтруктураНастроеек = Новый Структура();
	//Расположение проекта 
	СтруктураНастроеек.Вставить("КаталогПроекта", "C:\Users\admin\git\test_base_1");
	//Файлы конфигурации проекта edt
	СтруктураНастроеек.Вставить("PROJECT", "C:\Users\admin\git\test_base_1\conf");
	
	БазаДанных = Новый Структура();
	//Заголовок для сообщения в телеграмме
	БазаДанных.Вставить("Заголовок", " TEST UPDATE BASE");
	//Сервер публикации информационной базы
	БазаДанных.Вставить("СерверHttp", "localhost");
	//Сервер БД
	БазаДанных.Вставить("СерверБазыДанных", "192.168.1.1\SQL1");
	//Кластер сервера 
	БазаДанных.Вставить("СерверКластера", "localhost");
	//Имя базы данных
	БазаДанных.Вставить("ИмяБазыДанных", "test_developer");
	//Пользователь БД
	БазаДанных.Вставить("ПользовательБазыДанных", "sql_login");
	//Пароль пользователя БД
	БазаДанных.Вставить("ПарольБазыДанных", "sql_password");
	//Пользователь 1С
	БазаДанных.Вставить("Пользователь1С", "update1C");
	//Пароль пользоватлея 1С
	БазаДанных.Вставить("Пароль1С", "update1C");
	//URL http-сервиса
	БазаДанных.Вставить("АдресHttp", "test_developer/hs/api/v1");
	//Порт агента сервера
	БазаДанных.Вставить("Port", "1540");
	//Порт менеджера кластрера
	БазаДанных.Вставить("MainPort", "1541");
	//Логин кластера сервера 1С
	БазаДанных.Вставить("ClustersLogin", "log");
	//Пароль кластера сервера 1С
	БазаДанных.Вставить("ClustersPassword", "pswd");
	МассивБазДляОбновления.Добавить(БазаДанных);
	
	БазаДанных = Новый Структура();
	БазаДанных.Вставить("Заголовок", " TEST UPDATE BASE 2");
	БазаДанных.Вставить("СерверHttp", "localhost");
	БазаДанных.Вставить("СерверБазыДанных", "192.168.1.2\SQL2");
	БазаДанных.Вставить("СерверКластера", "localhost");
	БазаДанных.Вставить("ИмяБазыДанных", "test_developer2");
	БазаДанных.Вставить("ПользовательБазыДанных", "sql_login");
	БазаДанных.Вставить("ПарольБазыДанных", "sql_password");
	БазаДанных.Вставить("Пользователь1С", "update1C");
	БазаДанных.Вставить("Пароль1С", "update1C");
	БазаДанных.Вставить("АдресHttp", "test_developer2/hs/api/v1");
	БазаДанных.Вставить("Port", "1540");
	БазаДанных.Вставить("MainPort", "1541");
	БазаДанных.Вставить("ClustersLogin", "log");
	БазаДанных.Вставить("ClustersPassword", "pswd");
	МассивБазДляОбновления.Добавить(БазаДанных);
		
	СтруктураНастроеек.Вставить("МассивБазДляОбновления", МассивБазДляОбновления);
	
	МассивБазДляОбновления = Новый Массив();
	СтруктураНастроеек = Новый Структура();
	СтруктураНастроеек.Вставить("КаталогПроекта", "C:\Users\admin\git\test_base_2");
	СтруктураНастроеек.Вставить("PROJECT", "C:\Users\admin\git\test_base_2\conf");
	
	БазаДанных = Новый Структура();
	БазаДанных.Вставить("Заголовок", " TEST UPDATE BASE 3");
	БазаДанных.Вставить("СерверHttp", "localhost");
	БазаДанных.Вставить("СерверБазыДанных", "192.168.1.3\SQL3");
	БазаДанных.Вставить("СерверКластера", "localhost");
	БазаДанных.Вставить("ИмяБазыДанных", "test_developer3");
	БазаДанных.Вставить("ПользовательБазыДанных", "sql_login");
	БазаДанных.Вставить("ПарольБазыДанных", "sql_password");
	БазаДанных.Вставить("Пользователь1С", "update1C");
	БазаДанных.Вставить("Пароль1С", "update1C");
	БазаДанных.Вставить("АдресHttp", "test_developer3/hs/api/v1");
	БазаДанных.Вставить("Port", "1540");
	БазаДанных.Вставить("MainPort", "1541");
	БазаДанных.Вставить("ClustersLogin", "log");
	БазаДанных.Вставить("ClustersPassword", "pswd");
	МассивБазДляОбновления.Добавить(БазаДанных);
		
	СтруктураНастроеек.Вставить("МассивБазДляОбновления", МассивБазДляОбновления);

	МассивНастроеек.Добавить(СтруктураНастроеек);
		
	Возврат МассивНастроеек;

КонецФункции

// Получает ветку текущего релиза
//
// Параметры:
//   ТекстовыйДокумент - ТекстовыйДокумент - данные по веткам
//	 АктуальнаяВерсияЧислом - Число - Версия текущего релиза числом
//
// Возвращаемое значение:
//  - Строка - Имя ветки текщего релиза
Функция ПолучитьНачалоЛога(ТекстовыйДокумент,АктуальнаяВерсияЧислом)

	Ветки = ТекстовыйДокумент.КоличествоСтрок();
	Для к=1 По Ветки Цикл
		Ветка = СокрЛП(ТекстовыйДокумент.ПолучитьСтроку(к));
		Если СтрНачинаетсяС(Ветка, "origin/release/") Тогда
			СтрокаВетки = СтрЗаменить(Ветка, "origin/release/", "");
			ПроверяемаяВерсия = ВерсияЧислом(СтрокаВетки);
			Если ПроверяемаяВерсия = АктуальнаяВерсияЧислом Тогда
				Возврат Ветка;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат "";
	
КонецФункции

// Преобразует строку версии в число, сокращая до 3-го разряда
//
// Параметры:
//   ВерсияСтрокой - Строка - Версия в формате ХХ.ХХ.ХХ.ХХ
//
// Возвращаемое значение:
//  - Число - Версия в числовом эквиваленте
Функция ВерсияЧислом(Знач ВерсияСтрокой)
	
	Разрядность = СтрНайти(ВерсияСтрокой, ".", , , 3);
	Если Разрядность > 0 Тогда
		ВерсияСтрокой = Лев(ВерсияСтрокой, Разрядность-1);
	КонецЕсли;

	Если ПустаяСтрока(ВерсияСтрокой) Или ВерсияСтрокой = "0.0.0.0" Тогда
		Возврат 0;
	КонецЕсли;
	
	Разряд = 0;
	
	Результат = 0;
	
	ОписаниеТипаЧисло = Новый ОписаниеТипов("Число");
	Остаток = ВерсияСтрокой;
	ПозицияТочки = СтрНайти(Остаток, ".");
	Пока ПозицияТочки > 0 Цикл
		ЧислоСтрокой = Лев(Остаток, ПозицияТочки - 1);
		Число = ОписаниеТипаЧисло.ПривестиЗначение(ЧислоСтрокой);
		Результат = Результат * 1000 + Число;
		Остаток = Сред(Остаток, ПозицияТочки + 1);
		ПозицияТочки = СтрНайти(Остаток, ".");
		Разряд = Разряд + 1;
	КонецЦикла;
	
	Число = ОписаниеТипаЧисло.ПривестиЗначение(Остаток);
	Результат = Результат * 1000 + Число;
	Разряд = Разряд + 1;
	
	// Номера версии после 4 точки возвращает после запятой.
	// Например, для версии "1.2.3.4.5.6.7" вернет 1002003004,005006007.
	Если Разряд > 4 Тогда
		Результат = Результат / Pow(1000, Разряд - 4);
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

//Глобальные переменные (общие для всех баз)
СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ = "🟢";
СМАЙЛ_КРАСНЫЙ_КРУГ = "🔴";
СМАЙЛ_ИТОГ_ЗЕЛЕНЫЙ = "c89;";
СМАЙЛ_ИТОГ_КРАСНЫЙ = "c40;";

WORKSPACE = "C:\Users\admin\git\WS";
XML = "C:\Users\admin\git\XML";
LOGFILE="C:\Users\admin\workspace\log.txt";
BRANCH="C:\Users\admin\workspace\branch.txt";
LOGCOMMIT="C:\Users\admin\workspace\log_commit.txt";
//xx.xxxx заменить на версию 1С (например 22.1923)
ibcmd = "C:\Program Files\1cv8\8.3.xx.xxxx\bin\ibcmd.exe";
dir_backup = "D:\BACKUP\";

МассивБаз = ПолучитьМассивБазДляОбновления();

Для Каждого СтруктураОбновления ИЗ МассивБаз Цикл
			
	Команда = Новый Команда;
	
	Релиз = "0.0.0";
	НачалоЛога = "";
	ОкончаниеЛога = "";
	
	ТекстовыйДокументBRANCH = Новый ТекстовыйДокумент;
	
	//Переходи в кактлог проекта и загружаем коммиты, скачиваем все удаленные ветки. 
	//	Ищем релизные и записываем их в файл
	Команда.УстановитьСтрокуЗапуска("cd " 
		+ СтруктураОбновления.КаталогПроекта
		+ " & git fetch & git branch -r |  find ""origin/release/"" > """
		+ BRANCH + """ 2>&1");
	КодВозврата = Команда.Исполнить();
	ТекстовыйДокументBRANCH.Прочитать(BRANCH);
	
	МаксВерсияЧислом = ВерсияЧислом("0.0.0");
	
	Ветки = ТекстовыйДокументBRANCH.КоличествоСтрок();
	Для к=1 По Ветки Цикл
		Ветка = СокрЛП(ТекстовыйДокументBRANCH.ПолучитьСтроку(к));
		Если СтрНачинаетсяС(Ветка, "origin/release/") Тогда
			СтрокаВетки = СтрЗаменить(Ветка, "origin/release/", "");
			ПроверяемаяВерсия = ВерсияЧислом(СтрокаВетки);
			Если ПроверяемаяВерсия > МаксВерсияЧислом Тогда
				МаксВерсияЧислом = ПроверяемаяВерсия;
				ОкончаниеЛога = Ветка;
				Релиз = СтрокаВетки;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

	//проверка что релиз обновился
	Если НЕ Релиз = "0.0.0" Тогда
	
		КонфигурацияГотоваКЗагрузке = Ложь;
	
		Для Каждого База ИЗ СтруктураОбновления.МассивБазДляОбновления Цикл
		
			HTTPСоединение = Новый HTTPСоединение(База.СерверHttp);
		
			Заголовки = Новый Соответствие();
			HTTPЗапрос = Новый HTTPЗапрос(База.АдресHttp + "/version", Заголовки);
			Результат = HTTPСоединение.Получить(HTTPЗапрос);
			
			//если сервис недоступен, проверяем след базу
			Если НЕ Результат.КодСостояния = 200 Тогда
				Продолжить;
			КонецЕсли;		
			
			АктуальнаяВерсия = Результат.ПолучитьТелоКакСтроку();
			АктуальнаяВерсияЧислом = ВерсияЧислом(АктуальнаяВерсия);
			
			//Начинаем формировать сообщения для отправки в теелграмм
			СообщениеТелеграм = " Релиз: " + Релиз + "</b>";
			
			Если АктуальнаяВерсияЧислом < МаксВерсияЧислом Тогда
				
				Если НЕ КонфигурацияГотоваКЗагрузке Тогда
						
					//Переключаемся на релизную ветку и обновляем ее с сервера
					Команда.УстановитьСтрокуЗапуска("cd " + СтруктураОбновления.КаталогПроекта 
						+ " & git checkout " + ОкончаниеЛога + " & git pull");
					КодВозврата_checkout = Команда.Исполнить();

					СообщениеТелеграм = СообщениеТелеграм + Символы.ПС 
						+ ?(КодВозврата_checkout <= 1, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
						+ " получение данных с GitHub";
					
					//Очищаем каталоги для сборки. Удалив их и создав заново
					Команда.УстановитьСтрокуЗапуска("rd /S /Q """ + WORKSPACE 
						+ """ & rd /S /Q """ + XML+ """");
					КодВозврата_rd = Команда.Исполнить();
						
					Команда.УстановитьСтрокуЗапуска("md """ + WORKSPACE 
						+ """ & md """ + XML+ """");
					КодВозврата_md = Команда.Исполнить();
					СообщениеТелеграм = СообщениеТелеграм + Символы.ПС 
						+ ?(КодВозврата_rd+КодВозврата_md = 0, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
						+ " подготовка структуры каталогов";

					//Экспорт проекта в xml-выгрузку конфигурации
					//xxxx.x.x заменить на версию edt (например 2022.2.5)
					Команда.УстановитьСтрокуЗапуска("ring edt@xxxx.x.x:x86_64 workspace export --project """
						+ СтруктураОбновления.PROJECT 
						+ """ --configuration-files """ + XML
						+ """ --workspace-location """ + WORKSPACE + """ >> """
						+ LOGFILE + """ 2>&1");
					КодВозврата_export = Команда.Исполнить();
					СообщениеТелеграм = СообщениеТелеграм + Символы.ПС 
						+ ?(КодВозврата_export = 0, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
						+ " выгрузка конфигурации в XML";

					КонфигурацияГотоваКЗагрузке = Истина;

				КонецЕсли;
				
				СообщениеЛогаКоммитов = "";
				КодВозврата_apply = 1;
				КодВозврата_import = 1;
				Если КонфигурацияГотоваКЗагрузке Тогда
				
					НачалоЛога = ПолучитьНачалоЛога(ТекстовыйДокументBRANCH, АктуальнаяВерсияЧислом);
					
					//получаем для отображения информацию о коммитах
					Если ЗначениеЗаполнено(НачалоЛога) И ЗначениеЗаполнено(ОкончаниеЛога) Тогда
						ТекстовыйДокумент = Новый ТекстовыйДокумент;
						Команда.УстановитьСтрокуЗапуска("cd " + СтруктураОбновления.КаталогПроекта 
							+ " & git shortlog --pretty=format:""%an: %b"" --merges "
							+ НачалоЛога + ".." + ОкончаниеЛога
							+ " --grep=""release"" --invert-grep > """ 
							+ LOGCOMMIT + """ 2>&1");
						КодВозврата_log = Команда.Исполнить();
						ТекстовыйДокумент.Прочитать(LOGCOMMIT);
						СообщениеЛогаКоммитов = Символы.ПС + "<code>Задачи в релизе:"
							+ Символы.ПС + ТекстовыйДокумент.ПолучитьТекст() + "</code>";
					КонецЕсли;
				
					//для удобства разделим в логе базы
					Команда.УстановитьСтрокуЗапуска("echo %date% " + База.ИмяБазыДанных 
						+ " >> """ + LOGFILE + """ 2>&1");
					КодВозврата = Команда.Исполнить();
				
					//Завершение работы активных пользователей
					Заголовки = Новый Соответствие();
					Заголовки.Вставить("Port",  База.Port);
					Заголовки.Вставить("MainPort",  База.MainPort);
					Заголовки.Вставить("BaseName",  База.ИмяБазыДанных);
					Заголовки.Вставить("login",  База.ClustersLogin);
					Заголовки.Вставить("password",  База.ClustersPassword);
					Заголовки.Вставить("AgentSrv",  База.СерверКластера);
					HTTPЗапрос = Новый HTTPЗапрос(База.АдресHttp + "/disconnect",Заголовки);
					Результат = HTTPСоединение.Получить(HTTPЗапрос);
					СообщениеТелеграмБаза = СообщениеТелеграм + Символы.ПС 
						+ ?(Результат.КодСостояния = 200, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
						+ " завершение активных сеансов";
					//получаем имя файла бекапа
					ИмяБД = База.ИмяБазыДанных;
					//если нужно добавлять, а не перезаписывать 
					//ИмяБД = База.ИмяБазыДанных+Формат(ТекущаяДата(),"ДФ=_ггггММдд");
					
					//Делаем бекап базы перед обновлением
					Команда.УстановитьСтрокуЗапуска("sqlcmd -S " + База.СерверБазыДанных
						+ " -U """ + База.ПользовательБазыДанных
						+ """ -P """ + База.ПарольБазыДанных
						+ """ -b -Q ""BACKUP DATABASE " + База.ИмяБазыДанных
						+ " TO DISK = N'"+dir_backup+ИмяБД+".bak' WITH COMPRESSION, NOFORMAT, INIT, NAME = N'"
						+ ИмяБД + "', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM"" >> """ + LOGFILE + """ 2>&1");
					КодВозврата_backup = Команда.Исполнить();
										
					Если КодВозврата_backup = 0 Тогда
						СообщениеТелеграмБаза = СообщениеТелеграмБаза + Символы.ПС
							+ ?(КодВозврата_backup = 0, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ)
							+ " BACKUP: " + ИмяБД;

						//Импорт конфигурации из XML с помощью утилиты ibcmd
						Команда.УстановитьСтрокуЗапуска(""""+ibcmd
							+""" infobase config import --dbms=MSSQLServer --db-server=" + База.СерверБазыДанных
							+ " --db-name=" + База.ИмяБазыДанных
							+ " --db-user="+База.ПользовательБазыДанных
							+ " --db-pwd="""+База.ПарольБазыДанных
							+ """ --user="+База.Пользователь1С
							+ " --password="+База.Пароль1С
							+ " """+XML+""" >> """+LOGFILE+""" 2>&1");
						КодВозврата_import = Команда.Исполнить();
						СообщениеТелеграмБаза = СообщениеТелеграмБаза + Символы.ПС
							+ ?(КодВозврата_import = 0, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
							+ " загрузка конфигурации в базу из XML";
						
						//Обновление конфигурации 
						Команда.УстановитьСтрокуЗапуска(""""+ibcmd
							+ """ infobase config apply --dbms=MSSQLServer --db-server="+База.СерверБазыДанных
							+ " --db-name="+База.ИмяБазыДанных
							+ " --db-user="+База.ПользовательБазыДанных
							+ " --db-pwd="""+База.ПарольБазыДанных
							+ """ --user="+База.Пользователь1С
							+ " --password="+База.Пароль1С
							+ " --force >> """+LOGFILE+""" 2>&1");
						КодВозврата_apply = Команда.Исполнить();
						СообщениеТелеграмБаза = СообщениеТелеграмБаза + Символы.ПС 
							+ ?(КодВозврата_apply = 0, СМАЙЛ_ЗЕЛЕНЫЙ_КРУГ, СМАЙЛ_КРАСНЫЙ_КРУГ) 
							+ " обновление конфигурации";	
					Иначе
						СообщениеЛогаКоммитов = "";
						СообщениеТелеграмБаза = СообщениеТелеграм + Символы.ПС 
							+ СМАЙЛ_КРАСНЫЙ_КРУГ + " ОШИБКА создания BACKUP";
					КонецЕсли;	
				Иначе
					СообщениеТелеграмБаза = СообщениеТелеграм + Символы.ПС 
						+ СМАЙЛ_КРАСНЫЙ_КРУГ + " ОШИБКА экспорта конфигурации в файл";					
				КонецЕсли;
								
				СообщениеТелеграмБаза = "<b>" + ?(КодВозврата_md+КодВозврата_export+КодВозврата_import+КодВозврата_apply = 0, 
					СМАЙЛ_ИТОГ_ЗЕЛЕНЫЙ, СМАЙЛ_ИТОГ_КРАСНЫЙ) 
					+ База.Заголовок + СообщениеТелеграмБаза + СообщениеЛогаКоммитов;
				
				//Отправка сообщения в телеграмм
				Заголовки = Новый Соответствие();
				Заголовки.Вставить("Text",  КодироватьСтроку(СообщениеТелеграмБаза, СпособКодированияСтроки.КодировкаURL));
				HTTPЗапрос = Новый HTTPЗапрос(База.АдресHttp + "/telegram",Заголовки);
				Результат = HTTPСоединение.Получить(HTTPЗапрос);
			
			КонецЕсли;
			
		КонецЦикла;	
		
	КонецЕсли;

КонецЦикла;

Краткое описание работы скрипта.

Сначала формируется список параметров и массив баз для обновления. В дальнейшем что бы добавить или удалить базу редактируем в файле функцию ПолучитьМассивБазДляОбновления. Далее получаем актуальные данные веток и коммитов из git-а (который подключен по ssh). Получаем текущий релиз базы (версию в 1С), и сравниваем его с релизными ветками (release/*). Если есть новый релиз, тогда переключаемся на ветку релиза и скачиваем изменения. Подготавливаем структуру каталогов и экспортируем в нее проект edt в виде xml файлов. Перед обновлением делаем бекап базы. Если все прошло без ошибок, тогда в каждую конфигурацию, из массива, мы загружаем данные проекта из xml-файлов, и обновляем ее. В самом конце отправляем сообщение из 1С в зависимости от настроек.

Пример.

Посмотрим, что получается в итоге. На примере, перехода с релиза 0.1.9 на 0.1.10 тестовой конфигурации. В каждой релизной ветке повышаем релиз (версию конфигурации) на следующий. На скриншоте видно, что после релиза 0.1.9 у нас было несколько коммитов, а также в релизной ветке мы изменили версию конфигурации на 0.1.10.

Запускаем выполнение скрипта командой из cmd или вешаем на планировщик заданий в ОС Windows. Например, запуск из командной строке выглядит так

oscript C:\scripts\update1C.os

После выполнения скрипта получаем сообщение в чат с ботом и обновленную конфигурацию до 0.1.10. На скриншоте видно что сначала скачиваются данные и из них обновляются первые 2 базы, при чем вторая с некритической ошибкой. А вот третяя база не обновлеяется из за ошибки создания бекапа.

Если что-то не работает, смотрим логи в файле %LOGFILE%

 

Ссылки:

EDT Git GitFlow release OneScript version автоматическое обновление HTTP-сервис Telegram Bot DevOps

См. также

DevOps для 1С DevOps и автоматизация разработки Программист Стажер Платные (руб)

Данный онлайн-курс (интенсив) предусматривает изучение процессов, инструментов и методик DevOps, их применение при разработке на платформе 1С. 

2500 руб.

20.06.2023    22261    2    4    

310

Зарплата Регламентированный учет и отчетность Кадровый учет Обновление 1С Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Зарплата и Управление Персоналом 2.5 Бухгалтерский учет Налоговый учет Управленческий учет Акцизы ЕНВД ЕСН Земельный налог ИП, ПБОЮЛ, КФХ Налог на имущество Налог на прибыль НДС НДФЛ ФОМС, ЕФС Транспортный налог УСН ПСН (патентная система налогообложения) Платные (руб)

Обновления для конфигураций: КА 1.1; ЗУП 2.5; БУХ 2.0; КА 1.1 Комплексная автоматизация торговли алкогольной продукцией; КА 1.1 Комплексный учет сельскохозяйственного предприятия

27900 руб.

01.04.2020    147091    649    360    

235

SALE! 50%

1С-программирование DevOps и автоматизация разработки Групповая разработка (Git, хранилище) DevOps для 1С Программист Стажер Платформа 1С v8.3 Платные (руб)

Использования систем контроля версий — стандарт современной разработки. На курсе научимся использованию Хранилища 1С и GIT при разработке на 1С:Предприятие 8. Разберем подходы и приемы коллективной разработки, научимся самостоятельно настраивать системы и ориентироваться в них.

4900 2450 руб.

29.06.2022    11930    99    4    

131

DevOps и автоматизация разработки Тестирование QA Программист Пользователь Платформа 1С v8.3 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Зарплата и Управление Персоналом 3 и версии КОРП: 3.1.30.57.

2160 руб.

05.08.2024    1275    12    1    

7

DevOps и автоматизация разработки Логистика, склад и ТМЦ Системный администратор Программист Руководитель проекта Платформа 1С v8.3 Конфигурации 1cv8 1С:Франчайзи, автоматизация бизнеса Платные (руб)

Подсистема «Управление сборкой GLI» предназначена для динамического формирования сборочных линий Gitlab и отслеживания процесса доработок систем на базе1С:Предприятия Позволяет упростить выпуск новых релизов системы, подготовить описание доработок системы. Интегрируется с GitLab API по событиям Push, Merge-request, Pipeline. Уведомляет пользователей о результатах сборки/тестирования сборочных конвейеров через СВ, либо при её недоступности или отсутствию по E-Mail. Поможет при отправке исправлений ошибок в общую базу тестирования, сформирует запросы на слияние в ветку версии только по протестированному и подтверждённому функционалу. Подсистема рассчитана исключительно на клиент - серверную архитектуру тестовых ИБ. Поддерживаемая версии СППР 2.0.4.15, платформа не ниже 8.3.17.1549, 2.0.7.3 / не ниже 8.3.21.1664, начиная с релиза 1.0.4.30 требуется платформа не ниже 8.3.23 рекомендуемый релиз 8.3.23.1997

7000 руб.

26.08.2022    12552    10    10    

35

Тестирование QA DevOps и автоматизация разработки Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Налоговый учет Платные (руб)

Готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарии возможно использовать как для vanessa-automation, так и для СППР. Поддерживаемые версии конфигураций ERP2 и КА2: 2.5.17.113.

2400 руб.

04.07.2022    8367    38    1    

29

Тестирование QA DevOps и автоматизация разработки Программист Пользователь Платформа 1С v8.3 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Налоговый учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Бухгалтерия предприятие 3.0 и версии КОРП: 3.0.156.30.

1800 руб.

20.01.2022    7782    19    0    

13
Оставьте свое сообщение