Ć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 , który zawiera skompilowana aplikację internetową.

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 będę wiedzieć, 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 templates projektu, wybierz pozycję Plik > Zapisz. 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 pliku 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 zostały zdefiniowane wcześniej w celu skompilowania i opublikowania aplikacji. Jednak 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 plik azure-pipelines.yml , jak pokazano tutaj:

    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 plik azure-pipelines.yml i templates/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. Z poziomu usługi Azure Pipelines prześledzić kompilację za pomocą każdego z kroków, 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.

    Screenshot of Azure Pipelines showing the expanded template tasks. Included are build and publish tasks for both the Debug and Release configurations.

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

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

    Screenshot of Azure Pipelines showing the packaged application for both Debug and Release configurations.

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.