Ćwiczenie — kompilowanie wielu konfiguracji przy użyciu szablonów

Ukończone

W poprzednich ćwiczeniach zaimplementowano potok, który tworzy witrynę internetową Space Game . Rozpoczęto od skryptu, który wykonał każdą akcję kompilacji i zamapował każdą akcję na odpowiednie zadanie potoku. Dane wyjściowe potoku to plik .zip zawierający skompilowana aplikacja internetowa.

W tym ćwiczeniu użyjesz szablonu do zdefiniowania zadań kompilacji, które mogą tworzyć dowolną konfigurację zdefiniowaną w pliku projektu. Szablony umożliwiają zdefiniowanie logiki raz, a następnie ponowne użycie jej kilka razy. Szablony łączą zawartość wielu plików YAML w jeden potok.

Napiwek

Ten krok w module jest opcjonalny. Jeśli nie chcesz teraz dowiedzieć się więcej o szablonach, przejdź do następnego kroku, wyczyść środowisko usługi Azure DevOps. Aby uzyskać więcej informacji na temat szablonów, zobacz Typy szablonów i użycie.

Zacznijmy od zaewidencjonowania w Mara i Amita.

Pokaz

Mara, podekscytowana, aby podzielić się swoimi wynikami, śledzi Amitę, aby pokazać jej potok kompilacji.

Amita: Jestem pod wrażeniem, że to działa tak szybko! W rzeczywistości, po prostu przychodziłem, aby cię zobaczyć, ponieważ dostałem e-mail z informacją, że kompilacja była gotowa. Dziękujemy. Widzę, że potok kompiluje tylko konfigurację wydania. Używamy również kompilacji debugowania, abyśmy mogli przechwytywać dodatkowe informacje w przypadku awarii aplikacji. Czy możemy to dodać?

Mara: Absolutnie. Zapomniałem rozważyć kompilacje debugowania podczas konfigurowania. Jak usiąść razem i dodać go?

Amita: Pokazano mi plik YAML, który definiuje kroki kompilacji, ale nie jestem pewien, że wiem, jak go zmodyfikować.

Mara: To jest ok. Możesz oglądać podczas pisania. Możemy przez to myśleć razem.

Jak można zdefiniować obie konfiguracje kompilacji?

Rozważ następujące zadania, które kompilują i publikują konfigurację wydania projektu internetowego Space Game . (Nie dodawaj tego kodu do pliku azure-pipelines.yml ).

- task: DotNetCoreCLI@2
  displayName: 'Build the project - Release'
  inputs:
    command: 'build'
    arguments: '--no-restore --configuration Release'
    projects: '**/*.csproj'

- task: DotNetCoreCLI@2
  displayName: 'Publish the project - Release'
  inputs:
    command: 'publish'
    projects: '**/*.csproj'
    publishWebProjects: false
    arguments: '--no-build --configuration Release --output $(Build.ArtifactStagingDirectory)/Release'
    zipAfterPublish: true

Aby skompilować konfigurację debugowania, możesz powtórzyć te dwa zadania, ale zastąpić ciąg Release ciągiem Debug.

Dzięki temu otrzymasz wynik, którego szukasz, ale co się stanie, gdy kompilacja stanie się bardziej złożona lub zmienią się wymagania? Należy ręcznie zlokalizować i zmienić obie odmiany każdego zadania kompilacji. Po dodaniu dodatkowych wymagań dotyczących kompilacji należy również utworzyć dwa zadania— jedno dla konfiguracji debugowania i jedną dla wydania, aby spełnić te wymagania.

Lepszym rozwiązaniem jest użycie szablonu.

Co to są szablony?

Szablon umożliwia definiowanie typowych zadań kompilacji raz i wielokrotne używanie tych zadań.

W ramach kroku kompilacji wywołasz szablon z nadrzędnego potoku. Parametry można przekazać do szablonu z potoku nadrzędnego.

Mara może definiować zadania do kompilowania i publikowania aplikacji jako szablonu, a następnie stosować ten szablon do każdej wymaganej konfiguracji.

Definiowanie szablonu

Pamiętaj, że szablon umożliwia definiowanie typowych zadań kompilacji jednorazowo i wielokrotne używanie tych zadań. Szablon można wywołać z szablonu nadrzędnego jako krok kompilacji i przekazać parametry do szablonu z potoku nadrzędnego.

