├── .config ├── 1espt │ └── PipelineAutobaseliningConfig.yml ├── credscan │ └── Suppressions.json └── guardian │ └── .gdnbaselines ├── .editorconfig ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── CODE_OF_CONDUCT.md ├── Developer-guide.ipynb ├── Directory.Build.props ├── Directory.Build.targets ├── Directory.Packages.props ├── Dockerfile ├── DotNetTry.md ├── DotNetTryLocal.md ├── License.txt ├── NuGet.config ├── PeakyTests.ipynb ├── README.md ├── TryDotNet.sln ├── TryDotNet.v3.ncrunchsolution ├── azure-pipelines-CI.yml ├── azure-pipelines.yml ├── build-integration.cmd ├── build-js.cmd ├── build-js.sh ├── build.cmd ├── build.sh ├── eng ├── AfterSolutionBuild.targets ├── CIBuild.cmd ├── Publishing.props ├── SignCheckExclusionsFile.txt ├── Signing.props ├── Version.Details.xml ├── Versions.props ├── build.ps1 ├── build.sh ├── cibuild.sh ├── common │ ├── BuildConfiguration │ │ └── build-configuration.json │ ├── CIBuild.cmd │ ├── PSScriptAnalyzerSettings.psd1 │ ├── README.md │ ├── SetupNugetSources.ps1 │ ├── SetupNugetSources.sh │ ├── build.ps1 │ ├── build.sh │ ├── cibuild.sh │ ├── cross │ │ ├── arm │ │ │ ├── sources.list.bionic │ │ │ ├── sources.list.jessie │ │ │ ├── sources.list.xenial │ │ │ └── sources.list.zesty │ │ ├── arm64 │ │ │ ├── sources.list.bionic │ │ │ ├── sources.list.xenial │ │ │ └── sources.list.zesty │ │ ├── armel │ │ │ ├── armel.jessie.patch │ │ │ ├── sources.list.jessie │ │ │ └── tizen │ │ │ │ └── tizen.patch │ │ ├── armv6 │ │ │ └── sources.list.buster │ │ ├── build-android-rootfs.sh │ │ ├── build-rootfs.sh │ │ ├── ppc64le │ │ │ └── sources.list.bionic │ │ ├── riscv64 │ │ │ └── sources.list.sid │ │ ├── s390x │ │ │ └── sources.list.bionic │ │ ├── tizen-build-rootfs.sh │ │ ├── tizen-fetch.sh │ │ ├── toolchain.cmake │ │ └── x86 │ │ │ ├── sources.list.bionic │ │ │ └── sources.list.xenial │ ├── darc-init.ps1 │ ├── darc-init.sh │ ├── dotnet-install.cmd │ ├── dotnet-install.ps1 │ ├── dotnet-install.sh │ ├── enable-cross-org-publishing.ps1 │ ├── generate-locproject.ps1 │ ├── generate-sbom-prep.ps1 │ ├── generate-sbom-prep.sh │ ├── helixpublish.proj │ ├── init-tools-native.cmd │ ├── init-tools-native.ps1 │ ├── init-tools-native.sh │ ├── internal-feed-operations.ps1 │ ├── internal-feed-operations.sh │ ├── internal │ │ ├── Directory.Build.props │ │ ├── NuGet.config │ │ └── Tools.csproj │ ├── loc │ │ └── P22DotNetHtmlLocalization.lss │ ├── msbuild.ps1 │ ├── msbuild.sh │ ├── native │ │ ├── CommonLibrary.psm1 │ │ ├── common-library.sh │ │ ├── init-compiler.sh │ │ ├── init-distro-rid.sh │ │ ├── init-os-and-arch.sh │ │ ├── install-cmake-test.sh │ │ ├── install-cmake.sh │ │ └── install-tool.ps1 │ ├── pipeline-logging-functions.ps1 │ ├── pipeline-logging-functions.sh │ ├── post-build │ │ ├── add-build-to-channel.ps1 │ │ ├── check-channel-consistency.ps1 │ │ ├── nuget-validation.ps1 │ │ ├── post-build-utils.ps1 │ │ ├── publish-using-darc.ps1 │ │ ├── sourcelink-validation.ps1 │ │ ├── symbols-validation.ps1 │ │ └── trigger-subscriptions.ps1 │ ├── retain-build.ps1 │ ├── sdk-task.ps1 │ ├── sdl │ │ ├── NuGet.config │ │ ├── configure-sdl-tool.ps1 │ │ ├── execute-all-sdl-tools.ps1 │ │ ├── extract-artifact-archives.ps1 │ │ ├── extract-artifact-packages.ps1 │ │ ├── init-sdl.ps1 │ │ ├── packages.config │ │ ├── run-sdl.ps1 │ │ ├── sdl.ps1 │ │ └── trim-assets-version.ps1 │ ├── templates-official │ │ ├── job │ │ │ ├── job.yml │ │ │ ├── onelocbuild.yml │ │ │ ├── publish-build-assets.yml │ │ │ ├── source-build.yml │ │ │ └── source-index-stage1.yml │ │ ├── jobs │ │ │ ├── codeql-build.yml │ │ │ ├── jobs.yml │ │ │ └── source-build.yml │ │ ├── post-build │ │ │ ├── common-variables.yml │ │ │ ├── post-build.yml │ │ │ ├── setup-maestro-vars.yml │ │ │ └── trigger-subscription.yml │ │ ├── steps │ │ │ ├── add-build-to-channel.yml │ │ │ ├── build-reason.yml │ │ │ ├── component-governance.yml │ │ │ ├── enable-internal-runtimes.yml │ │ │ ├── execute-codeql.yml │ │ │ ├── execute-sdl.yml │ │ │ ├── generate-sbom.yml │ │ │ ├── get-delegation-sas.yml │ │ │ ├── get-federated-access-token.yml │ │ │ ├── publish-logs.yml │ │ │ ├── retain-build.yml │ │ │ ├── send-to-helix.yml │ │ │ └── source-build.yml │ │ └── variables │ │ │ ├── pool-providers.yml │ │ │ └── sdl-variables.yml │ ├── templates │ │ ├── job │ │ │ ├── execute-sdl.yml │ │ │ ├── job.yml │ │ │ ├── onelocbuild.yml │ │ │ ├── publish-build-assets.yml │ │ │ ├── source-build.yml │ │ │ └── source-index-stage1.yml │ │ ├── jobs │ │ │ ├── codeql-build.yml │ │ │ ├── jobs.yml │ │ │ └── source-build.yml │ │ ├── post-build │ │ │ ├── common-variables.yml │ │ │ ├── post-build.yml │ │ │ ├── setup-maestro-vars.yml │ │ │ └── trigger-subscription.yml │ │ ├── steps │ │ │ ├── add-build-to-channel.yml │ │ │ ├── build-reason.yml │ │ │ ├── component-governance.yml │ │ │ ├── enable-internal-runtimes.yml │ │ │ ├── execute-codeql.yml │ │ │ ├── execute-sdl.yml │ │ │ ├── generate-sbom.yml │ │ │ ├── get-delegation-sas.yml │ │ │ ├── get-federated-access-token.yml │ │ │ ├── publish-logs.yml │ │ │ ├── retain-build.yml │ │ │ ├── run-on-unix.yml │ │ │ ├── run-on-windows.yml │ │ │ ├── run-script-ifequalelse.yml │ │ │ ├── send-to-helix.yml │ │ │ ├── source-build.yml │ │ │ ├── telemetry-end.yml │ │ │ └── telemetry-start.yml │ │ └── variables │ │ │ ├── pool-providers.yml │ │ │ └── sdl-variables.yml │ ├── tools.ps1 │ └── tools.sh ├── resources │ ├── Directory.Build.props │ └── Directory.Build.targets ├── targets │ ├── NuGet.targets │ ├── Settings.props │ └── Versions.targets ├── templates │ ├── build-and-test-job-linux-templates.yml │ ├── build-and-test-job-windows-templates.yml │ ├── delete-dump-files-template.yml │ ├── setup-template.yml │ └── variables-template.yml └── tests │ └── UpToDate.ps1 ├── global.json ├── restore.cmd ├── restore.sh ├── src ├── Microsoft.TryDotNet.IntegrationTests │ ├── (Pocket) │ │ └── Logger │ │ │ └── Class1.cs │ ├── AsyncLazy.cs │ ├── CollectionDefinitionForIntegratedServicesFixture.cs │ ├── CommandLine.cs │ ├── CommandLineInvocationException.cs │ ├── DotNetOnline.cs │ ├── EditorTests.cs │ ├── IntegratedServicesFixture.cs │ ├── IntegrationTestFactAttribute.cs │ ├── LearnServer.cs │ ├── MessageInterceptor.cs │ ├── Microsoft.TryDotNet.IntegrationTests.csproj │ ├── Microsoft.TryDotNet.IntegrationTests.v3.ncrunchproject │ ├── PageExtensions.cs │ ├── PeakyTestDiscovery.cs │ ├── PeakyTests.cs │ ├── PlaywrightSession.cs │ ├── PlaywrightTestBase.cs │ ├── SerializableCodeRunnerResult.cs │ ├── TryDotNetJsIntegrationTests.cs │ ├── TryDotNetServer.cs │ ├── UriExtensions.cs │ ├── WasmRunnerMessage.cs │ └── WasmRunnerTests.cs ├── Microsoft.TryDotNet.SimulatorGenerator │ ├── ApiContractScenario.cs │ ├── ApiEndpointSimulatorGenerator.cs │ ├── MarkupTestFile.cs │ ├── Microsoft.TryDotNet.SimulatorGenerator.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── StringExtensions.cs ├── Microsoft.TryDotNet.Tests │ ├── (Pocket) │ │ └── Logger │ │ │ └── LogEvents.SubscribeToPocketLogger.cs │ ├── CodeRunnerTests.cs │ ├── CommandExecutionTests.cs │ ├── Microsoft.TryDotNet.Tests.csproj │ └── Microsoft.TryDotNet.Tests.v3.ncrunchproject ├── Microsoft.TryDotNet.WasmRunner │ ├── App.razor │ ├── AsyncContext.cs │ ├── CodeRunner.cs │ ├── CodeRunnerAdapter.cs │ ├── ConsoleOutput.cs │ ├── EntryPointDiscoverer.cs │ ├── Microsoft.TryDotNet.WasmRunner.csproj │ ├── MultiplexingTextWriter.cs │ ├── ObservableStringWriter.cs │ ├── Pages │ │ └── Index.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── RunResults.cs │ ├── Shared │ │ ├── MainLayout.razor │ │ └── MainLayout.razor.css │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.ico │ │ ├── icon-192.png │ │ └── index.html ├── Microsoft.TryDotNet │ ├── ContentGenerator.cs │ ├── EnvelopeExtensions.cs │ ├── KernelDiagnostics.cs │ ├── Microsoft.TryDotNet.csproj │ ├── PeakyTests │ │ ├── ApplicationInsightsClientException.cs │ │ ├── ApplicationInsightsSettings.cs │ │ ├── AuthorizedHostOrigin.cs │ │ ├── DomainParseResult.cs │ │ ├── EnvironmentSettings.cs │ │ ├── HostOriginAuthenticationHandler.cs │ │ ├── HostOriginAuthenticationHandlerExtensions.cs │ │ ├── HostOriginAuthenticationOptions.cs │ │ ├── HostOriginPolicies.cs │ │ ├── HostOriginPoliciesExtensions.cs │ │ ├── HostOriginPolicy.cs │ │ ├── HttpClientWithRequestHeaders.cs │ │ ├── HttpClientWithTelemetry.cs │ │ ├── HttpClientWithXsrfCookies.cs │ │ ├── IEnvironmentVariableAccess.cs │ │ ├── OutsideInTests.cs │ │ ├── PropertyDeserializationInfo.cs │ │ ├── SelfTests.cs │ │ ├── ShortNameAttribute.cs │ │ ├── TypeExtensions.cs │ │ ├── UriExtensions.cs │ │ ├── VersionSensor.cs │ │ └── XsrfCookieHandlingMessageHandler.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json ├── microsoft-learn-mock │ ├── .npmrc │ ├── .vscode │ │ └── settings.json │ ├── package-lock.json │ ├── package.json │ ├── rollup.config.js │ ├── site │ │ └── DocsHost.html │ ├── src │ │ ├── docs-strings.ts │ │ ├── event-bus.ts │ │ ├── index.ts │ │ ├── interactivity │ │ │ ├── activation.ts │ │ │ ├── originalCode.ts │ │ │ └── scaffolding.ts │ │ ├── load-library.ts │ │ └── theme-selection.ts │ └── tsconfig.json ├── microsoft-trydotnet-editor │ ├── .eslintignore │ ├── .eslintrc.json │ ├── .npmrc │ ├── .vscode │ │ └── settings.json │ ├── generateApiSimulator.ps1 │ ├── package-lock.json │ ├── package.json │ ├── playwright.config.ts │ ├── src │ │ ├── EditorAdapter.ts │ │ ├── ProjectKernelWithWASMRunner.ts │ │ ├── apiService.ts │ │ ├── debouncingKernel.ts │ │ ├── documentId.ts │ │ ├── factory.ts │ │ ├── index.css │ │ ├── index.ts │ │ ├── legacyContract.ts │ │ ├── legacyTryDotNetMessages.ts │ │ ├── log.ts │ │ ├── monacoAdapterImpl.ts │ │ ├── newContract.ts │ │ ├── projectKernel.ts │ │ ├── stringExtensions.ts │ │ ├── tryDotNetEditor.ts │ │ ├── wasmRunner.ts │ │ └── workspace.ts │ ├── testConfig.json │ ├── tests │ │ ├── apiServiceSimulator.ts │ │ ├── editorSimulator.tests.ts │ │ ├── monacoEditorSimulator.ts │ │ ├── projectKernel.tests.ts │ │ ├── simulatorConfigurations │ │ │ ├── apiService │ │ │ │ ├── compiles_with_error.json │ │ │ │ ├── compiles_with_no_warning.json │ │ │ │ ├── completions_produced_from_regions.json │ │ │ │ ├── diagnostics_produced_with_errors_in_code.json │ │ │ │ ├── diagnostics_produced_with_hidden_severity.json │ │ │ │ ├── open_document.json │ │ │ │ ├── open_document_with_region.json │ │ │ │ ├── open_project.json │ │ │ │ └── update_project.json │ │ │ └── wasmRunner │ │ │ │ └── executes_correct_code.json │ │ ├── testHelpers.ts │ │ ├── tryDotNetEditor.tests.ts │ │ ├── tryDotNetEditorMessagingApi.tests.ts │ │ └── wasmRunnerSimulator.ts │ ├── tsconfig.eslint.json │ ├── tsconfig.json │ ├── tsnode.js │ ├── wallaby.js │ ├── webpack-prod.config.js │ └── webpack.config.js ├── microsoft-trydotnet-styles │ ├── .npmrc │ ├── package-lock.json │ ├── package.json │ └── sass │ │ ├── constants.scss │ │ ├── output-panels.scss │ │ ├── run-button.scss │ │ └── trydotnet.scss └── microsoft-trydotnet │ ├── .npmrc │ ├── .vscode │ ├── launch.json │ └── settings.json │ ├── package-lock.json │ ├── package.json │ ├── rollup.config.js │ ├── src │ ├── apiMessages.ts │ ├── configuration.ts │ ├── diagnostics.ts │ ├── documentId.ts │ ├── editableDocument.ts │ ├── editor.ts │ ├── htmlDomHelpers.ts │ ├── index.ts │ ├── internals │ │ ├── document.ts │ │ ├── executionService.ts │ │ ├── messageBus.ts │ │ ├── monacoTextEditor.ts │ │ ├── requestIdGenerator.ts │ │ ├── responseFor.ts │ │ ├── session.ts │ │ ├── urlHelpers.ts │ │ └── workspace.ts │ ├── log.ts │ ├── newContract.ts │ ├── project.ts │ ├── session.ts │ ├── sessionFactory.ts │ ├── stringExtensions.ts │ └── textDisplay.ts │ ├── test │ ├── domUtilities.ts │ ├── fakes │ │ ├── fakeIdGenerator.ts │ │ ├── fakeMessageBus.ts │ │ └── fakeMonacoTextEditor.ts │ ├── internals │ │ ├── document.specs.ts │ │ ├── iframeMessageBus.specs.ts │ │ ├── monacoEditor.specs.ts │ │ ├── requestIdGenerator.specs.ts │ │ └── workspace.specs.ts │ ├── messagingMocks.ts │ ├── session.creationapi.specs.ts │ ├── session.documentapi.specs.ts │ ├── session.runapi.specs.ts │ ├── sessionFactory.ts │ └── wait.ts │ ├── testConfig.json │ ├── tsconfig.json │ └── wallaby.js └── test.sh /.config/1espt/PipelineAutobaseliningConfig.yml: -------------------------------------------------------------------------------- 1 | ## DO NOT MODIFY THIS FILE MANUALLY. This is part of auto-baselining from 1ES Pipeline Templates. Go to [https://aka.ms/1espt-autobaselining] for more details. 2 | 3 | pipelines: 4 | 494: 5 | retail: 6 | binary: 7 | credscan: 8 | lastModifiedDate: 2024-03-13 9 | binskim: 10 | lastModifiedDate: 2024-03-13 11 | spotbugs: 12 | lastModifiedDate: 2024-03-13 13 | source: 14 | credscan: 15 | lastModifiedDate: 2024-03-13 16 | eslint: 17 | lastModifiedDate: 2024-03-13 18 | psscriptanalyzer: 19 | lastModifiedDate: 2024-03-13 20 | armory: 21 | lastModifiedDate: 2024-03-13 22 | -------------------------------------------------------------------------------- /.config/credscan/Suppressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "tool": "Credential Scanner", 3 | "suppressions": [ 4 | { 5 | "file": "artifacts/bin/Microsoft.TryDotNet.IntegrationTests/Release/net9.0/.playwright/package/ThirdPartyNotices.txt", 6 | "_justification": "This file is a third party notice text file, but not a real issue, and not one we distribute" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /.config/guardian/.gdnbaselines: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/baselines" 4 | }, 5 | "version": "1.0.0", 6 | "baselines": { 7 | "default": { 8 | "name": "default", 9 | "createdDate": "2024-03-13 17:27:58Z", 10 | "lastUpdatedDate": "2024-03-13 17:27:58Z" 11 | } 12 | }, 13 | "results": { 14 | "dadd4935cc62146c68a2bc507ab14dbdaa10b05aed99d1c0afcf677bd22a0dba": { 15 | "signature": "dadd4935cc62146c68a2bc507ab14dbdaa10b05aed99d1c0afcf677bd22a0dba", 16 | "alternativeSignatures": [], 17 | "target": "artifacts/bin/Microsoft.TryDotNet.IntegrationTests/Release/net8.0/.playwright/package/ThirdPartyNotices.txt", 18 | "line": 1240, 19 | "memberOf": [ 20 | "default" 21 | ], 22 | "tool": "credscan", 23 | "ruleId": "CSCAN-GENERAL0030", 24 | "createdDate": "2024-03-13 17:44:29Z", 25 | "expirationDate": "2024-08-30 18:33:33Z", 26 | "justification": "This error is baselined with an expiration date of 180 days from 2024-03-13 18:33:33Z" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*.{c,c++,cc,cp,cpp,cu,cuh,cxx,h,hh,hpp,hxx,inc,inl,ino,ipp,mpp,proto,tpp}] 3 | indent_style=tab 4 | indent_size=tab 5 | tab_width=4 6 | 7 | [*.{asax,ascx,aspx,cs,cshtml,css,htm,html,js,jsx,master,razor,skin,ts,tsx,vb,xaml,xamlx,xoml}] 8 | indent_style=space 9 | indent_size=4 10 | tab_width=4 11 | 12 | [*.{appxmanifest,build,config,csproj,dbml,discomap,dtd,json,jsproj,lsproj,njsproj,nuspec,proj,props,resjson,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}] 13 | indent_style=space 14 | indent_size=2 15 | tab_width=2 16 | 17 | [*] 18 | 19 | # Microsoft .NET properties 20 | csharp_new_line_before_members_in_object_initializers=false 21 | csharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion 22 | csharp_style_var_elsewhere=true:hint 23 | csharp_style_var_for_built_in_types=true:hint 24 | csharp_style_var_when_type_is_apparent=true:hint 25 | dotnet_style_predefined_type_for_locals_parameters_members=true:hint 26 | dotnet_style_predefined_type_for_member_access=true:hint 27 | dotnet_style_qualification_for_event=false:warning 28 | dotnet_style_qualification_for_field=false:warning 29 | dotnet_style_qualification_for_method=false:warning 30 | dotnet_style_qualification_for_property=false:warning 31 | dotnet_style_require_accessibility_modifiers=for_non_interface_members:hint 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | #### Describe the bug 11 | Please provide as much information as you can. 12 | 13 | #### What is the URL where you saw the error? 14 | 15 | #### What kind of error was it? 16 | - [ ] User Interface (UI): For example the output never displayed 17 | - [ ] Service Error: For example "The service is temporarily unavailable. We are working on it" 18 | - [ ] Other: 19 | 20 | #### Screenshots 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | #### Please complete the following: 24 | - OS 25 | - [ ] Windows 26 | - [ ] macOS 27 | - [ ] Linux (Please specify distro) 28 | - [ ] iOS 29 | - [ ] Android 30 | - Browser 31 | - [ ] Chrome 32 | - [ ] Edge 33 | - [ ] Firefox 34 | - [ ] Safari 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Read More** 20 | https://github.com/dotnet/try/wiki/Project-Roadmap 21 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to find out which attributes exist for C# debugging 3 | // Use hover for the description of the existing attributes 4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | // If you have changed target frameworks, make sure to update the program path. 13 | "program": "${workspaceFolder}/MLS.Agent/bin/Debug/netcoreapp2.1/MLS.Agent.dll", 14 | "args": [], 15 | "cwd": "${workspaceFolder}/MLS.Agent", 16 | "stopAtEntry": false, 17 | "launchBrowser": { 18 | "enabled": true 19 | }, 20 | "env": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | }, 23 | "sourceFileMap": { 24 | "/Views": "${workspaceFolder}/Views" 25 | } 26 | }, 27 | { 28 | "name": ".NET Core Attach", 29 | "type": "coreclr", 30 | "request": "attach", 31 | "processId": "${command:pickProcess}" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/MLS.Agent/MLS.Agent.csproj" 11 | ], 12 | "problemMatcher": "$tsc" 13 | }, 14 | { 15 | "label": "publish", 16 | "command": "dotnet", 17 | "type": "process", 18 | "args": [ 19 | "publish", 20 | "${workspaceFolder}/MLS.Agent/MLS.Agent.csproj" 21 | ], 22 | "problemMatcher": "$tsc" 23 | }, 24 | { 25 | "label": "watch", 26 | "command": "dotnet", 27 | "type": "process", 28 | "args": [ 29 | "watch", 30 | "run", 31 | "${workspaceFolder}/MLS.Agent/MLS.Agent.csproj" 32 | ], 33 | "problemMatcher": "$tsc" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 6 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | true 10 | 11 | false 12 | false 13 | false 14 | 15 | 16 | $(NoWarn);NU5104 17 | 18 | 19 | 20 | 21 | 13.0.3 22 | 0.3.0 23 | 4.3.0 24 | 4.3.2 25 | 4.3.0 26 | 4.5.0 27 | 4.5.0 28 | 7.0.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:9.0-azurelinux3.0 AS build-env 2 | WORKDIR /App 3 | 4 | # Copy everything 5 | COPY . ./ 6 | 7 | # Make sure we run bash 8 | CMD ["bash"] 9 | 10 | # Make sure we get all the updates and tools we need to build 11 | RUN tdnf install gawk -y 12 | # This is Node v16. For 18, use nodejs18. 13 | RUN tdnf install nodejs -y 14 | RUN tdnf install npm -y 15 | RUN tdnf clean all 16 | 17 | # Build javascript library 18 | RUN /App/build-js.sh 19 | 20 | # Restore 21 | RUN dotnet restore --configfile /App/NuGet.config /App/TryDotNet.sln 22 | 23 | # Build and publish a release 24 | RUN dotnet publish -c Release -o out /App/src/Microsoft.TryDotNet 25 | 26 | # Build runtime image 27 | FROM mcr.microsoft.com/dotnet/sdk:9.0-azurelinux3.0 28 | ARG TRY_DOT_NET_BUILD_ID 29 | WORKDIR /App 30 | 31 | # Make sure we run bash 32 | CMD ["bash"] 33 | 34 | # Make sure we get all the tools we need 35 | RUN tdnf install procps -y 36 | RUN tdnf clean all 37 | 38 | # Copy from build image 39 | COPY --from=build-env /App/out . 40 | 41 | # Set up to run and expose app on port 80 42 | EXPOSE 80 43 | ENV ASPNETCORE_URLS=http://*:80/ 44 | 45 | # This is a workaround for the fact that the Try .NET website is not yet container-aware 46 | ENV TRY_DOT_NET_REQUEST_SCHEME=https 47 | ENV TRY_DOT_NET_BUILD_ID=$TRY_DOT_NET_BUILD_ID 48 | ENV TRY_DOT_NET_MANUAL_BUILD_ID=2 49 | 50 | # Run the Microsoft.TryDotNet website 51 | ENTRYPOINT ["dotnet", "Microsoft.TryDotNet.dll"] 52 | -------------------------------------------------------------------------------- /DotNetTry.md: -------------------------------------------------------------------------------- 1 | # Try .NET 2 | || [**Basics**](#basics) • [**Experiences**](#experiences) || [**Setup**](#setup) • [**Getting Started**](#getting-started) || [**Samples**](https://github.com/dotnet/try-samples) || 3 | 4 |  5 | 6 | [](https://dev.azure.com/dnceng-public/public/_build?definitionId=62&branchName=main) 7 | 8 | **What is Try .NET?**: Try .NET is an interactive documentation generator for .NET Core. 9 | 10 | ## Experiences 11 | Use Try .NET to create executable C# snippets for your websites, or interactive markdown files that users can run on their machine. 12 | 13 | ### Online, powered by Blazor 14 | 15 | Microsoft Learn uses Try .NET to create interactive documentation. Users can run and edit code all in the browser. 16 | 17 | _**Please Note**: At the moment, the Try .NET online experience only works with C# documentation._ 18 | 19 | 20 | 21 | ### Interactive .NET documentation 22 | 23 | Try .NET enables .NET developers to create interactive markdown files. 24 | To make your markdown files interactive, you will need to use [.NET Core 3.0 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.0), the dotnet try global tool and [Visual Studio](https://visualstudio.microsoft.com/) / [VS Code](https://code.visualstudio.com/) (or any other editor of your choice). 25 | 26 | 27 | 28 | To get started follow [setup](DotNetTryLocal.md) instructions 29 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Microsoft Corporation. 4 | All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /TryDotNet.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | True 5 | True 6 | True 7 | 8 | -------------------------------------------------------------------------------- /build-integration.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0eng\build.ps1" -noDotnet %* 3 | taskkill /F /IM dotnet.exe 4 | rmdir /s /q ".\src\Microsoft.TryDotNet.IntegrationTests\bin" 5 | rmdir /s /q ".\artifacts\bin\Microsoft.TryDotNet.IntegrationTests" 6 | -------------------------------------------------------------------------------- /build-js.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0eng\build.ps1" -noDotnet %* 3 | -------------------------------------------------------------------------------- /build-js.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd)" 15 | 16 | . "$scriptroot/eng/build.sh" --no-dotnet "$@" 17 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0eng\build.ps1" -build -restore -binaryLog %* 3 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd)" 15 | 16 | . "$scriptroot/eng/build.sh" --build --restore --binaryLog "$@" 17 | -------------------------------------------------------------------------------- /eng/AfterSolutionBuild.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /eng/CIBuild.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0build.ps1" -ci -restore -build -pack -publish -binaryLog %* 3 | -------------------------------------------------------------------------------- /eng/Publishing.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3 4 | 5 | 6 | -------------------------------------------------------------------------------- /eng/SignCheckExclusionsFile.txt: -------------------------------------------------------------------------------- 1 | *bundle.js 2 | blazor.*.js 3 | editor.worker.js 4 | interop.js 5 | mono.js 6 | trydotnet.min.js 7 | -------------------------------------------------------------------------------- /eng/Version.Details.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | https://github.com/dotnet/arcade 8 | 20ab70a74d52b68f4271bd946884e24049b14f83 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /eng/build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(PositionalBinding = $false)] 2 | param ( 3 | [string]$configuration = "Debug", 4 | [switch]$noDotnet, 5 | [switch]$test, 6 | [Parameter(ValueFromRemainingArguments = $true)][String[]]$arguments 7 | ) 8 | 9 | Set-StrictMode -version 2.0 10 | $ErrorActionPreference = "Stop" 11 | 12 | try { 13 | $repoRoot = Resolve-Path "$PSScriptRoot\.." 14 | $npmDirs = @( 15 | "src\microsoft-trydotnet", 16 | "src\microsoft-trydotnet-editor", 17 | "src\microsoft-trydotnet-styles", 18 | "src\microsoft-learn-mock" 19 | ) 20 | foreach ($npmDir in $npmDirs) { 21 | Push-Location "$repoRoot\$npmDir" 22 | Write-Host "Building NPM in directory $npmDir" 23 | npm ci 24 | if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } 25 | npm run buildProd 26 | if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } 27 | 28 | if ($test) { 29 | Write-Host "Testing NPM in directory $npmDir" 30 | npm run ciTest 31 | if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } 32 | } 33 | 34 | Pop-Location 35 | } 36 | 37 | if (-Not $noDotnet) { 38 | # promote switches to arguments 39 | $arguments += "-configuration" 40 | $arguments += $configuration 41 | 42 | # invoke regular build script 43 | $buildScript = (Join-Path $PSScriptRoot "common\build.ps1") 44 | Invoke-Expression "$buildScript $arguments" 45 | if ($LASTEXITCODE -ne 0) { 46 | exit $LASTEXITCODE 47 | } 48 | 49 | # playwright 50 | if ($test) { 51 | & $repoRoot\artifacts\bin\Microsoft.TryDotNet.IntegrationTests\$configuration\net9.0\playwright.ps1 install chromium 52 | } 53 | } 54 | } 55 | catch { 56 | Write-Host $_ 57 | Write-Host $_.Exception 58 | Write-Host $_.ScriptStackTrace 59 | exit 1 60 | } 61 | -------------------------------------------------------------------------------- /eng/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source="${BASH_SOURCE[0]}" 6 | 7 | # resolve $source until the file is no longer a symlink 8 | while [[ -h "$source" ]]; do 9 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 10 | source="$(readlink "$source")" 11 | # if $source was a relative symlink, we need to resolve it relative to the path where the 12 | # symlink file was located 13 | [[ $source != /* ]] && source="$scriptroot/$source" 14 | done 15 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 16 | 17 | # parse args 18 | args="" 19 | no_dotnet=false 20 | run_tests=false 21 | 22 | # scan for `--test` or `--ci` switches 23 | while [[ $# > 0 ]]; do 24 | opt="$(echo "$1" | awk '{print tolower($0)}')" 25 | case "$opt" in 26 | --no-dotnet) 27 | no_dotnet=true 28 | ;; 29 | --test|-t) 30 | run_tests=true 31 | ;; 32 | *) 33 | args="$args $1" 34 | ;; 35 | esac 36 | shift 37 | done 38 | 39 | # build and test NPM 40 | npmDirs='src/microsoft-trydotnet 41 | src/microsoft-trydotnet-editor 42 | src/microsoft-trydotnet-styles 43 | src/microsoft-learn-mock' 44 | for npmDir in $npmDirs; 45 | do 46 | echo "Building NPM in directory $npmDir" 47 | pushd $npmDir 48 | npm ci 49 | npm run buildProd 50 | if [[ "$run_tests" == true ]]; then 51 | echo "Testing NPM in directory $npmDir" 52 | npm run ciTest 53 | fi 54 | popd 55 | done 56 | 57 | if [[ "$no_dotnet" != true ]]; then 58 | # invoke regular build script 59 | . "$scriptroot/common/build.sh" $args 60 | fi 61 | -------------------------------------------------------------------------------- /eng/cibuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd)" 15 | 16 | echo "Building this commit:" 17 | git show --no-patch --pretty=raw HEAD 18 | 19 | . "$scriptroot/build.sh" --ci --restore --build --pack --binaryLog "$@" 20 | -------------------------------------------------------------------------------- /eng/common/BuildConfiguration/build-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "RetryCountLimit": 1, 3 | "RetryByAnyError": false 4 | } 5 | -------------------------------------------------------------------------------- /eng/common/CIBuild.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" -------------------------------------------------------------------------------- /eng/common/PSScriptAnalyzerSettings.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | IncludeRules=@('PSAvoidUsingCmdletAliases', 3 | 'PSAvoidUsingWMICmdlet', 4 | 'PSAvoidUsingPositionalParameters', 5 | 'PSAvoidUsingInvokeExpression', 6 | 'PSUseDeclaredVarsMoreThanAssignments', 7 | 'PSUseCmdletCorrectly', 8 | 'PSStandardDSCFunctionsInResource', 9 | 'PSUseIdenticalMandatoryParametersForDSC', 10 | 'PSUseIdenticalParametersForDSC') 11 | } -------------------------------------------------------------------------------- /eng/common/README.md: -------------------------------------------------------------------------------- 1 | # Don't touch this folder 2 | 3 | uuuuuuuuuuuuuuuuuuuu 4 | u" uuuuuuuuuuuuuuuuuu "u 5 | u" u$$$$$$$$$$$$$$$$$$$$u "u 6 | u" u$$$$$$$$$$$$$$$$$$$$$$$$u "u 7 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 8 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 9 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u 10 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 11 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 12 | $ $$$" ... "$... ...$" ... "$$$ ... "$$$ $ 13 | $ $$$u `"$$$$$$$ $$$ $$$$$ $$ $$$ $$$ $ 14 | $ $$$$$$uu "$$$$ $$$ $$$$$ $$ """ u$$$ $ 15 | $ $$$""$$$ $$$$ $$$u "$$$" u$$ $$$$$$$$ $ 16 | $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $ 17 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ 18 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 19 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 20 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" 21 | "u "$$$$$$$$$$$$$$$$$$$$$$$$" u" 22 | "u "$$$$$$$$$$$$$$$$$$$$" u" 23 | "u """""""""""""""""" u" 24 | """""""""""""""""""" 25 | 26 | !!! Changes made in this directory are subject to being overwritten by automation !!! 27 | 28 | The files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first. 29 | -------------------------------------------------------------------------------- /eng/common/cibuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 15 | 16 | . "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ -------------------------------------------------------------------------------- /eng/common/cross/arm/sources.list.bionic: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/arm/sources.list.jessie: -------------------------------------------------------------------------------- 1 | # Debian (sid) # UNSTABLE 2 | deb http://ftp.debian.org/debian/ sid main contrib non-free 3 | deb-src http://ftp.debian.org/debian/ sid main contrib non-free 4 | -------------------------------------------------------------------------------- /eng/common/cross/arm/sources.list.xenial: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/arm/sources.list.zesty: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/arm64/sources.list.bionic: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/arm64/sources.list.xenial: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/arm64/sources.list.zesty: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/armel/armel.jessie.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h 2 | --- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700 3 | +++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700 4 | @@ -69,10 +69,10 @@ 5 | #endif 6 | #ifdef UATOMIC_HAS_ATOMIC_SHORT 7 | case 2: 8 | - return __sync_val_compare_and_swap_2(addr, old, _new); 9 | + return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new); 10 | #endif 11 | case 4: 12 | - return __sync_val_compare_and_swap_4(addr, old, _new); 13 | + return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new); 14 | #if (CAA_BITS_PER_LONG == 64) 15 | case 8: 16 | return __sync_val_compare_and_swap_8(addr, old, _new); 17 | @@ -109,7 +109,7 @@ 18 | return; 19 | #endif 20 | case 4: 21 | - __sync_and_and_fetch_4(addr, val); 22 | + __sync_and_and_fetch_4((uint32_t*) addr, val); 23 | return; 24 | #if (CAA_BITS_PER_LONG == 64) 25 | case 8: 26 | @@ -148,7 +148,7 @@ 27 | return; 28 | #endif 29 | case 4: 30 | - __sync_or_and_fetch_4(addr, val); 31 | + __sync_or_and_fetch_4((uint32_t*) addr, val); 32 | return; 33 | #if (CAA_BITS_PER_LONG == 64) 34 | case 8: 35 | @@ -187,7 +187,7 @@ 36 | return __sync_add_and_fetch_2(addr, val); 37 | #endif 38 | case 4: 39 | - return __sync_add_and_fetch_4(addr, val); 40 | + return __sync_add_and_fetch_4((uint32_t*) addr, val); 41 | #if (CAA_BITS_PER_LONG == 64) 42 | case 8: 43 | return __sync_add_and_fetch_8(addr, val); 44 | -------------------------------------------------------------------------------- /eng/common/cross/armel/sources.list.jessie: -------------------------------------------------------------------------------- 1 | # Debian (jessie) # Stable 2 | deb http://ftp.debian.org/debian/ jessie main contrib non-free 3 | deb-src http://ftp.debian.org/debian/ jessie main contrib non-free 4 | -------------------------------------------------------------------------------- /eng/common/cross/armel/tizen/tizen.patch: -------------------------------------------------------------------------------- 1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so 2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 4 | @@ -2,4 +2,4 @@ 5 | Use the shared library, but some functions are only in 6 | the static library, so try that secondarily. */ 7 | OUTPUT_FORMAT(elf32-littlearm) 8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) ) 9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) ) 10 | -------------------------------------------------------------------------------- /eng/common/cross/armv6/sources.list.buster: -------------------------------------------------------------------------------- 1 | deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi 2 | deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi 3 | -------------------------------------------------------------------------------- /eng/common/cross/ppc64le/sources.list.bionic: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/riscv64/sources.list.sid: -------------------------------------------------------------------------------- 1 | deb http://deb.debian.org/debian-ports sid main 2 | -------------------------------------------------------------------------------- /eng/common/cross/s390x/sources.list.bionic: -------------------------------------------------------------------------------- 1 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 2 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe 3 | 4 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 5 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe 6 | 7 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 8 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted 9 | 10 | deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 11 | deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse 12 | -------------------------------------------------------------------------------- /eng/common/cross/tizen-build-rootfs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | ARCH=$1 5 | LINK_ARCH=$ARCH 6 | 7 | case "$ARCH" in 8 | arm) 9 | TIZEN_ARCH="armv7hl" 10 | ;; 11 | armel) 12 | TIZEN_ARCH="armv7l" 13 | LINK_ARCH="arm" 14 | ;; 15 | arm64) 16 | TIZEN_ARCH="aarch64" 17 | ;; 18 | x86) 19 | TIZEN_ARCH="i686" 20 | ;; 21 | x64) 22 | TIZEN_ARCH="x86_64" 23 | LINK_ARCH="x86" 24 | ;; 25 | *) 26 | echo "Unsupported architecture for tizen: $ARCH" 27 | exit 1 28 | esac 29 | 30 | __CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 31 | __TIZEN_CROSSDIR="$__CrossDir/${ARCH}/tizen" 32 | 33 | if [[ -z "$ROOTFS_DIR" ]]; then 34 | echo "ROOTFS_DIR is not defined." 35 | exit 1; 36 | fi 37 | 38 | TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp 39 | mkdir -p $TIZEN_TMP_DIR 40 | 41 | # Download files 42 | echo ">>Start downloading files" 43 | VERBOSE=1 $__CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR $TIZEN_ARCH 44 | echo "<>Start constructing Tizen rootfs" 47 | TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` 48 | cd $ROOTFS_DIR 49 | for f in $TIZEN_RPM_FILES; do 50 | rpm2cpio $f | cpio -idm --quiet 51 | done 52 | echo "<>Start configuring Tizen rootfs" 59 | ln -sfn asm-${LINK_ARCH} ./usr/include/asm 60 | patch -p1 < $__TIZEN_CROSSDIR/tizen.patch 61 | echo "<\\|?@*"() ]', '_' 11 | $SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName 12 | 13 | Write-Host "Artifact name before : $ArtifactName" 14 | Write-Host "Artifact name after : $SafeArtifactName" 15 | 16 | Write-Host "Creating dir $ManifestDirPath" 17 | 18 | # create directory for sbom manifest to be placed 19 | if (!(Test-Path -path $SbomGenerationDir)) 20 | { 21 | New-Item -ItemType Directory -path $SbomGenerationDir 22 | Write-Host "Successfully created directory $SbomGenerationDir" 23 | } 24 | else{ 25 | Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." 26 | } 27 | 28 | Write-Host "Updating artifact name" 29 | Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName" 30 | -------------------------------------------------------------------------------- /eng/common/generate-sbom-prep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where the 11 | # symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 15 | . $scriptroot/pipeline-logging-functions.sh 16 | 17 | # replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts. 18 | artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM" 19 | safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}" 20 | 21 | manifest_dir=$1 22 | 23 | # Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly 24 | # with their own overwriting ours. So we create it as a sub directory of the requested manifest path. 25 | sbom_generation_dir="$manifest_dir/$safe_artifact_name" 26 | 27 | if [ ! -d "$sbom_generation_dir" ] ; then 28 | mkdir -p "$sbom_generation_dir" 29 | echo "Sbom directory created." $sbom_generation_dir 30 | else 31 | Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." 32 | fi 33 | 34 | echo "Artifact name before : "$artifact_name 35 | echo "Artifact name after : "$safe_artifact_name 36 | export ARTIFACT_NAME=$safe_artifact_name 37 | echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name" 38 | 39 | exit 0 40 | -------------------------------------------------------------------------------- /eng/common/helixpublish.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | msbuild 5 | 6 | 7 | 8 | 9 | %(Identity) 10 | 11 | 12 | 13 | 14 | 15 | $(WorkItemDirectory) 16 | $(WorkItemCommand) 17 | $(WorkItemTimeout) 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /eng/common/init-tools-native.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*" 3 | exit /b %ErrorLevel% -------------------------------------------------------------------------------- /eng/common/internal/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /eng/common/internal/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /eng/common/loc/P22DotNetHtmlLocalization.lss: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /eng/common/msbuild.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding(PositionalBinding=$false)] 2 | Param( 3 | [string] $verbosity = 'minimal', 4 | [bool] $warnAsError = $true, 5 | [bool] $nodeReuse = $true, 6 | [switch] $ci, 7 | [switch] $prepareMachine, 8 | [switch] $excludePrereleaseVS, 9 | [string] $msbuildEngine = $null, 10 | [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs 11 | ) 12 | 13 | . $PSScriptRoot\tools.ps1 14 | 15 | try { 16 | if ($ci) { 17 | $nodeReuse = $false 18 | } 19 | 20 | MSBuild @extraArgs 21 | } 22 | catch { 23 | Write-Host $_.ScriptStackTrace 24 | Write-PipelineTelemetryError -Category 'Build' -Message $_ 25 | ExitWithExitCode 1 26 | } 27 | 28 | ExitWithExitCode 0 -------------------------------------------------------------------------------- /eng/common/msbuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $source until the file is no longer a symlink 6 | while [[ -h "$source" ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | # if $source was a relative symlink, we need to resolve it relative to the path where the 10 | # symlink file was located 11 | [[ $source != /* ]] && source="$scriptroot/$source" 12 | done 13 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 14 | 15 | verbosity='minimal' 16 | warn_as_error=true 17 | node_reuse=true 18 | prepare_machine=false 19 | extra_args='' 20 | 21 | while (($# > 0)); do 22 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" 23 | case $lowerI in 24 | --verbosity) 25 | verbosity=$2 26 | shift 2 27 | ;; 28 | --warnaserror) 29 | warn_as_error=$2 30 | shift 2 31 | ;; 32 | --nodereuse) 33 | node_reuse=$2 34 | shift 2 35 | ;; 36 | --ci) 37 | ci=true 38 | shift 1 39 | ;; 40 | --preparemachine) 41 | prepare_machine=true 42 | shift 1 43 | ;; 44 | *) 45 | extra_args="$extra_args $1" 46 | shift 1 47 | ;; 48 | esac 49 | done 50 | 51 | . "$scriptroot/tools.sh" 52 | 53 | if [[ "$ci" == true ]]; then 54 | node_reuse=false 55 | fi 56 | 57 | MSBuild $extra_args 58 | ExitWithExitCode 0 59 | -------------------------------------------------------------------------------- /eng/common/native/init-os-and-arch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Use uname to determine what the OS is. 4 | OSName=$(uname -s | tr '[:upper:]' '[:lower:]') 5 | 6 | if command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then 7 | OSName="android" 8 | fi 9 | 10 | case "$OSName" in 11 | freebsd|linux|netbsd|openbsd|sunos|android|haiku) 12 | os="$OSName" ;; 13 | darwin) 14 | os=osx ;; 15 | *) 16 | echo "Unsupported OS $OSName detected!" 17 | exit 1 ;; 18 | esac 19 | 20 | # On Solaris, `uname -m` is discouraged, see https://docs.oracle.com/cd/E36784_01/html/E36870/uname-1.html 21 | # and `uname -p` returns processor type (e.g. i386 on amd64). 22 | # The appropriate tool to determine CPU is isainfo(1) https://docs.oracle.com/cd/E36784_01/html/E36870/isainfo-1.html. 23 | if [ "$os" = "sunos" ]; then 24 | if uname -o 2>&1 | grep -q illumos; then 25 | os="illumos" 26 | else 27 | os="solaris" 28 | fi 29 | CPUName=$(isainfo -n) 30 | else 31 | # For the rest of the operating systems, use uname(1) to determine what the CPU is. 32 | CPUName=$(uname -m) 33 | fi 34 | 35 | case "$CPUName" in 36 | arm64|aarch64) 37 | arch=arm64 38 | ;; 39 | 40 | loongarch64) 41 | arch=loongarch64 42 | ;; 43 | 44 | riscv64) 45 | arch=riscv64 46 | ;; 47 | 48 | amd64|x86_64) 49 | arch=x64 50 | ;; 51 | 52 | armv7l|armv8l) 53 | if (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then 54 | arch=armel 55 | else 56 | arch=arm 57 | fi 58 | ;; 59 | 60 | armv6l) 61 | arch=armv6 62 | ;; 63 | 64 | i[3-6]86) 65 | echo "Unsupported CPU $CPUName detected, build might not succeed!" 66 | arch=x86 67 | ;; 68 | 69 | s390x) 70 | arch=s390x 71 | ;; 72 | 73 | ppc64le) 74 | arch=ppc64le 75 | ;; 76 | *) 77 | echo "Unknown CPU $CPUName detected!" 78 | exit 1 79 | ;; 80 | esac 81 | -------------------------------------------------------------------------------- /eng/common/post-build/add-build-to-channel.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory=$true)][int] $BuildId, 3 | [Parameter(Mandatory=$true)][int] $ChannelId, 4 | [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, 5 | [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', 6 | [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16' 7 | ) 8 | 9 | try { 10 | . $PSScriptRoot\post-build-utils.ps1 11 | 12 | # Check that the channel we are going to promote the build to exist 13 | $channelInfo = Get-MaestroChannel -ChannelId $ChannelId 14 | 15 | if (!$channelInfo) { 16 | Write-PipelineTelemetryCategory -Category 'PromoteBuild' -Message "Channel with BAR ID $ChannelId was not found in BAR!" 17 | ExitWithExitCode 1 18 | } 19 | 20 | # Get info about which channel(s) the build has already been promoted to 21 | $buildInfo = Get-MaestroBuild -BuildId $BuildId 22 | 23 | if (!$buildInfo) { 24 | Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "Build with BAR ID $BuildId was not found in BAR!" 25 | ExitWithExitCode 1 26 | } 27 | 28 | # Find whether the build is already assigned to the channel or not 29 | if ($buildInfo.channels) { 30 | foreach ($channel in $buildInfo.channels) { 31 | if ($channel.Id -eq $ChannelId) { 32 | Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!" 33 | ExitWithExitCode 0 34 | } 35 | } 36 | } 37 | 38 | Write-Host "Promoting build '$BuildId' to channel '$ChannelId'." 39 | 40 | Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId 41 | 42 | Write-Host 'done.' 43 | } 44 | catch { 45 | Write-Host $_ 46 | Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'" 47 | ExitWithExitCode 1 48 | } 49 | -------------------------------------------------------------------------------- /eng/common/post-build/check-channel-consistency.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory=$true)][string] $PromoteToChannels, # List of channels that the build should be promoted to 3 | [Parameter(Mandatory=$true)][array] $AvailableChannelIds # List of channel IDs available in the YAML implementation 4 | ) 5 | 6 | try { 7 | . $PSScriptRoot\post-build-utils.ps1 8 | 9 | if ($PromoteToChannels -eq "") { 10 | Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info." 11 | ExitWithExitCode 0 12 | } 13 | 14 | # Check that every channel that Maestro told to promote the build to 15 | # is available in YAML 16 | $PromoteToChannelsIds = $PromoteToChannels -split "\D" | Where-Object { $_ } 17 | 18 | $hasErrors = $false 19 | 20 | foreach ($id in $PromoteToChannelsIds) { 21 | if (($id -ne 0) -and ($id -notin $AvailableChannelIds)) { 22 | Write-PipelineTaskError -Message "Channel $id is not present in the post-build YAML configuration! This is an error scenario. Please contact @dnceng." 23 | $hasErrors = $true 24 | } 25 | } 26 | 27 | # The `Write-PipelineTaskError` doesn't error the script and we might report several errors 28 | # in the previous lines. The check below makes sure that we return an error state from the 29 | # script if we reported any validation error 30 | if ($hasErrors) { 31 | ExitWithExitCode 1 32 | } 33 | 34 | Write-Host 'done.' 35 | } 36 | catch { 37 | Write-Host $_ 38 | Write-PipelineTelemetryError -Category 'CheckChannelConsistency' -Message "There was an error while trying to check consistency of Maestro default channels for the build and post-build YAML configuration." 39 | ExitWithExitCode 1 40 | } 41 | -------------------------------------------------------------------------------- /eng/common/post-build/nuget-validation.ps1: -------------------------------------------------------------------------------- 1 | # This script validates NuGet package metadata information using this 2 | # tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage 3 | 4 | param( 5 | [Parameter(Mandatory=$true)][string] $PackagesPath, # Path to where the packages to be validated are 6 | [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to 7 | ) 8 | 9 | try { 10 | . $PSScriptRoot\post-build-utils.ps1 11 | 12 | $url = 'https://raw.githubusercontent.com/NuGet/NuGetGallery/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1' 13 | 14 | New-Item -ItemType 'directory' -Path ${ToolDestinationPath} -Force 15 | 16 | Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1 17 | 18 | & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg 19 | } 20 | catch { 21 | Write-Host $_.ScriptStackTrace 22 | Write-PipelineTelemetryError -Category 'NuGetValidation' -Message $_ 23 | ExitWithExitCode 1 24 | } 25 | -------------------------------------------------------------------------------- /eng/common/post-build/publish-using-darc.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory=$true)][int] $BuildId, 3 | [Parameter(Mandatory=$true)][int] $PublishingInfraVersion, 4 | [Parameter(Mandatory=$true)][string] $AzdoToken, 5 | [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', 6 | [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, 7 | [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, 8 | [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters 9 | ) 10 | 11 | try { 12 | . $PSScriptRoot\post-build-utils.ps1 13 | 14 | $darc = Get-Darc 15 | 16 | $optionalParams = [System.Collections.ArrayList]::new() 17 | 18 | if ("" -ne $ArtifactsPublishingAdditionalParameters) { 19 | $optionalParams.Add("--artifact-publishing-parameters") | Out-Null 20 | $optionalParams.Add($ArtifactsPublishingAdditionalParameters) | Out-Null 21 | } 22 | 23 | if ("" -ne $SymbolPublishingAdditionalParameters) { 24 | $optionalParams.Add("--symbol-publishing-parameters") | Out-Null 25 | $optionalParams.Add($SymbolPublishingAdditionalParameters) | Out-Null 26 | } 27 | 28 | if ("false" -eq $WaitPublishingFinish) { 29 | $optionalParams.Add("--no-wait") | Out-Null 30 | } 31 | 32 | & $darc add-build-to-channel ` 33 | --id $buildId ` 34 | --publishing-infra-version $PublishingInfraVersion ` 35 | --default-channels ` 36 | --source-branch main ` 37 | --azdev-pat "$AzdoToken" ` 38 | --bar-uri "$MaestroApiEndPoint" ` 39 | --ci ` 40 | @optionalParams 41 | 42 | if ($LastExitCode -ne 0) { 43 | Write-Host "Problems using Darc to promote build ${buildId} to default channels. Stopping execution..." 44 | exit 1 45 | } 46 | 47 | Write-Host 'done.' 48 | } 49 | catch { 50 | Write-Host $_ 51 | Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to publish build '$BuildId' to default channels." 52 | ExitWithExitCode 1 53 | } 54 | -------------------------------------------------------------------------------- /eng/common/retain-build.ps1: -------------------------------------------------------------------------------- 1 | 2 | Param( 3 | [Parameter(Mandatory=$true)][int] $buildId, 4 | [Parameter(Mandatory=$true)][string] $azdoOrgUri, 5 | [Parameter(Mandatory=$true)][string] $azdoProject, 6 | [Parameter(Mandatory=$true)][string] $token 7 | ) 8 | 9 | $ErrorActionPreference = 'Stop' 10 | Set-StrictMode -Version 2.0 11 | 12 | function Get-AzDOHeaders( 13 | [string] $token) 14 | { 15 | $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":${token}")) 16 | $headers = @{"Authorization"="Basic $base64AuthInfo"} 17 | return $headers 18 | } 19 | 20 | function Update-BuildRetention( 21 | [string] $azdoOrgUri, 22 | [string] $azdoProject, 23 | [int] $buildId, 24 | [string] $token) 25 | { 26 | $headers = Get-AzDOHeaders -token $token 27 | $requestBody = "{ 28 | `"keepForever`": `"true`" 29 | }" 30 | 31 | $requestUri = "${azdoOrgUri}/${azdoProject}/_apis/build/builds/${buildId}?api-version=6.0" 32 | write-Host "Attempting to retain build using the following URI: ${requestUri} ..." 33 | 34 | try { 35 | Invoke-RestMethod -Uri $requestUri -Method Patch -Body $requestBody -Header $headers -contentType "application/json" 36 | Write-Host "Updated retention settings for build ${buildId}." 37 | } 38 | catch { 39 | Write-Error "Failed to update retention settings for build: $_.Exception.Response.StatusDescription" 40 | exit 1 41 | } 42 | } 43 | 44 | Update-BuildRetention -azdoOrgUri $azdoOrgUri -azdoProject $azdoProject -buildId $buildId -token $token 45 | exit 0 46 | -------------------------------------------------------------------------------- /eng/common/sdl/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /eng/common/sdl/init-sdl.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string] $GuardianCliLocation, 3 | [string] $Repository, 4 | [string] $BranchName='master', 5 | [string] $WorkingDirectory, 6 | [string] $GuardianLoggerLevel='Standard' 7 | ) 8 | 9 | $ErrorActionPreference = 'Stop' 10 | Set-StrictMode -Version 2.0 11 | $disableConfigureToolsetImport = $true 12 | $global:LASTEXITCODE = 0 13 | 14 | # `tools.ps1` checks $ci to perform some actions. Since the SDL 15 | # scripts don't necessarily execute in the same agent that run the 16 | # build.ps1/sh script this variable isn't automatically set. 17 | $ci = $true 18 | . $PSScriptRoot\..\tools.ps1 19 | 20 | # Don't display the console progress UI - it's a huge perf hit 21 | $ProgressPreference = 'SilentlyContinue' 22 | 23 | Add-Type -AssemblyName System.IO.Compression.FileSystem 24 | 25 | try { 26 | # if the folder does not exist, we'll do a guardian init and push it to the remote repository 27 | Write-Host 'Initializing Guardian...' 28 | Write-Host "$GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel" 29 | & $GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel 30 | if ($LASTEXITCODE -ne 0) { 31 | Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian init failed with exit code $LASTEXITCODE." 32 | ExitWithExitCode $LASTEXITCODE 33 | } 34 | # We create the mainbaseline so it can be edited later 35 | Write-Host "$GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline" 36 | & $GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline 37 | if ($LASTEXITCODE -ne 0) { 38 | Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian baseline failed with exit code $LASTEXITCODE." 39 | ExitWithExitCode $LASTEXITCODE 40 | } 41 | ExitWithExitCode 0 42 | } 43 | catch { 44 | Write-Host $_.ScriptStackTrace 45 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ 46 | ExitWithExitCode 1 47 | } 48 | -------------------------------------------------------------------------------- /eng/common/sdl/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /eng/common/sdl/run-sdl.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string] $GuardianCliLocation, 3 | [string] $WorkingDirectory, 4 | [string] $GdnFolder, 5 | [string] $UpdateBaseline, 6 | [string] $GuardianLoggerLevel='Standard' 7 | ) 8 | 9 | $ErrorActionPreference = 'Stop' 10 | Set-StrictMode -Version 2.0 11 | $disableConfigureToolsetImport = $true 12 | $global:LASTEXITCODE = 0 13 | 14 | try { 15 | # `tools.ps1` checks $ci to perform some actions. Since the SDL 16 | # scripts don't necessarily execute in the same agent that run the 17 | # build.ps1/sh script this variable isn't automatically set. 18 | $ci = $true 19 | . $PSScriptRoot\..\tools.ps1 20 | 21 | # We store config files in the r directory of .gdn 22 | $gdnConfigPath = Join-Path $GdnFolder 'r' 23 | $ValidPath = Test-Path $GuardianCliLocation 24 | 25 | if ($ValidPath -eq $False) 26 | { 27 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Invalid Guardian CLI Location." 28 | ExitWithExitCode 1 29 | } 30 | 31 | $gdnConfigFiles = Get-ChildItem $gdnConfigPath -Recurse -Include '*.gdnconfig' 32 | Write-Host "Discovered Guardian config files:" 33 | $gdnConfigFiles | Out-String | Write-Host 34 | 35 | Exec-BlockVerbosely { 36 | & $GuardianCliLocation run ` 37 | --working-directory $WorkingDirectory ` 38 | --baseline mainbaseline ` 39 | --update-baseline $UpdateBaseline ` 40 | --logger-level $GuardianLoggerLevel ` 41 | --config @gdnConfigFiles 42 | Exit-IfNZEC "Sdl" 43 | } 44 | } 45 | catch { 46 | Write-Host $_.ScriptStackTrace 47 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ 48 | ExitWithExitCode 1 49 | } 50 | -------------------------------------------------------------------------------- /eng/common/sdl/sdl.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Install-Gdn { 3 | param( 4 | [Parameter(Mandatory=$true)] 5 | [string]$Path, 6 | 7 | [string]$Source = "https://pkgs.dev.azure.com/dnceng/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json", 8 | 9 | # If omitted, install the latest version of Guardian, otherwise install that specific version. 10 | [string]$Version 11 | ) 12 | 13 | $ErrorActionPreference = 'Stop' 14 | Set-StrictMode -Version 2.0 15 | $disableConfigureToolsetImport = $true 16 | $global:LASTEXITCODE = 0 17 | 18 | # `tools.ps1` checks $ci to perform some actions. Since the SDL 19 | # scripts don't necessarily execute in the same agent that run the 20 | # build.ps1/sh script this variable isn't automatically set. 21 | $ci = $true 22 | . $PSScriptRoot\..\tools.ps1 23 | 24 | $argumentList = @("install", "Microsoft.Guardian.Cli.win-x64", "-Source $Source", "-OutputDirectory $Path", "-NonInteractive", "-NoCache") 25 | 26 | if ($Version) { 27 | $argumentList += "-Version $Version" 28 | } 29 | 30 | Start-Process nuget -Verbose -ArgumentList $argumentList -NoNewWindow -Wait 31 | 32 | $gdnCliPath = Get-ChildItem -Filter guardian.cmd -Recurse -Path $Path 33 | 34 | if (!$gdnCliPath) 35 | { 36 | Write-PipelineTelemetryError -Category 'Sdl' -Message 'Failure installing Guardian' 37 | } 38 | 39 | return $gdnCliPath.FullName 40 | } -------------------------------------------------------------------------------- /eng/common/templates-official/jobs/codeql-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md 3 | continueOnError: false 4 | # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job 5 | jobs: [] 6 | # Optional: if specified, restore and use this version of Guardian instead of the default. 7 | overrideGuardianVersion: '' 8 | 9 | jobs: 10 | - template: /eng/common/templates-official/jobs/jobs.yml 11 | parameters: 12 | enableMicrobuild: false 13 | enablePublishBuildArtifacts: false 14 | enablePublishTestResults: false 15 | enablePublishBuildAssets: false 16 | enablePublishUsingPipelines: false 17 | enableTelemetry: true 18 | 19 | variables: 20 | - group: Publish-Build-Assets 21 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 22 | # sync with the packages.config file. 23 | - name: DefaultGuardianVersion 24 | value: 0.109.0 25 | - name: GuardianPackagesConfigFile 26 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config 27 | - name: GuardianVersion 28 | value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} 29 | 30 | jobs: ${{ parameters.jobs }} 31 | 32 | -------------------------------------------------------------------------------- /eng/common/templates-official/post-build/common-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | - group: Publish-Build-Assets 3 | 4 | # Whether the build is internal or not 5 | - name: IsInternalBuild 6 | value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} 7 | 8 | # Default Maestro++ API Endpoint and API Version 9 | - name: MaestroApiEndPoint 10 | value: "https://maestro.dot.net" 11 | - name: MaestroApiAccessToken 12 | value: $(MaestroAccessToken) 13 | - name: MaestroApiVersion 14 | value: "2020-02-20" 15 | 16 | - name: SourceLinkCLIVersion 17 | value: 3.0.0 18 | - name: SymbolToolVersion 19 | value: 1.0.1 20 | 21 | - name: runCodesignValidationInjection 22 | value: false 23 | -------------------------------------------------------------------------------- /eng/common/templates-official/post-build/trigger-subscription.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | ChannelId: 0 3 | 4 | steps: 5 | - task: PowerShell@2 6 | displayName: Triggering subscriptions 7 | inputs: 8 | filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 9 | arguments: -SourceRepo $(Build.Repository.Uri) 10 | -ChannelId ${{ parameters.ChannelId }} 11 | -MaestroApiAccessToken $(MaestroAccessToken) 12 | -MaestroApiEndPoint $(MaestroApiEndPoint) 13 | -MaestroApiVersion $(MaestroApiVersion) 14 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/add-build-to-channel.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | ChannelId: 0 3 | 4 | steps: 5 | - task: PowerShell@2 6 | displayName: Add Build to Channel 7 | inputs: 8 | filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 9 | arguments: -BuildId $(BARBuildId) 10 | -ChannelId ${{ parameters.ChannelId }} 11 | -MaestroApiAccessToken $(MaestroApiAccessToken) 12 | -MaestroApiEndPoint $(MaestroApiEndPoint) 13 | -MaestroApiVersion $(MaestroApiVersion) 14 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/build-reason.yml: -------------------------------------------------------------------------------- 1 | # build-reason.yml 2 | # Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons 3 | # to include steps (',' separated). 4 | parameters: 5 | conditions: '' 6 | steps: [] 7 | 8 | steps: 9 | - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: 10 | - ${{ parameters.steps }} 11 | - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: 12 | - ${{ parameters.steps }} 13 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/component-governance.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | disableComponentGovernance: false 3 | componentGovernanceIgnoreDirectories: '' 4 | 5 | steps: 6 | - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: 7 | - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" 8 | displayName: Set skipComponentGovernanceDetection variable 9 | - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: 10 | - task: ComponentGovernanceComponentDetection@0 11 | continueOnError: true 12 | inputs: 13 | ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} -------------------------------------------------------------------------------- /eng/common/templates-official/steps/enable-internal-runtimes.yml: -------------------------------------------------------------------------------- 1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64' 2 | # variable with the base64-encoded SAS token, by default 3 | 4 | parameters: 5 | - name: federatedServiceConnection 6 | type: string 7 | default: 'dotnetbuilds-internal-read' 8 | - name: outputVariableName 9 | type: string 10 | default: 'dotnetbuilds-internal-container-read-token-base64' 11 | - name: expiryInHours 12 | type: number 13 | default: 1 14 | - name: base64Encode 15 | type: boolean 16 | default: true 17 | 18 | steps: 19 | - ${{ if ne(variables['System.TeamProject'], 'public') }}: 20 | - template: /eng/common/templates-official/steps/get-delegation-sas.yml 21 | parameters: 22 | federatedServiceConnection: ${{ parameters.federatedServiceConnection }} 23 | outputVariableName: ${{ parameters.outputVariableName }} 24 | expiryInHours: ${{ parameters.expiryInHours }} 25 | base64Encode: ${{ parameters.base64Encode }} 26 | storageAccount: dotnetbuilds 27 | container: internal 28 | permissions: rl 29 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/get-federated-access-token.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: federatedServiceConnection 3 | type: string 4 | - name: outputVariableName 5 | type: string 6 | - name: stepName 7 | type: string 8 | default: 'getFederatedAccessToken' 9 | - name: condition 10 | type: string 11 | default: '' 12 | # Resource to get a token for. Common values include: 13 | # - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps 14 | # - 'https://storage.azure.com/' for storage 15 | # Defaults to Azure DevOps 16 | - name: resource 17 | type: string 18 | default: '499b84ac-1321-427f-aa17-267ca6975798' 19 | - name: isStepOutputVariable 20 | type: boolean 21 | default: false 22 | 23 | steps: 24 | - task: AzureCLI@2 25 | displayName: 'Getting federated access token for feeds' 26 | name: ${{ parameters.stepName }} 27 | ${{ if ne(parameters.condition, '') }}: 28 | condition: ${{ parameters.condition }} 29 | inputs: 30 | azureSubscription: ${{ parameters.federatedServiceConnection }} 31 | scriptType: 'pscore' 32 | scriptLocation: 'inlineScript' 33 | inlineScript: | 34 | $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv 35 | if ($LASTEXITCODE -ne 0) { 36 | Write-Error "Failed to get access token for resource '${{ parameters.resource }}'" 37 | exit 1 38 | } 39 | Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value" 40 | Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken" -------------------------------------------------------------------------------- /eng/common/templates-official/steps/publish-logs.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | StageLabel: '' 3 | JobLabel: '' 4 | 5 | steps: 6 | - task: Powershell@2 7 | displayName: Prepare Binlogs to Upload 8 | inputs: 9 | targetType: inline 10 | script: | 11 | New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ 12 | Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ 13 | continueOnError: true 14 | condition: always() 15 | 16 | - task: 1ES.PublishBuildArtifacts@1 17 | displayName: Publish Logs 18 | inputs: 19 | PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' 20 | PublishLocation: Container 21 | ArtifactName: PostBuildLogs 22 | continueOnError: true 23 | condition: always() 24 | -------------------------------------------------------------------------------- /eng/common/templates-official/steps/retain-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # Optional azure devops PAT with build execute permissions for the build's organization, 3 | # only needed if the build that should be retained ran on a different organization than 4 | # the pipeline where this template is executing from 5 | Token: '' 6 | # Optional BuildId to retain, defaults to the current running build 7 | BuildId: '' 8 | # Azure devops Organization URI for the build in the https://dev.azure.com/ format. 9 | # Defaults to the organization the current pipeline is running on 10 | AzdoOrgUri: '$(System.CollectionUri)' 11 | # Azure devops project for the build. Defaults to the project the current pipeline is running on 12 | AzdoProject: '$(System.TeamProject)' 13 | 14 | steps: 15 | - task: powershell@2 16 | inputs: 17 | targetType: 'filePath' 18 | filePath: eng/common/retain-build.ps1 19 | pwsh: true 20 | arguments: > 21 | -AzdoOrgUri: ${{parameters.AzdoOrgUri}} 22 | -AzdoProject ${{parameters.AzdoProject}} 23 | -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} 24 | -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} 25 | displayName: Enable permanent build retention 26 | env: 27 | SYSTEM_ACCESSTOKEN: $(System.AccessToken) 28 | BUILD_ID: $(Build.BuildId) -------------------------------------------------------------------------------- /eng/common/templates-official/variables/sdl-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 3 | # sync with the packages.config file. 4 | - name: DefaultGuardianVersion 5 | value: 0.109.0 6 | - name: GuardianPackagesConfigFile 7 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config -------------------------------------------------------------------------------- /eng/common/templates/jobs/codeql-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md 3 | continueOnError: false 4 | # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job 5 | jobs: [] 6 | # Optional: if specified, restore and use this version of Guardian instead of the default. 7 | overrideGuardianVersion: '' 8 | 9 | jobs: 10 | - template: /eng/common/templates/jobs/jobs.yml 11 | parameters: 12 | enableMicrobuild: false 13 | enablePublishBuildArtifacts: false 14 | enablePublishTestResults: false 15 | enablePublishBuildAssets: false 16 | enablePublishUsingPipelines: false 17 | enableTelemetry: true 18 | 19 | variables: 20 | - group: Publish-Build-Assets 21 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 22 | # sync with the packages.config file. 23 | - name: DefaultGuardianVersion 24 | value: 0.109.0 25 | - name: GuardianPackagesConfigFile 26 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config 27 | - name: GuardianVersion 28 | value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} 29 | 30 | jobs: ${{ parameters.jobs }} 31 | 32 | -------------------------------------------------------------------------------- /eng/common/templates/post-build/common-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | - group: Publish-Build-Assets 3 | 4 | # Whether the build is internal or not 5 | - name: IsInternalBuild 6 | value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} 7 | 8 | # Default Maestro++ API Endpoint and API Version 9 | - name: MaestroApiEndPoint 10 | value: "https://maestro.dot.net" 11 | - name: MaestroApiAccessToken 12 | value: $(MaestroAccessToken) 13 | - name: MaestroApiVersion 14 | value: "2020-02-20" 15 | 16 | - name: SourceLinkCLIVersion 17 | value: 3.0.0 18 | - name: SymbolToolVersion 19 | value: 1.0.1 20 | 21 | - name: runCodesignValidationInjection 22 | value: false 23 | -------------------------------------------------------------------------------- /eng/common/templates/post-build/trigger-subscription.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | ChannelId: 0 3 | 4 | steps: 5 | - task: PowerShell@2 6 | displayName: Triggering subscriptions 7 | inputs: 8 | filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 9 | arguments: -SourceRepo $(Build.Repository.Uri) 10 | -ChannelId ${{ parameters.ChannelId }} 11 | -MaestroApiAccessToken $(MaestroAccessToken) 12 | -MaestroApiEndPoint $(MaestroApiEndPoint) 13 | -MaestroApiVersion $(MaestroApiVersion) 14 | -------------------------------------------------------------------------------- /eng/common/templates/steps/add-build-to-channel.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | ChannelId: 0 3 | 4 | steps: 5 | - task: PowerShell@2 6 | displayName: Add Build to Channel 7 | inputs: 8 | filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 9 | arguments: -BuildId $(BARBuildId) 10 | -ChannelId ${{ parameters.ChannelId }} 11 | -MaestroApiAccessToken $(MaestroApiAccessToken) 12 | -MaestroApiEndPoint $(MaestroApiEndPoint) 13 | -MaestroApiVersion $(MaestroApiVersion) 14 | -------------------------------------------------------------------------------- /eng/common/templates/steps/build-reason.yml: -------------------------------------------------------------------------------- 1 | # build-reason.yml 2 | # Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons 3 | # to include steps (',' separated). 4 | parameters: 5 | conditions: '' 6 | steps: [] 7 | 8 | steps: 9 | - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: 10 | - ${{ parameters.steps }} 11 | - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: 12 | - ${{ parameters.steps }} 13 | -------------------------------------------------------------------------------- /eng/common/templates/steps/component-governance.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | disableComponentGovernance: false 3 | componentGovernanceIgnoreDirectories: '' 4 | 5 | steps: 6 | - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: 7 | - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" 8 | displayName: Set skipComponentGovernanceDetection variable 9 | - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: 10 | - task: ComponentGovernanceComponentDetection@0 11 | continueOnError: true 12 | inputs: 13 | ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} -------------------------------------------------------------------------------- /eng/common/templates/steps/enable-internal-runtimes.yml: -------------------------------------------------------------------------------- 1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64' 2 | # variable with the base64-encoded SAS token, by default 3 | 4 | parameters: 5 | - name: federatedServiceConnection 6 | type: string 7 | default: 'dotnetbuilds-internal-read' 8 | - name: outputVariableName 9 | type: string 10 | default: 'dotnetbuilds-internal-container-read-token-base64' 11 | - name: expiryInHours 12 | type: number 13 | default: 1 14 | - name: base64Encode 15 | type: boolean 16 | default: true 17 | 18 | steps: 19 | - ${{ if ne(variables['System.TeamProject'], 'public') }}: 20 | - template: /eng/common/templates/steps/get-delegation-sas.yml 21 | parameters: 22 | federatedServiceConnection: ${{ parameters.federatedServiceConnection }} 23 | outputVariableName: ${{ parameters.outputVariableName }} 24 | expiryInHours: ${{ parameters.expiryInHours }} 25 | base64Encode: ${{ parameters.base64Encode }} 26 | storageAccount: dotnetbuilds 27 | container: internal 28 | permissions: rl 29 | -------------------------------------------------------------------------------- /eng/common/templates/steps/get-federated-access-token.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: federatedServiceConnection 3 | type: string 4 | - name: outputVariableName 5 | type: string 6 | - name: stepName 7 | type: string 8 | default: 'getFederatedAccessToken' 9 | - name: condition 10 | type: string 11 | default: '' 12 | # Resource to get a token for. Common values include: 13 | # - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps 14 | # - 'https://storage.azure.com/' for storage 15 | # Defaults to Azure DevOps 16 | - name: resource 17 | type: string 18 | default: '499b84ac-1321-427f-aa17-267ca6975798' 19 | - name: isStepOutputVariable 20 | type: boolean 21 | default: false 22 | 23 | steps: 24 | - task: AzureCLI@2 25 | displayName: 'Getting federated access token for feeds' 26 | name: ${{ parameters.stepName }} 27 | ${{ if ne(parameters.condition, '') }}: 28 | condition: ${{ parameters.condition }} 29 | inputs: 30 | azureSubscription: ${{ parameters.federatedServiceConnection }} 31 | scriptType: 'pscore' 32 | scriptLocation: 'inlineScript' 33 | inlineScript: | 34 | $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv 35 | if ($LASTEXITCODE -ne 0) { 36 | Write-Error "Failed to get access token for resource '${{ parameters.resource }}'" 37 | exit 1 38 | } 39 | Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value" 40 | Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken" -------------------------------------------------------------------------------- /eng/common/templates/steps/publish-logs.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | StageLabel: '' 3 | JobLabel: '' 4 | 5 | steps: 6 | - task: Powershell@2 7 | displayName: Prepare Binlogs to Upload 8 | inputs: 9 | targetType: inline 10 | script: | 11 | New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ 12 | Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ 13 | continueOnError: true 14 | condition: always() 15 | 16 | - task: PublishBuildArtifacts@1 17 | displayName: Publish Logs 18 | inputs: 19 | PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' 20 | PublishLocation: Container 21 | ArtifactName: PostBuildLogs 22 | continueOnError: true 23 | condition: always() 24 | -------------------------------------------------------------------------------- /eng/common/templates/steps/retain-build.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # Optional azure devops PAT with build execute permissions for the build's organization, 3 | # only needed if the build that should be retained ran on a different organization than 4 | # the pipeline where this template is executing from 5 | Token: '' 6 | # Optional BuildId to retain, defaults to the current running build 7 | BuildId: '' 8 | # Azure devops Organization URI for the build in the https://dev.azure.com/ format. 9 | # Defaults to the organization the current pipeline is running on 10 | AzdoOrgUri: '$(System.CollectionUri)' 11 | # Azure devops project for the build. Defaults to the project the current pipeline is running on 12 | AzdoProject: '$(System.TeamProject)' 13 | 14 | steps: 15 | - task: powershell@2 16 | inputs: 17 | targetType: 'filePath' 18 | filePath: eng/common/retain-build.ps1 19 | pwsh: true 20 | arguments: > 21 | -AzdoOrgUri: ${{parameters.AzdoOrgUri}} 22 | -AzdoProject ${{parameters.AzdoProject}} 23 | -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} 24 | -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} 25 | displayName: Enable permanent build retention 26 | env: 27 | SYSTEM_ACCESSTOKEN: $(System.AccessToken) 28 | BUILD_ID: $(Build.BuildId) -------------------------------------------------------------------------------- /eng/common/templates/steps/run-on-unix.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | agentOs: '' 3 | steps: [] 4 | 5 | steps: 6 | - ${{ if ne(parameters.agentOs, 'Windows_NT') }}: 7 | - ${{ parameters.steps }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/run-on-windows.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | agentOs: '' 3 | steps: [] 4 | 5 | steps: 6 | - ${{ if eq(parameters.agentOs, 'Windows_NT') }}: 7 | - ${{ parameters.steps }} 8 | -------------------------------------------------------------------------------- /eng/common/templates/steps/run-script-ifequalelse.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # if parameter1 equals parameter 2, run 'ifScript' command, else run 'elsescript' command 3 | parameter1: '' 4 | parameter2: '' 5 | ifScript: '' 6 | elseScript: '' 7 | 8 | # name of script step 9 | name: Script 10 | 11 | # display name of script step 12 | displayName: If-Equal-Else Script 13 | 14 | # environment 15 | env: {} 16 | 17 | # conditional expression for step execution 18 | condition: '' 19 | 20 | steps: 21 | - ${{ if and(ne(parameters.ifScript, ''), eq(parameters.parameter1, parameters.parameter2)) }}: 22 | - script: ${{ parameters.ifScript }} 23 | name: ${{ parameters.name }} 24 | displayName: ${{ parameters.displayName }} 25 | env: ${{ parameters.env }} 26 | condition: ${{ parameters.condition }} 27 | 28 | - ${{ if and(ne(parameters.elseScript, ''), ne(parameters.parameter1, parameters.parameter2)) }}: 29 | - script: ${{ parameters.elseScript }} 30 | name: ${{ parameters.name }} 31 | displayName: ${{ parameters.displayName }} 32 | env: ${{ parameters.env }} 33 | condition: ${{ parameters.condition }} -------------------------------------------------------------------------------- /eng/common/templates/variables/sdl-variables.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in 3 | # sync with the packages.config file. 4 | - name: DefaultGuardianVersion 5 | value: 0.109.0 6 | - name: GuardianPackagesConfigFile 7 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config -------------------------------------------------------------------------------- /eng/resources/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /eng/resources/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /eng/targets/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /eng/targets/Settings.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MIT 5 | Microsoft 6 | dotnet try 7 | $(ArtifactsBinDir) 8 | $(CopyrightMicrosoft) 9 | 10 | 11 | -------------------------------------------------------------------------------- /eng/targets/Versions.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /eng/templates/build-and-test-job-linux-templates.yml: -------------------------------------------------------------------------------- 1 | # build-and-test-job-linux-template.yml 2 | parameters: 3 | buildConfig: 'Release' 4 | buildArgs: '' 5 | skipTests: false 6 | additionalArgs: '' # Additional arguments to pass to the test command 7 | 8 | steps: 9 | - template: /eng/templates/setup-template.yml@self 10 | 11 | - script: | 12 | mkdir -p "$(Build.SourcesDirectory)/artifacts" 13 | cp eng/resources/* "$(Build.SourcesDirectory)/artifacts" 14 | displayName: Prevent test directory crawling 15 | 16 | - pwsh: | 17 | $testArg = if ($env:SKIPTESTS -ne "true") { "--test" } else { "" } 18 | Write-Host "##vso[task.setvariable variable=_TestArgs]$testArg" 19 | displayName: Promote variables 20 | 21 | - script: $(Build.SourcesDirectory)/eng/cibuild.sh 22 | --configuration ${{ parameters.buildConfig }} 23 | --prepareMachine 24 | $(_TestArgs) 25 | displayName: Build 26 | env: 27 | POCKETLOGGER_LOG_PATH: $(PocketLoggerLogPath) 28 | TRYDOTNET_PREBUILDS_PATH: $(TryDotNetPrebuildsPath) 29 | 30 | - script: | 31 | dotnet test -l trx --no-build --blame-hang-timeout 15m --blame-hang-dump-type full -c ${{ parameters.buildConfig }} --results-directory $(Build.SourcesDirectory)/artifacts/TestResults/${{ parameters.buildConfig }} ${{ parameters.additionalArgs }} 32 | displayName: Test / Blame 33 | workingDirectory: $(Build.SourcesDirectory) 34 | condition: ne('${{ parameters.skipTests }}', 'true') 35 | env: 36 | RunIntegrationTests: $(RunIntegrationTests) 37 | 38 | - template: /eng/templates/delete-dump-files-template.yml@self 39 | parameters: 40 | buildConfig: ${{ parameters.buildConfig }} 41 | skipTests: ${{ parameters.skipTests }} -------------------------------------------------------------------------------- /eng/templates/build-and-test-job-windows-templates.yml: -------------------------------------------------------------------------------- 1 | # build-and-test-job-windows-template.yml 2 | parameters: 3 | buildConfig: 'Release' # Pass build configuration as a parameter 4 | buildArgs: '' # Pass additional arguments to the build script 5 | skipTests: false # Default is not skipping tests 6 | additionalArgs: '' # Additional arguments to pass to the test command 7 | 8 | steps: 9 | - template: /eng/templates/setup-template.yml@self 10 | 11 | - script: | 12 | robocopy "eng\resources" "$(Build.SourcesDirectory)\artifacts" 13 | :: robocopy return codes are terrible; 1 means files were copied 14 | if "%errorlevel%" == "1" exit /b 0 15 | exit /b 1 16 | displayName: Prevent test directory crawling 17 | 18 | - pwsh: | 19 | $testArg = if ($env:SKIPTESTS -ne "true") { "-test" } else { "" } 20 | Write-Host "##vso[task.setvariable variable=_TestArgs]$testArg" 21 | displayName: Promote variables 22 | 23 | - script: $(Build.SourcesDirectory)\eng\CIBuild.cmd 24 | -configuration ${{ parameters.buildConfig }} 25 | -prepareMachine 26 | -sign 27 | ${{ parameters.buildArgs }} 28 | $(_TestArgs) 29 | displayName: Build 30 | env: 31 | POCKETLOGGER_LOG_PATH: $(PocketLoggerLogPath) 32 | TRYDOTNET_PREBUILDS_PATH: $(TryDotNetPrebuildsPath) 33 | 34 | - script: | 35 | dotnet test -l trx --no-build --blame-hang-timeout 15m --blame-hang-dump-type full -c ${{ parameters.buildConfig }} --results-directory $(Build.SourcesDirectory)/artifacts/TestResults/${{ parameters.buildConfig }} ${{ parameters.additionalArgs }} 36 | displayName: Test / Blame 37 | workingDirectory: $(Build.SourcesDirectory) 38 | condition: ne('${{ parameters.skipTests }}', 'true') 39 | env: 40 | RunIntegrationTests: $(RunIntegrationTests) 41 | 42 | - template: /eng/templates/delete-dump-files-template.yml@self 43 | parameters: 44 | buildConfig: ${{ parameters.buildConfig }} 45 | skipTests: ${{ parameters.skipTests }} -------------------------------------------------------------------------------- /eng/templates/delete-dump-files-template.yml: -------------------------------------------------------------------------------- 1 | # delete-dump-files-template.yml 2 | parameters: 3 | buildConfig: '' 4 | skipTests: false 5 | 6 | steps: 7 | - pwsh: Get-ChildItem *.dmp -Recurse | Remove-Item 8 | displayName: Delete dump files 9 | workingDirectory: $(Build.SourcesDirectory)/artifacts/TestResults/${{ parameters.buildConfig }} 10 | condition: and(ne(variables['KeepDumps'], 'true'), ne('${{ parameters.skipTests }}', 'true')) -------------------------------------------------------------------------------- /eng/templates/setup-template.yml: -------------------------------------------------------------------------------- 1 | # setup-template.yml 2 | steps: 3 | - script: git config --global core.longpaths true 4 | displayName: Enable `git clean` to handle long paths 5 | 6 | - checkout: self 7 | clean: true 8 | 9 | - task: NodeTool@0 10 | displayName: Add NodeJS/npm 11 | inputs: 12 | versionSpec: $(NodeJSVersion) 13 | 14 | - task: UseDotNet@2 15 | displayName: Add dotnet 16 | inputs: 17 | packageType: sdk 18 | version: $(DotNetSdkVersion) 19 | installationPath: $(Agent.ToolsDirectory)/dotnet 20 | -------------------------------------------------------------------------------- /eng/templates/variables-template.yml: -------------------------------------------------------------------------------- 1 | # variables-template.yml 2 | 3 | variables: 4 | - name: _TeamName 5 | value: DotNetTry 6 | - name: _BuildConfig 7 | value: Release 8 | - name: _PublishUsingPipelines 9 | value: true 10 | - name: _DotNetArtifactsCategory 11 | value: .NETCore 12 | - name: DotNetSdkVersion 13 | value: '8.0.204' 14 | - name: NodeJSVersion 15 | value: '16.13.0' 16 | - name: Codeql.Enabled 17 | value: true -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.102", 4 | "allowPrerelease": true, 5 | "rollForward": "latestMinor" 6 | }, 7 | "tools": { 8 | "dotnet": "9.0.102", 9 | "rollForward": "latestMinor" 10 | }, 11 | "msbuild-sdks": { 12 | "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.25263.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /restore.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | powershell -noprofile -executionPolicy RemoteSigned -file "%~dp0eng\build.ps1" -restore -binaryLog %* 3 | -------------------------------------------------------------------------------- /restore.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd)" 15 | 16 | . "$scriptroot/eng/build.sh" --restore --binaryLog "$@" 17 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/(Pocket)/Logger/Class1.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Reflection; 6 | using Microsoft.DotNet.Interactive; 7 | using Microsoft.DotNet.Interactive.CSharpProject; 8 | using Microsoft.DotNet.Interactive.Documents; 9 | using Microsoft.TryDotNet.IntegrationTests; 10 | using Xunit.Abstractions; 11 | 12 | namespace Pocket; 13 | 14 | internal partial class LogEvents 15 | { 16 | public static IDisposable SubscribeToPocketLogger(this ITestOutputHelper output) => 17 | Subscribe( 18 | e => output.WriteLine(e.ToLogString()), 19 | AssembliesPublishingPocketLoggerEvents); 20 | 21 | public static Assembly[] AssembliesPublishingPocketLoggerEvents => 22 | [ 23 | typeof(Microsoft.TryDotNet.Program).Assembly, // Microsoft.TryDotNet.dll 24 | typeof(Kernel).Assembly, // Microsoft.DotNet.Interactive.dll 25 | typeof(CSharpProjectKernel).Assembly, // Microsoft.DotNet.Interactive.CSharpProject.dll 26 | typeof(InteractiveDocument).Assembly, // Microsoft.DotNet.Interactive.Documents.dll, 27 | typeof(IntegratedServicesFixture).Assembly // Microsoft.TryDotNet.IntegrationTests.dll 28 | ]; 29 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/AsyncLazy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.TryDotNet.IntegrationTests; 8 | 9 | internal class AsyncLazy 10 | { 11 | private readonly Lazy> _lazy; 12 | 13 | public AsyncLazy(Func> initialize) 14 | { 15 | if (initialize is null) 16 | { 17 | throw new ArgumentNullException(nameof(initialize)); 18 | } 19 | 20 | #pragma warning disable VSTHRD011 // Use AsyncLazy 21 | _lazy = new Lazy>(initialize); 22 | #pragma warning restore VSTHRD011 // Use AsyncLazy 23 | } 24 | 25 | public Task ValueAsync() => _lazy.Value; 26 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/CollectionDefinitionForIntegratedServicesFixture.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Xunit; 5 | 6 | namespace Microsoft.TryDotNet.IntegrationTests; 7 | 8 | [CollectionDefinition(nameof(IntegratedServicesFixture), DisableParallelization = true)] 9 | public class CollectionDefinitionForIntegratedServicesFixture : ICollectionFixture 10 | { 11 | // This class has no code, and is never created. Its purpose is simply 12 | // to be the place to apply [CollectionDefinition] and all the 13 | // ICollectionFixture<> interfaces. 14 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/CommandLineInvocationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.DotNet.Interactive.Utility; 3 | 4 | namespace Microsoft.TryDotNet.IntegrationTests; 5 | 6 | public class CommandLineInvocationException : Exception 7 | { 8 | public CommandLineInvocationException(CommandLineResult result, string? message = null) : base( 9 | $"{message}{Environment.NewLine}Exit code {result.ExitCode}: {string.Join("\n", result.Error)}".Trim()) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/DotNetOnline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.Playwright; 6 | 7 | namespace Microsoft.TryDotNet.IntegrationTests; 8 | 9 | public class DotNetOnline 10 | { 11 | private readonly IPage _page; 12 | 13 | public DotNetOnline(IPage page) 14 | { 15 | _page = page; 16 | } 17 | 18 | public Task FocusAsync() 19 | { 20 | return _page.EvaluateAsync("() => { dotnetOnline.focus(); }"); 21 | } 22 | 23 | public Task ExecuteAsync() 24 | { 25 | return _page.EvaluateAsync("() => { dotnetOnline.execute(); }"); 26 | } 27 | 28 | public Task SetCodeAsync(string code) 29 | { 30 | return _page.EvaluateAsync("(code) => { dotnetOnline.setCode(code); }",code); 31 | } 32 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/IntegrationTestFactAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Runtime.InteropServices; 6 | 7 | using Xunit; 8 | 9 | namespace Microsoft.TryDotNet.IntegrationTests 10 | { 11 | internal class IntegrationTestFactAttribute : FactAttribute 12 | { 13 | private const string EnvironmentVariableName = "RunIntegrationTests"; 14 | 15 | public IntegrationTestFactAttribute(string? skipReason = null) 16 | { 17 | var variableValue = Environment.GetEnvironmentVariable(EnvironmentVariableName) ?? "false"; 18 | switch (variableValue.ToLowerInvariant()) 19 | { 20 | case "1": 21 | case "true": 22 | if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) 23 | { 24 | Skip = string.IsNullOrWhiteSpace(skipReason) ? "Ignored on Linux" : skipReason; 25 | } 26 | break; 27 | default: 28 | Skip = $"Skipping integration tests because environment variable '{EnvironmentVariableName}' was not 'true' or '1'."; 29 | break; 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/MessageInterceptor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Collections.Concurrent; 6 | using System.Collections.Generic; 7 | using System.Diagnostics; 8 | using System.Text.Json; 9 | using System.Threading.Tasks; 10 | using Microsoft.Playwright; 11 | 12 | namespace Microsoft.TryDotNet.IntegrationTests; 13 | 14 | internal class MessageInterceptor 15 | { 16 | private readonly ConcurrentDictionary> _completionSources = new (StringComparer.OrdinalIgnoreCase); 17 | public List Messages { get; } = new(); 18 | 19 | public async Task InstallAsync(IPage page) 20 | { 21 | await page.ExposeFunctionAsync("postMessageLogger", async (JsonElement message) => 22 | { 23 | await Task.Yield(); 24 | Messages.Add(message); 25 | if (message.TryGetProperty("type", out var typeProperty)) 26 | { 27 | var messageType = typeProperty.GetString(); 28 | if (messageType is not null) 29 | { 30 | if (_completionSources.TryRemove(messageType, out var cs)) 31 | { 32 | cs.SetResult(message); 33 | } 34 | } 35 | } 36 | 37 | }); 38 | } 39 | 40 | public Task AwaitForMessage(string messageType, TimeSpan? timeOut = null) 41 | { 42 | var cs = _completionSources.GetOrAdd(messageType, _ => new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously)); 43 | 44 | if (Debugger.IsAttached) 45 | { 46 | return cs.Task; 47 | } 48 | 49 | return cs.Task.Timeout(timeOut ?? TimeSpan.FromMinutes(1), $"Timeout waiting for message of type {messageType}"); 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/Microsoft.TryDotNet.IntegrationTests.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | 5 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/PeakyTestDiscovery.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using Peaky.Client; 6 | using Peaky.XUnit; 7 | 8 | namespace Microsoft.TryDotNet.IntegrationTests; 9 | 10 | public class PeakyTestDiscovery : PeakyXunitTestBase 11 | { 12 | private static readonly Uri _testDiscoveryUri = new("https://mls-monitoring.azurewebsites.net/tests/staging/orchestrator?deployment=true"); 13 | 14 | private readonly PeakyClient _peakyClient = new(_testDiscoveryUri); 15 | 16 | public override PeakyClient PeakyClient => _peakyClient; 17 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/PeakyTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Net.Http; 6 | using System.Threading.Tasks; 7 | using FluentAssertions; 8 | using Peaky.Client; 9 | using Xunit; 10 | using Xunit.Abstractions; 11 | 12 | namespace Microsoft.TryDotNet.IntegrationTests; 13 | 14 | public class PeakyTests 15 | { 16 | private readonly ITestOutputHelper _output; 17 | 18 | private readonly PeakyClient _peakyClient = new(new HttpClient()); 19 | 20 | public PeakyTests(ITestOutputHelper output) 21 | { 22 | _output = output; 23 | } 24 | 25 | [Theory(Skip = "Work in progress")] 26 | [ClassData(typeof(PeakyTestDiscovery))] 27 | public async Task The_peaky_test_passes(Uri url) 28 | { 29 | var result = await _peakyClient.GetTestResultAsync(url); 30 | 31 | _output.WriteLine(result.Content); 32 | 33 | result.Passed.Should().BeTrue(); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/PlaywrightSession.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Threading.Tasks; 7 | using Microsoft.Playwright; 8 | 9 | namespace Microsoft.TryDotNet.IntegrationTests; 10 | 11 | public class PlaywrightSession : IDisposable 12 | { 13 | private IPlaywright _playwright; 14 | 15 | public PlaywrightSession(IPlaywright playwright, IBrowser browser) 16 | { 17 | _playwright = playwright; 18 | Browser = browser; 19 | } 20 | 21 | public IBrowser Browser { get; } 22 | 23 | public static async Task StartAsync() 24 | { 25 | var exitCode = Playwright.Program.Main(["install", "chromium"]); 26 | if (exitCode is not 0) 27 | { 28 | throw new Exception($"Playwright exited with code {exitCode}"); 29 | } 30 | 31 | var session = await Playwright.Playwright.CreateAsync().Timeout(TimeSpan.FromMinutes(5), "Timeout creating Playwright session"); 32 | 33 | var browserTypeLaunchOptions = new BrowserTypeLaunchOptions(); 34 | 35 | if (Debugger.IsAttached) 36 | { 37 | browserTypeLaunchOptions.Headless = false; 38 | browserTypeLaunchOptions.Devtools = true; 39 | } 40 | 41 | var browser = await session.Chromium.LaunchAsync(browserTypeLaunchOptions).Timeout(TimeSpan.FromMinutes(5), "Timeout launching browser"); 42 | 43 | return new PlaywrightSession(session, browser); 44 | } 45 | 46 | public void Dispose() => _playwright.Dispose(); 47 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/PlaywrightTestBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using Microsoft.Playwright; 7 | using Pocket; 8 | using Xunit; 9 | using Xunit.Abstractions; 10 | 11 | [assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly, DisableTestParallelization = true)] 12 | 13 | namespace Microsoft.TryDotNet.IntegrationTests; 14 | 15 | [Collection(nameof(IntegratedServicesFixture))] 16 | public abstract class PlaywrightTestBase : IDisposable 17 | { 18 | private readonly CompositeDisposable _disposables = new(); 19 | 20 | protected PlaywrightTestBase( 21 | IntegratedServicesFixture services, 22 | ITestOutputHelper output) 23 | { 24 | Services = services; 25 | Output = output; 26 | } 27 | 28 | public IntegratedServicesFixture Services { get; } 29 | 30 | public ITestOutputHelper Output { get; } 31 | 32 | protected async Task NewPageAsync() 33 | { 34 | var playwright = await Services.GetPlaywrightAsync(); 35 | return await playwright.Browser.NewPageAsync(); 36 | } 37 | 38 | protected async Task TryDotNetUrlAsync() 39 | { 40 | var server = await Services.GetTryDotNetServerAsync(); 41 | return server.Url; 42 | } 43 | 44 | protected async Task LearnUrlAsync() 45 | { 46 | var server = await Services.GetLearnServerAsync(); 47 | return server.Url; 48 | } 49 | 50 | public void Dispose() 51 | { 52 | _disposables.Dispose(); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/SerializableCodeRunnerResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | 5 | namespace Microsoft.TryDotNet.IntegrationTests; 6 | 7 | internal record SerializableCodeRunnerResult(bool success, string? error, string? runnerError); -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/UriExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System; 5 | 6 | namespace Microsoft.TryDotNet.IntegrationTests; 7 | 8 | internal static class UriExtensions 9 | { 10 | public static Uri ToLocalHost(this Uri source) 11 | { 12 | var root = new Uri($"{source.Scheme}://127.0.0.1:{source.Port}"); 13 | return new Uri(root,source.PathAndQuery); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.IntegrationTests/WasmRunnerMessage.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | 5 | namespace Microsoft.TryDotNet.IntegrationTests; 6 | 7 | internal record WasmRunnerMessage(string type, string? message = null, SerializableCodeRunnerResult? result = null) { } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.SimulatorGenerator/ApiContractScenario.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.DotNet.Interactive.Commands; 2 | 3 | namespace Microsoft.TryDotNet.SimulatorGenerator; 4 | 5 | internal record ApiContractScenario(string Label, KernelCommand[][] CommandBatches); -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.SimulatorGenerator/Microsoft.TryDotNet.SimulatorGenerator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | embedded 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.SimulatorGenerator/Program.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using Microsoft.TryDotNet.SimulatorGenerator; 3 | 4 | var existingOnlyOption = new Option("--destination-folder") 5 | { 6 | Description = "Location to write the simulator files", 7 | IsRequired = true 8 | }.ExistingOnly(); 9 | 10 | var command = new RootCommand 11 | { 12 | existingOnlyOption 13 | }; 14 | 15 | command.SetHandler(async (DirectoryInfo destinationFolder) => 16 | { 17 | 18 | await ApiEndpointSimulatorGenerator.CreateScenarioFiles(destinationFolder); 19 | }, existingOnlyOption); 20 | 21 | return command.Invoke(args); 22 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.SimulatorGenerator/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Microsoft.TryDotNet.SimulatorGenerator": { 4 | "commandName": "Project", 5 | "commandLineArgs": "--destination-folder \"$(MSBuildThisFileDirectory)../microsoft-trydotnet-editor/tests/simulatorConfigurations/apiService\"" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.SimulatorGenerator/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace Microsoft.TryDotNet.SimulatorGenerator; 4 | 5 | internal static class StringExtensions 6 | { 7 | public static string FixedToken(this string source) 8 | { 9 | return Regex.Replace(source, @"""token""\s*:\s*""(?([^""\\]|(\\.))*)""", @"""token"": ""command-token""", RegexOptions.IgnoreCase); 10 | } 11 | 12 | public static string FixedId(this string source) 13 | { 14 | return Regex.Replace(source, @"""id""\s*:\s*""(?([^""\\]|(\\.))*)""", @"""id"": ""command-id""", RegexOptions.IgnoreCase); 15 | } 16 | 17 | public static string FixedNewLine(this string source) 18 | { 19 | return Regex.Replace(source, @"\\r\\n", @"\n"); 20 | } 21 | 22 | public static string FixedAssembly(this string source) 23 | { 24 | return Regex.Replace(source, @"(?""assembly""\s*:\s*\{\s*""value""\s*:\s*"")(?([^""\\]|(\\.))*)(?""\s*\}\s*)", "${start}AABBCC${end}", RegexOptions.Multiline); 25 | } 26 | 27 | 28 | public static string Fixed(this string source) 29 | { 30 | return source.FixedId().FixedToken().FixedNewLine().FixedAssembly(); 31 | } 32 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.Tests/(Pocket)/Logger/LogEvents.SubscribeToPocketLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.DotNet.Interactive.CSharpProject; 5 | using Microsoft.DotNet.Interactive.Events; 6 | using Xunit.Abstractions; 7 | 8 | namespace Pocket; 9 | 10 | internal partial class LogEvents 11 | { 12 | public static IDisposable SubscribeToPocketLogger(this ITestOutputHelper output) => 13 | Subscribe( 14 | e => output.WriteLine(e.ToLogString()), 15 | new[] 16 | { 17 | typeof(LogEvents).Assembly, 18 | typeof(KernelEvent).Assembly, 19 | typeof(CSharpProjectKernel).Assembly 20 | }); 21 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.Tests/Microsoft.TryDotNet.Tests.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/App.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.TryDotNet.WasmRunner 2 | @using Microsoft.TryDotNet.WasmRunner.Shared 3 | 4 | 5 | 6 | 7 | 8 | 9 | Not found 10 | 11 | Sorry, there's nothing at this address. 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/AsyncContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | 5 | namespace Microsoft.TryDotNet.WasmRunner; 6 | 7 | internal static class AsyncContext 8 | { 9 | private static int _seed = 0; 10 | 11 | private static readonly AsyncLocal _id = new(); 12 | 13 | public static int? Id => _id.Value; 14 | 15 | public static bool TryEstablish(out int id) 16 | { 17 | if (_id.Value is { } value) 18 | { 19 | id = _id.Value.Value; 20 | return false; 21 | } 22 | else 23 | { 24 | _id.Value = Interlocked.Increment(ref _seed); 25 | id = _id.Value.Value; 26 | return true; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/CodeRunnerAdapter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.JSInterop; 5 | 6 | namespace Microsoft.TryDotNet.WasmRunner; 7 | 8 | internal class CodeRunnerAdapter 9 | { 10 | private readonly CodeRunner _runner; 11 | private readonly IJSRuntime _jsInterop; 12 | 13 | public CodeRunnerAdapter(CodeRunner runner, IJSRuntime jsInterop) 14 | { 15 | _runner = runner; 16 | _jsInterop = jsInterop; 17 | } 18 | 19 | [JSInvokable] 20 | public async Task RunAssembly(string base64EncodedAssembly) 21 | { 22 | var result = await _runner.RunAssemblyEntryPoint(base64EncodedAssembly, 23 | output => _jsInterop.InvokeAsync("publishCodeRunnerStdOut", output), 24 | error => _jsInterop.InvokeAsync("publishCodeRunnerStdError", error) 25 | ); 26 | 27 | return new SerializableCodeRunnerResult(result.Succeeded, result.Exception?.ToString(), result.RunnerException?.ToString()); 28 | } 29 | } 30 | 31 | internal record SerializableCodeRunnerResult(bool Success, string? Error, string? RunnerError); -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Microsoft.TryDotNet.WasmRunner.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | wasmrunner 8 | false 9 | embedded 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @inject IJSRuntime JS 3 | WasmRunner 9000 4 | 5 | @code 6 | { 7 | private CodeRunnerAdapter? _runner; 8 | 9 | protected override async Task OnAfterRenderAsync(bool firstRender) 10 | { 11 | await base.OnAfterRenderAsync(firstRender); 12 | if (firstRender) 13 | { 14 | _runner = new CodeRunnerAdapter(new CodeRunner(), JS); 15 | 16 | var runnerReference = DotNetObjectReference.Create(_runner); 17 | 18 | await JS.InvokeVoidAsync("setCodeRunner", runnerReference); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components.Web; 2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 3 | using Microsoft.TryDotNet.WasmRunner; 4 | 5 | 6 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 7 | builder.RootComponents.Add("#app"); 8 | builder.RootComponents.Add("head::after"); 9 | 10 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 11 | 12 | await builder.Build().RunAsync(); 13 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:1654", 7 | "sslPort": 44300 8 | } 9 | }, 10 | "profiles": { 11 | "Microsoft.TryDotNet.WasmRunner": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 16 | "applicationUrl": "https://localhost:7002;http://localhost:5002", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development" 19 | } 20 | }, 21 | "IIS Express": { 22 | "commandName": "IISExpress", 23 | "launchBrowser": true, 24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/RunResults.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.WasmRunner; 5 | 6 | public class RunResults 7 | { 8 | public RunResults(bool succeeded, Exception? exception = null, Exception? runnerException = null) 9 | { 10 | Exception = exception; 11 | Succeeded = succeeded; 12 | RunnerException = runnerException; 13 | } 14 | 15 | public Exception? Exception { get; } 16 | public bool Succeeded { get; } 17 | public Exception? RunnerException { get; } 18 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | 4 | @Body 5 | 6 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row ::deep .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | text-decoration: none; 28 | } 29 | 30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { 31 | text-decoration: underline; 32 | } 33 | 34 | .top-row ::deep a:first-child { 35 | overflow: hidden; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | @media (max-width: 640.98px) { 40 | .top-row:not(.auth) { 41 | display: none; 42 | } 43 | 44 | .top-row.auth { 45 | justify-content: space-between; 46 | } 47 | 48 | .top-row ::deep a, .top-row ::deep .btn-link { 49 | margin-left: 0; 50 | } 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .page { 55 | flex-direction: row; 56 | } 57 | 58 | .sidebar { 59 | width: 250px; 60 | height: 100vh; 61 | position: sticky; 62 | top: 0; 63 | } 64 | 65 | .top-row { 66 | position: sticky; 67 | top: 0; 68 | z-index: 1; 69 | } 70 | 71 | .top-row.auth ::deep a:first-child { 72 | flex: 1; 73 | text-align: right; 74 | width: 0; 75 | } 76 | 77 | .top-row, article { 78 | padding-left: 2rem !important; 79 | padding-right: 1.5rem !important; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using Microsoft.TryDotNet.WasmRunner 10 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet.WasmRunner/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/try/85f7d1ecfe0434bd478e35788c3ebda9419704ef/src/Microsoft.TryDotNet.WasmRunner/wwwroot/icon-192.png -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/EnvelopeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Text.Json; 5 | using Microsoft.DotNet.Interactive.Connection; 6 | 7 | namespace Microsoft.TryDotNet; 8 | 9 | public static class EnvelopeExtensions 10 | { 11 | public static JsonElement ToJsonElement(this IKernelEventEnvelope envelope) 12 | { 13 | return JsonDocument.Parse(KernelEventEnvelope.Serialize(envelope)).RootElement; 14 | } 15 | 16 | public static JsonElement ToJsonElement(this IKernelCommandEnvelope envelope) 17 | { 18 | return JsonDocument.Parse(KernelCommandEnvelope.Serialize(envelope)).RootElement; 19 | } 20 | 21 | public static IEnumerable ToJsonElements(this IEnumerable envelopes) 22 | { 23 | return envelopes.Select(e => e.ToJsonElement()); 24 | } 25 | 26 | public static IEnumerable ToJsonElements(this IEnumerable envelopes) 27 | { 28 | return envelopes.Select(e => e.ToJsonElement()); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/KernelDiagnostics.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using System.Diagnostics; 5 | using Microsoft.DotNet.Interactive; 6 | using Microsoft.DotNet.Interactive.Formatting; 7 | using Pocket; 8 | 9 | namespace Microsoft.TryDotNet; 10 | 11 | internal static class KernelDiagnostics 12 | { 13 | [DebuggerStepThrough] 14 | public static T LogCommandsToPocketLogger(this T kernel) 15 | where T : Kernel 16 | { 17 | kernel.AddMiddleware(async (command, context, next) => 18 | { 19 | using var _ = Logger.Log.OnEnterAndExit(); 20 | Logger.Log.Info(command); 21 | 22 | await next(command, context); 23 | }); 24 | return kernel; 25 | } 26 | 27 | [DebuggerStepThrough] 28 | public static T LogEventsToPocketLogger(this T kernel) 29 | where T : Kernel 30 | { 31 | var disposables = new CompositeDisposable(); 32 | 33 | kernel.VisitSubkernelsAndSelf(k => 34 | { 35 | disposables.Add( 36 | k.KernelEvents.Subscribe(e => 37 | { 38 | Logger.Log.Info("{kernel}: {event} ({details})", 39 | k.Name, 40 | e, 41 | e.ToDisplayString("text/plain")); 42 | })); 43 | }); 44 | 45 | kernel.RegisterForDisposal(disposables); 46 | 47 | return kernel; 48 | } 49 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/Microsoft.TryDotNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | $(NoWarn);NU5100 9 | embedded 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | 20 | 21 | all 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/ApplicationInsightsClientException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | public class ApplicationInsightsClientException : Exception 7 | { 8 | public ApplicationInsightsClientException(string message) : base(message) 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/ApplicationInsightsSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | namespace Microsoft.TryDotNet.PeakyTests; 7 | 8 | [ShortName("Insights")] 9 | internal class ApplicationInsightsSettings : IEquatable 10 | { 11 | public string WriteKey { get; set; } 12 | public string ReadKey { get; set; } 13 | public string AppId { get; set; } 14 | public bool DeveloperMode { get; set; } 15 | 16 | public override bool Equals(object obj) => Equals(obj as ApplicationInsightsSettings); 17 | public override int GetHashCode() => throw new NotSupportedException(); 18 | 19 | public static ApplicationInsightsSettings ForLocal => new() { AppId = "local", ReadKey = "ReadKey", WriteKey = "WriteKey" }; 20 | 21 | public bool Equals(ApplicationInsightsSettings other) => 22 | other != null && 23 | WriteKey.Equals(other.WriteKey) && 24 | ReadKey.Equals(other.ReadKey) && 25 | AppId.Equals(other.AppId) && 26 | DeveloperMode == other.DeveloperMode; 27 | 28 | public override string ToString() => $"Key: {WriteKey}, ApiKey: secret, DeveloperMode: {DeveloperMode}"; 29 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/DomainParseResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | namespace Microsoft.TryDotNet.PeakyTests; 7 | 8 | internal class DomainParseResult 9 | { 10 | public DomainParseResult( 11 | string secondLevelDomain = null, 12 | string thirdLevelDomain = null, 13 | string fourthLevelDomain = null, 14 | string fifthLevelDomain = null) 15 | { 16 | SecondLevelDomain = secondLevelDomain; 17 | ThirdLevelDomain = thirdLevelDomain; 18 | FourthLevelDomain = fourthLevelDomain; 19 | FifthLevelDomain = fifthLevelDomain; 20 | } 21 | 22 | public string SecondLevelDomain { get; } 23 | public string ThirdLevelDomain { get; } 24 | public string FourthLevelDomain { get; } 25 | public string FifthLevelDomain { get; } 26 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/EnvironmentSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | namespace Microsoft.TryDotNet.PeakyTests; 7 | 8 | public record EnvironmentSettings(string RegionId, string HostOrigin, bool IsHttpsEnabled) 9 | { 10 | public static EnvironmentSettings ForLocal { get; } = new("localhost", "http://localhost:7061", false); 11 | 12 | public static EnvironmentSettings ForProduction { get; } = new("production", "https://trydotnet.microsoft.com", true); 13 | 14 | public static EnvironmentSettings ForPreProduction { get; } = new("ppe", "https://try-ppe.dot.net/", true); 15 | 16 | public override string ToString() 17 | { 18 | return $"{nameof(HostOrigin)}: {HostOrigin}, {nameof(IsHttpsEnabled)}: {IsHttpsEnabled}, {nameof(RegionId)}: {RegionId}"; 19 | } 20 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HostOriginAuthenticationHandlerExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | internal static class HostOriginAuthenticationHandlerExtensions 7 | { 8 | public static void AddHostOriginAuth(this IServiceCollection services, HostOriginPolicies policies) 9 | { 10 | if (services == null) 11 | { 12 | throw new ArgumentNullException(nameof(services)); 13 | } 14 | 15 | if (policies == null) 16 | { 17 | throw new ArgumentNullException(nameof(policies)); 18 | } 19 | 20 | services.AddSingleton(policies); 21 | 22 | var authenticationBuilder = services.AddAuthentication(options => 23 | { 24 | options.DefaultAuthenticateScheme = "HostOrigin"; 25 | options.DefaultChallengeScheme = "HostOrigin"; 26 | }); 27 | 28 | authenticationBuilder.AddScheme( 29 | "HostOrigin", 30 | "HostOriginAuth", 31 | _ => { }); 32 | 33 | services.AddAuthorization( 34 | options => options.AddPolicy("HostOrigin", 35 | policy => policy.RequireClaim("HostOriginDomain"))); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HostOriginAuthenticationOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | using Microsoft.AspNetCore.Authentication; 5 | 6 | namespace Microsoft.TryDotNet.PeakyTests; 7 | 8 | public class HostOriginAuthenticationOptions : AuthenticationSchemeOptions 9 | { 10 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HostOriginPoliciesExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | using System.Collections.ObjectModel; 7 | 8 | namespace Microsoft.TryDotNet.PeakyTests; 9 | 10 | internal static class HostOriginPoliciesExtensions 11 | { 12 | public static IReadOnlyDictionary ToReadOnly(this IDictionary subject) 13 | { 14 | subject = subject ?? throw new ArgumentNullException(nameof(subject)); 15 | 16 | return new ReadOnlyDictionary(subject); 17 | } 18 | 19 | public static IDictionary Add( 20 | this IDictionary dictionary, 21 | string domain, 22 | string[] authorizedPools, 23 | bool enableBranding = true) 24 | { 25 | dictionary.Add(domain, 26 | new HostOriginPolicy(domain, 27 | authorizedPools, 28 | enableBranding, 29 | maxAgentReassignmentsPerRequest: 1)); 30 | return dictionary; 31 | } 32 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HostOriginPolicy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | public class HostOriginPolicy 7 | { 8 | public HostOriginPolicy( 9 | string hostingDomain, 10 | IReadOnlyCollection authorizedForPools, 11 | bool enableBranding, 12 | uint maxAgentReassignmentsPerRequest = 0) 13 | { 14 | HostingDomain = hostingDomain 15 | ?? throw new ArgumentNullException(nameof(hostingDomain)); 16 | 17 | AuthorizedForPools = authorizedForPools; 18 | MaxAgentReassignmentsPerRequest = maxAgentReassignmentsPerRequest; 19 | EnableBranding = enableBranding; 20 | } 21 | 22 | public IReadOnlyCollection AuthorizedForPools { get; } 23 | 24 | public string HostingDomain { get; } 25 | 26 | public uint MaxAgentReassignmentsPerRequest { get; } 27 | 28 | public bool EnableBranding { get; } 29 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HttpClientWithRequestHeaders.cs: -------------------------------------------------------------------------------- 1 | using Peaky; 2 | 3 | namespace Microsoft.TryDotNet.PeakyTests; 4 | 5 | public class HttpClientWithRequestHeaders : HttpClient 6 | { 7 | public HttpClientWithRequestHeaders(TestTarget testTarget) : base(new XsrfCookieHandlingMessageHandler(testTarget.BaseAddress), false) 8 | { 9 | BaseAddress = testTarget?.BaseAddress ?? 10 | throw new ArgumentNullException(nameof(testTarget)); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HttpClientWithTelemetry.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Peaky; 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | public class HttpClientWithTelemetry : HttpClient 7 | { 8 | private readonly string _baseRequestId = $"Peaky-{Guid.NewGuid()}"; 9 | private int _requestSequenceNumber; 10 | 11 | public HttpClientWithTelemetry(TestTarget testTarget) 12 | { 13 | BaseAddress = testTarget?.BaseAddress ?? 14 | throw new ArgumentNullException(nameof(testTarget)); 15 | } 16 | 17 | internal HttpClientWithTelemetry( 18 | TestTarget testTarget, 19 | HttpMessageHandler messageHandler) : base(messageHandler, false) 20 | { 21 | BaseAddress = testTarget?.BaseAddress ?? 22 | throw new ArgumentNullException(nameof(testTarget)); 23 | } 24 | 25 | public static HttpClientWithTelemetry Hack_CreateHttpClientWithTelemetryButHideCtorFromPocketContainer(TestTarget testTarget, HttpMessageHandler messageHandler) 26 | { 27 | return new HttpClientWithTelemetry(testTarget, messageHandler); 28 | } 29 | 30 | public new Task SendAsync(HttpRequestMessage request) 31 | { 32 | var requestId = GetNextRequestId(); 33 | 34 | request.Headers.Add("Request-Id", requestId); 35 | 36 | Trace.WriteLine($"Request-Id: {requestId}"); 37 | 38 | return base.SendAsync(request); 39 | } 40 | 41 | public override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 42 | { 43 | var requestId = GetNextRequestId(); 44 | 45 | request.Headers.Add("Request-Id", requestId); 46 | 47 | Trace.WriteLine($"Request-Id: {requestId}"); 48 | 49 | return base.SendAsync(request, cancellationToken); 50 | } 51 | 52 | private string GetNextRequestId() => $"{_baseRequestId}-{Interlocked.Increment(ref _requestSequenceNumber)}"; 53 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/HttpClientWithXsrfCookies.cs: -------------------------------------------------------------------------------- 1 | using Peaky; 2 | 3 | namespace Microsoft.TryDotNet.PeakyTests; 4 | 5 | public class HttpClientWithXsrfCookies : HttpClientWithTelemetry 6 | { 7 | public HttpClientWithXsrfCookies(TestTarget testTarget) : base(testTarget, new XsrfCookieHandlingMessageHandler(testTarget.BaseAddress)) 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/IEnvironmentVariableAccess.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | internal interface IEnvironmentVariableAccess 7 | { 8 | string Get(string name); 9 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/PropertyDeserializationInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | using System.Reflection; 7 | 8 | namespace Microsoft.TryDotNet.PeakyTests; 9 | 10 | internal class PropertyDeserializationInfo 11 | { 12 | public string PropertyName { get; set; } 13 | public PropertyInfo PropertyInfo { get; set; } 14 | public string EnvironmentVariableName { get; set; } 15 | public string EnvironmentVariableValue { get; set; } 16 | public object PropertyValue { get; set; } 17 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/ShortNameAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | internal class ShortNameAttribute : Attribute 7 | { 8 | public string Name; 9 | 10 | public ShortNameAttribute(string v) 11 | { 12 | this.Name = v; 13 | } 14 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | #nullable disable 4 | 5 | using System.Reflection; 6 | 7 | namespace Microsoft.TryDotNet.PeakyTests; 8 | 9 | internal static class TypeExtensions 10 | { 11 | static readonly Type[] EmptyTypeArray = new Type[] { }; 12 | 13 | public static bool HasDefaultConstructor(this Type type) 14 | { 15 | type = type ?? throw new ArgumentNullException(nameof(type)); 16 | 17 | return type.GetDefaultConstructor() != null; 18 | } 19 | 20 | public static ConstructorInfo GetDefaultConstructor(this Type type) 21 | { 22 | return type.GetConstructor(EmptyTypeArray); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/VersionSensor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | #nullable disable 5 | 6 | using System.Reflection; 7 | 8 | namespace Microsoft.TryDotNet.PeakyTests; 9 | 10 | internal class VersionSensor 11 | { 12 | private static readonly Lazy buildInfo = new(() => 13 | { 14 | var assembly = typeof(VersionSensor).GetTypeInfo().Assembly; 15 | 16 | var info = new BuildInfo 17 | { 18 | AssemblyName = assembly.GetName().Name, 19 | AssemblyInformationalVersion = assembly 20 | .GetCustomAttribute() 21 | .InformationalVersion, 22 | AssemblyVersion = assembly.GetName().Version.ToString(), 23 | BuildDate = new FileInfo(new Uri(assembly.Location).LocalPath).CreationTimeUtc.ToString("o") 24 | }; 25 | 26 | return info; 27 | }); 28 | 29 | public static BuildInfo Version() 30 | { 31 | return buildInfo.Value; 32 | } 33 | 34 | public class BuildInfo 35 | { 36 | public string AssemblyVersion { get; set; } 37 | public string BuildDate { get; set; } 38 | public string AssemblyInformationalVersion { get; set; } 39 | public string AssemblyName { get; set; } 40 | public string ServiceVersion { get; set; } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/PeakyTests/XsrfCookieHandlingMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using FluentAssertions; 3 | 4 | namespace Microsoft.TryDotNet.PeakyTests; 5 | 6 | public class XsrfCookieHandlingMessageHandler : HttpClientHandler 7 | { 8 | private readonly Uri _baseAddress; 9 | private Cookie? _xsrfCookie; 10 | 11 | public XsrfCookieHandlingMessageHandler(Uri baseAddress) 12 | { 13 | _baseAddress = baseAddress; 14 | CookieContainer = new CookieContainer(); 15 | } 16 | 17 | protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 18 | { 19 | if (_xsrfCookie is null) 20 | { 21 | var cookieRequest = new HttpRequestMessage(HttpMethod.Get, _baseAddress); 22 | 23 | await base.SendAsync(cookieRequest, cancellationToken); 24 | } 25 | 26 | var cookies = CookieContainer.GetCookies(_baseAddress).ToArray(); 27 | 28 | cookies.Should().Contain(c => c.Name == "XSRF-TOKEN"); 29 | 30 | _xsrfCookie = cookies.First(c => c.Name == "XSRF-TOKEN"); 31 | 32 | request.Headers.Add("xsrf-token", _xsrfCookie.Value); 33 | 34 | return await base.SendAsync(request, cancellationToken); 35 | } 36 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:14261", 8 | "sslPort": 44320 9 | } 10 | }, 11 | "profiles": { 12 | "TryDotNet-Development": { 13 | "commandName": "Project", 14 | "launchBrowser": true, 15 | "launchUrl": "tests", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | }, 19 | "applicationUrl": "https://localhost:7061;http://localhost:5061", 20 | "dotnetRunMessages": true 21 | }, 22 | 23 | "TryDotNet-Staging": { 24 | "commandName": "Project", 25 | "launchBrowser": true, 26 | "launchUrl": "editor", 27 | "environmentVariables": { 28 | "ASPNETCORE_ENVIRONMENT": "Staging" 29 | }, 30 | "applicationUrl": "https://localhost:7061;http://localhost:5061", 31 | "dotnetRunMessages": true 32 | }, 33 | 34 | "TryDotNet-Production": { 35 | "commandName": "Project", 36 | "launchBrowser": true, 37 | "launchUrl": "editor", 38 | "environmentVariables": { 39 | "ASPNETCORE_ENVIRONMENT": "Production" 40 | }, 41 | "applicationUrl": "https://localhost:7061;http://localhost:5061", 42 | "dotnetRunMessages": true 43 | }, 44 | 45 | "IIS Express": { 46 | "commandName": "IISExpress", 47 | "launchBrowser": true, 48 | "launchUrl": "swagger", 49 | "environmentVariables": { 50 | "ASPNETCORE_ENVIRONMENT": "Development" 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Microsoft.TryDotNet/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/microsoft-learn-mock/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ 2 | -------------------------------------------------------------------------------- /src/microsoft-learn-mock/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "microsoft-learn-mock", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "compile": "tsc -p .", 8 | "buildProd": "npm run rollup", 9 | "rollup": "rollup -c", 10 | "ciTest": "echo \"NOOP\"" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@rollup/plugin-commonjs": "22.0.0", 16 | "@rollup/plugin-node-resolve": "13.3.0", 17 | "http-server": "14.1.1", 18 | "typescript": "4.7.3", 19 | "rollup": "2.75.6", 20 | "rollup-plugin-typescript2": "0.32.1" 21 | } 22 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/rollup.config.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import typescript from 'rollup-plugin-typescript2' 5 | import resolve from '@rollup/plugin-node-resolve'; 6 | import commonjs from '@rollup/plugin-commonjs'; 7 | import pkg from './package.json'; 8 | 9 | export default { 10 | 11 | input: 'src/index.ts', 12 | output: [ 13 | { 14 | sourcemap: 'inline', 15 | file: 'site/index.js', 16 | format: 'iife', 17 | } 18 | ], 19 | external: [ 20 | // ...Object.keys(pkg.dependencies || {}), 21 | ...Object.keys(pkg.peerDependencies || {}), 22 | ...Object.keys(pkg.devDependencies || {}), 23 | ], 24 | plugins: [ 25 | typescript({ 26 | typescript: require('typescript'), 27 | tsconfigOverride: { 28 | compilerOptions: { 29 | "module": "ES2015" 30 | } 31 | }, 32 | }), 33 | resolve({ 34 | jsnext: true, 35 | main: true, 36 | browser: true, 37 | customResolveOptions: { 38 | moduleDirectories: ['node_modules'] 39 | } 40 | }), 41 | commonjs() 42 | ], 43 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/docs-strings.ts: -------------------------------------------------------------------------------- 1 | export const loc_clear = "sruff_loc_clear"; 2 | export const loc_dotnetEditor = "sruff_loc_dotnetEditor"; 3 | export const loc_dotnetEditor_acceleratorCtrlSpace = "sruff_loc_dotnetEditor_acceleratorCtrlSpace"; 4 | export const loc_dotnetEditor_acceleratorF1 = "sruff_loc_dotnetEditor_acceleratorF1"; 5 | export const loc_dotnetEditor_acceleratorShiftF10 = "sruff_loc_dotnetEditor_acceleratorShiftF10"; 6 | export const loc_dotnetEditor_commonAcceleratorsAriaLabel = "sruff_loc_dotnetEditor_commonAcceleratorsAriaLabel"; 7 | export const loc_dotnetEditor_exitEditorActionShortcut = "sruff_loc_dotnetEditor_exitEditorActionShortcut"; 8 | export const loc_dotnetEditor_exitEditorActionShortcutMacOS = "sruff_loc_dotnetEditor_exitEditorActionShortcutMacOS"; 9 | export const loc_feedback = "sruff_loc_feedback"; 10 | export const loc_loading = "sruff_loc_loading"; 11 | export const loc_noOutput = "sruff_loc_noOutput"; 12 | export const loc_output = "sruff_loc_output"; 13 | export const loc_run = "sruff_loc_run"; 14 | export const loc_serviceUnavailable = "sruff_loc_serviceUnavailable"; -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/index.ts: -------------------------------------------------------------------------------- 1 | import { DotNetOnline } from "./interactivity/originalCode"; 2 | 3 | function setup(global: any) { 4 | const container = document.querySelector("div.dotnet-online"); 5 | if (container) { 6 | const interactive = new DotNetOnline(container); 7 | if (global) { 8 | console.log("Setting up dotnetOnline on global"); 9 | global.dotnetOnline = interactive; 10 | } 11 | } 12 | } 13 | 14 | setup(window); -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/interactivity/activation.ts: -------------------------------------------------------------------------------- 1 | export interface InteractiveComponent { 2 | element: Element; 3 | /** 4 | * Called at activation - will be passed the text content from the associated code block. 5 | */ 6 | setCode: (code: string, scaffoldingType?: string) => Promise; 7 | /** 8 | * Execution code called when the "Try It" button is clicked. 9 | */ 10 | execute: () => void; 11 | dispose: () => void; 12 | } 13 | 14 | export interface RegisterInteractiveTypeArgs { 15 | name: InteractiveType; 16 | activateButtonConfig: ActivateButtonConfig; 17 | create: () => InteractiveComponent; 18 | } 19 | 20 | export type InteractiveType = 21 | | 'bash' 22 | | 'csharp' 23 | | 'http' 24 | | 'powershell' 25 | | 'lab-on-demand' 26 | | 'msgraph'; 27 | 28 | export interface ActivateButtonConfig { 29 | name: string; 30 | iconClass: string; 31 | attributes: { name: string; value: string }[]; 32 | } 33 | 34 | export interface RegisterInteractiveTypeArgs { 35 | name: InteractiveType; 36 | activateButtonConfig: ActivateButtonConfig; 37 | create: () => InteractiveComponent; 38 | } 39 | 40 | const interactiveTypes: { [name: string]: RegisterInteractiveTypeArgs } = {}; 41 | 42 | export function registerInteractiveType(interactiveType: RegisterInteractiveTypeArgs) { 43 | interactiveTypes[interactiveType.name] = interactiveType; 44 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/interactivity/scaffolding.ts: -------------------------------------------------------------------------------- 1 | export const scaffoldingMethod = `using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Globalization; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace Program 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | #region controller 15 | ____ 16 | #endregion 17 | } 18 | } 19 | }`; 20 | 21 | export const scaffoldingClass = `using System; 22 | using System.Collections.Generic; 23 | using System.Linq; 24 | using System.Text; 25 | using System.Globalization; 26 | using System.Text.RegularExpressions; 27 | 28 | namespace Program 29 | { 30 | class Program 31 | { 32 | #region controller 33 | ____ 34 | #endregion 35 | } 36 | }`; 37 | 38 | export function scaffoldCode(code: string, scaffoldingType: string): string { 39 | switch (scaffoldingType) { 40 | case 'try-dotnet-class': 41 | code = scaffoldingClass.replace('____', () => code); 42 | break; 43 | case 'try-dotnet-method': 44 | code = scaffoldingMethod.replace('____', () => code); 45 | break; 46 | case 'try-dotnet': 47 | break; 48 | default: 49 | code = scaffoldingMethod.replace('____', () => code); 50 | break; 51 | } 52 | return code; 53 | } 54 | 55 | export const scaffoldContainsRegion = ['try-dotnet-class', 'try-dotnet-method']; 56 | -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/load-library.ts: -------------------------------------------------------------------------------- 1 | export function loadLibrary( 2 | url: string, 3 | integrityHash: string | null, 4 | globalName?: string, 5 | timeLimit?: number 6 | ): Promise { 7 | return new Promise((resolve, reject) => { 8 | if (timeLimit) { 9 | setTimeout(() => { 10 | reject(`${url} load timeout`); 11 | }, timeLimit); 12 | } 13 | 14 | const script = document.createElement('script'); 15 | script.src = url; 16 | script.async = true; 17 | script.defer = true; 18 | script.onload = resolve; 19 | if (integrityHash) { 20 | // script.integrity = integrityHash; 21 | script.crossOrigin = 'anonymous'; 22 | } 23 | script.onerror = () => { 24 | reject(`Failed to load ${url}`); 25 | }; 26 | (document.body || document.head).appendChild(script); 27 | }).then(() => { 28 | if (globalName === undefined) { 29 | return undefined; 30 | } 31 | if ((window as { [key: string]: any })[globalName] === undefined) { 32 | throw new Error(`${url} loaded successfully but ${globalName} is undefined.`); 33 | } 34 | return (window as { [key: string]: any })[globalName] as Promise; 35 | }); 36 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/src/theme-selection.ts: -------------------------------------------------------------------------------- 1 | // * Global 2 | 3 | /** 4 | * The globally available descriptor of the current theme. It is updated each time setTheme is called. 5 | */ 6 | export let currentTheme: ThemeType = 'light'; 7 | 8 | // * Types 9 | 10 | export type ThemeType = keyof ThemeTypeMap; 11 | 12 | export interface ThemeTypeInfo { 13 | documentClass: string; 14 | name: string; 15 | text: string; 16 | icon: string; 17 | } 18 | 19 | export interface ThemeTypeMap { 20 | light: ThemeTypeInfo; 21 | dark: ThemeTypeInfo; 22 | 'high-contrast': ThemeTypeInfo; 23 | } 24 | 25 | 26 | // * Events 27 | 28 | export interface ThemeChangeInfo { 29 | currentTheme: ThemeType; 30 | previousTheme: ThemeType; 31 | } 32 | 33 | /** 34 | * Global Event that fires when the visual theme is changed. 35 | * @param currentTheme A string descriptor of the current theme (the theme just applied). 36 | * @param previousTheme A string descriptor of the previous theme. 37 | */ 38 | export class ThemeChangedEvent implements ThemeChangeInfo { 39 | constructor(public readonly currentTheme: ThemeType, public readonly previousTheme: ThemeType) {} 40 | } -------------------------------------------------------------------------------- /src/microsoft-learn-mock/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "esModuleInterop": true, 5 | "extendedDiagnostics": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "importHelpers": true, 8 | "lib": [ 9 | "dom", 10 | "es2020" 11 | ], 12 | "module": "commonjs", 13 | "moduleResolution": "node", 14 | // "noImplicitAny": true, 15 | // "noImplicitReturns": true, 16 | // "noImplicitThis": true, 17 | // "noUnusedLocals": true, 18 | // "noUnusedParameters": true, 19 | // "outDir": "dist", 20 | // "resolveJsonModule": true, 21 | "strict": true, 22 | "target": "es2020", 23 | "typeRoots": [ 24 | "./@types" 25 | ] 26 | }, 27 | "include": [ 28 | "src" 29 | ] 30 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/.eslintignore: -------------------------------------------------------------------------------- 1 | jupyter.d.ts 2 | vscode.proposed.*.d.ts 3 | vscode.d.ts 4 | vscode.proposed.d.ts 5 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "project": [ 7 | "./tsconfig.json", 8 | "./tsconfig.eslint.json" 9 | ], 10 | "sourceType": "module" 11 | }, 12 | "plugins": [ 13 | "@typescript-eslint", 14 | "deprecation" 15 | ], 16 | "rules": { 17 | "@typescript-eslint/semi": "warn", 18 | "curly": "warn", 19 | "deprecation/deprecation": "warn", 20 | "eqeqeq": "warn", 21 | "no-throw-literal": "warn", 22 | "semi": "off" 23 | } 24 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/.npmrc: -------------------------------------------------------------------------------- 1 | @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ 2 | registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ 3 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/generateApiSimulator.ps1: -------------------------------------------------------------------------------- 1 | dotnet build ../Microsoft.TryDotNet.SimulatorGenerator -o ./simulatorGenerator/ 2 | cd ./simulatorGenerator/ 3 | dotnet Microsoft.TryDotNet.SimulatorGenerator.dll --destination-folder ../tests/simulatorConfigurations/apiService 4 | cd .. -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/playwright.config.ts: -------------------------------------------------------------------------------- 1 | // playwright.config.ts 2 | import { PlaywrightTestConfig, devices } from '@playwright/test'; 3 | 4 | const config: PlaywrightTestConfig = { 5 | testDir: './tests', 6 | forbidOnly: !!process.env.CI, 7 | retries: process.env.CI ? 2 : 0, 8 | use: { 9 | trace: 'on-first-retry', 10 | }, 11 | projects: [ 12 | { 13 | name: 'chromium', 14 | use: { ...devices['Desktop Chrome'] }, 15 | 16 | } 17 | ], 18 | expect: { 19 | toMatchSnapshot: { threshold: 0.1 }, 20 | }, 21 | }; 22 | export default config; -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: auto; 3 | height: auto; 4 | margin: 0; 5 | } 6 | 7 | .monaco-editor { 8 | padding: 0.5rem; 9 | } 10 | 11 | iframe[role="wasm-runner"] { 12 | opacity: 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/src/legacyContract.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export interface legacyContract { 5 | requestId: string; 6 | } 7 | 8 | export interface CreateProjectRequest extends legacyContract { 9 | projectTemplate: string; 10 | } 11 | 12 | export interface IWorkspace { 13 | language?: string; 14 | files?: IWorkspaceFile[]; 15 | buffers: IWorkspaceBuffer[]; 16 | usings?: string[]; 17 | activeBufferId?: string; 18 | } 19 | 20 | export interface IWorkspaceFile { 21 | name: string; 22 | text: string; 23 | } 24 | 25 | export interface IWorkspaceBuffer { 26 | id: string; 27 | content: string; 28 | position: number; 29 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/src/log.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as polyglotNotebooks from '@microsoft/polyglot-notebooks'; 5 | 6 | export function configureLogging(configuration: { enableLogging: boolean }) { 7 | if (configuration.enableLogging === true) { 8 | polyglotNotebooks.Logger.configure("trydotnet-editor", (entry) => { 9 | switch (entry.logLevel) { 10 | case polyglotNotebooks.LogLevel.Info: 11 | console.log(`[${entry.source}] ${entry.message}`); 12 | break; 13 | case polyglotNotebooks.LogLevel.Warn: 14 | console.warn(`[${entry.source}] ${entry.message}`); 15 | break; 16 | case polyglotNotebooks.LogLevel.Error: 17 | console.error(`[${entry.source}] ${entry.message}`); 18 | break; 19 | } 20 | 21 | }); 22 | } else { 23 | polyglotNotebooks.Logger.configure("trydotnet-editor", (_entry) => { }); 24 | } 25 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/src/stringExtensions.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export function isNullOrUndefinedOrWhitespace(input: string): boolean { 5 | if (isNullOrUndefined(input)) { 6 | return true; 7 | } 8 | return input.replace(/\s/g, "").length < 1; 9 | } 10 | 11 | export function isNullOrUndefined(input: string): boolean { 12 | return input === undefined || input === null; 13 | } 14 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/src/wasmRunner.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as polyglotNotebooks from '@microsoft/polyglot-notebooks'; 5 | export interface IWasmRunner { 6 | (runRequest: { 7 | assembly: polyglotNotebooks.Base64EncodedAssembly, 8 | onOutput: (output: string) => void, 9 | onError: (error: string) => void, 10 | }): Promise 11 | } 12 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/testConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "reporterEnabled": "spec,mocha-trx-reporter", 3 | "mochaTrxReporterReporterOptions": { 4 | "output": "../../artifacts/TestResults/Release/microsoft-trydotnet-editor.trx" 5 | } 6 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tests/editorSimulator.tests.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { expect } from "chai"; 5 | import { describe } from "mocha"; 6 | 7 | import * as monacoEditorSimulator from "./monacoEditorSimulator"; 8 | 9 | describe("editor simulator", () => { 10 | it("can manipulate empty text", () => { 11 | let newState = monacoEditorSimulator.modifyText("", { line: 1, column: 1 }, "hello"); 12 | expect(newState.newText).to.equal("hello"); 13 | expect(newState.line).to.equal(1); 14 | expect(newState.column).to.equal(6); 15 | }); 16 | 17 | 18 | it("can edit previous text", () => { 19 | let newState = monacoEditorSimulator.modifyText("hello !", { line: 1, column: 7 }, "world"); 20 | expect(newState.newText).to.equal("hello world!"); 21 | expect(newState.line).to.equal(1); 22 | expect(newState.column).to.equal(12); 23 | }); 24 | 25 | it("updates position correctly", () => { 26 | let newState = monacoEditorSimulator.modifyText("hello world!!", { line: 1, column: 13 }, "\nThank you"); 27 | expect(newState.newText).to.equal("hello world!\nThank you!"); 28 | expect(newState.line).to.equal(2); 29 | expect(newState.column).to.equal(10); 30 | }); 31 | }); -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tests/simulatorConfigurations/wasmRunner/executes_correct_code.json: -------------------------------------------------------------------------------- 1 | { 2 | "requests": [ 3 | { 4 | "assembly": "AABBCC", 5 | "events": [ 6 | { 7 | "source": "stdOut", 8 | "value": "2" 9 | } 10 | ] 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tests/testHelpers.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export function delay(ms: number) { 5 | return new Promise(function (resolve) { 6 | setTimeout(resolve, ms); 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "./tests/**/*" 4 | ], 5 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "target": "ES6", 7 | "outDir": "./lib", 8 | "lib": [ 9 | "dom", 10 | "es2021" 11 | ], 12 | "types": [], 13 | "baseUrl": "./node_modules", 14 | "jsx": "preserve", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ] 18 | }, 19 | "include": [ 20 | "./src/**/*" 21 | ], 22 | "exclude": [ 23 | "node_modules" 24 | ] 25 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/tsnode.js: -------------------------------------------------------------------------------- 1 | const tsAutoMockTransformer = require('ts-auto-mock/transformer').default; 2 | require('ts-node').register({ 3 | transformers: program => ({ 4 | before: [ 5 | tsAutoMockTransformer(program) 6 | ] 7 | }) 8 | }); -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/wallaby.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | module.exports = function (wallaby) { 5 | return { 6 | env: { 7 | type: "node" 8 | }, 9 | files: [ 10 | "src/**/*.ts*", 11 | { pattern: "tests/**/*.json", instrument: false }, 12 | { pattern: "tests/**/*.ts*", instrument: true }, 13 | "!tests/**/*.tests.ts*", 14 | ], 15 | tests: ["tests/**/*.tests.ts*"], 16 | compilers: { 17 | '**/*.ts?(x)': wallaby.compilers.typeScript({}) 18 | }, 19 | testFramework: 'mocha', 20 | debug: true, 21 | setup: function (wallaby) { 22 | var mocha = wallaby.testFramework; 23 | mocha.timeout(10000); 24 | } 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/webpack-prod.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebPackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | mode: 'production', 6 | output: { 7 | globalObject: 'self', 8 | filename: '[name].bundle.js', 9 | path: path.resolve(__dirname, '..', 'Microsoft.TryDotNet', 'wwwroot', 'api', 'editor') 10 | } 11 | }; -------------------------------------------------------------------------------- /src/microsoft-trydotnet-editor/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebPackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | mode: 'development', 6 | entry: { 7 | app: './src/index.ts', 8 | 'editor.worker': 'monaco-editor/esm/vs/editor/editor.worker.js', 9 | 'json.worker': 'monaco-editor/esm/vs/language/json/json.worker', 10 | 'css.worker': 'monaco-editor/esm/vs/language/css/css.worker', 11 | 'html.worker': 'monaco-editor/esm/vs/language/html/html.worker', 12 | 'ts.worker': 'monaco-editor/esm/vs/language/typescript/ts.worker' 13 | }, 14 | resolve: { 15 | extensions: ['.ts', '.js'] 16 | }, 17 | output: { 18 | globalObject: 'self', 19 | filename: '[name].bundle.js', 20 | path: path.resolve(__dirname, 'dist'), 21 | clean: true 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.ts?$/, 27 | use: 'ts-loader', 28 | exclude: /node_modules/ 29 | }, 30 | { 31 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 32 | type: 'asset/resource', 33 | }, 34 | { 35 | test: /\.css$/, 36 | use: [{ 37 | loader: 'style-loader' 38 | }, 39 | { 40 | loader: 'css-loader', 41 | options: { 42 | url: true, 43 | } 44 | }] 45 | }, 46 | { 47 | test: /\.(woff|woff2|eot|ttf|otf)$/i, 48 | type: 'asset/resource' 49 | } 50 | ] 51 | }, 52 | plugins: [ 53 | new HtmlWebPackPlugin({ 54 | title: 'trydotnet editor' 55 | }) 56 | ] 57 | }; -------------------------------------------------------------------------------- /src/microsoft-trydotnet-styles/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ 2 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet-styles/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microsoft/trydotnet-styles", 3 | "version": "1.0.0", 4 | "description": "css for trydotnet", 5 | "main": "sass/trydotnet.scss", 6 | "scripts": { 7 | "css-build": "sass --no-source-map sass/trydotnet.scss css/trydotnet.css", 8 | "css-watch": "npm run css-build -- --watch", 9 | "start": "npm run build -- --watch", 10 | "build": "sass --no-source-map sass/trydotnet.scss ../Microsoft.TryDotNet/wwwroot/css/trydotnet.css", 11 | "buildProd": "sass --no-source-map sass/trydotnet.scss ../Microsoft.TryDotNet/wwwroot/css/trydotnet.css", 12 | "release": "sass --no-source-map --style=compressed sass/trydotnet.scss", 13 | "ciCreateDir": "npx mkdirp ", 14 | "ciTest": "echo \"NOOP\"" 15 | }, 16 | "author": "Diego Colombo", 17 | "license": "MIT", 18 | "devDependencies": { 19 | "@mdi/font": "6.7.96", 20 | "fstream": "1.0.12", 21 | "github-markdown-css": "5.1.0", 22 | "lodash": "4.17.21", 23 | "mkdirp": "1.0.4", 24 | "sass": "1.52.3", 25 | "tar": "6.1.11" 26 | } 27 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet-styles/sass/constants.scss: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | @charset "utf-8"; 5 | $text: black; 6 | $red: red; 7 | $white: white; 8 | $dotnet-purple: #512bd4; 9 | $header-footer-color: white; 10 | $dotnet-try-cmd-color: $header-footer-color; 11 | $dotnet-try-cmd-font-size: 1.5em; 12 | $footer-background-color: $dotnet-purple; 13 | $content-height: 92vh; 14 | $output-panel-min-height: 200px; 15 | $expansion-time: 0.5s; 16 | $run-failure-background: $red; 17 | $run-failure-foreground: $white; 18 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/.npmrc: -------------------------------------------------------------------------------- 1 | @microsoft:registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/npm/registry/ 2 | registry=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ 3 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Attach", 9 | "type": "coreclr", 10 | "request": "attach", 11 | "processId": "${command:pickProcess}" 12 | }, 13 | { 14 | "type": "node", 15 | "request": "launch", 16 | "name": "Mocha Tests", 17 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", 18 | "args": [ 19 | "--timeout", 20 | "999999", 21 | "--opts", 22 | "${workspaceFolder}/mocha.opts" 23 | ], 24 | "sourceMaps": true, 25 | "console": "integratedTerminal", 26 | "internalConsoleOptions": "neverOpen", 27 | "protocol": "inspector" 28 | }, 29 | { 30 | "type": "node", 31 | "request": "launch", 32 | "name": "Launch Program", 33 | "program": "${file}" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/rollup.config.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import typescript from 'rollup-plugin-typescript2' 5 | import resolve from '@rollup/plugin-node-resolve'; 6 | import commonjs from '@rollup/plugin-commonjs'; 7 | import pkg from './package.json'; 8 | 9 | export default { 10 | 11 | input: 'src/index.ts', 12 | output: [ 13 | { 14 | sourcemap: 'inline', 15 | file: pkg.main, 16 | format: 'umd', 17 | name: 'trydotnet', 18 | }, 19 | { 20 | sourcemap: 'inline', 21 | file: pkg.module, 22 | format: 'es', 23 | } 24 | ], 25 | external: [ 26 | // ...Object.keys(pkg.dependencies || {}), 27 | ...Object.keys(pkg.peerDependencies || {}), 28 | ...Object.keys(pkg.devDependencies || {}), 29 | ], 30 | plugins: [ 31 | typescript({ 32 | typescript: require('typescript'), 33 | tsconfigOverride: { 34 | compilerOptions: { 35 | "module": "ES2015" 36 | } 37 | }, 38 | }), 39 | resolve({ 40 | jsnext: true, 41 | main: true, 42 | browser: true, 43 | customResolveOptions: { 44 | moduleDirectories: ['node_modules'] 45 | } 46 | }), 47 | commonjs() 48 | ], 49 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/apiMessages.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | 5 | // run api 6 | export const RUN_REQUEST = "run"; 7 | export const RUN_RESPONSE = "RunCompleted"; 8 | export const RUN_STARTED_EVENT = "RunStarted"; 9 | export const RUN_COMPLETED_EVENT = "RunCompleted"; 10 | export const SERVICE_ERROR_RESPONSE = "ServiceError"; 11 | 12 | 13 | // events 14 | export const MONACO_READY_EVENT = "MonacoEditorReady"; 15 | export const HOST_EDITOR_READY_EVENT = "HostEditorReady"; 16 | export const HOST_RUN_READY_EVENT = "HostRunReady"; 17 | 18 | // focus api 19 | export const FOCUS_EDITOR_REQUEST = "focusEditor"; 20 | export const SHOW_EDITOR_REQUEST = "showEditor"; 21 | 22 | 23 | 24 | export type ApiMessage = 25 | { 26 | type: typeof RUN_REQUEST, 27 | requestId?: string, 28 | parameters?: { [key: string]: any } 29 | } | { 30 | type: typeof RUN_RESPONSE, 31 | requestId?: string, 32 | outcome: "Success" | "Exception" | "CompilationError", 33 | [key: string]: any 34 | } | { 35 | type: typeof FOCUS_EDITOR_REQUEST 36 | } | { 37 | type: typeof SHOW_EDITOR_REQUEST 38 | } | { 39 | type: typeof HOST_EDITOR_READY_EVENT, 40 | editorId?: string 41 | } | { 42 | type: typeof HOST_RUN_READY_EVENT, 43 | editorId?: string 44 | } | { 45 | type: typeof SERVICE_ERROR_RESPONSE, 46 | statusCode: string, 47 | message: string, 48 | requestId?: string, 49 | }; -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/configuration.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { MonacoEditorConfiguration } from "./editor"; 5 | 6 | export type Configuration = { 7 | hostOrigin?: string, 8 | trydotnetOrigin?: string, 9 | editorConfiguration?: MonacoEditorConfiguration, 10 | enableLogging?: boolean, 11 | } 12 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/diagnostics.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export type Diagnostic = { 5 | start: number, 6 | end: number, 7 | message: string, 8 | severity: number 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/editableDocument.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { DocumentId } from "./documentId"; 5 | 6 | 7 | export type Region = string; 8 | 9 | export interface IDocument { 10 | id(): DocumentId; 11 | setContent(content: string): Promise; 12 | getContent(): string; 13 | } 14 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/editor.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { ITextDisplay } from "./textDisplay"; 5 | import { Observable } from "rxjs"; 6 | import { DocumentId } from "./documentId"; 7 | 8 | export type TextChangedEvent = { 9 | text: string, 10 | documentId: DocumentId, 11 | cursor?: number, 12 | editorId?: string 13 | }; 14 | 15 | export type Theme = string | MonacoEditorTheme; 16 | 17 | export type MonacoEditorTheme = 18 | { 19 | name: string, 20 | monacoEditorTheme: {} 21 | } 22 | 23 | 24 | export type MonacoEditorConfiguration = { 25 | theme?: Theme, 26 | options?: MonacoEditorOptions 27 | }; 28 | 29 | export type MonacoEditorOptions = { 30 | 31 | } 32 | 33 | export interface ITextEditor extends ITextDisplay { 34 | textChanges: Observable; 35 | } 36 | 37 | export interface IMonacoEditor extends ITextEditor { 38 | setTheme(theme: Theme): void; 39 | setOptions(options: MonacoEditorOptions): void; 40 | configure(configuration: MonacoEditorConfiguration): void; 41 | setSize(size: { width: number, height: number }): void; 42 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/htmlDomHelpers.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { Configuration } from "./configuration"; 5 | import { generateEditorUrl } from "./internals/urlHelpers"; 6 | 7 | export function configureEmbeddableEditorIFrame(iframe: HTMLIFrameElement, configuration: Configuration): HTMLIFrameElement { 8 | if (configuration) { 9 | let src = iframe.getAttribute("src") 10 | if (!src) { 11 | const url = generateEditorUrl(configuration); 12 | iframe.setAttribute("src", url); 13 | } 14 | } 15 | return iframe; 16 | } 17 | 18 | 19 | export function configureEmbeddableEditorIFrameWithPackage(iframe: HTMLIFrameElement, configuration: Configuration, packageName: string): HTMLIFrameElement { 20 | if (configuration) { 21 | let src = iframe.getAttribute("src") 22 | if (!src) { 23 | const url = generateEditorUrl(configuration, packageName); 24 | iframe.setAttribute("src", url); 25 | } 26 | } 27 | return iframe; 28 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export * from "./session"; 5 | export * from "./sessionFactory"; 6 | export * from "./configuration"; 7 | export * from "./editor"; 8 | export * from "./editableDocument"; 9 | export * from "./diagnostics"; 10 | export * from "./textDisplay"; 11 | export * from "./htmlDomHelpers"; 12 | export * from "./project"; 13 | 14 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/internals/requestIdGenerator.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export interface IRequestIdGenerator { 5 | getNewRequestId(): Promise; 6 | } 7 | 8 | export class RequestIdGenerator implements IRequestIdGenerator { 9 | private static instanceId = 1; 10 | 11 | private id: string; 12 | private seed: number; 13 | constructor() { 14 | this.id = `trydotnetjs.session.${RequestIdGenerator.instanceId++}`; 15 | this.seed = 0; 16 | 17 | } 18 | public getNewRequestId(): Promise { 19 | const requestId = `${this.id}_${this.seed++}`; 20 | 21 | 22 | return Promise.resolve(requestId); 23 | } 24 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/internals/urlHelpers.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as polyglotNotebooks from "@microsoft/polyglot-notebooks"; 5 | import { Configuration } from "../configuration"; 6 | 7 | export function generateEditorUrl(configuration: Configuration, packageName?: string): string { 8 | polyglotNotebooks.Logger.default.info(`${JSON.stringify(configuration)}`); 9 | const host = configuration.trydotnetOrigin ? configuration.trydotnetOrigin : "https://try.dot.net"; 10 | let url = new URL(host); 11 | url.pathname = "/editor"; 12 | 13 | url.searchParams.append("waitForConfiguration", "true"); 14 | 15 | url.searchParams.append("editorId", "-0-"); 16 | if (configuration.enableLogging) { 17 | url.searchParams.append("enableLogging", "true"); 18 | } 19 | 20 | buildQueryString(url, packageName); 21 | return url.href; 22 | } 23 | 24 | function buildQueryString(url: URL, packageName?: string) { 25 | if (packageName) { 26 | url.searchParams.append("workspaceType", packageName); 27 | } 28 | } 29 | 30 | export function extractTargetOriginFromIFrame(iframe: HTMLIFrameElement): string { 31 | let origin = "*"; 32 | let src = iframe.getAttribute("src"); 33 | if (src) { 34 | let url = new URL(src); 35 | origin = url.origin; 36 | } 37 | return origin; 38 | } 39 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/log.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as polyglotNotebooks from '@microsoft/polyglot-notebooks'; 5 | 6 | export function configureLogging(configuration: { enableLogging: boolean }) { 7 | if (configuration.enableLogging === true) { 8 | polyglotNotebooks.Logger.configure("trydotnet-js", (entry) => { 9 | switch (entry.logLevel) { 10 | case polyglotNotebooks.LogLevel.Info: 11 | console.log(`[${entry.source}] ${entry.message}`); 12 | break; 13 | case polyglotNotebooks.LogLevel.Warn: 14 | console.warn(`[${entry.source}] ${entry.message}`); 15 | break; 16 | case polyglotNotebooks.LogLevel.Error: 17 | console.error(`[${entry.source}] ${entry.message}`); 18 | break; 19 | } 20 | 21 | }); 22 | } else { 23 | polyglotNotebooks.Logger.configure("trydotnet-js", (_entry) => { }); 24 | } 25 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/project.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { isNullOrUndefinedOrWhitespace } from "./stringExtensions"; 5 | 6 | export type Project = { 7 | package: string, 8 | packageVersion?: string, 9 | language?: string, 10 | files: SourceFile[], 11 | [key: string]: any 12 | }; 13 | 14 | export type SourceFile = { 15 | name: string, 16 | content: string, 17 | }; 18 | 19 | export type SourceFileRegion = { 20 | id: string, 21 | content: string, 22 | }; 23 | 24 | export function createProject(args: { packageName: string, files: SourceFile[], usings?: string[], language?: string }): Promise { 25 | if (isNullOrUndefinedOrWhitespace(args.packageName)) { 26 | throw new Error("packageName can not be null or empty"); 27 | } 28 | 29 | if (!args.files || args.files.length === 0) { 30 | throw new Error("at least a file is required"); 31 | } 32 | 33 | let project: Project = { 34 | package: args.packageName, 35 | files: JSON.parse(JSON.stringify(args.files)) 36 | }; 37 | 38 | if (isNullOrUndefinedOrWhitespace(args.language)) { 39 | project.language = "csharp"; 40 | } else { 41 | project.language = args.language; 42 | } 43 | 44 | if (args.usings) { 45 | project.usings = JSON.parse(JSON.stringify(args.usings)); 46 | } 47 | 48 | return Promise.resolve(project); 49 | } 50 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/stringExtensions.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export function isNullOrUndefinedOrWhitespace(input: string): boolean { 5 | if (isNullOrUndefined(input)) { 6 | return true; 7 | } 8 | return input.replace(/\s/g, "").length < 1; 9 | } 10 | 11 | export function isNullOrUndefined(input: string): boolean { 12 | return input === undefined || input === null; 13 | } 14 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/src/textDisplay.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export interface ITextDisplay { 5 | setContent(content: string): Promise; 6 | id(): string; 7 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/domUtilities.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { Configuration } from "../src"; 5 | import { JSDOM } from "jsdom"; 6 | 7 | export function buildSimpleIFrameDom(configuration: Configuration): JSDOM { 8 | let dom = new JSDOM( 9 | ` 10 | 11 | 12 | 13 | 14 | `, 15 | { 16 | url: configuration.hostOrigin, 17 | runScripts: "dangerously" 18 | }); 19 | 20 | return dom; 21 | } 22 | 23 | 24 | export function getEditorIFrame(dom: JSDOM): HTMLIFrameElement { 25 | let iframe = (dom.window.document.body.querySelector("iframe")); 26 | return iframe; 27 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/fakes/fakeIdGenerator.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { IRequestIdGenerator } from "../../src/internals/requestIdGenerator"; 5 | 6 | export class FakeIdGenerator implements IRequestIdGenerator { 7 | getNewRequestId(): Promise { 8 | return Promise.resolve("TestRun"); 9 | } 10 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/fakes/fakeMessageBus.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { IMessageBus } from "../../src/internals/messageBus"; 5 | import { Subject, Unsubscribable, Observer } from "rxjs"; 6 | import { ApiMessage } from "../../src/apiMessages"; 7 | 8 | export class FakeMessageBus implements IMessageBus { 9 | 10 | private _requests = new Subject<{ 11 | type: string; requestId?: string;[key: string]: any 12 | }>(); 13 | 14 | private _responses = new Subject<{ 15 | type: string; requestId?: string;[key: string]: any 16 | }>(); 17 | constructor(private busId: string) { 18 | } 19 | subscribe(observer: Partial>): Unsubscribable { 22 | return this._responses.subscribe(observer); 23 | } 24 | 25 | dispose(): void { 26 | } 27 | 28 | post(message: { 29 | type: string; requestId?: string;[key: string]: any 30 | }): void { 31 | this._requests.next(message); 32 | } 33 | 34 | postResponse(message: { 35 | type: string; requestId?: string;[key: string]: any 36 | }): void { 37 | this._responses.next(message); 38 | } 39 | 40 | public get requests(): Subject<{ 41 | type: string; requestId?: string;[key: string]: any 42 | }> { 43 | return this._requests; 44 | } 45 | 46 | // subscribe(observer?: PartialObserver<{ type: string, requestId?: string }>): Unsubscribable; 47 | // subscribe(next?: (value: { type: string, requestId?: string }) => void, error?: (error: any) => void, complete?: () => void): Unsubscribable; 48 | // subscribe(next?: any, error?: any, complete?: any): Unsubscribable { 49 | // return this.channel.subscribe({ next, error, complete }); 50 | // } 51 | 52 | id(): string { 53 | return this.busId; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/internals/document.specs.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as chai from "chai"; 5 | import { DocumentId } from "../../src/documentId"; 6 | import { Document } from "../../src/internals/document"; 7 | import { FakeMonacoTextEditor } from "../fakes/fakeMonacoTextEditor"; 8 | 9 | chai.should(); 10 | 11 | 12 | describe("a document", () => { 13 | 14 | it("is not marked as modified at creation", () => { 15 | let document = new Document(DocumentId.parse("program.cs"), "content"); 16 | document.isModified.should.be.false; 17 | }); 18 | 19 | it("is not marked as modified when the content is changed from editor", async () => { 20 | let document = new Document(DocumentId.parse("program.cs"), "content"); 21 | let editor = new FakeMonacoTextEditor("0"); 22 | await document.bindToEditor(editor); 23 | editor.raiseTextEvent("other content"); 24 | document.isModified.should.be.false; 25 | document.getContent().should.be.equal("other content"); 26 | }); 27 | 28 | it("is active if bound to an editor", async () => { 29 | let document = new Document(DocumentId.parse("program.cs"), "content"); 30 | let editor = new FakeMonacoTextEditor("0"); 31 | document.isActiveInEditor().should.be.false; 32 | await document.bindToEditor(editor); 33 | document.isActiveInEditor().should.be.true; 34 | }); 35 | 36 | it("is marked as modified when the content is changed via setContent", async () => { 37 | let document = new Document(DocumentId.parse("program.cs"), "content"); 38 | await document.setContent("modified content"); 39 | document.isModified.should.be.true; 40 | }); 41 | 42 | }); -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/internals/requestIdGenerator.specs.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import * as chai from "chai"; 5 | import { buildSimpleIFrameDom } from "../domUtilities"; 6 | import * as trydotnet from "../../src/index"; 7 | import { IFrameMessageBus } from "../../src/internals/messageBus"; 8 | import { configureEmbeddableEditorIFrame } from "../../src/htmlDomHelpers"; 9 | import { RequestIdGenerator } from "../../src/internals/requestIdGenerator"; 10 | 11 | chai.should(); 12 | 13 | describe("a request id generator", () => { 14 | 15 | const defaultConfiguration: trydotnet.Configuration = { hostOrigin: "https://learn.microsoft.com" }; 16 | 17 | it("uses local generator ", async () => { 18 | var dom = buildSimpleIFrameDom(defaultConfiguration); 19 | 20 | let iframe = (dom.window.document.querySelector("iframe")); 21 | iframe = configureEmbeddableEditorIFrame(iframe, defaultConfiguration); 22 | 23 | let bus = new IFrameMessageBus(iframe, dom.window); 24 | 25 | let generator = new RequestIdGenerator(); 26 | 27 | let opId = await generator.getNewRequestId(); 28 | 29 | opId.should.contain("trydotnetjs.session"); 30 | }); 31 | }); -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/sessionFactory.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | import { DOMWindow } from "jsdom"; 5 | import { ISession, createSession, Configuration } from "../src"; 6 | import { notifyEditorReadyWithId } from "./messagingMocks"; 7 | 8 | export function createReadySession(configuration: Configuration, editorIFrame: HTMLIFrameElement, window: DOMWindow): Promise { 9 | let awaitableSession = createSession(configuration, [editorIFrame], window); 10 | notifyEditorReadyWithId(configuration, window, "0"); 11 | return awaitableSession; 12 | } 13 | 14 | export function createReadySessionWithMultipleEditors(configuration: Configuration, editorIFrames: HTMLIFrameElement[], window: DOMWindow): Promise { 15 | let awaitableSession = createSession(configuration, editorIFrames, window); 16 | for (let editorIframe of editorIFrames) { 17 | notifyEditorReadyWithId(configuration, window, editorIframe.dataset.trydotnetEditorId!); 18 | } 19 | return awaitableSession; 20 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/test/wait.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | export function wait(ms: number): Promise { 5 | return new Promise((resolve, _reject) => { 6 | setTimeout(resolve, ms); 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /src/microsoft-trydotnet/testConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "reporterEnabled": "spec,mocha-trx-reporter", 3 | "mochaTrxReporterReporterOptions": { 4 | "output": "../../artifacts/TestResults/Release/microsoft-trydotnet.trx" 5 | } 6 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "es2021", 5 | "dom" 6 | ], 7 | "declaration": true, 8 | "noImplicitAny": true, 9 | "module": "commonjs", 10 | "outDir": "./dist", 11 | "target": "es6" 12 | }, 13 | "include": [ 14 | "src/**/*" 15 | ], 16 | "exclude": [ 17 | "node_modules" 18 | ] 19 | } -------------------------------------------------------------------------------- /src/microsoft-trydotnet/wallaby.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 | 4 | module.exports = function (wallaby) { 5 | return { 6 | env: { 7 | type: "node" 8 | }, 9 | files: [ 10 | "src/**/*.ts", 11 | { pattern: "test/**/*.ts", instrument: true }, 12 | "!test/**/*.specs.ts*" 13 | ], 14 | tests: ["test/**/*.specs.ts"], 15 | compilers: { 16 | '**/*.ts?(x)': wallaby.compilers.typeScript({ 17 | typescript: require('typescript'), 18 | module: 'commonjs', 19 | }) 20 | }, 21 | testFramework: 'mocha', 22 | debug: true, 23 | setup: function (wallaby) { 24 | var mocha = wallaby.testFramework; 25 | mocha.timeout(10000); 26 | } 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source="${BASH_SOURCE[0]}" 4 | 5 | # resolve $SOURCE until the file is no longer a symlink 6 | while [[ -h $source ]]; do 7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" 8 | source="$(readlink "$source")" 9 | 10 | # if $source was a relative symlink, we need to resolve it relative to the path where 11 | # the symlink file was located 12 | [[ $source != /* ]] && source="$scriptroot/$source" 13 | done 14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd)" 15 | 16 | . "$scriptroot/eng/build.sh" --test --binaryLog "$@" 17 | --------------------------------------------------------------------------------
Sorry, there's nothing at this address.