diff --git a/.ado/jobs/cli-init-windows.yml b/.ado/jobs/cli-init-windows.yml new file mode 100644 index 00000000000..35e9736c8bb --- /dev/null +++ b/.ado/jobs/cli-init-windows.yml @@ -0,0 +1,90 @@ +parameters: + - name: buildEnvironment + type: string + default: PullRequest + values: + - PullRequest + - Continuous + - name: AgentPool + type: object + - name: buildMatrix + type: object + default: + - BuildEnvironment: PullRequest + Matrix: + - Name: FabricX64Release + template: cpp-app + configuration: Release + platform: x64 + additionalRunArguments: --no-autolink + - Name: FabricX86Debug + template: cpp-app + configuration: Debug + platform: x86 + additionalRunArguments: --no-autolink + - BuildEnvironment: Continuous + Matrix: + - Name: FabricX64Debug + template: cpp-app + configuration: Debug + platform: x64 + additionalRunArguments: --no-autolink + - Name: FabricX64Release + template: cpp-app + configuration: Release + platform: x64 + additionalRunArguments: --no-autolink + - Name: FabricX86Debug + template: cpp-app + configuration: Debug + platform: x86 + additionalRunArguments: --no-autolink + - Name: FabricX86Release + template: cpp-app + configuration: Release + platform: x86 + additionalRunArguments: --no-autolink +jobs: + - ${{ each config in parameters.buildMatrix }}: + - ${{ if eq(config.BuildEnvironment, parameters.buildEnvironment) }}: + - ${{ each matrix in config.Matrix }}: + - job: CliInitWindows${{ matrix.Name }} + displayName: Verify CliInitWindows ${{ matrix.Name }} + + variables: [template: ../variables/windows.yml] + + ${{ if eq(matrix.lowResource, true) }}: + pool: ${{ parameters.AgentPool.Small }} + ${{ else }}: + pool: ${{ parameters.AgentPool.Medium }} + timeoutInMinutes: 60 + cancelTimeoutInMinutes: 5 + + steps: + - template: ../templates/checkout-full.yml + parameters: + persistCredentials: false # We don't need git creds in this job + + - template: ../templates/prepare-js-env.yml + + - template: ../templates/prepare-build-env.yml + parameters: + platform: ${{ parameters.platform }} + configuration: ${{ parameters.configuration }} + buildEnvironment: ${{ parameters.buildEnvironment }} + + - task: CmdLine@2 + displayName: Create npm directory + name: createNpmDirectory + inputs: + script: mkdir %APPDATA%\npm + + - template: ../templates/react-native-init-windows.yml + parameters: + template: ${{ matrix.template }} + configuration: ${{ matrix.configuration }} + platform: ${{ matrix.platform }} + additionalInitArguments: ${{ matrix.additionalInitArguments }} + additionalRunArguments: ${{ matrix.additionalRunArguments }} + runWack: ${{ coalesce(matrix.runWack, false) }} + buildEnvironment: ${{ parameters.buildEnvironment }} \ No newline at end of file diff --git a/.ado/jobs/cli-init.yml b/.ado/jobs/cli-init.yml index 572408f4feb..3c1b7915474 100644 --- a/.ado/jobs/cli-init.yml +++ b/.ado/jobs/cli-init.yml @@ -96,20 +96,6 @@ parameters: platform: x64 projectType: app lowResource: true - - Name: FabricX64Release - language: cpp - configuration: Release - platform: x64 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink - - Name: FabricX86Debug - language: cpp - configuration: Debug - platform: x86 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink - BuildEnvironment: Continuous Matrix: - Name: X64ReleaseCpp @@ -283,34 +269,7 @@ parameters: platform: x64 projectType: app lowResource: true - - Name: FabricX64Debug - language: cpp - configuration: Debug - platform: x64 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink - - Name: FabricX64Release - language: cpp - configuration: Release - platform: x64 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink - - Name: FabricX86Debug - language: cpp - configuration: Debug - platform: x86 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink - - Name: FabricX86Release - language: cpp - configuration: Release - platform: x86 - projectType: app - initPath: InitWindows - additionalRunArguments: --no-autolink + jobs: - ${{ each config in parameters.buildMatrix }}: - ${{ if eq(config.BuildEnvironment, parameters.buildEnvironment) }}: @@ -357,7 +316,6 @@ jobs: configuration: ${{ matrix.configuration }} platform: ${{ matrix.platform }} projectType: ${{ matrix.projectType }} - initPath: ${{ coalesce(matrix.initPath, 'ReactNativeWindowsInit') }} additionalInitArguments: ${{ matrix.additionalInitArguments }} additionalRunArguments: ${{ matrix.additionalRunArguments }} runWack: ${{ coalesce(matrix.runWack, false) }} diff --git a/.ado/stages.yml b/.ado/stages.yml index 5960f6dcf18..42f6c548352 100644 --- a/.ado/stages.yml +++ b/.ado/stages.yml @@ -85,3 +85,8 @@ stages: buildEnvironment: ${{ parameters.buildEnvironment }} AgentPool: ${{ parameters.AgentPool }} buildNuGetOnly: false + + - template: jobs/cli-init-windows.yml + parameters: + buildEnvironment: ${{ parameters.buildEnvironment }} + AgentPool: ${{ parameters.AgentPool }} diff --git a/.ado/templates/react-native-debug-info.yml b/.ado/templates/react-native-debug-info.yml new file mode 100644 index 00000000000..b0ffb8042ac --- /dev/null +++ b/.ado/templates/react-native-debug-info.yml @@ -0,0 +1,28 @@ +# +parameters: + - name: workingDirectory + type: string + - name: doctor + type: boolean + default: true + - name: config + type: boolean + default: true + +steps: + # Useful info to have in the log, but also a necessary workaround to make sure the cli is cached by npx + - script: npx react-native info + displayName: React Native Info + workingDirectory: ${{ parameters.workingDirectory }} + + - ${{ if eq(parameters.doctor, true) }}: + # Verify react-native doctor command works + - script: npx react-native doctor + displayName: React Native Doctor + workingDirectory: ${{ parameters.workingDirectory }} + + - ${{ if eq(parameters.config, true) }}: + # Print the config for debugging react-native CLI commands + - script: npx react-native config + displayName: React Native Config + workingDirectory: ${{ parameters.workingDirectory }} diff --git a/.ado/templates/react-native-init-windows.yml b/.ado/templates/react-native-init-windows.yml new file mode 100644 index 00000000000..69ee0b100a8 --- /dev/null +++ b/.ado/templates/react-native-init-windows.yml @@ -0,0 +1,140 @@ +# +parameters: + - name: template + type: string + - name: platform + type: string + values: + - x86 + - x64 + - ARM64 + - name: configuration + type: string + values: + - Debug + - Release + - name: additionalRunArguments + type: string + default: '' + - name: additionalInitArguments + type: string + default: '' + - name: runWack + type: boolean + default: false + - name: buildEnvironment + type: string + default: PullRequest + values: + - PullRequest + - Continuous + +steps: + # Start npm test server + - template: verdaccio-start.yml + + - template: set-version-vars.yml + parameters: + buildEnvironment: ${{ parameters.buildEnvironment }} + + - ${{ if endsWith(parameters.template, '-app') }}: + - script: | + npx --yes react-native@$(reactNativeDevDependency) init testcli --template react-native@$(reactNativeDevDependency) + displayName: Init new app project + workingDirectory: $(Agent.BuildDirectory) + + - ${{ if endsWith(parameters.template, '-lib') }}: + - script: | + npx --yes create-react-native-module@0.20.2 --package-name "testcli" testcli + displayName: Init new lib project + workingDirectory: $(Agent.BuildDirectory) + + - script: | + rmdir /s /q android + displayName: Remove broken android folder # See issue https://github.com/microsoft/react-native-windows/issues/12209 + workingDirectory: $(Agent.BuildDirectory)\testcli + + - script: | + call yarn install + call yarn upgrade react@$(reactDevDependency) --dev + call yarn upgrade react-native@$(reactNativeDevDependency) --dev + displayName: Update project react and react-native dev versions + workingDirectory: $(Agent.BuildDirectory)\testcli + + - script: | + call yarn add react-native-windows@$(npmVersion) + displayName: yarn add react-native-windows@$(npmVersion) + workingDirectory: $(Agent.BuildDirectory)\testcli + env: + npm_config_registry: http://localhost:4873 + + - script: | + call yarn react-native init-windows --template ${{ parameters.template }} --overwrite --logging ${{ parameters.additionalInitArguments }} + displayName: Call react-native init-windows + workingDirectory: $(Agent.BuildDirectory)\testcli + env: + npm_config_registry: http://localhost:4873 + + - ${{ if endsWith(parameters.template, '-app') }}: + - powershell: | + $path = (Get-ChildItem -Filter "Package.appxmanifest" -File -Recurse).FullName; + [xml] $manifest = Get-Content $path + $manifest.Package.Identity.Name = 'ReactNative.InitTest' + $manifest.Save("$path") + displayName: Set AppX package name to "ReactNative.InitTest" + workingDirectory: $(Agent.BuildDirectory)\testcli\windows + + # End npm test server + - template: verdaccio-stop.yml + + - task: PowerShell@2 + displayName: Start tracing + inputs: + targetType: filePath # filePath | inline + filePath: $(Build.SourcesDirectory)\vnext\Scripts\Tracing\Start-Tracing.ps1 + + - template: react-native-debug-info.yml + parameters: + workingDirectory: $(Agent.BuildDirectory)\testcli + + - template: ../templates/run-windows-with-certificates.yml + parameters: + buildEnvironment: ${{ parameters.BuildEnvironment }} + certificateName: RNWEncodedKey + buildConfiguration: ${{ parameters.configuration }} + buildPlatform: ${{ parameters.platform }} + deployOption: ${{ parameters.additionalRunArguments }} + buildLogDirectory: $(Build.BinariesDirectory)\${{ parameters.platform }}\${{ parameters.configuration }}\BuildLogs + workingDirectory: $(Agent.BuildDirectory)\testcli + restoreLockedMode: false # Allow new lockfile to be created + + - template: upload-build-logs.yml + parameters: + buildLogDirectory: '$(Build.BinariesDirectory)\${{ parameters.platform }}\${{ parameters.configuration }}\BuildLogs' + + # Only test bundling in debug since we already bundle as part of release builds + - ${{ if and(endsWith(parameters.template, '-app'), eq(parameters.configuration, 'Debug')) }}: + - script: npx react-native bundle --entry-file index.js --platform windows --bundle-output test.bundle + displayName: Create bundle testcli + workingDirectory: $(Agent.BuildDirectory)\testcli + + - ${{ if eq(parameters.runWack, true) }}: + - template: ../templates/run-wack.yml + parameters: + packageName: ReactNative.InitTest + reportArtifact: 'Template App WACK Report ${{ parameters.platform }} ${{ parameters.configuration }} ($(System.JobAttempt))' + + - task: PowerShell@2 + displayName: Stop tracing + inputs: + targetType: filePath # filePath | inline + filePath: $(Build.SourcesDirectory)\vnext\Scripts\Tracing\Stop-Tracing.ps1 + arguments: -NoAnalysis -outputFolder $(Build.StagingDirectory)/Tracing + condition: succeededOrFailed() + + - task: PublishBuildArtifacts@1 + displayName: Upload traces + inputs: + pathtoPublish: '$(Build.StagingDirectory)/Tracing' + artifactName: 'Traces - $(Agent.JobName)-$(System.JobAttempt)' + condition: succeededOrFailed() diff --git a/.ado/templates/react-native-init.yml b/.ado/templates/react-native-init.yml index b8637dd9665..6c00615b7a9 100644 --- a/.ado/templates/react-native-init.yml +++ b/.ado/templates/react-native-init.yml @@ -30,12 +30,6 @@ parameters: - name: runWack type: boolean default: false - - name: initPath - type: string - default: ReactNativeWindowsInit - values: - - ReactNativeWindowsInit - - InitWindows - name: additionalInitArguments type: string default: '' @@ -47,19 +41,8 @@ parameters: - Continuous steps: - - powershell: start-process verdaccio.cmd -ArgumentList @('--config', './.ado/verdaccio/config.yaml') - displayName: Launch test npm server (verdaccio) - - - script: node .ado/scripts/waitForVerdaccio.js - displayName: Wait for verdaccio server to boot - - - script: node .ado/scripts/npmAddUser.js user pass mail@nomail.com http://localhost:4873 - displayName: Add npm user to verdaccio - - - template: compute-beachball-branch-name.yml - - - script: npx beachball publish --branch origin/$(BeachBallBranchName) --no-push --registry http://localhost:4873 --yes --verbose --access public --changehint "Run `yarn change` from root of repo to generate a change file." - displayName: Publish packages to verdaccio + # Start npm test server + - template: verdaccio-start.yml - template: set-version-vars.yml parameters: @@ -104,56 +87,32 @@ steps: displayName: Update lib project react and react-native dev versions workingDirectory: $(Agent.BuildDirectory)\testcli - - script: yarn config set registry http://localhost:4873 - displayName: Modify yarn config to point to local verdaccio server - - - ${{ if eq(parameters.initPath, 'ReactNativeWindowsInit') }}: - - - ${{ if eq(parameters.useNuget, true) }}: - - script: | - npx --yes react-native-windows-init@latest --verbose --version $(npmVersion) --overwrite --language ${{ parameters.language }} --projectType ${{ parameters.projectType }} ${{ parameters.additionalInitArguments }} --experimentalNuGetDependency true --nuGetTestFeed $(System.DefaultWorkingDirectory)\NuGetTestFeed - displayName: Apply windows template (with nuget) - workingDirectory: $(Agent.BuildDirectory)\testcli - env: - npm_config_registry: http://localhost:4873 - - - ${{ if eq(parameters.useNuget, false) }}: - - script: | - npx --yes react-native-windows-init@latest --verbose --version $(npmVersion) --overwrite --language ${{ parameters.language }} --projectType ${{ parameters.projectType }} ${{ parameters.additionalInitArguments }} - displayName: Apply windows template (without nuget) - workingDirectory: $(Agent.BuildDirectory)\testcli - env: - npm_config_registry: http://localhost:4873 - - - ${{ if eq(parameters.projectType, 'app') }}: - - powershell: | - [xml] $manifest = Get-Content .\Package.appxmanifest - $manifest.Package.Identity.Name = 'ReactNative.InitTest' - $manifest.Save("$pwd\Package.appxmanifest") - displayName: Set AppX package name to "ReactNative.InitTest" - workingDirectory: $(Agent.BuildDirectory)\testcli\windows\testcli - - - ${{ if eq(parameters.initPath, 'InitWindows') }}: - - ${{ if and(eq(parameters.projectType, 'app'), eq(parameters.language, 'cpp')) }}: - - script: | - call yarn add react-native-windows@$(npmVersion) - call yarn react-native init-windows --template cpp-app --overwrite --logging ${{ parameters.additionalInitArguments }} - displayName: Call react-native init-windows - workingDirectory: $(Agent.BuildDirectory)\testcli - env: - npm_config_registry: http://localhost:4873 - - - powershell: | - [xml] $manifest = Get-Content .\Package.appxmanifest - $manifest.Package.Identity.Name = 'ReactNative.InitTest' - $manifest.Save("$pwd\Package.appxmanifest") - displayName: Set AppX package name to "ReactNative.InitTest" - workingDirectory: $(Agent.BuildDirectory)\testcli\windows\testcli.Package - - # Reclaim memory used by Verdaccio to reduce the chance of build OOM issues - - script: tskill node - displayName: Kill Verdaccio - condition: succeededOrFailed() + - ${{ if eq(parameters.useNuget, true) }}: + - script: | + npx --yes react-native-windows-init@latest --verbose --version $(npmVersion) --overwrite --language ${{ parameters.language }} --projectType ${{ parameters.projectType }} ${{ parameters.additionalInitArguments }} --experimentalNuGetDependency true --nuGetTestFeed $(System.DefaultWorkingDirectory)\NuGetTestFeed + displayName: Apply windows template (with nuget) + workingDirectory: $(Agent.BuildDirectory)\testcli + env: + npm_config_registry: http://localhost:4873 + + - ${{ if eq(parameters.useNuget, false) }}: + - script: | + npx --yes react-native-windows-init@latest --verbose --version $(npmVersion) --overwrite --language ${{ parameters.language }} --projectType ${{ parameters.projectType }} ${{ parameters.additionalInitArguments }} + displayName: Apply windows template (without nuget) + workingDirectory: $(Agent.BuildDirectory)\testcli + env: + npm_config_registry: http://localhost:4873 + + - ${{ if eq(parameters.projectType, 'app') }}: + - powershell: | + [xml] $manifest = Get-Content .\Package.appxmanifest + $manifest.Package.Identity.Name = 'ReactNative.InitTest' + $manifest.Save("$pwd\Package.appxmanifest") + displayName: Set AppX package name to "ReactNative.InitTest" + workingDirectory: $(Agent.BuildDirectory)\testcli\windows\testcli + + # End npm test server + - template: verdaccio-stop.yml - task: PowerShell@2 displayName: Start tracing @@ -161,15 +120,9 @@ steps: targetType: filePath # filePath | inline filePath: $(Build.SourcesDirectory)\vnext\Scripts\Tracing\Start-Tracing.ps1 - # Useful info to have in the log, but also a necessary workaround to make sure the cli is cached by npx - - script: npx react-native info - displayName: React Native Info - workingDirectory: $(Agent.BuildDirectory)\testcli - - # Verify react-native doctor command works - - script: npx react-native doctor - displayName: React Native Doctor - workingDirectory: $(Agent.BuildDirectory)\testcli + - template: react-native-debug-info.yml + parameters: + workingDirectory: $(Agent.BuildDirectory)\testcli - template: ../templates/run-windows-with-certificates.yml parameters: @@ -198,15 +151,6 @@ steps: packageName: ReactNative.InitTest reportArtifact: 'Template App WACK Report ${{ parameters.platform }} ${{ parameters.configuration }} ($(System.JobAttempt))' - # We are experiencing random package restore failures. - # We want to uploading the vedaccio logs to aid in diagnosing if it is verdaccio or npmjs.org - - task: PublishPipelineArtifact@1 - displayName: Upload Verdaccio.log (on failure) - inputs: - targetPath: 'verdaccio.log' - artifact: '$(Agent.JobName).Verdaccio.log-$(System.JobAttempt)' - condition: failed() - - task: PowerShell@2 displayName: Stop tracing inputs: diff --git a/.ado/templates/verdaccio-start.yml b/.ado/templates/verdaccio-start.yml new file mode 100644 index 00000000000..294219a8016 --- /dev/null +++ b/.ado/templates/verdaccio-start.yml @@ -0,0 +1,24 @@ +# +parameters: + - name: beachballPublish + type: boolean + default: true + +steps: + - powershell: start-process verdaccio.cmd -ArgumentList @('--config', './.ado/verdaccio/config.yaml') + displayName: Launch test npm server (verdaccio) + + - script: node .ado/scripts/waitForVerdaccio.js + displayName: Wait for verdaccio server to boot + + - script: node .ado/scripts/npmAddUser.js user pass mail@nomail.com http://localhost:4873 + displayName: Add npm user to verdaccio + + - template: compute-beachball-branch-name.yml + + - ${{ if eq(parameters.beachballPublish, true) }}: + - script: npx beachball publish --branch origin/$(BeachBallBranchName) --no-push --registry http://localhost:4873 --yes --verbose --access public --changehint "Run `yarn change` from root of repo to generate a change file." + displayName: Publish packages to verdaccio + + - script: yarn config set registry http://localhost:4873 + displayName: Modify yarn config to point to local verdaccio server diff --git a/.ado/templates/verdaccio-stop.yml b/.ado/templates/verdaccio-stop.yml new file mode 100644 index 00000000000..18c7a21566f --- /dev/null +++ b/.ado/templates/verdaccio-stop.yml @@ -0,0 +1,21 @@ +# +parameters: + - name: uploadLogs + type: boolean + default: true + +steps: + # Reclaim memory used by Verdaccio to reduce the chance of build OOM issues + - script: tskill node + displayName: Kill Verdaccio + condition: succeededOrFailed() + + - ${{ if eq(parameters.uploadLogs, true) }}: + # We are experiencing random package restore failures. + # We want to uploading the vedaccio logs to aid in diagnosing if it is verdaccio or npmjs.org + - task: PublishPipelineArtifact@1 + displayName: Upload Verdaccio.log (on failure) + inputs: + targetPath: 'verdaccio.log' + artifact: '$(Agent.JobName).Verdaccio.log-$(System.JobAttempt)' + condition: failed()