diff --git a/.gitattributes b/.gitattributes index 1b274cb93..e67ee2ab0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,9 @@ # Auto detect text files and perform LF normalization *text eol=lf +# Explicitly set bash scripts to have unix endings +*.sh text eol=lf + # Custom for Visual Studio *.cs diff=csharp *.sln merge=union diff --git a/.gitignore b/.gitignore index 46478856c..ed6772d69 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,8 @@ _rawPackage/ _dotTrace* _tests/ *.Result.xml +coverage*.xml +coverage*.json setup/Output/ *.~is diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0eda1292a..000000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: csharp - -os: - - linux - - osx - -addons: - apt: - packages: - - dos2unix - - libchromaprint-tools - update: true - homebrew: - packages: - - yarn - - dos2unix - update: true - -solution: src/Lidarr.sln - -before_install: - - nvm install 10 - - nvm use 10 - - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.13.0 - - export PATH=$HOME/.yarn/bin:$PATH - -cache: - yarn: true - directories: - - node_modules - -script: - - ./build.sh - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./test.sh Mac Unit; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./test.sh Linux Unit; fi diff --git a/README.md b/README.md index 8b1d85882..48f813e0b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Lidarr -[![Build status](https://ci.appveyor.com/api/projects/status/tpm5mj5milne88nc?svg=true)](https://ci.appveyor.com/project/lidarr/lidarr) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4e6d014aee9542189b4abb0b1439980f)](https://www.codacy.com/app/Lidarr/Lidarr?utm_source=github.com&utm_medium=referral&utm_content=lidarr/Lidarr&utm_campaign=Badge_Grade) +[![Build Status](https://dev.azure.com/Lidarr/Lidarr/_apis/build/status/lidarr.Lidarr?branchName=develop)](https://dev.azure.com/Lidarr/Lidarr/_build/latest?definitionId=1&branchName=develop) [![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/lidarr.svg)](https://github.com/lidarr/Lidarr/wiki/Docker) ![Github Downloads](https://img.shields.io/github/downloads/lidarr/lidarr/total.svg) [![Backers on Open Collective](https://opencollective.com/lidarr/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/lidarr/sponsors/badge.svg)](#sponsors) diff --git a/appveyor-package.sh b/appveyor-package.sh deleted file mode 100755 index 57c61c63e..000000000 --- a/appveyor-package.sh +++ /dev/null @@ -1,43 +0,0 @@ -#! /bin/bash - -artifactsFolder="./_artifacts"; -artifactsFolderWindows=$artifactsFolder/windows -artifactsFolderLinux=$artifactsFolder/linux -artifactsFolderMacOS=$artifactsFolder/macos -artifactsFolderMacOSApp=$artifactsFolder/macos-app - -PublishArtifacts() -{ - 7z a $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.windows.zip $artifactsFolderWindows/* - - 7z a $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.osx-app.zip $artifactsFolderMacOSApp/* - - 7z a -ttar $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.osx.tar $artifactsFolderMacOS/* - 7z a -tgzip $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.osx.tar.gz $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.osx.tar - rm -f $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.osx.tar - - 7z a -ttar $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.linux.tar $artifactsFolderLinux/* - 7z a -tgzip $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.linux.tar.gz $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.linux.tar - rm -f $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.linux.tar - - if [ "${CI_WINDOWS}" = "True" ]; then - ./setup/inno/ISCC.exe "./setup/lidarr.iss" - cp ./setup/output/Lidarr.*windows.exe $artifactsFolder/Lidarr.${APPVEYOR_REPO_BRANCH}.${APPVEYOR_BUILD_VERSION}.windows-installer.exe - fi -} - -PublishSourceMaps() -{ - # Only create release on develop - # Secure SENTRY_AUTH_TOKEN will only be decoded on branch builds, not PRs - if [ "${CI_WINDOWS}" = "True" ] && [ "${APPVEYOR_REPO_BRANCH}" = "develop" ] && [ ! -z "${SENTRY_AUTH_TOKEN}" ]; then - echo "Uploading source maps to sentry" - yarn sentry-cli releases new --finalize -p lidarr -p lidarr-ui -p lidarr-update "${APPVEYOR_BUILD_VERSION}-debug" - yarn sentry-cli releases -p lidarr-ui files "${APPVEYOR_BUILD_VERSION}-debug" upload-sourcemaps _output/UI/ --rewrite - yarn sentry-cli releases set-commits --auto "${APPVEYOR_BUILD_VERSION}-debug" - yarn sentry-cli releases deploys "${APPVEYOR_BUILD_VERSION}-debug" new -e nightly - fi -} - -PublishArtifacts -PublishSourceMaps diff --git a/appveyor.yml b/appveyor.yml index 933149456..a12a1e32f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,72 +1,3 @@ -version: '0.6.2.{build}' - -image: - - Visual Studio 2017 - - Ubuntu1804 - -assembly_info: - patch: true - file: 'src\NzbDrone.Common\Properties\SharedAssemblyInfo.cs' - assembly_version: '{version}' - assembly_file_version: '{version}' - assembly_informational_version: '{version}-rc1' - -environment: - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - nodejs_version: "10" - SENTRY_AUTH_TOKEN: - secure: dIzaGkyqP8JefC+GyXH2RtBHCufpzegoJnxvwGenCsMZNgaVbnoNo4ZMnPY2WYpstCcdXmZb7hbPYmu4FRkKQ8xDQ34YNGlKRKnlFuOQoq8= - SENTRY_ORG: "lidarr" - -install: - - git submodule update --init --recursive - - cmd: powershell Install-Product node $env:nodejs_version - - cmd: powershell Set-Service SCardSvr -StartupType Manual - - sh: nvm install $nodejs_version - - sh: sudo apt update - - sh: sudo apt install -y libchromaprint-tools - -build_script: - - cmd: C:\msys64\usr\bin\bash -lc "cd \"$APPVEYOR_BUILD_FOLDER\" && exec ./build.sh - - sh: ./build.sh - -after_build: - - cmd: C:\msys64\usr\bin\bash -lc "cd \"$APPVEYOR_BUILD_FOLDER\" && exec ./appveyor-package.sh - - sh: ./appveyor-package.sh - - ps: Get-ChildItem .\_artifacts\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - - ps: Get-ChildItem .\_artifacts\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - - ps: Get-ChildItem .\_artifacts\*.tar.gz | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - -test_script: - - node --version - - yarn --version - - cmd: C:\msys64\usr\bin\bash -lc "cd \"$APPVEYOR_BUILD_FOLDER\" && exec ./test.sh Windows Unit - - sh: ./test.sh Linux Unit - - sh: find "$APPVEYOR_BUILD_FOLDER" -type f -name 'myresults.xml' -print0 | xargs -0 -I '{}' curl -F 'file=@{}' "https://ci.appveyor.com/api/testresults/nunit3/$APPVEYOR_JOB_ID" - -cache: - - node_modules -> package.json - -pull_requests: - do_not_increment_build_number: true - -skip_branch_with_pr: true - -on_failure: - - ps: Get-ChildItem .\_artifacts\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - - ps: Get-ChildItem .\_artifacts\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - - ps: Get-ChildItem .\_artifacts\*.tar.gz | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } - -only_commits: +skip_commits: files: - - src/ - - osx/ - - gulp/ - - logo/ - - setup/ - - frontend/ - - appveyor.yml - - build.sh - - test.sh - - package.json - - appveyor-package.sh + - '**/**' \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..da117db86 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,506 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +variables: + outputFolder: './_output' + artifactsFolder: './_artifacts' + testsFolder: './_tests' + majorVersion: '0.6.2' + minorVersion: $[counter('minorVersion', 1076)] + lidarrVersion: '$(majorVersion).$(minorVersion)' + buildName: '$(Build.SourceBranchName).$(lidarrVersion)' + windowsInstaller: 'Lidarr.$(buildName).windows-installer.exe' + windowsZip: 'Lidarr.$(buildName).windows.zip' + macOsApp: 'Lidarr.$(buildName).osx-app.zip' + macOsTar: 'Lidarr.$(buildName).osx.tar.gz' + linuxTar: 'Lidarr.$(buildName).linux.tar.gz' + sentryOrg: 'lidarr' + +trigger: + branches: + include: + - develop + +pr: +- develop + +stages: + - stage: Build_Backend + displayName: Build Backend + + jobs: + - job: Backend + strategy: + matrix: + Linux: + osName: 'Linux' + imageName: 'ubuntu-16.04' + Mac: + osName: 'Mac' + imageName: 'macos-10.13' + Windows: + osName: 'Windows' + imageName: 'vs2017-win2016' + + pool: + vmImage: $(imageName) + steps: + # Set the build name properly. The 'name' property won't recursively expand so hack here: + - powershell: Write-Host "##vso[build.updatebuildnumber]$($env:LIDARRVERSION)" + displayName: Set Build Name + - checkout: self + submodules: true + fetchDepth: 1 + - task: Assembly-Info-NetFramework@2 + displayName: Patch AssemblyInfo + inputs: + Path: '$(Build.SourcesDirectory)' + FileNames: 'src/NzbDrone.Common/Properties/SharedAssemblyInfo.cs' + InsertAttributes: false + FileEncoding: 'auto' + WriteBOM: false + VersionNumber: '$(lidarrVersion)' + FileVersionNumber: '$(lidarrVersion)' + InformationalVersion: '$(lidarrVersion)-rc1' + - bash: ./build.sh --only-backend + displayName: Build Lidarr Backend + - publish: $(outputFolder) + artifact: '$(osName)Backend' + displayName: Publish Backend + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + - publish: $(Build.SourcesDirectory) + artifact: 'CoverageBuild' + displayName: Publish Coverage Package + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + - publish: $(testsFolder) + artifact: '$(osName)Tests' + displayName: Publish Test Package + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + + - stage: Build_Frontend + displayName: Build Frontend + dependsOn: [] + + jobs: + - job: Frontend + strategy: + matrix: + Linux: + osName: 'Linux' + imageName: 'ubuntu-16.04' + Mac: + osName: 'Mac' + imageName: 'macos-10.13' + Windows: + osName: 'Windows' + imageName: 'vs2017-win2016' + pool: + vmImage: $(imageName) + steps: + - task: NodeTool@0 + displayName: Set Node.js version + inputs: + versionSpec: '10.x' + - checkout: self + submodules: true + fetchDepth: 1 + - bash: ./build.sh --only-frontend + displayName: Build Lidarr Frontend + env: + FORCE_COLOR: 0 + - publish: $(outputFolder) + artifact: '$(osName)Frontend' + displayName: Publish Frontend + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + + - stage: Package + dependsOn: + - Build_Backend + - Build_Frontend + jobs: + - job: Windows_Installer + displayName: Create Installer + pool: + vmImage: 'vs2017-win2016' + steps: + - checkout: self + fetchDepth: 1 + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: WindowsBackend + targetPath: _output + displayName: Fetch Backend + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: WindowsFrontend + targetPath: _output + displayName: Fetch Frontend + - bash: ./build.sh --only-packages + displayName: Create Packages + - bash: | + ./setup/inno/ISCC.exe "./setup/lidarr.iss" + cp ./setup/output/Lidarr.*windows.exe ${BUILD_ARTIFACTSTAGINGDIRECTORY}/${WINDOWSINSTALLER} + displayName: Create Windows installer + - publish: $(Build.ArtifactStagingDirectory) + artifact: 'WindowsInstaller' + displayName: Publish Installer + + - job: Other_Packages + displayName: Create Standard Packages + pool: + vmImage: 'ubuntu-16.04' + steps: + - bash: sudo apt install dos2unix + - checkout: self + fetchDepth: 1 + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: WindowsBackend + targetPath: _output + displayName: Fetch Backend + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: WindowsFrontend + targetPath: _output + displayName: Fetch Frontend + - bash: ./build.sh --only-packages + displayName: Create Packages + - bash: | + chmod a+x $(artifactsFolder)/macos/Lidarr/fpcalc + chmod a+x $(artifactsFolder)/macos-app/Lidarr.app/Contents/MacOS/fpcalc + displayName: Make fpcalc Executable + - task: ArchiveFiles@2 + displayName: Create Windows zip + inputs: + archiveFile: '$(Build.ArtifactStagingDirectory)/$(windowsZip)' + archiveType: 'zip' + includeRootFolder: false + rootFolderOrFile: $(artifactsFolder)/windows + - task: ArchiveFiles@2 + displayName: Create MacOS app + inputs: + archiveFile: '$(Build.ArtifactStagingDirectory)/$(macOsApp)' + archiveType: 'zip' + includeRootFolder: false + rootFolderOrFile: $(artifactsFolder)/macos-app + - task: ArchiveFiles@2 + displayName: Create MacOS tar + inputs: + archiveFile: '$(Build.ArtifactStagingDirectory)/$(macOsTar)' + archiveType: 'tar' + tarCompression: 'gz' + includeRootFolder: false + rootFolderOrFile: $(artifactsFolder)/macos + - task: ArchiveFiles@2 + displayName: Create Linux tar + inputs: + archiveFile: '$(Build.ArtifactStagingDirectory)/$(linuxTar)' + archiveType: 'tar' + tarCompression: 'gz' + includeRootFolder: false + rootFolderOrFile: $(artifactsFolder)/linux + - publish: $(Build.ArtifactStagingDirectory) + artifact: 'Packages' + displayName: Publish Packages + - bash: | + echo "Uploading source maps to sentry" + yarn sentry-cli releases new --finalize -p lidarr -p lidarr-ui -p lidarr-update "${LIDARRVERSION}-debug" + yarn sentry-cli releases -p lidarr-ui files "${LIDARRVERSION}-debug" upload-sourcemaps _output/UI/ --rewrite + yarn sentry-cli releases set-commits --auto "${LIDARRVERSION}-debug" + yarn sentry-cli releases deploys "${LIDARRVERSION}-debug" new -e nightly + displayName: Publish Sentry Source Maps + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) + env: + SENTRY_AUTH_TOKEN: $(sentryAuthToken) + + - stage: Unit_Test + displayName: Unit Tests + dependsOn: Build_Backend + condition: succeeded() + jobs: + - job: Unit + strategy: + matrix: + Linux: + osName: 'Linux' + imageName: 'ubuntu-16.04' + Mac: + osName: 'Mac' + imageName: 'macos-10.13' + Windows: + osName: 'Windows' + imageName: 'vs2017-win2016' + + pool: + vmImage: $(imageName) + + steps: + - checkout: none + - task: DownloadPipelineArtifact@2 + displayName: Download Test Artifact + inputs: + buildType: 'current' + artifactName: WindowsTests + targetPath: $(testsFolder) + - bash: | + wget https://github.com/acoustid/chromaprint/releases/download/v1.4.3/chromaprint-fpcalc-1.4.3-linux-x86_64.tar.gz + sudo tar xf chromaprint-fpcalc-1.4.3-linux-x86_64.tar.gz --strip-components=1 --directory /usr/bin + displayName: Install fpcalc + condition: and(succeeded(), eq(variables['osName'], 'Linux')) + - powershell: Set-Service SCardSvr -StartupType Manual + displayName: Enable Windows Test Service + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + - bash: | + chmod a+x _tests/fpcalc + export DYLD_FALLBACK_LIBRARY_PATH=${BUILD_SOURCESDIRECTORY}/_tests + displayName: Make fpcalc Executable + condition: and(succeeded(), eq(variables['osName'], 'Mac')) + - task: Bash@3 + displayName: Run Tests + env: + DYLD_FALLBACK_LIBRARY_PATH: $(Build.SourcesDirectory)/_tests + TEST_DIR: $(Build.SourcesDirectory)/_tests + inputs: + targetType: 'filePath' + filePath: '$(testsFolder)/test.sh' + arguments: '$(osName) Unit Test' + - publish: TestResult.xml + artifact: 'TestResult' + displayName: Publish Test Result + condition: and(succeeded(), eq(variables['osName'], 'Windows')) + - task: PublishTestResults@2 + displayName: Publish Test Results + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '**/TestResult.xml' + testRunTitle: '$(osName) Unit Tests' + + - stage: Integration_Automation + displayName: Integration / Automation + dependsOn: Package + jobs: + + - job: Integration + strategy: + matrix: + Linux: + osName: 'Linux' + imageName: 'ubuntu-16.04' + pattern: 'Lidarr.**.linux.tar.gz' + # Mac: + # osName: 'Mac' + # imageName: 'macos-10.13' + # pattern: 'Lidarr.**.osx.tar.gz' + Windows: + osName: 'Windows' + imageName: 'vs2017-win2016' + pattern: 'Lidarr.**.windows.zip' + + pool: + vmImage: $(imageName) + + steps: + - script: | + wget https://github.com/acoustid/chromaprint/releases/download/v1.4.3/chromaprint-fpcalc-1.4.3-linux-x86_64.tar.gz + sudo tar xf chromaprint-fpcalc-1.4.3-linux-x86_64.tar.gz --strip-components=1 --directory /usr/bin + displayName: Install fpcalc + condition: and(succeeded(), eq(variables['osName'], 'Linux')) + - checkout: none + - task: DownloadPipelineArtifact@2 + displayName: Download Test Artifact + inputs: + buildType: 'current' + artifactName: WindowsTests + targetPath: $(testsFolder) + - task: DownloadPipelineArtifact@2 + displayName: Download Build Artifact + inputs: + buildType: 'current' + artifactName: Packages + itemPattern: '**/$(pattern)' + targetPath: $(Build.ArtifactStagingDirectory) + - task: ExtractFiles@1 + inputs: + archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' + destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' + displayName: Extract Package + - bash: | + mkdir -p ./bin/ + cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Lidarr/. ./bin/ + displayName: Move Package Contents + - task: Bash@3 + displayName: Run Integration Tests + inputs: + targetType: 'filePath' + filePath: '$(testsFolder)/test.sh' + arguments: $(osName) Integration Test + - task: PublishTestResults@2 + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '**/TestResult.xml' + testRunTitle: '$(osName) Integration Tests' + displayName: Publish Test Results + + - job: Automation + strategy: + matrix: + Linux: + osName: 'Linux' + imageName: 'ubuntu-16.04' + pattern: 'Lidarr.**.linux.tar.gz' + Mac: + osName: 'Mac' + imageName: 'macos-10.13' + pattern: 'Lidarr.**.osx.tar.gz' + Windows: + osName: 'Windows' + imageName: 'vs2017-win2016' + pattern: 'Lidarr.**.windows.zip' + + pool: + vmImage: $(imageName) + + steps: + - checkout: none + - task: DownloadPipelineArtifact@2 + displayName: Download Test Artifact + inputs: + buildType: 'current' + artifactName: WindowsTests + targetPath: $(testsFolder) + - task: DownloadPipelineArtifact@2 + displayName: Download Build Artifact + inputs: + buildType: 'current' + artifactName: Packages + itemPattern: '**/$(pattern)' + targetPath: $(Build.ArtifactStagingDirectory) + - task: ExtractFiles@1 + inputs: + archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)' + destinationFolder: '$(Build.ArtifactStagingDirectory)/bin' + displayName: Extract Package + - bash: | + mkdir -p ./bin/ + cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Lidarr/. ./bin/ + displayName: Move Package Contents + - bash: | + if [[ $OSNAME == "Mac" ]]; then + url=https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-macos.tar.gz + elif [[ $OSNAME == "Linux" ]]; then + url=https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz + else + echo "Unhandled OS" + exit 1 + fi + curl -s -L "$url" | tar -xz + chmod +x geckodriver + mv geckodriver _tests + displayName: Install Gecko Driver + condition: and(succeeded(), ne(variables['osName'], 'Windows')) + - bash: ls -lR + - task: Bash@3 + displayName: Run Automation Tests + inputs: + targetType: 'filePath' + filePath: '$(testsFolder)/test.sh' + arguments: $(osName) Automation Test + - task: PublishTestResults@2 + inputs: + testResultsFormat: 'NUnit' + testResultsFiles: '**/TestResult.xml' + testRunTitle: '$(osName) Automation Tests' + displayName: Publish Test Results + + - stage: Coverage + dependsOn: Build_Backend + condition: succeeded() + jobs: + - job: Windows_Coverage + displayName: Windows + pool: + vmImage: 'vs2017-win2016' + steps: + - checkout: none + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: CoverageBuild + targetPath: $(Build.SourcesDirectory) + - task: Bash@3 + displayName: Coverage Unit Tests + inputs: + targetType: 'filePath' + filePath: ./test.sh + arguments: Windows Unit Coverage + - publish: ./_tests/CoverageResults + artifact: 'CoverageResults' + displayName: Publish Coverage Result Artifact + + - stage: Coverage_Upload + dependsOn: Coverage + condition: succeeded() + displayName: Coverage Upload + jobs: + - job: Upload + pool: + vmImage: 'vs2017-win2016' + steps: + - checkout: self + fetchDepth: 1 + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: CoverageResults + targetPath: 'CoverageResults' + - task: PublishCodeCoverageResults@1 + displayName: Publish Coverage Results + inputs: + codeCoverageTool: 'cobertura' + summaryFileLocation: './CoverageResults/coverage.cobertura.xml' + + - stage: Analyze + dependsOn: + - Coverage + - Unit_Test + displayName: Analyze + + jobs: + - job: Analyze + pool: + vmImage: vs2017-win2016 + steps: + - checkout: self + submodules: true + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: CoverageResults + targetPath: $(Build.SourcesDirectory)/CoverageResults + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + artifactName: TestResult + targetPath: $(Build.SourcesDirectory)/TestResults + - task: SonarCloudPrepare@1 + env: + SONAR_SCANNER_OPTS: '' + inputs: + SonarCloud: 'SonarCloud' + organization: 'lidarr' + scannerMode: 'CLI' + configMode: 'manual' + cliProjectKey: 'lidarr_Lidarr' + cliProjectName: 'Lidarr' + cliSources: '.' + extraProperties: | + sonar.exclusions=**/obj/**,**/*.dll,**/NzbDrone.Core.Test/Files/**/* + sonar.cs.opencover.reportsPaths=$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml + sonar.cs.nunit.reportsPaths=$(Build.SourcesDirectory)/TestResults/**/TestResult.xml + - task: SonarCloudAnalyze@1 diff --git a/build.sh b/build.sh index 11d7727bb..9ebe84062 100755 --- a/build.sh +++ b/build.sh @@ -145,26 +145,6 @@ RunGulp() ProgressEnd 'Running gulp' } -CreateMdbs() -{ - local path=$1 - if [ $runtime = "dotnet" ] ; then - local pdbFiles=( $(find $path -name "*.pdb") ) - for filename in "${pdbFiles[@]}" - do - if [ -e ${filename%.pdb}.dll ] ; then - tools/pdb2mdb/pdb2mdb.exe ${filename%.pdb}.dll - fi - if [ -e ${filename%.pdb}.exe ] ; then - tools/pdb2mdb/pdb2mdb.exe ${filename%.pdb}.exe - fi - done - - echo "Removing PDBs" - find $path -name "*.pdb" -exec rm "{}" \; - fi -} - PackageMono() { ProgressStart 'Creating Mono Package' @@ -174,9 +154,6 @@ PackageMono() echo "Copying Binaries" cp -r $outputFolder $outputFolderLinux - echo "Creating MDBs" - CreateMdbs $outputFolderLinux - echo "Removing Service helpers" rm -f $outputFolderLinux/ServiceUninstall.* rm -f $outputFolderLinux/ServiceInstall.* @@ -268,10 +245,7 @@ PackageTests() cp $outputFolder/*.dll $testPackageFolder cp $outputFolder/*.exe $testPackageFolder cp $outputFolder/fpcalc $testPackageFolder - cp ./*.sh $testPackageFolder - - echo "Creating MDBs for tests" - CreateMdbs $testPackageFolder + cp ./test.sh $testPackageFolder rm -f $testPackageFolder/*.log.config @@ -283,8 +257,8 @@ PackageTests() echo "Copying CurlSharp libraries" cp $sourceFolder/ExternalModules/CurlSharp/libs/i386/* $testPackageFolder - echo "Copying dylibs" - cp -r $outputFolderMacOS/*.dylib $testPackageFolder + echo "Adding sqlite dylibs" + cp $sourceFolder/Libraries/Sqlite/*.dylib $testPackageFolder ProgressEnd 'Creating Test Package' } @@ -338,11 +312,51 @@ case "$(uname -s)" in ;; esac -Build -RunGulp -PackageMono -PackageMacOS -PackageMacOSApp -PackageTests -CleanupWindowsPackage -PackageArtifacts +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + --only-backend) + ONLY_BACKEND=YES + shift # past argument + ;; + --only-frontend) + ONLY_FRONTEND=YES + shift # past argument + ;; + --only-packages) + ONLY_PACKAGES=YES + shift # past argument + ;; + *) # unknown option + POSITIONAL+=("$1") # save it in an array for later + shift # past argument + ;; +esac +done +set -- "${POSITIONAL[@]}" # restore positional parameters + +# Only build backend if we haven't set only-frontend or only-packages +if [ -z "$ONLY_FRONTEND" ] && [ -z "$ONLY_PACKAGES" ]; +then + Build + PackageTests +fi + +# Only build frontend if we haven't set only-backend or only-packages +if [ -z "$ONLY_BACKEND" ] && [ -z "$ONLY_PACKAGES" ]; +then + RunGulp +fi + +# Only package if we haven't set only-backend or only-frontend +if [ -z "$ONLY_BACKEND" ] && [ -z "$ONLY_FRONTEND" ]; +then + PackageMono + PackageMacOS + PackageMacOSApp + CleanupWindowsPackage + PackageArtifacts +fi diff --git a/package.json b/package.json index 3964c0e66..caec6c2e2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "build": "gulp build", "start": "gulp watch", "watch": "gulp watch", - "clean": "rimraf ./_output/UI", + "clean": "git clean -fXd", "eslint": "esprint check", "eslint-fix": "eslint --fix frontend/** ", "stylelint-linux": "stylelint $(find frontend -name '*.css') --config frontend/.stylelintrc", @@ -114,7 +114,6 @@ "redux-thunk": "2.3.0", "require-nocache": "1.0.0", "reselect": "4.0.0", - "rimraf": "2.6.3", "run-sequence": "2.2.1", "signalr": "2.4.1", "streamqueue": "1.1.2", diff --git a/setup/lidarr.iss b/setup/lidarr.iss index aa2462ee3..f5f5299c5 100644 --- a/setup/lidarr.iss +++ b/setup/lidarr.iss @@ -7,9 +7,9 @@ #define ForumsURL "https://forums.lidarr.audio/" #define AppExeName "Lidarr.exe" #define BaseVersion "0.6.2" -#define BuildNumber GetEnv('APPVEYOR_BUILD_NUMBER') -#define BuildVersion GetEnv('APPVEYOR_BUILD_VERSION') -#define BranchName GetEnv('APPVEYOR_REPO_BRANCH') +#define BuildNumber GetEnv('MINORVERSION') +#define BuildVersion GetEnv('LIDARRVERSION') +#define BranchName GetEnv('BUILD_SOURCEBRANCHNAME') [Setup] ; NOTE: The value of AppId uniquely identifies this application. diff --git a/src/NzbDrone.Automation.Test/AutomationTest.cs b/src/NzbDrone.Automation.Test/AutomationTest.cs index 2a855b06c..e835cabd7 100644 --- a/src/NzbDrone.Automation.Test/AutomationTest.cs +++ b/src/NzbDrone.Automation.Test/AutomationTest.cs @@ -34,7 +34,9 @@ namespace NzbDrone.Automation.Test [OneTimeSetUp] public void SmokeTestSetup() { - driver = new FirefoxDriver(); + var options = new FirefoxOptions(); + options.AddArguments("--headless"); + driver = new FirefoxDriver(options); _runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger()); _runner.KillAll(); @@ -45,7 +47,7 @@ namespace NzbDrone.Automation.Test var page = new PageBase(driver); page.WaitForNoSpinner(); - driver.ExecuteScript("window.NzbDrone.NameViews = true;"); + driver.ExecuteScript("window.Lidarr.NameViews = true;"); GetPageErrors().Should().BeEmpty(); } diff --git a/src/NzbDrone.Automation.Test/MainPagesTest.cs b/src/NzbDrone.Automation.Test/MainPagesTest.cs index 76e68e296..005d55cec 100644 --- a/src/NzbDrone.Automation.Test/MainPagesTest.cs +++ b/src/NzbDrone.Automation.Test/MainPagesTest.cs @@ -1,4 +1,4 @@ -using FluentAssertions; +using FluentAssertions; using NUnit.Framework; using NzbDrone.Automation.Test.PageModel; using OpenQA.Selenium; @@ -21,7 +21,7 @@ namespace NzbDrone.Automation.Test { page.ArtistNavIcon.Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-artist-index-artistindexlayout").Should().NotBeNull(); + page.Find(By.CssSelector("div[class*='ArtistIndex']")).Should().NotBeNull(); } [Test] @@ -30,7 +30,7 @@ namespace NzbDrone.Automation.Test page.CalendarNavIcon.Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-calendar-calendarlayout").Should().NotBeNull(); + page.Find(By.CssSelector("div[class*='CalendarPage']")).Should().NotBeNull(); } [Test] @@ -39,7 +39,9 @@ namespace NzbDrone.Automation.Test page.ActivityNavIcon.Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-activity-activitylayout").Should().NotBeNull(); + page.Find(By.LinkText("Queue")).Should().NotBeNull(); + page.Find(By.LinkText("History")).Should().NotBeNull(); + page.Find(By.LinkText("Blacklist")).Should().NotBeNull(); } [Test] @@ -48,7 +50,8 @@ namespace NzbDrone.Automation.Test page.WantedNavIcon.Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-wanted-missing-missinglayout").Should().NotBeNull(); + page.Find(By.LinkText("Missing")).Should().NotBeNull(); + page.Find(By.LinkText("Cutoff Unmet")).Should().NotBeNull(); } [Test] @@ -57,20 +60,20 @@ namespace NzbDrone.Automation.Test page.SystemNavIcon.Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-system-systemlayout").Should().NotBeNull(); + page.Find(By.CssSelector("div[class*='Health']")).Should().NotBeNull(); } [Test] - public void add_series_page() + public void add_artist_page() { page.ArtistNavIcon.Click(); page.WaitForNoSpinner(); - page.Find(By.LinkText("Add Artist")).Click(); + page.Find(By.LinkText("Add New")).Click(); page.WaitForNoSpinner(); - page.FindByClass("iv-addartist-addartistlayout").Should().NotBeNull(); + page.Find(By.CssSelector("input[class*='AddNewArtist-searchInput']")).Should().NotBeNull(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Automation.Test/NzbDrone.Automation.Test.csproj b/src/NzbDrone.Automation.Test/NzbDrone.Automation.Test.csproj index fc9ffb6e5..50bf57b92 100644 --- a/src/NzbDrone.Automation.Test/NzbDrone.Automation.Test.csproj +++ b/src/NzbDrone.Automation.Test/NzbDrone.Automation.Test.csproj @@ -85,8 +85,14 @@ 3.11.0 + + 0.24.0 + - 3.2.0 + 3.141.0 + + + 3.141.0 diff --git a/src/NzbDrone.Automation.Test/PageModel/PageBase.cs b/src/NzbDrone.Automation.Test/PageModel/PageBase.cs index 16bacc540..720eafd8c 100644 --- a/src/NzbDrone.Automation.Test/PageModel/PageBase.cs +++ b/src/NzbDrone.Automation.Test/PageModel/PageBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using OpenQA.Selenium; using OpenQA.Selenium.Remote; @@ -47,16 +47,16 @@ namespace NzbDrone.Automation.Test.PageModel }); } - public IWebElement ArtistNavIcon => FindByClass("x-artist-nav"); + public IWebElement ArtistNavIcon => Find(By.LinkText("Artist")); - public IWebElement CalendarNavIcon => FindByClass("x-calendar-nav"); + public IWebElement CalendarNavIcon => Find(By.LinkText("Calendar")); - public IWebElement ActivityNavIcon => FindByClass("x-activity-nav"); + public IWebElement ActivityNavIcon => Find(By.LinkText("Activity")); - public IWebElement WantedNavIcon => FindByClass("x-wanted-nav"); + public IWebElement WantedNavIcon => Find(By.LinkText("Wanted")); - public IWebElement SettingNavIcon => FindByClass("x-settings-nav"); + public IWebElement SettingNavIcon => Find(By.LinkText("Settings")); - public IWebElement SystemNavIcon => FindByClass("x-system-nav"); + public IWebElement SystemNavIcon => Find(By.PartialLinkText("System")); } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Common/NzbDrone.Common.csproj b/src/NzbDrone.Common/NzbDrone.Common.csproj index 72ccda376..087b1b639 100644 --- a/src/NzbDrone.Common/NzbDrone.Common.csproj +++ b/src/NzbDrone.Common/NzbDrone.Common.csproj @@ -236,10 +236,6 @@ {74420a79-cc16-442c-8b1e-7c1b913844f0} CurlSharp - - {9DC31DE3-79FF-47A8-96B4-6BA18F6BB1CB} - LogentriesNLog - @@ -270,4 +266,4 @@ --> - + \ No newline at end of file diff --git a/test.sh b/test.sh index bfb443ff4..9cb45d057 100755 --- a/test.sh +++ b/test.sh @@ -1,37 +1,63 @@ #! /bin/bash PLATFORM=$1 TYPE=$2 +COVERAGE=$3 WHERE="cat != ManualTest" -TEST_DIR="." TEST_PATTERN="*Test.dll" ASSEMBLIES="" TEST_LOG_FILE="TestLog.txt" +echo "test dir: $TEST_DIR" +if [ -z "$TEST_DIR" ]; then + TEST_DIR="." +fi + if [ -d "$TEST_DIR/_tests" ]; then TEST_DIR="$TEST_DIR/_tests" fi +COVERAGE_RESULT_DIRECTORY="$TEST_DIR/CoverageResults/" + rm -f "$TEST_LOG_FILE" # Uncomment to log test output to a file instead of the console export LIDARR_TESTS_LOG_OUTPUT="File" -if [[ -z "${APPVEYOR}" ]]; then - NUNIT="$TEST_DIR/NUnit.ConsoleRunner.3.7.0/tools/nunit3-console.exe" - NUNIT_COMMAND="$NUNIT" - NUNIT_PARAMS="--workers=1" -elif [ "$PLATFORM" = "Windows" ]; then - NUNIT="nunit3-console" - NUNIT_COMMAND="$NUNIT" - NUNIT_PARAMS="--result=myresults.xml;format=AppVeyor --workers=1" - unset TMP - unset TEMP -else - NUNIT="$TEST_DIR/NUnit.ConsoleRunner.3.7.0/tools/nunit3-console.exe" - NUNIT_COMMAND="$NUNIT" - NUNIT_PARAMS="--result=myresults.xml --workers=1" - unset TMP - unset TEMP +NUNIT="$TEST_DIR/NUnit.ConsoleRunner.3.7.0/tools/nunit3-console.exe" +NUNIT_COMMAND="$NUNIT" +NUNIT_PARAMS="--workers=1" + +if [ "$PLATFORM" = "Mac" ]; then + + #set up environment + if [[ -x '/opt/local/bin/mono' ]]; then + # Macports and mono-supplied installer path + export PATH="/opt/local/bin:$PATH" + elif [[ -x '/usr/local/bin/mono' ]]; then + # Homebrew-supplied path to mono + export PATH="/usr/local/bin:$PATH" + fi + + echo $TEST_DIR + export DYLD_FALLBACK_LIBRARY_PATH="$TEST_DIR" + + if [ -e /Library/Frameworks/Mono.framework ]; then + MONO_FRAMEWORK_PATH=/Library/Frameworks/Mono.framework/Versions/Current + export PATH="$MONO_FRAMEWORK_PATH/bin:$PATH" + export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$MONO_FRAMEWORK_PATH/lib" + fi + + if [[ -f '/opt/local/lib/libsqlite3.0.dylib' ]]; then + export DYLD_FALLBACK_LIBRARY_PATH="/opt/local/lib:$DYLD_FALLBACK_LIBRARY_PATH" + fi + + export DYLD_FALLBACK_LIBRARY_PATH="$DYLD_FALLBACK_LIBRARY_PATH:$HOME/lib:/usr/local/lib:/lib:/usr/lib" + echo $LD_LIBRARY_PATH + echo $DYLD_LIBRARY_PATH + echo $DYLD_FALLBACK_LIBRARY_PATH + + # To debug which libraries are being loaded: + # export DYLD_PRINT_LIBRARIES=YES fi if [ "$PLATFORM" = "Windows" ]; then @@ -61,16 +87,27 @@ for i in `find $TEST_DIR -name "$TEST_PATTERN"`; do ASSEMBLIES="$ASSEMBLIES $i" done -$NUNIT_COMMAND --where "$WHERE" $NUNIT_PARAMS $ASSEMBLIES; -EXIT_CODE=$? - -if [ "$EXIT_CODE" -ge 0 ]; then - if [[ -z "${APPVEYOR}" ]]; then - echo "Failed tests: $EXIT_CODE" +if [ "$COVERAGE" = "Coverage" ]; then + if [ "$PLATFORM" = "Windows" ] || [ "$PLATFORM" = "Linux" ]; then + dotnet tool install coverlet.console --tool-path="$TEST_DIR/coverlet/" + mkdir $COVERAGE_RESULT_DIRECTORY + OPEN_COVER="$TEST_DIR/coverlet/coverlet" + $OPEN_COVER "$TEST_DIR/" --verbosity "detailed" --format "cobertura" --format "opencover" --output "$COVERAGE_RESULT_DIRECTORY" --exclude "[Lidarr.*.Test]*" --exclude "[Lidarr.Test.*]*" --exclude "[Marr.Data]*" --exclude "[MonoTorrent]*" --exclude "[CurlSharp]*" --target "$NUNIT" --targetargs "$NUNIT_PARAMS --where=\"$WHERE\" $ASSEMBLIES"; + EXIT_CODE=$? else - echo "Failed tests: $EXIT_CODE" - appveyor AddMessage "Failed tests: $EXIT_CODE" + echo "Coverage only supported on Windows and Linux" + exit 3 fi +elif [ "$COVERAGE" = "Test" ] ; then + $NUNIT_COMMAND --where "$WHERE" $NUNIT_PARAMS $ASSEMBLIES; + EXIT_CODE=$? +else + echo "Run Type must be provided as third argument: Coverage or Test" + exit 3 +fi + +if [ "$EXIT_CODE" -ge 0 ]; then + echo "Failed tests: $EXIT_CODE" exit 0 else exit $EXIT_CODE