В прошлый раз мы заглянул под капотом Статических веб-приложений, мы обнаружили контейнер Docker, который позволил нам делать пользовательские развертывания. Это, однако, оставило нас с проблемой, когда мы могли создать постановку обстановки, но не могли бы совсем назвать ее день, когда мы не могли убрать после себя.
Есть больше для пользовательских развертываний
Дальнейшая проверка действий Действия GitHub показала, что есть еще одно действие, которое мы могли бы потенциально использовать, чтобы получить полное преимущество пользовательских рабочих процессов. Это называется «Закрыть»:
name: Azure Static Web Apps CI/CD .... jobs: close_pull_request_job: ... bunch of conditions here action: "close" # that is our hint!
С приведенным вышеупомянутым, мы можем сделать образованный догадка о том, как вызовить его с Docker:
docker run -it --rm \ -e INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN=\ -e DEPLOYMENT_PROVIDER=DevOps \ -e GITHUB_WORKSPACE="/working_dir" \ -e IS_PULL_REQUEST=true \ -e BRANCH="TEST_BRANCH" \ -e ENVIRONMENT_NAME="TESTENV" \ -e PULL_REQUEST_TITLE="PR-TITLE" \ mcr.microsoft.com/appsvc/staticappsclient:stable \ ./bin/staticsites/StaticSitesClient close --verbose
Бег это действительно закрывает окружающую среду. Вот и все!
Можем ли мы построить трубопровод ADO?
Просто запущенные контейнеры Docker на самом деле не так полезны, поскольку эти действия предназначены для трубопроводов CI/CD. К сожалению, нет ни одного файла конфигурации, который мы можем редактировать, чтобы достичь его с помощью Azure DEVOPS: нам придется взять немного больше рук на подход. Примерно решение выглядит так:
Во-первых, мы создадим Филиал политика Чтобы загнать развертывание до обстановки окружающей среды. Тогда мы будем использовать Сервисный крючок Чтобы вызвать функцию Azure на успешном PR Merge. Наконец, Совместные стандартные статические веб-приложения Задача будет работать на Мастер
ветвь, когда новый коммит продвигается.
Филиал Политика
Создание сама политика филиала очень проста: сначала нам понадобится отдельное определение трубопровода:
pr: - master pool: vmImage: ubuntu-latest steps: - checkout: self - bash: | docker run \ --rm \ -e INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN=$(deployment_token) \ -e DEPLOYMENT_PROVIDER=DevOps \ -e GITHUB_WORKSPACE="/working_dir" \ -e IS_PULL_REQUEST=true \ -e BRANCH=$(System.PullRequest.SourceBranch) \ -e ENVIRONMENT_NAME="TESTENV" \ -e PULL_REQUEST_TITLE="PR # $(System.PullRequest.PullRequestId)" \ -e INPUT_APP_LOCATION="." \ -e INPUT_API_LOCATION="./api" \ -v ${PWD}:/working_dir \ mcr.microsoft.com/appsvc/staticappsclient:stable \ ./bin/staticsites/StaticSitesClient upload
Здесь мы используем PR-триггер, а также некоторые переменные, чтобы протолкнуть к Azure Static Web Apps. Кроме того, это простое докер, которое мы уже имели успех. Чтобы подключить это, нам нужен Создание проверки
Убедитесь, что это будет вызвать этот трубопровод:
Определение трубопровода разрыва
Вторая часть немного сложнее и требует функции Azure, чтобы снять. Давайте начнем с определения трубопровода, который будет работать наша функция:
trigger: none pool: vmImage: ubuntu-latest steps: - script: | docker run --rm \ -e INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN=$(deployment_token) \ -e DEPLOYMENT_PROVIDER=DevOps \ -e GITHUB_WORKSPACE="/working_dir" \ -e IS_PULL_REQUEST=true \ -e BRANCH=$(PullRequest_SourceBranch) \ -e ENVIRONMENT_NAME="TESTENV" \ -e PULL_REQUEST_TITLE="PR # $(PullRequest_PullRequestId)" \ mcr.microsoft.com/appsvc/staticappsclient:stable \ ./bin/staticsites/StaticSitesClient close --verbose displayName: 'Cleanup staging environment'
Одно следует отметить здесь, это ручной триггер — мы отказываемся от CI/CD. Затем мы отмечаем записку переменных среды, которые наша функция должна заполнить.
Функция Azure
Это действительно не имеет значения, какую функцию мы создаем. В этом случае мы выбираем C # код, который мы можем автор прямо из портала для простоты. Нам также надо генерировать пэт Таким образом, наша функция может позвонить ADO.
#r "Newtonsoft.Json" using System.Net; using System.Net.Http.Headers; using System.Text; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; private const string personalaccesstoken = ""; private const string organization = " "; private const string project = " "; private const int pipelineId = ; public static async Task Run([FromBody]HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); log.LogInformation($"eventType: {data?.eventType}"); log.LogInformation($"message text: {data?.message?.text}"); log.LogInformation($"pullRequestId: {data?.resource?.pullRequestId}"); log.LogInformation($"sourceRefName: {data?.resource?.sourceRefName}"); try { using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", ToBase64(personalaccesstoken)); string payload = @"{ ""variables"": { ""System.PullRequest.SourceBranch"": { ""isSecret"": false, ""value"": """ + data?.resource?.sourceRefName + @""" }, ""System.PullRequest.PullRequestId"": { ""isSecret"": false, ""value"": "+ data?.resource?.pullRequestId + @" } } }"; var url = $"https://dev.azure.com/{organization}/{project}/_apis/pipelines/{pipelineId}/runs?api-version=6.0-preview.1"; log.LogInformation($"sending payload: {payload}"); log.LogInformation($"api url: {url}"); using (HttpResponseMessage response = await client.PostAsync(url, new StringContent(payload, Encoding.UTF8, "application/json"))) { response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync(); return new OkObjectResult(responseBody); } } } catch (Exception ex) { log.LogError("Error running pipeline", ex.Message); return new JsonResult(ex) { StatusCode = 500 }; } } private static string ToBase64(string input) { return Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", input))); }
Сервисный крючок
Со всей подготовленной работой все, что мы оставили сделать, это подключить PR Merge событие для функции Call:
Функциональный URL должен содержать ключ доступа, если это было определено. Самый простой, вероятно, скопировать его прямо из портала Код + тест
лезвие:
Это также может быть хорошая идея для проверки соединения во второй форме, прежде чем заканчиваться.
Вывод
После того, как все подключено, трубопроводы должны создавать/удалять промежуточные среды, аналогичные, что делает GitHub. Одним из возможных улучшений, которые мы могли бы потенциально делать, было бы заменить политику филиала еще одним сервисным крюком для функции, чтобы название PR правильно отражено на портале.
Но я оставлю это как проблему для читателей для завершения.
Оригинал: «https://dev.to/timur_kh/azure-static-web-apps-adding-pr-support-to-azure-devops-pipeline-23k7»