Teraz utworzysz szablon, który może utworzyć dowolną konfigurację zdefiniowaną w pliku projektu.

  1. W konsoli zintegrowanej programu Visual Studio Code w katalogu głównym projektu utwórz katalog szablonów .

    mkdir templates
    

    W praktyce można umieścić plik szablonu w dowolnej lokalizacji. Nie musisz umieszczać ich w katalogu templates .

  2. W programie Visual Studio Code wybierz pozycję Plik > nowy plik. Następnie, aby zapisać pusty plik jako build.yml w katalogu szablonów projektu, wybierz pozycję Zapisz plik>. Przykładem może być ~/mslearn-tailspin-spacegame-web/templates.

    Ważne

    Tak jak poprzednio, w systemie Windows na liście Zapisz jako typ wybierz pozycję YAML.

  3. W programie Visual Studio Code dodaj ten kod do build.yml:

    parameters:
      buildConfiguration: 'Release'
    
    steps:
    - task: DotNetCoreCLI@2
      displayName: 'Build the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'build'
        arguments: '--no-restore --configuration ${{ parameters.buildConfiguration }}'
        projects: '**/*.csproj'
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish the project - ${{ parameters.buildConfiguration }}'
      inputs:
        command: 'publish'
        projects: '**/*.csproj'
        publishWebProjects: false
        arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --output $(Build.ArtifactStagingDirectory)/${{ parameters.buildConfiguration }}'
        zipAfterPublish: true
    

    Te zadania wyglądają jak te, które zdefiniowano wcześniej w celu skompilowania i opublikowania aplikacji; ale w szablonie pracujesz z parametrami wejściowymi inaczej niż w przypadku normalnych zmiennych. Oto dwie różnice:

    • W pliku szablonu użyj parameters sekcji zamiast variables do zdefiniowania danych wejściowych.
    • W pliku szablonu użyj ${{ }} składni zamiast $() odczytywać wartość parametru. Podczas odczytywania wartości parametru dołączysz sekcję parameters w jego nazwie. Na przykład ${{ parameters.buildConfiguration }}.

Wywoływanie szablonu z potoku

Teraz wywołasz szablon utworzony na podstawie potoku. Zrobisz to jeden raz dla konfiguracji debugowania, a następnie powtórz proces konfiguracji wydania.

  1. W programie Visual Studio Code zmodyfikuj azure-pipelines.yml , jak pokazano poniżej:

    trigger:
    - '*'
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.x'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK $(dotnetSdkVersion)'
      inputs:
        version: '$(dotnetSdkVersion)'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    
    - task: gulp@1
      displayName: 'Run gulp tasks'
    
    - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
      displayName: 'Write build info'
      workingDirectory: $(wwwrootDir)
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    
    trigger:
    - '*'
    
    pool:
      name: 'Default' #replace if needed with name of your agent pool
    
    variables:
      buildConfiguration: 'Release'
      wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
      dotnetSdkVersion: '6.x'
    
    steps:
    - task: UseDotNet@2
      displayName: 'Use .NET SDK $(dotnetSdkVersion)'
      inputs:
        version: '$(dotnetSdkVersion)'
    
    - task: Npm@1
      displayName: 'Run npm install'
      inputs:
        verbose: false
    
    - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
      displayName: 'Compile Sass assets'
    
    - task: gulp@1
      displayName: 'Run gulp tasks'
    
    - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
      displayName: 'Write build info'
      workingDirectory: $(wwwrootDir)
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore project dependencies'
      inputs:
        command: 'restore'
        projects: '**/*.csproj'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Debug'
    
    - template: templates/build.yml
      parameters:
        buildConfiguration: 'Release'
    
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
      condition: succeeded()
    

    Ten plik wygląda jak oryginalny, z tą różnicą, że zastępuje zadania kompilacji i publikowania wywołaniami szablonu, który wykonuje te same zadania.

    Zobaczysz, że szablon jest wywoływany jeden raz dla każdej konfiguracji. Aby przekazać nazwę konfiguracji do szablonu, każde template zadanie używa argumentu parameters .

Uruchamianie potoku

Teraz wypchniesz zmiany do usługi GitHub i zobaczysz uruchomienie potoku.

  1. W zintegrowanym terminalu dodaj azure-pipelines.yml i szablony/build.yml do indeksu, zatwierdź zmiany i wypchnij zmiany do usługi GitHub.

    git add azure-pipelines.yml templates/build.yml
    git commit -m "Support build configurations"
    git push origin build-pipeline
    
  2. W usłudze Azure Pipelines śledź kompilację, wykonując poszczególne kroki, tak jak wcześniej.

    Podczas uruchamiania potoku zobaczysz, że proces rozszerza zadania w szablonie. Zadania kompilujące i publikujące projekt są uruchamiane dwa razy, raz dla każdej konfiguracji kompilacji.

    Zrzut ekranu usługi Azure Pipelines przedstawiający rozwinięte zadania szablonu. Uwzględnione są zadania kompilacji i publikowania dla konfiguracji debugowania i wydania.

  3. Po zakończeniu kompilacji wróć do strony podsumowania i wybierz opublikowany artefakt tak jak poprzednio. Rozwiń folder upuszczania.

    Zobaczysz, że potok generuje plik .zip zarówno dla konfiguracji debugowania, jak i konfiguracji wydania.

    Zrzut ekranu przedstawiający usługę Azure Pipelines z spakowanym aplikacją dla konfiguracji debugowania i wydania.

Scal gałąź z gałęzią główną

W tym momencie masz działający potok kompilacji, który realizuje wszystko, czego potrzebuje Teraz Mara.

W praktyce należy przesłać żądanie ściągnięcia, które scala build-pipeline gałąź z gałęziąmain.

Na razie pominiemy ten krok. W następnym module dowiesz się, jak współpracować z zespołem w usłudze GitHub, w tym jak przesyłać, przeglądać i scalać żądania ściągnięcia.