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

21.06.23

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

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

Скачать файл

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

Наименование По подписке [?] Купить один файл
Автоматизация обновления до последнего релиза: Расширение с веб-сервисом
.cfe 9,07Kb
3
3 Скачать (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    23618    20    4    

320

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

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

4900 руб.

29.06.2022    12509    106    4    

138

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

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

3000 руб.

05.08.2024    1675    17    1    

11

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

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

2160 руб.

20.01.2022    8157    24    0    

14

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

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

2400 руб.

04.07.2022    8728    39    1    

30

Обновление 1С Программист Платформа 1С v8.3 1С:Управление торговлей 10 Россия Бухгалтерский учет Налоговый учет Управленческий учет ИП, ПБОЮЛ, КФХ НДС УСН Абонемент ($m)

Обновление, доработка для 1С: Управление торговлей 10.3 (УТ 10.3) организаций на упрощенной системе с 2025 года для использования ставок НДС 5 и 7 % в документах и печатных формах документов. Начиная с релиза 10.3.40.

4 стартмани

10.01.2025    1834    41    zhuravlev_as    37    

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