diff --git a/.ci/azure-pipelines-compat.yml b/.ci/azure-pipelines-compat.yml new file mode 100644 index 0000000000..6af956e1a7 --- /dev/null +++ b/.ci/azure-pipelines-compat.yml @@ -0,0 +1,96 @@ +parameters: + - name: Packages + type: object + default: {} + - name: LinuxImage + type: string + default: "ubuntu-latest" + - name: DotNetSdkVersion + type: string + default: 3.1.100 + +jobs: + - job: CompatibilityCheck + displayName: Compatibility Check + pool: + vmImage: "${{ parameters.LinuxImage}}" + # only execute for pull requests + condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber']) + strategy: + matrix: + ${{ each Package in parameters.Packages }}: + ${{ Package.key }}: + NugetPackageName: ${{ Package.value.NugetPackageName }} + AssemblyFileName: ${{ Package.value.AssemblyFileName }} + maxParallel: 2 + dependsOn: MainBuild + steps: + - checkout: none + + - task: UseDotNet@2 + displayName: "Update DotNet" + inputs: + packageType: sdk + version: ${{ parameters.DotNetSdkVersion }} + + - task: DownloadPipelineArtifact@2 + displayName: "Download New Assembly Build Artifact" + inputs: + source: "current" + artifact: "$(NugetPackageName)" + path: "$(System.ArtifactsDirectory)/new-artifacts" + runVersion: "latest" + + - task: CopyFiles@2 + displayName: "Copy New Assembly Build Artifact" + inputs: + sourceFolder: $(System.ArtifactsDirectory)/new-artifacts + contents: "**/*.dll" + targetFolder: $(System.ArtifactsDirectory)/new-release + cleanTargetFolder: true + overWrite: true + flattenFolders: true + + - task: DownloadPipelineArtifact@2 + displayName: "Download Reference Assembly Build Artifact" + inputs: + source: "specific" + artifact: "$(NugetPackageName)" + path: "$(System.ArtifactsDirectory)/current-artifacts" + project: "$(System.TeamProjectId)" + pipeline: "$(System.DefinitionId)" + runVersion: "latestFromBranch" + runBranch: "refs/heads/$(System.PullRequest.TargetBranch)" + + - task: CopyFiles@2 + displayName: "Copy Reference Assembly Build Artifact" + inputs: + sourceFolder: $(System.ArtifactsDirectory)/current-artifacts + contents: "**/*.dll" + targetFolder: $(System.ArtifactsDirectory)/current-release + cleanTargetFolder: true + overWrite: true + flattenFolders: true + + - task: DownloadGitHubRelease@0 + displayName: "Download ABI Compatibility Check Tool" + inputs: + connection: Jellyfin Release Download + userRepository: EraYaN/dotnet-compatibility + defaultVersionType: "latest" + itemPattern: "**-ci.zip" + downloadPath: "$(System.ArtifactsDirectory)" + + - task: ExtractFiles@1 + displayName: "Extract ABI Compatibility Check Tool" + inputs: + archiveFilePatterns: "$(System.ArtifactsDirectory)/*-ci.zip" + destinationFolder: $(System.ArtifactsDirectory)/tools + cleanDestinationFolder: true + + # The `--warnings-only` switch will swallow the return code and not emit any errors. + - task: CmdLine@2 + displayName: "Execute ABI Compatibility Check Tool" + inputs: + script: "dotnet tools/CompatibilityCheckerCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines --warnings-only" + workingDirectory: $(System.ArtifactsDirectory) diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml new file mode 100644 index 0000000000..9880bbfaa2 --- /dev/null +++ b/.ci/azure-pipelines-main.yml @@ -0,0 +1,101 @@ +parameters: + LinuxImage: "ubuntu-latest" + RestoreBuildProjects: "Jellyfin.Server/Jellyfin.Server.csproj" + DotNetSdkVersion: 3.1.100 + +jobs: + - job: MainBuild + displayName: Main Build + strategy: + matrix: + Release: + BuildConfiguration: Release + Debug: + BuildConfiguration: Debug + maxParallel: 2 + pool: + vmImage: "${{ parameters.LinuxImage }}" + steps: + - checkout: self + clean: true + submodules: true + persistCredentials: true + + - task: CmdLine@2 + displayName: "Clone Web Client (Master, Release, or Tag)" + condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + script: "git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + + - task: CmdLine@2 + displayName: "Clone Web Client (PR)" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest')) + inputs: + script: "git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + + - task: NodeTool@0 + displayName: "Install Node" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + versionSpec: "10.x" + + - task: CmdLine@2 + displayName: "Build Web Client" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + script: yarn install + workingDirectory: $(Agent.TempDirectory)/jellyfin-web + + - task: CopyFiles@2 + displayName: "Copy Web Client" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist + contents: "**" + targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web + cleanTargetFolder: true + overWrite: true + flattenFolders: false + + - task: UseDotNet@2 + displayName: "Update DotNet" + inputs: + packageType: sdk + version: ${{ parameters.DotNetSdkVersion }} + + - task: DotNetCoreCLI@2 + displayName: "Publish Server" + inputs: + command: publish + publishWebProjects: false + projects: "${{ parameters.RestoreBuildProjects }}" + arguments: "--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)" + zipAfterPublish: false + + - task: PublishPipelineArtifact@0 + displayName: "Publish Artifact Naming" + condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) + inputs: + targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/Emby.Naming.dll" + artifactName: "Jellyfin.Naming" + + - task: PublishPipelineArtifact@0 + displayName: "Publish Artifact Controller" + condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) + inputs: + targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Controller.dll" + artifactName: "Jellyfin.Controller" + + - task: PublishPipelineArtifact@0 + displayName: "Publish Artifact Model" + condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) + inputs: + targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Model.dll" + artifactName: "Jellyfin.Model" + + - task: PublishPipelineArtifact@0 + displayName: "Publish Artifact Common" + condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) + inputs: + targetPath: "$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Common.dll" + artifactName: "Jellyfin.Common" diff --git a/.ci/azure-pipelines-test.yml b/.ci/azure-pipelines-test.yml new file mode 100644 index 0000000000..4455632e15 --- /dev/null +++ b/.ci/azure-pipelines-test.yml @@ -0,0 +1,65 @@ +parameters: + - name: ImageNames + type: object + default: + Linux: "ubuntu-latest" + Windows: "windows-latest" + macOS: "macos-latest" + - name: TestProjects + type: string + default: "tests/**/*Tests.csproj" + - name: DotNetSdkVersion + type: string + default: 3.1.100 + +jobs: + - job: MainTest + displayName: Main Test + strategy: + matrix: + ${{ each imageName in parameters.ImageNames }}: + ${{ imageName.key }}: + ImageName: ${{ imageName.value }} + maxParallel: 3 + pool: + vmImage: "$(ImageName)" + steps: + - checkout: self + clean: true + submodules: true + persistCredentials: false + + - task: UseDotNet@2 + displayName: "Update DotNet" + inputs: + packageType: sdk + version: ${{ parameters.DotNetSdkVersion }} + + - task: DotNetCoreCLI@2 + displayName: Run .NET Core CLI tests + inputs: + command: "test" + projects: ${{ parameters.TestProjects }} + arguments: '--configuration Release --collect:"XPlat Code Coverage" --settings tests/coverletArgs.runsettings --verbosity minimal "-p:GenerateDocumentationFile=False"' + publishTestResults: true + testRunTitle: $(Agent.JobName) + workingDirectory: "$(Build.SourcesDirectory)" + + - task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4 + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging + displayName: ReportGenerator (merge) + inputs: + reports: "$(Agent.TempDirectory)/**/coverage.cobertura.xml" + targetdir: "$(Agent.TempDirectory)/merged/" + reporttypes: "Cobertura" + + ## V2 is already in the repository but it does not work "wrong number of segments" YAML error. + - task: PublishCodeCoverageResults@1 + condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging + displayName: Publish Code Coverage + inputs: + codeCoverageTool: "cobertura" + #summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml' # !!THIS IS FOR V2 + summaryFileLocation: "$(Agent.TempDirectory)/merged/**.xml" + pathToSources: $(Build.SourcesDirectory) + failIfCoverageEmpty: true diff --git a/.ci/azure-pipelines-windows.yml b/.ci/azure-pipelines-windows.yml new file mode 100644 index 0000000000..32d1d1382d --- /dev/null +++ b/.ci/azure-pipelines-windows.yml @@ -0,0 +1,82 @@ +parameters: + WindowsImage: "windows-latest" + TestProjects: "tests/**/*Tests.csproj" + DotNetSdkVersion: 3.1.100 + +jobs: + - job: PublishWindows + displayName: Publish Windows + pool: + vmImage: ${{ parameters.WindowsImage }} + steps: + - checkout: self + clean: true + submodules: true + persistCredentials: true + + - task: CmdLine@2 + displayName: "Clone Web Client (Master, Release, or Tag)" + condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'tag')), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + script: "git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + + - task: CmdLine@2 + displayName: "Clone Web Client (PR)" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest')) + inputs: + script: "git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + + - task: NodeTool@0 + displayName: "Install Node" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + versionSpec: "10.x" + + - task: CmdLine@2 + displayName: "Build Web Client" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + script: yarn install + workingDirectory: $(Agent.TempDirectory)/jellyfin-web + + - task: CopyFiles@2 + displayName: "Copy Web Client" + condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + inputs: + sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist + contents: "**" + targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web + cleanTargetFolder: true + overWrite: true + flattenFolders: false + + - task: CmdLine@2 + displayName: "Clone UX Repository" + inputs: + script: git clone --depth=1 https://github.com/jellyfin/jellyfin-ux $(Agent.TempDirectory)\jellyfin-ux + + - task: PowerShell@2 + displayName: "Build NSIS Installer" + inputs: + targetType: "filePath" + filePath: ./deployment/windows/build-jellyfin.ps1 + arguments: -InstallFFMPEG -InstallNSSM -MakeNSIS -InstallTrayApp -UXLocation $(Agent.TempDirectory)\jellyfin-ux -InstallLocation $(build.artifactstagingdirectory) + errorActionPreference: "stop" + workingDirectory: $(Build.SourcesDirectory) + + - task: CopyFiles@2 + displayName: "Copy NSIS Installer" + inputs: + sourceFolder: $(Build.SourcesDirectory)/deployment/windows/ + contents: "jellyfin*.exe" + targetFolder: $(System.ArtifactsDirectory)/setup + cleanTargetFolder: true + overWrite: true + flattenFolders: true + + - task: PublishPipelineArtifact@0 + displayName: "Publish Artifact Setup" + condition: succeeded() + inputs: + targetPath: "$(build.artifactstagingdirectory)/setup" + artifactName: "Jellyfin Server Setup" diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 7bcaed70cd..f79a85b210 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -2,9 +2,11 @@ name: $(Date:yyyyMMdd)$(Rev:.r) variables: - name: TestProjects - value: 'tests/**/*Tests.csproj' + value: "tests/**/*Tests.csproj" - name: RestoreBuildProjects - value: 'Jellyfin.Server/Jellyfin.Server.csproj' + value: "Jellyfin.Server/Jellyfin.Server.csproj" + - name: DotNetSdkVersion + value: 3.1.100 pr: autoCancel: true @@ -13,234 +15,26 @@ trigger: batch: true jobs: - - job: main_build - displayName: Main Build - pool: - vmImage: ubuntu-latest - strategy: - matrix: - Release: - BuildConfiguration: Release - Debug: - BuildConfiguration: Debug - maxParallel: 2 - steps: - - checkout: self - clean: true - submodules: true - persistCredentials: true + - template: azure-pipelines-main.yml + parameters: + LinuxImage: "ubuntu-latest" + RestoreBuildProjects: $(RestoreBuildProjects) - - task: CmdLine@2 - displayName: "Clone Web Client (Master, Release, or Tag)" - condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web' + - template: azure-pipelines-test.yml + parameters: + ImageNames: + Linux: "ubuntu-latest" + Windows: "windows-latest" + macOS: "macos-latest" - - task: CmdLine@2 - displayName: "Clone Web Client (PR)" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest')) - inputs: - script: 'git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web' + - template: azure-pipelines-windows.yml + parameters: + WindowsImage: "windows-latest" + TestProjects: $(TestProjects) - - task: NodeTool@0 - displayName: 'Install Node' - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - versionSpec: '10.x' - - - task: CmdLine@2 - displayName: "Build Web Client" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - script: yarn install - workingDirectory: $(Agent.TempDirectory)/jellyfin-web - - - task: CopyFiles@2 - displayName: 'Copy Web Client' - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist # Optional - contents: '**' - targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web - cleanTargetFolder: true # Optional - overWrite: true # Optional - flattenFolders: false # Optional - - - task: UseDotNet@2 - displayName: 'Update DotNet' - inputs: - packageType: sdk - version: 3.1.100 - - - task: DotNetCoreCLI@2 - displayName: 'Publish Server' - inputs: - command: publish - publishWebProjects: false - projects: '$(RestoreBuildProjects)' - arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)' - zipAfterPublish: false - - - task: PublishPipelineArtifact@0 - displayName: 'Publish Artifact Naming' - condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) - inputs: - targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/Emby.Naming.dll' - artifactName: 'Jellyfin.Naming' - - - task: PublishPipelineArtifact@0 - displayName: 'Publish Artifact Controller' - condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) - inputs: - targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Controller.dll' - artifactName: 'Jellyfin.Controller' - - - task: PublishPipelineArtifact@0 - displayName: 'Publish Artifact Model' - condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) - inputs: - targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Model.dll' - artifactName: 'Jellyfin.Model' - - - task: PublishPipelineArtifact@0 - displayName: 'Publish Artifact Common' - condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) - inputs: - targetPath: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Common.dll' - artifactName: 'Jellyfin.Common' - - - job: main_test - displayName: Main Test - pool: - vmImage: windows-latest - steps: - - checkout: self - clean: true - submodules: true - persistCredentials: false - - - task: DotNetCoreCLI@2 - displayName: Build - inputs: - command: build - publishWebProjects: false - projects: '$(TestProjects)' - arguments: '--configuration $(BuildConfiguration)' - zipAfterPublish: false - - - task: VisualStudioTestPlatformInstaller@1 - inputs: - packageFeedSelector: 'nugetOrg' # Options: nugetOrg, customFeed, netShare - versionSelector: 'latestPreRelease' # Required when packageFeedSelector == NugetOrg || PackageFeedSelector == CustomFeed# Options: latestPreRelease, latestStable, specificVersion - - task: VSTest@2 - inputs: - testSelector: 'testAssemblies' # Options: testAssemblies, testPlan, testRun - testAssemblyVer2: | # Required when testSelector == TestAssemblies - **\bin\$(BuildConfiguration)\**\*tests.dll - **\bin\$(BuildConfiguration)\**\*test.dll - !**\obj\** - !**\xunit.runner.visualstudio.testadapter.dll - !**\xunit.runner.visualstudio.dotnetcore.testadapter.dll - searchFolder: '$(System.DefaultWorkingDirectory)' - runInParallel: True # Optional - runTestsInIsolation: True # Optional - codeCoverageEnabled: True # Optional - configuration: 'Debug' # Optional - publishRunAttachments: true # Optional - testRunTitle: $(Agent.JobName) - otherConsoleOptions: '/platform:x64 /Framework:.NETCoreApp,Version=v3.1 /logger:console;verbosity="normal"' - - - job: main_build_win - displayName: Publish Windows - pool: - vmImage: windows-latest - strategy: - matrix: - Release: - BuildConfiguration: Release - maxParallel: 2 - steps: - - checkout: self - clean: true - submodules: true - persistCredentials: true - - - task: CmdLine@2 - displayName: "Clone Web Client (Master, Release, or Tag)" - condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'tag')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web' - - - task: CmdLine@2 - displayName: "Clone Web Client (PR)" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest')) - inputs: - script: 'git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web' - - - task: NodeTool@0 - displayName: 'Install Node' - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - versionSpec: '10.x' - - - task: CmdLine@2 - displayName: "Build Web Client" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - script: yarn install - workingDirectory: $(Agent.TempDirectory)/jellyfin-web - - - task: CopyFiles@2 - displayName: 'Copy Web Client' - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist # Optional - contents: '**' - targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web - cleanTargetFolder: true # Optional - overWrite: true # Optional - flattenFolders: false # Optional - - - task: CmdLine@2 - displayName: 'Clone UX Repository' - inputs: - script: git clone --depth=1 https://github.com/jellyfin/jellyfin-ux $(Agent.TempDirectory)\jellyfin-ux - - - task: PowerShell@2 - displayName: 'Build NSIS Installer' - inputs: - targetType: 'filePath' # Optional. Options: filePath, inline - filePath: ./deployment/windows/build-jellyfin.ps1 # Required when targetType == FilePath - arguments: -InstallFFMPEG -InstallNSSM -MakeNSIS -InstallTrayApp -UXLocation $(Agent.TempDirectory)\jellyfin-ux -InstallLocation $(build.artifactstagingdirectory) - errorActionPreference: 'stop' # Optional. Options: stop, continue, silentlyContinue - workingDirectory: $(Build.SourcesDirectory) # Optional - - - task: CopyFiles@2 - displayName: 'Copy NSIS Installer' - inputs: - sourceFolder: $(Build.SourcesDirectory)/deployment/windows/ # Optional - contents: 'jellyfin*.exe' - targetFolder: $(System.ArtifactsDirectory)/setup - cleanTargetFolder: true # Optional - overWrite: true # Optional - flattenFolders: true # Optional - - - task: PublishPipelineArtifact@0 - displayName: 'Publish Artifact Setup' - condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded()) - inputs: - targetPath: '$(build.artifactstagingdirectory)/setup' - artifactName: 'Jellyfin Server Setup' - - - job: dotnet_compat - displayName: Compatibility Check - pool: - vmImage: ubuntu-latest - dependsOn: main_build - # only execute for pull requests - condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber']) - strategy: - matrix: + - template: azure-pipelines-compat.yml + parameters: + Packages: Naming: NugetPackageName: Jellyfin.Naming AssemblyFileName: Emby.Naming.dll @@ -253,74 +47,4 @@ jobs: Common: NugetPackageName: Jellyfin.Common AssemblyFileName: MediaBrowser.Common.dll - maxParallel: 2 - steps: - - checkout: none - - - task: UseDotNet@2 - displayName: 'Update DotNet' - inputs: - packageType: sdk - version: 3.1.100 - - - task: DownloadPipelineArtifact@2 - displayName: 'Download New Assembly Build Artifact' - inputs: - source: 'current' # Options: current, specific - artifact: '$(NugetPackageName)' # Optional - path: '$(System.ArtifactsDirectory)/new-artifacts' - runVersion: 'latest' # Required when source == Specific. Options: latest, latestFromBranch, specific - - - task: CopyFiles@2 - displayName: 'Copy New Assembly Build Artifact' - inputs: - sourceFolder: $(System.ArtifactsDirectory)/new-artifacts # Optional - contents: '**/*.dll' - targetFolder: $(System.ArtifactsDirectory)/new-release - cleanTargetFolder: true # Optional - overWrite: true # Optional - flattenFolders: true # Optional - - - task: DownloadPipelineArtifact@2 - displayName: 'Download Reference Assembly Build Artifact' - inputs: - source: 'specific' # Options: current, specific - artifact: '$(NugetPackageName)' # Optional - path: '$(System.ArtifactsDirectory)/current-artifacts' - project: '$(System.TeamProjectId)' # Required when source == Specific - pipeline: '$(System.DefinitionId)' # Required when source == Specific - runVersion: 'latestFromBranch' # Required when source == Specific. Options: latest, latestFromBranch, specific - runBranch: 'refs/heads/$(System.PullRequest.TargetBranch)' # Required when source == Specific && runVersion == LatestFromBranch - - - task: CopyFiles@2 - displayName: 'Copy Reference Assembly Build Artifact' - inputs: - sourceFolder: $(System.ArtifactsDirectory)/current-artifacts # Optional - contents: '**/*.dll' - targetFolder: $(System.ArtifactsDirectory)/current-release - cleanTargetFolder: true # Optional - overWrite: true # Optional - flattenFolders: true # Optional - - - task: DownloadGitHubRelease@0 - displayName: 'Download ABI Compatibility Check Tool' - inputs: - connection: Jellyfin Release Download - userRepository: EraYaN/dotnet-compatibility - defaultVersionType: 'latest' # Options: latest, specificVersion, specificTag - itemPattern: '**-ci.zip' # Optional - downloadPath: '$(System.ArtifactsDirectory)' - - - task: ExtractFiles@1 - displayName: 'Extract ABI Compatibility Check Tool' - inputs: - archiveFilePatterns: '$(System.ArtifactsDirectory)/*-ci.zip' - destinationFolder: $(System.ArtifactsDirectory)/tools - cleanDestinationFolder: true - - # The `--warnings-only` switch will swallow the return code and not emit any errors. - - task: CmdLine@2 - displayName: 'Execute ABI Compatibility Check Tool' - inputs: - script: 'dotnet tools/CompatibilityCheckerCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines --warnings-only' - workingDirectory: $(System.ArtifactsDirectory) # Optional + LinuxImage: "ubuntu-latest" diff --git a/.ci/publish-nightly.yml b/.ci/publish-nightly.yml deleted file mode 100644 index a693e10f6c..0000000000 --- a/.ci/publish-nightly.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Nightly-$(date:yyyyMMdd).$(rev:r) - -variables: - - name: Version - value: '1.0.0' - -trigger: none -pr: none - -jobs: - - job: publish_artifacts_nightly - displayName: Publish Artifacts Nightly - pool: - vmImage: ubuntu-latest - steps: - - checkout: none - - task: DownloadPipelineArtifact@2 - displayName: Download the Windows Setup Artifact - inputs: - source: 'specific' # Options: current, specific - artifact: 'Jellyfin Server Setup' # Optional - path: '$(System.ArtifactsDirectory)/win-installer' - project: '$(System.TeamProjectId)' # Required when source == Specific - pipelineId: 1 # Required when source == Specific - runVersion: 'latestFromBranch' # Required when source == Specific. Options: latest, latestFromBranch, specific - runBranch: 'refs/heads/master' # Required when source == Specific && runVersion == LatestFromBranch - - - task: SSH@0 - displayName: 'Create Drop directory' - inputs: - sshEndpoint: 'Jellyfin Build Server' - commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_nightly_azure_upload' - - - task: CopyFilesOverSSH@0 - displayName: 'Copy the Windows Setup to the Repo' - inputs: - sshEndpoint: 'Jellyfin Build Server' - sourceFolder: '$(System.ArtifactsDirectory)/win-installer' - contents: 'jellyfin_*.exe' - targetFolder: '/srv/incoming/jellyfin_nightly_azure_upload/win-installer' - - - task: SSH@0 - displayName: 'Clean up SCP symlink' - inputs: - sshEndpoint: 'Jellyfin Build Server' - commands: 'rm -f /srv/incoming/jellyfin_nightly_azure_upload' diff --git a/.ci/publish-release.yml b/.ci/publish-release.yml deleted file mode 100644 index 57e77ae5aa..0000000000 --- a/.ci/publish-release.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Release-$(Version)-$(date:yyyyMMdd).$(rev:r) - -variables: - - name: Version - value: '1.0.0' - - name: UsedRunId - value: 0 - -trigger: none -pr: none - -jobs: - - job: publish_artifacts_release - displayName: Publish Artifacts Release - pool: - vmImage: ubuntu-latest - steps: - - checkout: none - - task: DownloadPipelineArtifact@2 - displayName: Download the Windows Setup Artifact - inputs: - source: 'specific' # Options: current, specific - artifact: 'Jellyfin Server Setup' # Optional - path: '$(System.ArtifactsDirectory)/win-installer' - project: '$(System.TeamProjectId)' # Required when source == Specific - pipelineId: 1 # Required when source == Specific - runVersion: 'specific' # Required when source == Specific. Options: latest, latestFromBranch, specific - runId: $(UsedRunId) - - - task: SSH@0 - displayName: 'Create Drop directory' - inputs: - sshEndpoint: 'Jellyfin Build Server' - commands: 'mkdir -p /srv/incoming/jellyfin_$(Version)/win-installer && ln -s /srv/incoming/jellyfin_$(Version) /srv/incoming/jellyfin_release_azure_upload' - - - task: CopyFilesOverSSH@0 - displayName: 'Copy the Windows Setup to the Repo' - inputs: - sshEndpoint: 'Jellyfin Build Server' - sourceFolder: '$(System.ArtifactsDirectory)/win-installer' - contents: 'jellyfin_*.exe' - targetFolder: '/srv/incoming/jellyfin_release_azure_upload/win-installer' - - - task: SSH@0 - displayName: 'Clean up SCP symlink' - inputs: - sshEndpoint: 'Jellyfin Build Server' - commands: 'rm -f /srv/incoming/jellyfin_release_azure_upload' diff --git a/tests/coverletArgs.runsettings b/tests/coverletArgs.runsettings new file mode 100644 index 0000000000..3113957e0a --- /dev/null +++ b/tests/coverletArgs.runsettings @@ -0,0 +1,17 @@ + + + + + + + cobertura + [coverlet.*.tests?]*,[*]Coverlet.Core*,[*]Moq* + Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute + false + true + false + + + + + \ No newline at end of file