# Validation pipeline for manifest on pull requests. # Name of the run name: '$(Build.DefinitionName)-$(Build.DefinitionVersion)-$(System.PullRequest.PullRequestNumber)-$(Date:yyyyMMdd)-$(Rev:r)' trigger: none pr: none jobs: # Agent phase. Process pull request changes and validate manifests. - job: 'FileValidation' displayName: 'Pull Request Validation' pool: vmImage: 'windows-latest' variables: skipComponentGovernanceDetection: ${{ true }} runCodesignValidationInjection: ${{ false }} steps: # Downloads all the setup files and its dependencies. - task: AzureCLI@1 displayName: 'Azure Setup' inputs: azureSubscription: '$(WinGet.Subscription)' scriptLocation: inlineScript inlineScript: 'az storage blob download-batch -d . --pattern * -s servicewrapper --output none' env: AZURE_STORAGE_CONNECTION_STRING: $(ValidationStorageAccountConnectionString) # WinGet setup - script: 'winget_validation_setup.cmd' name: 'wingetsetup' displayName: 'WinGet Setup' workingDirectory: scripts env: HOST_KEY: $(AzureFunctionHostKey) SMART_SCREEN_ENDPOINT: $(AzFuncSmartScreenEndpoint) DOMAIN_URLS_VALIDATION_ENDPOINT: $(AzFuncDomainUrlValEndpoint) MANIFEST_POLICY_ENDPOINT: $(AzFuncManifestPolicyEndpoint) SCAN_ENDPOINT: $(AzFuncScanEndpoint) INSTALLATION_ENDPOINT: $(AzFuncInstallationVerificationEndpoint) LABEL_ENDPOINT: $(AzFuncSetLabelOnPullRequestEndpoint) CLEANUP_ENDPOINT: $(AzFuncCleanupEndpoint) LABEL_KEY: $(AzureFunctionLabelKey) # Validates integrity of pull request. - task: CmdLine@2 displayName: 'Validate Pull Request' inputs: script: 'WinGetSvcWrapper.exe process-pr --operationId %BUILD_BUILDNUMBER%' failOnStderr: true condition: succeeded() env: ValidationConnectionString: $(ValidationStorageAccountConnectionString) ExecutionEnvironment: $(ExecutionEnvironment) DIApplicationInsightKey: $(DIApplicationInsightKey) WinGet:AppConfig:Primary: $(AppConfigPrimary) WinGet:AppConfig:Secondary: $(AppConfigSecondary) # Validates manifest integrity. - task: CmdLine@2 displayName: 'Validate Manifest' inputs: script: 'WinGetSvcWrapper.exe validate-manifests --operationId %BUILD_BUILDNUMBER%' failOnStderr: true condition: succeeded() env: ValidationConnectionString: $(ValidationStorageAccountConnectionString) DIApplicationInsightKey: $(DIApplicationInsightKey) WinGet:AppConfig:Primary: $(AppConfigPrimary) WinGet:AppConfig:Secondary: $(AppConfigSecondary) # Agentless phase. Depends on previous job. - job: 'ContentValidation' pool: server displayName: 'Manifest Content Validation' timeoutInMinutes: 1500 dependsOn: - 'FileValidation' variables: HostKeySecret: $[ dependencies.FileValidation.outputs['wingetsetup.hostkey']] SmartScreenEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.smartScreenEndpoint']] DomainUrlValidationEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.domainUrlValidationEndpoint']] ManiestPolicyEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.manifestPolicyEndpoint']] steps: # Scans all the urls from manifest contents. - task: AzureFunction@1 displayName: 'URLs Validation' inputs: function: '$(SmartScreenEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "BuildId": "$(Build.BuildId)", "PlanUrl": "$(system.CollectionUri)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true" # Domain url validations. - task: AzureFunction@1 displayName: 'URL Domain validation' inputs: function: '$(DomainUrlValidationEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "BuildId": "$(Build.BuildId)", "PlanUrl": "$(system.CollectionUri)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true" # Manifest policy checks. - task: AzureFunction@1 displayName: 'Manifest Policy Validation' inputs: function: '$(ManiestPolicyEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "BuildId": "$(Build.BuildId)", "PlanUrl": "$(system.CollectionUri)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true" # Agentless phase. Depends on previous job. - job: 'InstallerValidation' pool: server displayName: 'Installer Validation' timeoutInMinutes: 1500 dependsOn: - 'FileValidation' - 'ContentValidation' variables: HostKeySecret: $[ dependencies.FileValidation.outputs['wingetsetup.hostkey']] ScanEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.scanEndpoint']] InstallationEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.installationEndpoint']] steps: # Scan installers in manifests. - task: AzureFunction@1 displayName: 'Installers Scan' inputs: function: '$(ScanEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "BuildId": "$(Build.BuildId)", "PlanUrl": "$(system.CollectionUri)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true" # Validates installation. - task: AzureFunction@1 displayName: 'Installation Validation' inputs: function: '$(InstallationEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "BuildId": "$(Build.BuildId)", "PlanUrl": "$(system.CollectionUri)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true" # Agentless phase. Runs even if previous jobs failed. - job: 'postvalidation' pool: server displayName: 'Post Validation' dependsOn: - 'FileValidation' - 'ContentValidation' - 'InstallerValidation' condition: succeededOrFailed() variables: HostKeySecret: $[ dependencies.FileValidation.outputs['wingetsetup.hostkey']] LabelKeySecret : $[ dependencies.FileValidation.outputs['wingetsetup.labelkey']] LabelEndpointSecret: $[ dependencies.FileValidation.outputs['wingetsetup.labelEndpoint']] RepositoryId: $[ dependencies.FileValidation.outputs['wingetsetup.repoId']] CleanupEndpointSecret: $[ dependencies.filevalidation.outputs['wingetsetup.cleanupEndpoint']] steps: # Set label in GitHub PullRequest. - task: AzureFunction@1 displayName: 'Set Label' condition: eq(variables['WinGet.RepositoryType'], 'GitHub') inputs: function: '$(LabelEndpointSecret)' key: '$(LabelKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "PlanUrl": "$(system.CollectionUri)", "BuildId": "$(Build.BuildId)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)", "BuildRepositoryId": "$(RepositoryId)", "PullRequestNumber": "$(System.PullRequest.PullRequestNumber)", } waitForCompletion: "true" # Cleanup resources. - task: AzureFunction@1 displayName: 'Validation cleanup' inputs: function: '$(CleanupEndpointSecret)' key: '$(HostKeySecret)' body: | { "operationId": "$(Build.BuildNumber)", "PlanUrl": "$(system.CollectionUri)", "BuildId": "$(Build.BuildId)", "HubName": "$(system.HostType)", "ProjectId": "$(system.TeamProjectId)", "PlanId": "$(system.PlanId)", "JobId": "$(system.JobId)", "TimelineId": "$(system.TimelineId)", "TaskInstanceId": "$(system.TaskInstanceId)", "AuthToken": "$(system.AccessToken)" } waitForCompletion: "true"