├── .CodeQL.yml ├── .azure-pipelines ├── build-job.yml ├── build-jobs.yml ├── get-pat.yml ├── package-vcredist.yml ├── pipeline.yml ├── scripts │ ├── Get-SigntoolPath.ps1 │ ├── RemoveSignatureForThirdPartyAssemlies.ps1 │ ├── RemoveSignatureScript.ps1 │ ├── run-and-verify.js │ ├── switch-branch.ps1 │ └── switch-branch.sh └── signing.yml ├── .editorconfig ├── .gdn └── .gdnbaselines ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ ├── feature.yml │ └── question.yml ├── labelChecker │ ├── index.js │ ├── package-lock.json │ └── package.json ├── pull_request_template.md └── workflows │ ├── autoAssignABTT.yml │ ├── labelChecker.yml │ ├── localization-automerge.yml │ └── stale.yml ├── .gitignore ├── .vscode └── settings.json ├── .vsts.ci.yml ├── .vsts.release.yml ├── LICENSE ├── README.md ├── SECURITY.md ├── assets.json ├── azure-pipelines-agent.sln ├── docs ├── contribute.md ├── design │ ├── auth.md │ ├── byos.md │ ├── clientcert.md │ ├── coreclr.md │ ├── jobcancellation.md │ ├── logprocessors.md │ ├── non-glibc-containers.md │ ├── percentEncoding.md │ ├── proxy.md │ ├── res │ │ ├── 01AgentConfig.png │ │ ├── 02AgentStartListen.png │ │ ├── 03AgentQueueBuild.png │ │ ├── AgentLogProcessors.png │ │ ├── AgentLogProcessors.xml │ │ ├── byos1.png │ │ └── byos2.png │ └── setMTU.md ├── git.md ├── jobdirectories.md ├── layers.md ├── node6.md ├── noderunner.md ├── preview │ ├── consumeoutputvariable.md │ ├── latebreaking.md │ ├── logdecorations.md │ ├── outdated │ │ ├── conditions.md │ │ ├── pipeline.md │ │ ├── resources.md │ │ ├── yaml │ │ │ ├── dot-net-core-template.yaml │ │ │ ├── dot-net-core.yaml │ │ │ ├── vsbuild-template.yaml │ │ │ └── vsbuild.yaml │ │ ├── yamldeserialization.md │ │ └── yamlscripts.md │ ├── outputvariable.md │ ├── runtaskindocker.md │ ├── yaml-authz-troubleshooting.md │ └── yamlgettingstarted.md ├── res │ ├── apple_med.png │ ├── apple_sm.png │ ├── dependencies.svg │ ├── linux_med.png │ ├── linux_sm.png │ ├── redhat_med.png │ ├── redhat_sm.png │ ├── ubuntu_med.png │ ├── ubuntu_sm.png │ ├── win_med.png │ └── win_sm.png ├── start │ ├── configonprem.md │ ├── configvsts.md │ ├── envlinux.md │ ├── envosx.md │ ├── envredhat.md │ ├── envubuntu.md │ ├── envwin.md │ ├── moreconfig.md │ ├── nixsvc.md │ ├── proxyconfig.md │ ├── resourceconfig.md │ ├── roles.md │ ├── roles.png │ ├── scopes.png │ ├── svcosx.md │ └── svcsystemd.md └── troubleshooting.md ├── images └── readme.md ├── open-pullrequest.ps1 ├── release ├── Send-PRsNotification.ps1 ├── createAdoPrs.js ├── createReleaseBranch.js ├── fillReleaseNotesTemplate.js ├── package-lock.json ├── package.json ├── rollrelease.js └── util.js ├── releaseNote.md ├── send-notifications.ps1 ├── src ├── .helpers.sh ├── Agent.Listener │ ├── Agent.Listener.csproj │ ├── Agent.cs │ ├── CommandLine │ │ ├── BaseCommand.cs │ │ ├── ConfigureAgent.cs │ │ ├── ConfigureOrRemoveBase.cs │ │ ├── ReAuthAgent.cs │ │ ├── RemoveAgent.cs │ │ ├── RunAgent.cs │ │ └── WarmupAgent.cs │ ├── CommandSettings.cs │ ├── Configuration.Linux │ │ └── SystemdControlManager.cs │ ├── Configuration.Windows │ │ ├── AutoLogonManager.cs │ │ ├── AutoLogonRegistryManager.cs │ │ ├── NativeWindowsServiceHelper.cs │ │ ├── RSAEncryptedFileKeyManager.cs │ │ ├── WindowsRegistryManager.cs │ │ └── WindowsServiceControlManager.cs │ ├── Configuration.macOS │ │ └── MacOSServiceControlManager.cs │ ├── Configuration │ │ ├── ConfigurationManager.cs │ │ ├── ConfigurationProvider.cs │ │ ├── CredentialManager.cs │ │ ├── CredentialProvider.cs │ │ ├── FeatureFlagProvider.cs │ │ ├── IRSAKeyManager.cs │ │ ├── IntegratedCredential.cs │ │ ├── NegotiateCredential.cs │ │ ├── OAuthCredential.cs │ │ ├── PromptManager.cs │ │ ├── RSAFileKeyManager.cs │ │ ├── ServiceControlManager.cs │ │ └── Validators.cs │ ├── Diagnostics │ │ ├── DiagnosticSuite.cs │ │ ├── DiagnosticsTests.cs │ │ ├── DiskInfo.cs │ │ ├── DnsTest.cs │ │ ├── FolderPermissionInfo.cs │ │ ├── IDiagnosticInfo.cs │ │ ├── IDiagnosticTest.cs │ │ ├── MtuInfo.cs │ │ └── PingTest.cs │ ├── DistributedTask.Pipelines │ │ ├── TaskResources.g.cs │ │ ├── Update-FromVso.ps1 │ │ └── Yaml │ │ │ ├── Contracts │ │ │ ├── CheckoutStep.cs │ │ │ ├── DeploymentTarget.cs │ │ │ ├── IPhase.cs │ │ │ ├── IPhaseTarget.cs │ │ │ ├── ISimpleStep.cs │ │ │ ├── IStep.cs │ │ │ ├── IVariable.cs │ │ │ ├── Phase.cs │ │ │ ├── PhaseSelector.cs │ │ │ ├── PhasesTemplate.cs │ │ │ ├── PhasesTemplateReference.cs │ │ │ ├── Process.cs │ │ │ ├── ProcessResource.cs │ │ │ ├── ProcessTemplate.cs │ │ │ ├── ProcessTemplateReference.cs │ │ │ ├── QueueTarget.cs │ │ │ ├── ServerTarget.cs │ │ │ ├── StepGroup.cs │ │ │ ├── StepsTemplate.cs │ │ │ ├── StepsTemplateReference.cs │ │ │ ├── TaskReference.cs │ │ │ ├── TaskStep.cs │ │ │ ├── Variable.cs │ │ │ ├── VariablesTemplate.cs │ │ │ └── VariablesTemplateReference.cs │ │ │ ├── FileData.cs │ │ │ ├── IFileProvider.cs │ │ │ ├── ITraceWriter.cs │ │ │ ├── ParseOptions.cs │ │ │ ├── PipelineParser.cs │ │ │ └── TypeConverters │ │ │ ├── ConverterUtil.general.cs │ │ │ ├── ConverterUtil.phases.cs │ │ │ ├── ConverterUtil.processes.cs │ │ │ ├── ConverterUtil.steps.cs │ │ │ ├── ConverterUtil.variables.cs │ │ │ ├── PhasesTemplateConverter.cs │ │ │ ├── ProcessConverter.cs │ │ │ ├── ProcessTemplateConverter.cs │ │ │ ├── StepsTemplateConverter.cs │ │ │ ├── VariablesTemplateConverter.cs │ │ │ └── YamlConstants.cs │ ├── JobDispatcher.cs │ ├── MessageListener.cs │ ├── NuGet.Config │ ├── Program.cs │ ├── SelfUpdater.cs │ ├── Telemetry │ │ ├── CustomerIntelligenceServer.cs │ │ └── TelemetryPublisher.cs │ ├── ValidationHelper │ │ ├── InstallerVerifier.cs │ │ ├── UnsafeNativeMethods.cs │ │ ├── Utility.cs │ │ └── VerificationException.cs │ ├── net6.json │ └── net8.json ├── Agent.PluginHost │ ├── Agent.PluginHost.csproj │ └── Program.cs ├── Agent.Plugins │ ├── Agent.Plugins.csproj │ ├── Artifact │ │ ├── ArtifactDownloadParameters.cs │ │ ├── ArtifactItemFilters.cs │ │ ├── ArtifactProviderFactory.cs │ │ ├── BuildServer.cs │ │ ├── FileContainerProvider.cs │ │ ├── FileShareProvider.cs │ │ ├── IArtifactProvider.cs │ │ ├── PipelineArtifactConstants.cs │ │ ├── PipelineArtifactProvider.cs │ │ └── PipelineArtifactServer.cs │ ├── ArtifactsTracer.cs │ ├── BuildArtifact │ │ ├── BuildArtifactPluginConstants.cs │ │ └── BuildArtifactPluginV1.cs │ ├── GitCliManager.cs │ ├── GitSourceProvider.cs │ ├── ITfsVCCliManager.cs │ ├── PipelineArtifact │ │ ├── FilePathServer.cs │ │ ├── PipelineArtifactPlugin.cs │ │ ├── PipelineArtifactPluginConstants.cs │ │ ├── PipelineArtifactPluginUtil.cs │ │ ├── PipelineArtifactPluginV1.cs │ │ ├── PipelineArtifactPluginV2.cs │ │ └── Telemetry │ │ │ ├── FileShareActionRecord.cs │ │ │ └── PipelineArtifactActionRecord.cs │ ├── PipelineCache │ │ ├── FingerprintCreator.cs │ │ ├── PipelineCachePluginConstants.cs │ │ ├── PipelineCacheServer.cs │ │ ├── PipelineCacheTaskPluginBase.cs │ │ ├── RestorePipelineCacheV0.cs │ │ ├── SavePipelineCacheV0.cs │ │ ├── TarUtils.cs │ │ └── Telemetry │ │ │ └── PipelineCacheActionRecord.cs │ ├── RepositoryPlugin.cs │ ├── SvnCliManager.cs │ ├── SvnSourceProvider.cs │ ├── TFCliManager.cs │ ├── TeeCliManager.cs │ ├── TestFilePublisher │ │ ├── ClientFactory.cs │ │ ├── Finder │ │ │ ├── ITestFileFinder.cs │ │ │ └── TestFileFinder.cs │ │ ├── PipelineConfig.cs │ │ ├── Plugin │ │ │ └── TestFilePublisherLogPlugin.cs │ │ ├── SimpleTimer.cs │ │ ├── Telemetry │ │ │ ├── TelemetryConstants.cs │ │ │ ├── TelemetryDataCollector.cs │ │ │ └── TelemetryDataWrapper.cs │ │ ├── TestFilePublisher.cs │ │ ├── TestRunContextBuilder.cs │ │ ├── TraceListener.cs │ │ └── TraceLogger.cs │ ├── TestResultParser │ │ ├── Bus │ │ │ └── IBus.cs │ │ ├── ClientFactory.cs │ │ ├── Gateway │ │ │ ├── ILogParserGateway.cs │ │ │ ├── ILogPreProcessor.cs │ │ │ ├── LogParserGateway.cs │ │ │ └── LogPreProcessor.cs │ │ ├── IEnumerableExtension.cs │ │ ├── ParserFactory.cs │ │ ├── PipelineConfig.cs │ │ ├── PipelineTestRun.cs │ │ ├── PipelineTestRunPublisher.cs │ │ ├── Plugin │ │ │ └── TestResultLogPlugin.cs │ │ ├── SimpleTimer.cs │ │ ├── Telemetry │ │ │ ├── TelemetryConstants.cs │ │ │ ├── TelemetryDataCollector.cs │ │ │ └── TelemetryDataWrapper.cs │ │ ├── TestRunManager.cs │ │ └── TraceLogger.cs │ ├── TfsVCCliManager.cs │ └── TfsVCSourceProvider.cs ├── Agent.Sdk │ ├── Agent.Sdk.csproj │ ├── AgentClientCertificateManager.cs │ ├── AgentWebProxy.cs │ ├── AssemblyInfo.cs │ ├── CommandPlugin.cs │ ├── CommandStringConvertor.cs │ ├── ContainerInfo.cs │ ├── DockerVersion.cs │ ├── ExecutionTargetInfo.cs │ ├── ITraceWriter.cs │ ├── Knob │ │ ├── AgentKnobs.cs │ │ ├── BuiltInDefaultKnobSource.cs │ │ ├── CompositeKnobSource.cs │ │ ├── EnvironmentKnobSource.cs │ │ ├── ICompositeKnobSource.cs │ │ ├── IEnvironmentKnobSource.cs │ │ ├── IKnobSource.cs │ │ ├── IKnobValueContext.cs │ │ ├── Knob.cs │ │ ├── KnobValue.cs │ │ ├── PipelineFeatureSource.cs │ │ └── RuntimeKnobSource.cs │ ├── LogPlugin.cs │ ├── MountVolume.cs │ ├── PortMapping.cs │ ├── ProcessInvoker.MacLinux.cs │ ├── ProcessInvoker.Windows.cs │ ├── ProcessInvoker.cs │ ├── ScopedEnvironment.cs │ ├── SecretMasking │ │ ├── ILoggedSecretMasker.cs │ │ ├── LoggedSecretMasker.cs │ │ └── OssSecretMasker.cs │ ├── TaskPlugin.cs │ └── Util │ │ ├── ArgUtil │ │ ├── ArgUtil.cs │ │ ├── ArgUtilInstanced.cs │ │ └── IArgUtilInstanced.cs │ │ ├── AzureInstanceMetadataProvider.cs │ │ ├── BlobStoreWarningInfoProvider.cs │ │ ├── ExceptionsUtil.cs │ │ ├── IOUtil.cs │ │ ├── MaskingUtil.cs │ │ ├── NetFrameworkUtil.cs │ │ ├── NullTraceWriter.cs │ │ ├── PathUtil.cs │ │ ├── PlatformUtil.cs │ │ ├── PsModulePathUtil.cs │ │ ├── RepositoryUtil.cs │ │ ├── SslUtil.cs │ │ ├── StringUtil.cs │ │ ├── TeeUtil.cs │ │ ├── UrlUtil.cs │ │ ├── UtilKnobValueContext.cs │ │ ├── VssUtil.cs │ │ ├── WellKnownSecretAliases.cs │ │ ├── WhichUtil.cs │ │ └── WindowsProcessUtil.cs ├── Agent.Service │ └── Windows │ │ ├── AgentService.Designer.cs │ │ ├── AgentService.cs │ │ ├── AgentService.csproj │ │ ├── App.config │ │ ├── FinalPublicKey.snk │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── Resource.Designer.cs │ │ ├── Resource.de-de.resx │ │ ├── Resource.es-es.resx │ │ ├── Resource.fr-fr.resx │ │ ├── Resource.it-IT.resx │ │ ├── Resource.ja-jp.resx │ │ ├── Resource.ko-KR.resx │ │ ├── Resource.resx │ │ ├── Resource.ru-RU.resx │ │ ├── Resource.zh-CN.resx │ │ └── Resource.zh-TW.resx ├── Agent.Worker │ ├── Agent.Worker.csproj │ ├── AgentLogPlugin.cs │ ├── AgentPluginManager.cs │ ├── AsyncCommandContext.cs │ ├── Build │ │ ├── ArtifactCommandExtension.cs │ │ ├── BuildCommandExtension.cs │ │ ├── BuildDirectoryManager.cs │ │ ├── BuildJobExtension.cs │ │ ├── BuildServer.cs │ │ ├── Enums.cs │ │ ├── FileContainerServer.cs │ │ ├── GitCommandManager.cs │ │ ├── GitSourceProvider.cs │ │ ├── LegacyTrackingConfig.cs │ │ ├── SourceProvider.cs │ │ ├── SvnCommandManager.cs │ │ ├── SvnSourceProvider.cs │ │ ├── TFCommandManager.cs │ │ ├── TeeCommandManager.cs │ │ ├── TfsVCCommandManager.cs │ │ ├── TfsVCSourceProvider.cs │ │ ├── TopLevelTrackingConfig.cs │ │ ├── TrackingConfig.cs │ │ ├── TrackingConfigBase.cs │ │ ├── TrackingConfigHashAlgorithm.cs │ │ ├── TrackingManager.cs │ │ ├── UploadResult.cs │ │ └── WorkspaceMaintenanceProvider.cs │ ├── CodeCoverage │ │ ├── CoberturaSummaryReader.cs │ │ ├── CodeCoverageCommands.cs │ │ ├── CodeCoverageConstants.cs │ │ ├── CodeCoveragePublisher.cs │ │ ├── CodeCoverageServer.cs │ │ ├── CodeCoverageUtilities.cs │ │ ├── FeatureFlagUtility.cs │ │ ├── ICodeCoverageSummaryReader.cs │ │ └── JaCoCoSummaryReader.cs │ ├── Container │ │ ├── DockerCommandManager.cs │ │ └── DockerUtil.cs │ ├── ContainerOperationProvider.cs │ ├── DiagnosticLogManager.cs │ ├── ExecutionContext.cs │ ├── ExpressionManager.cs │ ├── GitManager.cs │ ├── Handlers │ │ ├── AgentPluginHandler.cs │ │ ├── Handler.cs │ │ ├── HandlerFactory.cs │ │ ├── LegacyPowerShellHandler.cs │ │ ├── NodeHandler.cs │ │ ├── PowerShell3Handler.cs │ │ ├── PowerShellExeHandler.cs │ │ ├── ProcessHandler │ │ │ ├── CmdArgsSanitizer.cs │ │ │ ├── Exceptions.cs │ │ │ ├── ProcessHandler.cs │ │ │ ├── ProcessHandlerHelper.cs │ │ │ └── ProcessHandlerV2.cs │ │ └── StepHost.cs │ ├── JobExtension.cs │ ├── JobExtensionRunner.cs │ ├── JobRunner.cs │ ├── Maintenance │ │ └── MaintenanceJobExtension.cs │ ├── ManagementScriptStep.cs │ ├── NodeJsUtil.cs │ ├── NuGet.Config │ ├── PluginInternalCommandExtension.cs │ ├── Program.cs │ ├── Release │ │ ├── AgentUtilities.cs │ │ ├── Artifacts │ │ │ ├── ArtifactDirectoryCreationFailedException.cs │ │ │ ├── ArtifactDownloadException.cs │ │ │ ├── BuildArtifact.cs │ │ │ ├── CommitsDownloadException.cs │ │ │ ├── CustomArtifact.cs │ │ │ ├── Definition │ │ │ │ ├── ArtifactDefinition.cs │ │ │ │ ├── BuildArtifactDetails.cs │ │ │ │ ├── CustomArtifactDetails.cs │ │ │ │ ├── CustomArtifactDownloadDetails.cs │ │ │ │ ├── CustomArtifactVersionDetails.cs │ │ │ │ ├── GitHubArtifactDetails.cs │ │ │ │ ├── IArtifactDetails.cs │ │ │ │ ├── JenkinsArtifactDetails.cs │ │ │ │ ├── TfsGitArtifactDetails.cs │ │ │ │ ├── TfsVCArtifactDetails.cs │ │ │ │ └── WellKnownStreamTypes.cs │ │ │ ├── FileShareArtifact.cs │ │ │ ├── GenericHttpClient.cs │ │ │ ├── GitHubArtifact.cs │ │ │ ├── GitHubHttpClient.cs │ │ │ ├── JenkinsArtifact.cs │ │ │ ├── TfsGitArtifact.cs │ │ │ └── TfsVCArtifact.cs │ │ ├── ContainerFetchEngine │ │ │ ├── ContainerFetchEngine.cs │ │ │ ├── ContainerFetchEngineDefaultOptions.cs │ │ │ ├── ContainerFetchEngineOptions.cs │ │ │ ├── ContainerItem.cs │ │ │ ├── FetchEngine.cs │ │ │ ├── HttpRetryOnTimeoutHandler.cs │ │ │ ├── HttpRetryOnTimeoutOptions.cs │ │ │ ├── IConatinerFetchEngineLogger.cs │ │ │ ├── IContainerProvider.cs │ │ │ ├── ItemType.cs │ │ │ └── NullExecutionLogger.cs │ │ ├── ContainerProvider │ │ │ ├── FileContainerProvider.cs │ │ │ └── Helpers │ │ │ │ ├── AsyncLazy.cs │ │ │ │ ├── ContainerProviderFactory.cs │ │ │ │ ├── ExecutionLogger.cs │ │ │ │ └── VssConnectionFactory.cs │ │ ├── DeploymentJobExtension.cs │ │ ├── IArtifactExtension.cs │ │ ├── IReleaseDirectoryManager.cs │ │ ├── ReleaseCommandExtension.cs │ │ ├── ReleaseDirectoryManager.cs │ │ ├── ReleaseFileSystemManager.cs │ │ ├── ReleaseJobExtension.cs │ │ ├── ReleaseServer.cs │ │ ├── ReleaseTrackingConfig.cs │ │ ├── ReleaseTrackingManager.cs │ │ ├── RetryExecutor.cs │ │ └── ZipStreamDownloader.cs │ ├── ResourceMetricsManager.cs │ ├── RetryHelper.cs │ ├── SignatureService.cs │ ├── SimpleTimer.cs │ ├── StepsRunner.cs │ ├── TaskCommandExtension.cs │ ├── TaskDecoratorManager.cs │ ├── TaskManager.cs │ ├── TaskRestrictionsChecker.cs │ ├── TaskRestrictionsExtension.cs │ ├── TaskRunner.cs │ ├── Telemetry │ │ ├── CustomerIntelligenceServer.cs │ │ └── TelemetryCommandExtension.cs │ ├── TempDirectoryManager.cs │ ├── TestResults │ │ ├── CommandTraceListener.cs │ │ ├── Legacy │ │ │ ├── AttachmentData.cs │ │ │ ├── ContainerStructureTestResultReader.cs │ │ │ ├── CtestResultReader.cs │ │ │ ├── IConverter.cs │ │ │ ├── IResultReader.cs │ │ │ ├── JunitResultReader.cs │ │ │ ├── LegacyTestRunDataPublisher.cs │ │ │ ├── NunitResultReader.cs │ │ │ ├── TestCaseResultData.cs │ │ │ ├── TestCaseResultDataConverter.cs │ │ │ ├── TestCaseSubResultData.cs │ │ │ ├── TestCaseSubResultDataConverter.cs │ │ │ ├── TestResultsServer.cs │ │ │ ├── TestRunContext.cs │ │ │ ├── TestRunData.cs │ │ │ ├── TestRunPublisher.cs │ │ │ ├── TrxResultReader.cs │ │ │ └── XunitResultReader.cs │ │ ├── Parser.cs │ │ ├── PublishToEvidenceStoreCommand.cs │ │ ├── ResultsCommandExtension.cs │ │ ├── TestDataPublisher.cs │ │ ├── TestRunDataPublisherHelper.cs │ │ └── Utils │ │ │ ├── FeatureFlagService.cs │ │ │ ├── InputValidator.cs │ │ │ ├── PublisherInputValidator.cs │ │ │ ├── TestResultUtils.cs │ │ │ └── TestResultsConstants.cs │ ├── TfManager.cs │ ├── Variables.cs │ ├── Worker.cs │ ├── WorkerCommandManager.cs │ └── WorkerUtilties.cs ├── Common.props ├── Microsoft.VisualStudio.Services.Agent │ ├── AdditionalMaskingRegexes.cs │ ├── AgentCertificateManager.cs │ ├── AgentCredentialStore │ │ ├── LinuxAgentCredentialStore.cs │ │ ├── MacOSAgentCredentialStore.cs │ │ ├── NoOpAgentCredentialStore.cs │ │ └── WindowsAgentCredentialStore.cs │ ├── AgentServer.cs │ ├── AgentService.cs │ ├── AsyncManualResetEvent.cs │ ├── Blob │ │ ├── BlobFileInfo.cs │ │ ├── BlobStoreClientTelemetryTfs.cs │ │ ├── BlobStoreUtils.cs │ │ ├── BlobstoreClientSettings.cs │ │ ├── BuildArtifactActionRecord.cs │ │ ├── CustomerIntelligenceTelemetrySender.cs │ │ ├── DedupManifestArtifactClientFactory.cs │ │ ├── IDedupRecord.cs │ │ ├── PipelineTelemetryRecord.cs │ │ └── TimelineRecordAttachmentTelemetryRecord.cs │ ├── Capabilities │ │ ├── AgentCapabilitiesProvider.cs │ │ ├── CapabilitiesManager.cs │ │ ├── EnvironmentCapabilitiesProvider.cs │ │ ├── NixCapabilitiesProvider.cs │ │ ├── PowerShellCapabilitiesProvider.cs │ │ └── UserCapabilitiesProvider.cs │ ├── Command.cs │ ├── ConfigurationStore.cs │ ├── Constants.cs │ ├── CredentialData.cs │ ├── DeploymentGroupServer.cs │ ├── EnvironmentsServer.cs │ ├── Exceptions.cs │ ├── ExtensionManager.cs │ ├── Extensions.cs │ ├── HostContext.cs │ ├── HostTraceListener.cs │ ├── IAgentCredentialStore.cs │ ├── IExtension.cs │ ├── JobNotification.cs │ ├── JobServer.cs │ ├── JobServerQueue.cs │ ├── LocationServer.cs │ ├── Logging.cs │ ├── Microsoft.VisualStudio.Services.Agent.csproj │ ├── NuGet.Config │ ├── ProcessChannel.cs │ ├── ProcessExtensions.cs │ ├── ProcessInvoker.cs │ ├── StreamString.cs │ ├── TaskServer.cs │ ├── Terminal.cs │ ├── ThrottlingReportHandler.cs │ ├── TraceManager.cs │ ├── TraceSetting.cs │ ├── Tracing.cs │ ├── Util │ │ ├── EnumUtil.cs │ │ ├── PlanUtil.cs │ │ ├── PowerShellExeUtil.cs │ │ ├── ServerUtil.cs │ │ ├── TaskResultUtil.cs │ │ ├── UnixUtil.cs │ │ └── VarUtil.cs │ ├── VstsAgentWebProxy.cs │ └── WindowsEnvVarHelper.cs ├── Misc │ ├── BuildConstants.ch │ ├── InstallAgentPackage.template.xml │ ├── Publish.template.ps1 │ ├── UpdateAgentPackage.template.xml │ ├── check-symlinks.sh │ ├── externals.sh │ ├── layoutbin │ │ ├── AgentService.js │ │ ├── containerHandlerInvoker.js.template │ │ ├── darwin.svc.sh.template │ │ ├── de-DE │ │ │ └── strings.json │ │ ├── en-US │ │ │ └── strings.json │ │ ├── es-ES │ │ │ └── strings.json │ │ ├── fr-FR │ │ │ └── strings.json │ │ ├── installdependencies.sh │ │ ├── it-IT │ │ │ └── strings.json │ │ ├── ja-JP │ │ │ └── strings.json │ │ ├── ko-KR │ │ │ └── strings.json │ │ ├── powershell │ │ │ ├── Add-AndroidSdkCapabilities.ps1 │ │ │ ├── Add-AntCapabilities.ps1 │ │ │ ├── Add-ApplicationCapabilities.ps1 │ │ │ ├── Add-AzureGuestAgentCapabilities.ps1 │ │ │ ├── Add-AzurePowerShellCapabilities.ps1 │ │ │ ├── Add-Capabilities.ps1 │ │ │ ├── Add-ChefCapabilities.ps1 │ │ │ ├── Add-DotNetFrameworkCapabilities.ps1 │ │ │ ├── Add-JavaCapabilities.ps1 │ │ │ ├── Add-MSBuildCapabilities.ps1 │ │ │ ├── Add-MavenCapabilities.ps1 │ │ │ ├── Add-PowerShellCapabilities.ps1 │ │ │ ├── Add-ScvmmAdminConsoleCapabilities.ps1 │ │ │ ├── Add-SqlPackageCapabilities.ps1 │ │ │ ├── Add-VisualStudioCapabilities.ps1 │ │ │ ├── Add-WindowsKitCapabilities.ps1 │ │ │ ├── Add-WindowsSdkCapabilities.ps1 │ │ │ ├── Add-XamarinAndroidCapabilities.ps1 │ │ │ ├── CapabilityHelpers │ │ │ │ ├── CapabilityFunctions.ps1 │ │ │ │ ├── CapabilityHelpers.psm1 │ │ │ │ ├── PathFunctions.ps1 │ │ │ │ ├── RegistryFunctions.ps1 │ │ │ │ ├── VersionFunctions.ps1 │ │ │ │ └── VisualStudioFunctions.ps1 │ │ │ ├── Get-LocalGroupMembership.ps1 │ │ │ └── Start-AzpTask.ps1 │ │ ├── ru-RU │ │ │ └── strings.json │ │ ├── runsvc.sh │ │ ├── systemd.svc.sh.template │ │ ├── tasks-exception-list.json │ │ ├── update.cmd.template │ │ ├── update.sh.template │ │ ├── vsts.agent.plist.template │ │ ├── vsts.agent.service.template │ │ ├── zh-CN │ │ │ └── strings.json │ │ └── zh-TW │ │ │ └── strings.json │ ├── layoutroot │ │ ├── config.cmd │ │ ├── config.sh │ │ ├── env.sh │ │ ├── license.html │ │ ├── reauth.cmd │ │ ├── reauth.sh │ │ ├── run-docker.sh │ │ ├── run.cmd │ │ └── run.sh │ └── osxsvclayout.txt ├── NuGet.Config ├── Test │ ├── CodeCoverage.runsettings │ ├── L0 │ │ ├── ConstantGenerationL0.cs │ │ ├── Container │ │ │ ├── ContainerInfoL0.cs │ │ │ └── DockerUtilL0.cs │ │ ├── ExtensionManagerL0.cs │ │ ├── HostContextExtensionL0.cs │ │ ├── HostContextL0.cs │ │ ├── KnobL0.cs │ │ ├── Listener │ │ │ ├── AgentL0.cs │ │ │ ├── CommandSettingsL0.cs │ │ │ ├── Configuration │ │ │ │ ├── AgentAutoLogonTestL0.cs │ │ │ │ ├── AgentCapabilitiesProviderTestL0.cs │ │ │ │ ├── AgentCredentialL0.cs │ │ │ │ ├── ArgumentValidatorTestsL0.cs │ │ │ │ ├── ConfigurationManagerL0.cs │ │ │ │ ├── Mocks │ │ │ │ │ └── MockNativeWindowsServiceHelper.cs │ │ │ │ ├── NativeWindowsServiceHelperL0.cs │ │ │ │ ├── PromptManagerTestsL0.cs │ │ │ │ ├── ServiceControlManagerL0.cs │ │ │ │ └── UserCapabilitiesProviderTestL0.cs │ │ │ ├── JobDispatcherL0.cs │ │ │ ├── MessageListenerL0.cs │ │ │ └── PipelineParserL0.cs │ │ ├── LocStringsL0.cs │ │ ├── NodeHandlerL0.cs │ │ ├── PagingLoggerL0.cs │ │ ├── Plugin │ │ │ ├── ChunkerTests.cs │ │ │ ├── FingerprintCreatorTests.cs │ │ │ ├── FingerprintTests.cs │ │ │ ├── IsPathyTests.cs │ │ │ ├── LogPluginHostL0.cs │ │ │ ├── MatchingTests.cs │ │ │ ├── RepositoryPluginL0.cs │ │ │ ├── TarUtilsL0.cs │ │ │ ├── TestFileContainerProvider │ │ │ │ └── TestFileContainerProviderL0.cs │ │ │ ├── TestFilePublisher │ │ │ │ ├── TestFileFinderL0.cs │ │ │ │ ├── TestFilePublisherL0.cs │ │ │ │ └── TestFilePublisherLogPluginL0.cs │ │ │ ├── TestFileShareProvider │ │ │ │ ├── MockDedupManifestArtifactClientFactory.cs │ │ │ │ ├── TestFileShareProviderL0.cs │ │ │ │ └── TestTelemetrySender.cs │ │ │ ├── TestGitCliManager │ │ │ │ ├── MockAgentTaskPluginExecutionContext.cs │ │ │ │ ├── MockGitCliManager.cs │ │ │ │ └── TestGitCliManagerL0.cs │ │ │ ├── TestGitSourceProvider │ │ │ │ ├── GitSourceProviderL0.cs │ │ │ │ ├── MockAgentTaskPluginExecutionContext.cs │ │ │ │ ├── MockGitCliManager.cs │ │ │ │ └── MockGitSoureProvider.cs │ │ │ └── TestResultParser │ │ │ │ ├── EnumerableExtensionL0.cs │ │ │ │ ├── LogPreProcessorL0.cs │ │ │ │ ├── PipelineTestRunPublisherL0.cs │ │ │ │ ├── TestResultLogPluginL0.cs │ │ │ │ └── TestRunManagerL0.cs │ │ ├── ProcessExtensionL0.cs │ │ ├── ProcessInvokerL0.cs │ │ ├── ProxyConfigL0.cs │ │ ├── SecretMaskerTests │ │ │ ├── LoggedSecretMaskerL0.cs │ │ │ └── SecretMaskerL0.cs │ │ ├── ServiceInterfacesL0.cs │ │ ├── TestHostContext.cs │ │ ├── TestUtil.cs │ │ ├── Util │ │ │ ├── ArgUtilL0.cs │ │ │ ├── IOUtilL0.cs │ │ │ ├── ProcessUtilL0.cs │ │ │ ├── RepositoryUtilL0.cs │ │ │ ├── StringUtilL0.cs │ │ │ ├── TaskResultUtilL0.cs │ │ │ ├── TelemetryPropsUtil.cs │ │ │ ├── UrlUtilL0.cs │ │ │ ├── VarUtilL0.cs │ │ │ ├── VssUtilL0.cs │ │ │ └── WhichUtilL0.cs │ │ ├── VstsAgentWebProxyL0.cs │ │ └── Worker │ │ │ ├── AgentPluginManagerL0.cs │ │ │ ├── Build │ │ │ ├── BuildDirectoryManagerL0.cs │ │ │ ├── BuildJobExtensionL0.cs │ │ │ ├── GitCommandManagerL0.cs │ │ │ ├── GitSourceProviderL0.cs │ │ │ ├── TfsVCCommandManagerL0.cs │ │ │ ├── TfsVCSourceProvider.WorkspaceUtilL0.cs │ │ │ ├── TfsVCSourceProviderL0.cs │ │ │ ├── TrackingConfigHashAlgorithmL0.cs │ │ │ ├── TrackingConfigL0.cs │ │ │ ├── TrackingManagerL0.cs │ │ │ └── WorkspaceMaintenanceProvicerL0.cs │ │ │ ├── CodeCoverage │ │ │ ├── CoberturaSummaryReaderTests.cs │ │ │ ├── CodeCoverageCommandExtensionTests.cs │ │ │ ├── CodeCoverageConstants.cs │ │ │ ├── CodeCoverageUtilitiesTests.cs │ │ │ ├── JacocoSummaryReaderTests.cs │ │ │ ├── frame-summary.html │ │ │ └── index.html │ │ │ ├── ExecutionContextL0.cs │ │ │ ├── ExpressionManagerL0.cs │ │ │ ├── GitManagerL0.cs │ │ │ ├── Handlers │ │ │ ├── CmdArgsSanitizerL0.cs │ │ │ ├── ProcessHandlerHelperL0.cs │ │ │ ├── ProcessHandlerHelperTelemetryL0.cs │ │ │ └── ProcessHandlerL0.cs │ │ │ ├── JobExtensionL0.cs │ │ │ ├── JobRunnerL0.cs │ │ │ ├── LoggingCommandL0.cs │ │ │ ├── PluginInternalUpdateRepositoryPathCommandL0.cs │ │ │ ├── Release │ │ │ ├── AgentUtlitiesL0.cs │ │ │ ├── FetchEngineL0.cs │ │ │ ├── GitHubArtifactL0.cs │ │ │ ├── JenkinsArtifactL0.cs │ │ │ ├── ReleaseDirectoryManagerL0.cs │ │ │ ├── ReleaseJobExtensionL0.cs │ │ │ ├── TfsGitArtifactL0.cs │ │ │ └── TfsVCArtifactL0.cs │ │ │ ├── SetVariableRestrictionsL0.cs │ │ │ ├── StepsRunnerL0.cs │ │ │ ├── TaskCommandExtensionL0.cs │ │ │ ├── TaskDecoratorManagerL0.cs │ │ │ ├── TaskManagerL0.cs │ │ │ ├── TaskRunnerL0.cs │ │ │ ├── Telemetry │ │ │ └── TelemetryCommandExtensionTests.cs │ │ │ ├── TestResults │ │ │ ├── Legacy │ │ │ │ ├── CtestResultReaderTests.cs │ │ │ │ ├── JunitResultReaderTests.cs │ │ │ │ ├── NUnitResultReaderTests.cs │ │ │ │ ├── TestRunPublisherTests.cs │ │ │ │ ├── TrxResultReaderTests.cs │ │ │ │ └── XUnitResultReaderTests.cs │ │ │ ├── ParserTests.cs │ │ │ └── ResultsCommandExtensionTests.cs │ │ │ ├── TfManagerL0.cs │ │ │ ├── VariablesL0.cs │ │ │ ├── WorkerCommandManagerL0.cs │ │ │ └── WorkerL0.cs │ ├── L1 │ │ ├── L1HostContext.cs │ │ ├── Mock │ │ │ ├── FakeAgentPluginManager.cs │ │ │ ├── FakeBuildServer.cs │ │ │ ├── FakeConfigurationStore.cs │ │ │ ├── FakeCustomerIntelligenceServer.cs │ │ │ ├── FakeJobServer.cs │ │ │ ├── FakeReleaseServer.cs │ │ │ ├── FakeResourceMetricsManager.cs │ │ │ ├── FakeTaskManager.cs │ │ │ └── FakeTaskServer.cs │ │ ├── Plugins │ │ │ ├── FakeCheckoutTask.cs │ │ │ └── FakeGitCliManager.cs │ │ └── Worker │ │ │ ├── CheckoutL1Tests.cs │ │ │ ├── ConditionsL1Tests.cs │ │ │ ├── ConfigL1Tests.cs │ │ │ ├── ContainerL1Tests.cs │ │ │ ├── CoreL1Tests.cs │ │ │ ├── L1TestBase.cs │ │ │ ├── SigningL1Tests.cs │ │ │ └── VariableL1Tests.cs │ ├── NuGet.Config │ ├── Test.csproj │ └── TestData │ │ └── TaskManagerL0 │ │ └── task.json ├── agentversion ├── dev.cmd ├── dev.sh └── dir.proj └── tools ├── FindAgentsNotCompatibleWithAgent ├── QueryAgentPoolsForCompatibleOS.ps1 └── readme.md └── FindPipelinesUsingRetiredImages ├── QueryJobHistoryForRetiredImages.ps1 └── readme.md /.CodeQL.yml: -------------------------------------------------------------------------------- 1 | path_classifiers: 2 | test: 3 | # Note: use only forward slash / as a path separator. 4 | # * Matches any sequence of characters except a forward slash. 5 | # ** Matches any sequence of characters, including a forward slash. 6 | # This wildcard must either be surrounded by forward slash symbols, or used as the first segment of a path. 7 | # It matches zero or more whole directory segments. There is no need to use a wildcard at the end of a directory path because all sub-directories are automatically matched. 8 | # That is, /anything/ matches the anything directory and all its subdirectories. 9 | # Always enclose the expression in double quotes if it includes *. 10 | - src/Test 11 | 12 | # The default behavior is to tag all files created during the 13 | # build as `generated`. Results are hidden for generated code. You can tag 14 | # further files as being generated by adding them to the `generated` section. 15 | generated: 16 | - _reports 17 | -------------------------------------------------------------------------------- /.azure-pipelines/get-pat.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - task: AzureCLI@2 3 | inputs: 4 | azureSubscription: ARM - WIF - manual 5 | scriptType: pscore 6 | scriptLocation: inlineScript 7 | inlineScript: | 8 | az account set --subscription $(SUBSCRIPTION_ID) 9 | $accessToken = az account get-access-token --resource $(RESOURCE_ID) --query accessToken --output tsv 10 | echo "##vso[task.setvariable variable=ACCESS_TOKEN;issecret=true]$accessToken" 11 | displayName: Get Access Token 12 | -------------------------------------------------------------------------------- /.azure-pipelines/package-vcredist.yml: -------------------------------------------------------------------------------- 1 | # This Yaml Document has been converted by ESAI Yaml Pipeline Conversion Tool. 2 | parameters: 3 | - name: layoutRoot 4 | type: string 5 | - name: flavor 6 | type: string 7 | 8 | steps: 9 | 10 | # Package .NET Core Windows dependency (VC++ Redistributable) 11 | - powershell: | 12 | Write-Host "Downloading 'VC++ Redistributable' package." 13 | $outDir = Join-Path -Path $env:TMP -ChildPath ([Guid]::NewGuid()) 14 | New-Item -Path $outDir -ItemType directory 15 | $outFile = Join-Path -Path $outDir -ChildPath "ucrt.zip" 16 | Invoke-WebRequest -Uri https://vstsagenttools.blob.core.windows.net/tools/ucrt/ucrt_${{ parameters.flavor }}.zip -OutFile $outFile 17 | Write-Host "Unzipping 'VC++ Redistributable' package to agent layout." 18 | $unzipDir = Join-Path -Path $outDir -ChildPath "unzip" 19 | Add-Type -AssemblyName System.IO.Compression.FileSystem 20 | [System.IO.Compression.ZipFile]::ExtractToDirectory($outFile, $unzipDir) 21 | $agentLayoutBin = Join-Path -Path $(Build.SourcesDirectory) -ChildPath "${{ parameters.layoutRoot }}\bin" 22 | Copy-Item -Path $unzipDir -Destination $agentLayoutBin -Force 23 | displayName: Package UCRT -------------------------------------------------------------------------------- /.azure-pipelines/scripts/Get-SigntoolPath.ps1: -------------------------------------------------------------------------------- 1 | function Get-Signtool() { 2 | <# 3 | .SYNOPSIS 4 | Function used to get signtool from windows SDK 5 | #> 6 | 7 | $systemBit = "x64" 8 | $programFiles = ${Env:ProgramFiles(x86)} 9 | 10 | if((Get-WmiObject Win32_Processor).AddressWidth -ne 64) { 11 | $systemBit = "x86" 12 | $programFiles = ${Env:ProgramFiles} 13 | } 14 | 15 | Write-Host "##[debug]System architecture is $systemBit" 16 | 17 | $signtoolPath = "" 18 | try { 19 | $windowsSdkPath=Get-ChildItem "$programFiles\Windows Kits\10\bin\1*" | Select-Object FullName | Sort-Object -Descending { [version](Split-Path $_.FullName -leaf)} | Select-Object -first 1 20 | 21 | $signtoolPath = "$($windowsSdkPath.FullName)\$systemBit\signtool.exe" 22 | return $signtoolPath 23 | } catch { 24 | Write-Host "##[error]Unbable to get signtool in $signtoolPath" 25 | exit 1 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.azure-pipelines/scripts/RemoveSignatureForThirdPartyAssemlies.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script is used as a start point for the process of removing signature from the third party assemlies 4 | 5 | .PARAMETER LayoutRoot 6 | Parameter that contains path to the _layout directory for current agent build 7 | #> 8 | 9 | [CmdletBinding()] 10 | param( 11 | [Parameter(Mandatory = $true)] 12 | [string]$LayoutRoot 13 | ) 14 | 15 | . $PSScriptRoot\Get-SigntoolPath.ps1 16 | . $PSScriptRoot\RemoveSignatureScript.ps1 17 | 18 | $signtoolPath = Get-Signtool | Select -Last 1 19 | 20 | if ( ($signToolPath -ne "") -and (Test-Path -Path $signtoolPath) ) { 21 | Remove-ThirdPartySignatures -SigntoolPath "$signToolPath" -LayoutRoot "$LayoutRoot" 22 | } else { 23 | Write-Host "##[error]$signToolPath is not a valid path" 24 | exit 1 25 | } 26 | -------------------------------------------------------------------------------- /.azure-pipelines/scripts/switch-branch.ps1: -------------------------------------------------------------------------------- 1 | git config user.email "azure-pipelines-bot@microsoft.com" 2 | git config user.name "azure-pipelines-bot" 3 | 4 | git checkout -f origin/$env:TARGET_BRANCH 5 | 6 | if ($LASTEXITCODE -ne 0){ 7 | Write-Error "git checkout failed with exit code $LASTEXITCODE" -ErrorAction Stop 8 | } 9 | -------------------------------------------------------------------------------- /.azure-pipelines/scripts/switch-branch.sh: -------------------------------------------------------------------------------- 1 | git config user.email "azure-pipelines-bot@microsoft.com" 2 | git config user.name "azure-pipelines-bot" 3 | 4 | git checkout -f origin/$TARGET_BRANCH 5 | 6 | last_exit_code=$? 7 | 8 | if [[ $last_exit_code != 0 ]]; then 9 | echo "git checkout failed with exit code $last_exit_code" 10 | exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Global rule: 2 | * @microsoft/azure-pipelines-tasks-and-agent @microsoft/azure-pipelines-platform 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Developer Community 4 | url: https://developercommunity.visualstudio.com/AzureDevOps 5 | about: For other Azure DevOps issues 6 | - name: Tasks issue 7 | url: https://github.com/microsoft/azure-pipelines-tasks/issues/new 8 | about: If you have issues with tasks, please place your issues here. 9 | - name: Security issue 10 | url: https://github.com/microsoft/azure-pipelines-agent/security/policy 11 | about: For security issues, please check our policy 12 | - name: Issue with YAML 13 | url: https://github.com/Microsoft/azure-pipelines-yaml 14 | about: Over there we discuss YAML templates, samples for Azure Pipelines, and designs for upcoming YAML features. Also a place for the community to share best practices, ideas, and so on. File suggestions and issues here if they're specific to YAML pipelines. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Use this template to submit a feature request 3 | title: "[enhancement]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to raise a question 10 | - type: markdown 11 | attributes: 12 | value: | 13 | ## Having issue with Tasks? 14 | Log an issue at [Azure-Pipelines-Tasks](https://github.com/Microsoft/azure-pipelines-tasks). It contains all of the in-box tasks we ship with Azure-Pipelines/VSTS/TFS. If you're having issues with tasks in Build/Release jobs (e.g. unreasonable task failure) please log an issue there. 15 | - type: textarea 16 | id: what-happened 17 | attributes: 18 | label: Describe your feature request here 19 | placeholder: Put your question here. 20 | description: Please try to provide as much details as possible 21 | validations: 22 | required: true -------------------------------------------------------------------------------- /.github/labelChecker/index.js: -------------------------------------------------------------------------------- 1 | const rm = require('typed-rest-client/RestClient'); 2 | const core = require('@actions/core'); 3 | const github = require('@actions/github'); 4 | 5 | async function main() { 6 | try { 7 | const issueTypes = ['bug', 'enhancement', 'misc', 'internal']; 8 | const pullRequestNumber = github.context.issue.number; 9 | console.log(`Running for PR: ${pullRequestNumber}\n`); 10 | let rest = new rm.RestClient('labelChecker'); 11 | console.log('Getting label info\n'); 12 | let res = await rest.get(`https://api.github.com/repos/microsoft/azure-pipelines-agent/issues/${pullRequestNumber}/labels`); 13 | console.log(`Labels: ${JSON.stringify(res.result)}`); 14 | let labelCount = 0; 15 | res.result.forEach(tag => { 16 | let name = tag.name.toLowerCase(); 17 | if (issueTypes.indexOf(name) > -1) { 18 | console.log(`Found tag: ${name}`); 19 | labelCount++; 20 | } 21 | }); 22 | 23 | if (labelCount === 0) { 24 | throw `Must be labeled one of ${issueTypes.join(', ')}` 25 | } 26 | if (labelCount > 1) { 27 | throw `Cannot contain more than one label of ${issueTypes.join(', ')}. Currently contains ${labelCount}` 28 | } 29 | } catch (err) { 30 | core.setFailed(err); 31 | } 32 | 33 | } 34 | 35 | main(); 36 | -------------------------------------------------------------------------------- /.github/labelChecker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "labelchecker", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@actions/core": "1.2.6", 13 | "@actions/github": "2.1.1", 14 | "typed-rest-client": "^1.8.9" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### **Context** 2 | _Explain the context or motivation behind this PR. Include links to any related Azure DevOps Work Items or GitHub issues._ 3 | 📌 [How to link to ADO Work Items](https://learn.microsoft.com/en-us/azure/devops/boards/github/link-to-from-github?view=azure-devops) 4 | 5 | --- 6 | 7 | ### **Description** 8 | _Provide a concise summary of the changes introduced in this PR._ 9 | 10 | --- 11 | 12 | ### **Risk Assessment** (Low / Medium / High) 13 | _Assess the risk level and justify your assessment. For example: code path sensitivity, usage scope, or backward compatibility concerns._ 14 | 15 | --- 16 | 17 | ### **Unit Tests Added or Updated** (Yes / No) 18 | _Indicate whether unit tests were added or modified to reflect the changes._ 19 | 20 | --- 21 | 22 | ### **Additional Testing Performed** 23 | _List manual or automated tests performed beyond unit tests (e.g., integration, scenario, regression)._ 24 | -------------------------------------------------------------------------------- /.github/workflows/autoAssignABTT.yml: -------------------------------------------------------------------------------- 1 | name: Auto Assign ABTT to Project Board 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | assign_one_project: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | issues: write 13 | name: Assign to ABTT Project 14 | steps: 15 | - name: "Add triage and area labels" 16 | uses: actions-ecosystem/action-add-labels@v1 17 | with: 18 | github_token: ${{ secrets.GITHUB_TOKEN }} 19 | labels: | 20 | Area: Agent 21 | triage 22 | 23 | - name: "Assign issues with 'Area: ABTT' label to project board" 24 | uses: actions/add-to-project@v0.4.1 25 | with: 26 | project-url: https://github.com/orgs/microsoft/projects/755 27 | github-token: ${{ secrets.ABTT_TOKEN }} 28 | -------------------------------------------------------------------------------- /.github/workflows/labelChecker.yml: -------------------------------------------------------------------------------- 1 | # This workflow ensures that all PRs are correctly labeled 2 | 3 | name: LabelChecker 4 | on: [pull_request] 5 | 6 | jobs: 7 | label: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | - run: | 14 | cd .github/labelChecker 15 | npm install 16 | node index.js 17 | -------------------------------------------------------------------------------- /.github/workflows/localization-automerge.yml: -------------------------------------------------------------------------------- 1 | name: 'LEGO automerge' 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | branches: 8 | - Localization 9 | 10 | jobs: 11 | worker: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | issues: write 15 | if: github.actor == 'csigs' 16 | steps: 17 | - uses: actions-ecosystem/action-add-labels@v1 18 | with: 19 | github_token: ${{ secrets.GITHUB_TOKEN }} 20 | labels: enhancement 21 | 22 | - uses: actions/github-script@v3 23 | with: 24 | github-token: ${{ secrets.GITHUB_TOKEN }} 25 | script: | 26 | github.pulls.merge({ 27 | owner: context.payload.repository.owner.login, 28 | repo: context.payload.repository.name, 29 | pull_number: context.payload.pull_request.number, 30 | merge_method: 'squash' 31 | }) 32 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Mark stale issues and pull requests 2 | 3 | on: 4 | schedule: 5 | - cron: "0 * * * *" 6 | 7 | jobs: 8 | stale: 9 | 10 | runs-on: ubuntu-latest 11 | permissions: 12 | issues: write 13 | steps: 14 | - uses: actions/stale@v3 15 | with: 16 | repo-token: ${{ secrets.GITHUB_TOKEN }} 17 | stale-issue-message: 'This issue has had no activity in 180 days. Please comment if it is not actually stale' 18 | stale-issue-label: 'stale' 19 | days-before-stale: 180 20 | days-before-close: 7 21 | exempt-pr-label: 'no-stale' 22 | exempt-issue-label: 'no-stale' 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/bin 2 | **/obj 3 | **/libs 4 | **/*.xproj 5 | **/*.xproj.user 6 | **/.vs 7 | **/.vscode 8 | **/*.error 9 | **/*.json.pretty 10 | **/.taskkey 11 | node_modules 12 | **/node_modules 13 | _downloads 14 | _hashes 15 | _l1 16 | _layout 17 | _package 18 | _package_hash 19 | _reports 20 | _dotnetsdk 21 | TestResults 22 | TestLogs 23 | .DS_Store 24 | **/*.DotSettings.user 25 | src/Misc/dotnet-install.* 26 | 27 | #generated 28 | src/Microsoft.VisualStudio.Services.Agent/BuildConstants.cs 29 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotnet-test-explorer.testProjectPath": "src/Test/Test.csproj", 3 | "dotnet-test-explorer.testArguments": "--no-build" 4 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) Microsoft Corporation 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. -------------------------------------------------------------------------------- /docs/design/jobcancellation.md: -------------------------------------------------------------------------------- 1 | 2 | # Agent jobs cancellation 3 | 4 | Agent receives cancellation signal from server - which initiates job cancellation process. 5 | 6 | ## How agent cancells job execution in details? 7 | 8 | When agent receives cancellation signal from server (this usually happens when job execution is timed out, or it was cancelled manually by user) - it sends SIGINT signal to the child process responsible for task execution. 9 | 10 | If child process has been successfully stopped by SIGINT signal - agent considers that task has been cancelled; otherwise, the agent will send SIGTERM signal to this process. 11 | 12 | You can find relevant source code [here](https://github.com/microsoft/azure-pipelines-agent/blob/master/src/Agent.Sdk/ProcessInvoker.cs#L418). 13 | -------------------------------------------------------------------------------- /docs/design/res/01AgentConfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/01AgentConfig.png -------------------------------------------------------------------------------- /docs/design/res/02AgentStartListen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/02AgentStartListen.png -------------------------------------------------------------------------------- /docs/design/res/03AgentQueueBuild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/03AgentQueueBuild.png -------------------------------------------------------------------------------- /docs/design/res/AgentLogProcessors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/AgentLogProcessors.png -------------------------------------------------------------------------------- /docs/design/res/byos1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/byos1.png -------------------------------------------------------------------------------- /docs/design/res/byos2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/design/res/byos2.png -------------------------------------------------------------------------------- /docs/design/setMTU.md: -------------------------------------------------------------------------------- 1 | # Set custom MTU parameter 2 | 3 | ## Goals 4 | - Allow specifying MTU value for networks used by container jobs (useful for docker-in-docker scenarios in k8s cluster). 5 | 6 | ## Configuration 7 | 8 | You need to set the environment variable AGENT_MTU_VALUE to set the MTU value, after that restart the self-hosted agent. You can find more about agent restart [here](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-windows?view=azure-devops#how-do-i-restart-the-agent) and about setting different environment variables for each individual agent [here](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-windows?view=azure-devops#how-do-i-set-different-environment-variables-for-each-individual-agent). 9 | 10 | This allows you to set up a network parameter for the job container, the use of this command is similar to the use of the next command while container network configuration: 11 | 12 | ```-o com.docker.network.driver.mtu=AGENT_MTU_VALUE``` 13 | -------------------------------------------------------------------------------- /docs/layers.md: -------------------------------------------------------------------------------- 1 | # Architectural Layers of the Agent Code 2 | 3 | `Agent.Listener`, `Agent.Worker`, `Agent.PluginHost`, and `Agent.Plugins` are at the top. 4 | They do not depend on each other. 5 | 6 | `Agent.Listener` and `Agent.Worker` both depend on `Microsoft.VisualStudio.Services.Agent`. 7 | (This could likely be renamed `Agent.Core` or `Agent.Common` for more clarity.) 8 | 9 | All of the assemblies mentioned so far depend on `Agent.Sdk`, and many of them depend on the various `Microsoft.VisualStudio.Services.*` web APIs. 10 | Additionally, `Agent.SDK` depends on some `Microsoft.TeamFoundation.*` assemblies. 11 | 12 | ## Diagram 13 | 14 | In rough terms, dependencies look like this: 15 | 16 | ![Dependency graph](res/dependencies.svg) 17 | 18 | ```mermaid 19 | graph TB 20 | subgraph App 21 | Agent.Listener 22 | Agent.Worker 23 | Agent.PluginHost 24 | Agent.Plugins 25 | end 26 | subgraph Platform 27 | agentcore[MS.VS.Services.Agent] 28 | agentsdk[Agent.SDK] 29 | end 30 | subgraph Infrastructure 31 | webapi[MS.VS.Services.*.WebAPI] 32 | tf[Microsoft.TeamFoundation.*] 33 | end 34 | Agent.Listener --> agentcore 35 | Agent.Worker --> agentcore 36 | Agent.PluginHost --> agentsdk 37 | Agent.Plugins --> agentsdk 38 | agentcore --> agentsdk 39 | agentcore --> webapi 40 | agentsdk --> tf 41 | ``` -------------------------------------------------------------------------------- /docs/node6.md: -------------------------------------------------------------------------------- 1 | # Agent Packages and Node versions 2 | 3 | Agent tasks can be implemented in PowerShell or Node. The agent ships with multiple versions of Node that tasks can target. 4 | 5 | As new Node versions are released, [tasks](https://github.com/microsoft/azure-pipelines-tasks) are updated to use new Node versions. The runtimes are included with the agent. 6 | 7 | As Node versions exit out of the upstream maintenance window, some Pipelines tasks still depend on it. Azure DevOps updates supported tasks to a supported Node version. Third party tasks may still need older Node versions to run. 8 | 9 | To accommodate this, we have 2 flavors of packages: 10 | 11 | | Packages | Node versions | Description | 12 | |----------------------|---------------|----------------------------| 13 | | `vsts-agent-*` | 6, 10, 16, 20 | Includes all Node versions that can be used as task execution handler | 14 | | `pipelines-agents-*` | 16, 20 | Includes only recent Node versions. The goal for these packages is to not include any end-of-life version of Node. | 15 | -------------------------------------------------------------------------------- /docs/preview/latebreaking.md: -------------------------------------------------------------------------------- 1 | # VSTS Agent System Pre-Requisites 2 | 3 | ## ![win](../res/win_med.png) Windows 4 | 5 | [Windows System Pre-Requisties](../start/envwin.md) 6 | 7 | ## ![osx](../res/apple_med.png) OSX 8 | 9 | [OSX System Pre-Requisties](../start/envosx.md) 10 | 11 | ## ![ubuntu](../res/ubuntu_med.png) Ubuntu 16.04 12 | 13 | [Ubuntu System Pre-Requisties](../start/envubuntu.md) 14 | 15 | ## ![redhat](../res/redhat_med.png) RedHat and CentOS 16 | 17 | [Redhat/CentOS System Pre-Requisties](../start/envredhat.md) 18 | -------------------------------------------------------------------------------- /docs/preview/outdated/yaml/dot-net-core.yaml: -------------------------------------------------------------------------------- 1 | template: 2 | name: dot-net-core-template.yaml 3 | parameters: 4 | buildProjects: "**/*.sln" 5 | buildConfiguration: "Debug" 6 | testProjects: "test/**/*.csproj" 7 | -------------------------------------------------------------------------------- /docs/preview/outdated/yaml/vsbuild.yaml: -------------------------------------------------------------------------------- 1 | # target: 2 | # type: queue 3 | # name: myQueue 4 | template: 5 | name: vsbuild-template.yaml 6 | parameters: 7 | queue: myQueue 8 | projects: myProject.sln 9 | matrix: 10 | - buildConfiguration: debug 11 | buildPlatform: any cpu 12 | - buildConfiguration: release 13 | buildPlatform: any cpu 14 | variables: 15 | myCustomVar1: my value 1 16 | myCustomVar2: my value 2 17 | steps: 18 | preBuild: 19 | - task: credscan@1.* 20 | -------------------------------------------------------------------------------- /docs/preview/yaml-authz-troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Moved! 2 | 3 | Moved to [the official docs site](https://docs.microsoft.com/azure/devops/pipelines/process/resources). -------------------------------------------------------------------------------- /docs/preview/yamlgettingstarted.md: -------------------------------------------------------------------------------- 1 | # Moved! 2 | 3 | We've moved the YAML documentation out of preview and over to the official [docs site](https://docs.microsoft.com/azure/devops/pipelines/get-started-yaml). 4 | 5 | If you're really stuck and need to get the old preview docs, the last commit where they were updated is 3d39fca. -------------------------------------------------------------------------------- /docs/res/apple_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/apple_med.png -------------------------------------------------------------------------------- /docs/res/apple_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/apple_sm.png -------------------------------------------------------------------------------- /docs/res/linux_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/linux_med.png -------------------------------------------------------------------------------- /docs/res/linux_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/linux_sm.png -------------------------------------------------------------------------------- /docs/res/redhat_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/redhat_med.png -------------------------------------------------------------------------------- /docs/res/redhat_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/redhat_sm.png -------------------------------------------------------------------------------- /docs/res/ubuntu_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/ubuntu_med.png -------------------------------------------------------------------------------- /docs/res/ubuntu_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/ubuntu_sm.png -------------------------------------------------------------------------------- /docs/res/win_med.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/win_med.png -------------------------------------------------------------------------------- /docs/res/win_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/res/win_sm.png -------------------------------------------------------------------------------- /docs/start/envlinux.md: -------------------------------------------------------------------------------- 1 | # System requirements: Linux 2 | 3 | [This page has moved.](https://docs.microsoft.com/azure/devops/pipelines/agents/v2-linux#check-prerequisites) 4 | -------------------------------------------------------------------------------- /docs/start/envosx.md: -------------------------------------------------------------------------------- 1 | # System requirements: macOS 2 | 3 | [This page has moved.](https://docs.microsoft.com/azure/devops/pipelines/agents/v2-osx#check-prerequisites) 4 | -------------------------------------------------------------------------------- /docs/start/envredhat.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ![redhat](../res/redhat_med.png) Red Hat/CentOS System Prerequisites [2.124.0 or below] 4 | 5 | ## Versions 6 | 7 | Tested on Red Hat 7.2. Not domain joined. 8 | 9 | 64-bit supported. 10 | 11 | ## Dependency Packages 12 | 13 | ```bash 14 | sudo yum -y install libunwind.x86_64 icu 15 | ``` 16 | If you're still having issues: 17 | [Full List Needed](https://github.com/dotnet/core/blob/master/Documentation/prereqs.md) 18 | 19 | ## Git 20 | 21 | If you use git, git >= 2.9.0 is a pre-requisite for Red Hat/CentOS agents. 22 | 23 | [Based on Install Latest Git on Red Hat/CentOS](http://tecadmin.net/install-git-2-x-on-centos-rhel-and-fedora/#) 24 | 25 | ```bash 26 | $ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel 27 | $ yum install gcc perl-ExtUtils-MakeMaker 28 | 29 | $ cd /usr/src 30 | $ wget https://www.kernel.org/pub/software/scm/git/git-2.9.2.tar.gz 31 | $ tar xzf git-2.9.2.tar.gz 32 | 33 | $ cd git-2.9.2 34 | $ make prefix=/usr/local/git all 35 | $ make prefix=/usr/local/git install 36 | ``` 37 | 38 | In /etc/bashrc 39 | ```bash 40 | export PATH=$PATH:/usr/local/git/bin 41 | ``` 42 | 43 | ## Optionally Java if TfsVc 44 | 45 | The agent distributes [Team Explorer Everywhere (TEE)](https://www.visualstudio.com/products/team-explorer-everywhere-vs.aspx). 46 | 47 | But, if you are using TfsVc, install Oracle Java 1.8+ as TEE uses Java. 48 | 49 | ## RHEL Universal Base Images (UBI) packages 50 | 51 | ```bash 52 | yum install -y git unzip libicu 53 | ``` 54 | 55 | UBI 8 will require `glibc-langpack-en` to be installed: 56 | ```bash 57 | yum -y install glibc-langpack-en 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/start/envubuntu.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ![Ubuntu](../res/ubuntu_med.png) Ubuntu System Prerequisites [2.124.0 or below] 4 | 5 | ## Versions 6 | 7 | Tested on 18.04 LTS (Bionic), 16.04 LTS (Xenial) and 14.04 LTS (Trusty). Not domain joined. 8 | 9 | 18.04 is recommended since it's the latest and supports SystemD for running as a service. 10 | 11 | ## Dependency Packages 12 | 13 | ### Ubuntu 18.04 (x64, ARM32), 16.04 (x64 only) 14 | ```bash 15 | sudo apt-get install -y libunwind8 libcurl3 16 | ``` 17 | 18 | ### Ubuntu 14.04 (x64 only) 19 | ```bash 20 | sudo apt-get install -y libunwind8 libcurl3 libicu52 21 | ``` 22 | 23 | If you're still having issues: 24 | [Full List Needed](https://github.com/dotnet/core/blob/master/Documentation/prereqs.md) 25 | 26 | ## Git 27 | 28 | If you use git, git >= 2.9.0 is a pre-requisite for Ubuntu agents. 29 | 30 | [Install Latest Git on Ubuntu](http://askubuntu.com/questions/568591/how-do-i-install-the-latest-version-of-git-with-apt/568596) 31 | 32 | ```bash 33 | $ sudo apt-add-repository ppa:git-core/ppa 34 | $ sudo apt-get update 35 | $ sudo apt-get install git 36 | ``` 37 | 38 | ## Optionally Java if using TFVC 39 | 40 | The agent distributes Team Explorer Everywhere. 41 | 42 | But, if you are using TFVC, install Oracle Java 1.8+ as TEE uses Java. 43 | 44 | ## Etc 45 | 46 | There was an assertion that on Ubuntu 16 this was needed. We didn't need. Adding in case it helps someone. We will verify on clean build and dev boxes. 47 | 48 | ```bash 49 | apt-get install libcurl4-openssl-dev 50 | ``` 51 | 52 | -------------------------------------------------------------------------------- /docs/start/envwin.md: -------------------------------------------------------------------------------- 1 | # System requirements: Windows 2 | 3 | [This page has moved.](https://docs.microsoft.com/azure/devops/pipelines/agents/v2-windows#check-prerequisites) 4 | -------------------------------------------------------------------------------- /docs/start/moreconfig.md: -------------------------------------------------------------------------------- 1 | # Replacing an agent 2 | 3 | If an agent already exists, configuration will ask you if you want to replace it. The name will default to the machine name so if configure two agents on the same machine, you can enter N and it will give you a chance to provide another name. 4 | 5 | If you are reconfiguring the agent, then choose Y. 6 | 7 | If you intended to actually replace an different agent, ensure the other agent is unconfigured. If two instances run with the same agent name, one will get a conflict. After a few minutes of conflicts, one will shut down. 8 | 9 | ```bash 10 | Enter agent name (press enter for mymachine) > 11 | Scanning for tool capabilities. 12 | Connecting to the server. 13 | Enter replace? (Y/N) (press enter for N) > N 14 | Enter agent name (press enter for mymachine) > testagent 15 | Scanning for tool capabilities. 16 | Connecting to the server. 17 | Successfully added the agent 18 | ``` 19 | 20 | # Unconfigure 21 | 22 | > Important: If you're running as a service on Linux/OSX, ensure you `stop` then `uninstall` the service before unconfiguring. See [Nix Service Config](nixsvc.md) 23 | 24 | ```bash 25 | $ ./config.sh remove 26 | Removing service 27 | Does not exist. Skipping Removing service 28 | Removing agent from the server 29 | Enter authentication type (press enter for PAT) > 30 | Enter personal access token > **************************************************** 31 | Succeeded: Removing agent from the server 32 | Removing .Credentials 33 | Succeeded: Removing .Credentials 34 | Removing .Agent 35 | Succeeded: Removing .Agent 36 | ``` 37 | 38 | # Help 39 | 40 | ```bash 41 | ./config.sh --help 42 | ``` -------------------------------------------------------------------------------- /docs/start/roles.md: -------------------------------------------------------------------------------- 1 | # Configure Account and Roles 2 | 3 | ## VSTS 4 | 5 | Create a PAT token. [Step by Step here](https://www.visualstudio.com/en-us/docs/setup-admin/team-services/use-personal-access-tokens-to-authenticate) 6 | 7 | Choose all scopes or the minimum "Agent Pools (read, manage)" scope. 8 | 9 | ![PAT Scope](scopes.png "PAT Scope") 10 | 11 | ## On Premises TFS 12 | 13 | You can use a domain user but it's recommended to create a local windows user on each of your application tiers specifically for registering build agents. 14 | 15 | ## Add to Role 16 | 17 | Add the user from above to only the Agent Pool Administrators which allows you to register the agent. 18 | 19 | ![Agent Roles](roles.png "Agent Roles") 20 | 21 | >> TIPS: 22 | >> You can add to roles for a specific pool or select "All Pools" on the left and grant for all pools. This allows the account owner to delegate build administration globally or for specific pools. [More here](https://msdn.microsoft.com/en-us/Library/vs/alm/Build/agents/admin) 23 | >> The role is only needed to register the agent. A token is downloaded to listen to the queue. 24 | >> When a build is run, it will generate an OAuth token for the scoped identity selected on the general tab of the build definition. That token is short lived and will be used to access resource in VSTS. The account used to register the agent has no bearing on the build run time credentials 25 | -------------------------------------------------------------------------------- /docs/start/roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/start/roles.png -------------------------------------------------------------------------------- /docs/start/scopes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/docs/start/scopes.png -------------------------------------------------------------------------------- /images/readme.md: -------------------------------------------------------------------------------- 1 | # Docker Images for the Agent CI/CD Pipeline 2 | 3 | ## Docker Hub 4 | 5 | In order to publish these images, you need to be a member of the organization `azpagentinfra` 6 | 7 | ## How to Build 8 | 9 | ```bash 10 | docker build --tag "azpagentinfra/alpine:latest" ./images/alpine/ 11 | ``` 12 | 13 | ## How to Push 14 | 15 | ```bash 16 | docker push "azpagentinfra/alpine:latest" 17 | ``` 18 | -------------------------------------------------------------------------------- /open-pullrequest.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory)] 3 | [string] 4 | $SourceBranch 5 | ) 6 | 7 | # Getting a created PR. Result object has interface in accordance with article https://docs.github.com/en/rest/reference/pulls#get-a-pull-request 8 | function Get-PullRequest() { 9 | return (gh api -X GET repos/:owner/:repo/pulls -F head=":owner:$SourceBranch" -f state=open -f base=master | ConvertFrom-Json) 10 | } 11 | 12 | $openedPR = Get-PullRequest 13 | 14 | if ($openedPR.html_url.length -ne 0) { 15 | throw "A PR from $SourceBranch to master already exists." 16 | } 17 | 18 | $buildUrl = "$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI$env:SYSTEM_TEAMPROJECT/_build/results?buildId=$env:BUILD_BUILDID&_a=summary" 19 | $body = "This PR was auto-generated with [the localization pipeline build]($buildUrl)." 20 | 21 | gh pr create --head $SourceBranch --title 'Localization update' --body $body --label "misc" 22 | 23 | # Getting a number to the opened PR 24 | $PR_NUMBER = (Get-PullRequest).number 25 | Write-Host "##vso[task.setvariable variable=PR_NUMBER]$PR_NUMBER" 26 | 27 | # Getting a link to the opened PR 28 | $PR_LINK = (Get-PullRequest).html_url 29 | Write-Host "##vso[task.setvariable variable=PR_LINK]$PR_LINK" 30 | -------------------------------------------------------------------------------- /release/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "@octokit/rest": "^16.43.2", 5 | "@octokit/graphql": "^7.1.1", 6 | "azure-devops-node-api": "^12.0.0", 7 | "azure-pipelines-task-lib": "^4.3.1", 8 | "got": "^11.8.6", 9 | "node-getopt": "^0.3.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/.helpers.sh: -------------------------------------------------------------------------------- 1 | function failed() 2 | { 3 | local error=${1:-Undefined error} 4 | echo "Failed: $error" >&2 5 | popd 6 | exit 1 7 | } 8 | 9 | function warn() 10 | { 11 | local error=${1:-Undefined error} 12 | echo "WARNING - FAILED: $error" >&2 13 | } 14 | 15 | function checkRC() { 16 | local rc=$? 17 | if [ $rc -ne 0 ]; then 18 | failed "${1} Failed with return code $rc" 19 | fi 20 | } 21 | 22 | function heading() 23 | { 24 | echo 25 | echo 26 | echo "-----------------------------------------" 27 | echo " ${1}" 28 | echo "-----------------------------------------" 29 | } 30 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/BaseCommand.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | public class BaseCommand 7 | { 8 | [Option(Constants.Agent.CommandLine.Flags.Help)] 9 | public bool Help { get; set; } 10 | 11 | [Option(Constants.Agent.CommandLine.Flags.Version)] 12 | public bool Version { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/ConfigureOrRemoveBase.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | public class ConfigureOrRemoveBase : BaseCommand 7 | { 8 | [Option(Constants.Agent.CommandLine.Args.Auth)] 9 | public string Auth { get; set; } 10 | 11 | [Option(Constants.Agent.CommandLine.Flags.LaunchBrowser)] 12 | public bool LaunchBrowser { get; set; } 13 | 14 | [Option(Constants.Agent.CommandLine.Args.Password)] 15 | public string Password { get; set; } 16 | 17 | [Option(Constants.Agent.CommandLine.Args.Token)] 18 | public string Token { get; set; } 19 | 20 | [Option(Constants.Agent.CommandLine.Flags.Unattended)] 21 | public bool Unattended { get; set; } 22 | 23 | [Option(Constants.Agent.CommandLine.Args.UserName)] 24 | public string UserName { get; set; } 25 | 26 | [Option(Constants.Agent.CommandLine.Args.ClientId)] 27 | public string ClientId { get; set; } 28 | 29 | [Option(Constants.Agent.CommandLine.Args.TenantId)] 30 | public string TenantId { get; set; } 31 | 32 | [Option(Constants.Agent.CommandLine.Args.ClientSecret)] 33 | public string ClientSecret { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/ReAuthAgent.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | [Verb(Constants.Agent.CommandLine.Commands.ReAuth)] 7 | public class ReAuthAgent : ConfigureOrRemoveBase 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/RemoveAgent.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | [Verb(Constants.Agent.CommandLine.Commands.Remove)] 7 | public class RemoveAgent : ConfigureOrRemoveBase 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/RunAgent.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | // Default Non-Requried Verb 7 | [Verb(Constants.Agent.CommandLine.Commands.Run)] 8 | public class RunAgent : BaseCommand 9 | { 10 | [Option(Constants.Agent.CommandLine.Flags.Commit)] 11 | public bool Commit { get; set; } 12 | 13 | [Option(Constants.Agent.CommandLine.Flags.Diagnostics)] 14 | public bool Diagnostics { get; set; } 15 | 16 | [Option(Constants.Agent.CommandLine.Flags.Once)] 17 | public bool RunOnce { get; set; } 18 | 19 | [Option(Constants.Agent.CommandLine.Args.StartupType)] 20 | public string StartupType { get; set; } 21 | 22 | [Option(Constants.Agent.CommandLine.Flags.DebugMode)] 23 | public bool DebugMode { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Agent.Listener/CommandLine/WarmupAgent.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | using Microsoft.VisualStudio.Services.Agent; 3 | 4 | namespace Agent.Listener.CommandLine 5 | { 6 | [Verb(Constants.Agent.CommandLine.Commands.Warmup)] 7 | public class WarmupAgent : BaseCommand 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Agent.Listener/Configuration/IntegratedCredential.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | using Microsoft.VisualStudio.Services.Common; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Configuration 8 | { 9 | public sealed class IntegratedCredential : CredentialProvider 10 | { 11 | public IntegratedCredential() : base(Constants.Configuration.Integrated) { } 12 | 13 | public override VssCredentials GetVssCredentials(IHostContext context) 14 | { 15 | ArgUtil.NotNull(context, nameof(context)); 16 | Tracing trace = context.GetTrace(nameof(IntegratedCredential)); 17 | trace.Info(nameof(GetVssCredentials)); 18 | 19 | // Create instance of VssConnection using default Windows credentials (NTLM) 20 | VssCredentials creds = new VssCredentials(true); 21 | 22 | trace.Verbose("cred created"); 23 | 24 | return creds; 25 | } 26 | 27 | public override void EnsureCredential(IHostContext context, CommandSettings command, string serverUrl) 28 | { 29 | //Integrated credentials do not require any configuration parameters 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Agent.Listener/Diagnostics/DiagnosticSuite.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.Services.Agent.Listener.Diagnostics; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Agent.Listener.Diagnostics 7 | { 8 | class DiagnosticSuite 9 | { 10 | public string SuiteName { get; set; } 11 | public List DiagnosticInfo { get; set; } 12 | public List DiagnosticTests { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Listener/Diagnostics/DnsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Diagnostics 5 | { 6 | class DnsTest : IDiagnosticTest 7 | { 8 | public bool Execute(ITerminal terminal) 9 | { 10 | try 11 | { 12 | IPHostEntry host = Dns.GetHostEntry(c_hostname); 13 | 14 | terminal.WriteLine(string.Format("GetHostEntry: {0} returns:", c_hostname)); 15 | foreach (IPAddress address in host.AddressList) 16 | { 17 | terminal.WriteLine($" {address}"); 18 | } 19 | return true; 20 | } 21 | catch (Exception ex) 22 | { 23 | terminal.WriteError(ex); 24 | return false; 25 | } 26 | } 27 | 28 | private const string c_hostname = "www.bing.com"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Agent.Listener/Diagnostics/IDiagnosticInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Diagnostics 2 | { 3 | public interface IDiagnosticInfo 4 | { 5 | void Execute(ITerminal terminal); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Agent.Listener/Diagnostics/IDiagnosticTest.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Diagnostics 2 | { 3 | public interface IDiagnosticTest 4 | { 5 | bool Execute(ITerminal terminal); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Agent.Listener/Diagnostics/PingTest.cs: -------------------------------------------------------------------------------- 1 | using System.Net.NetworkInformation; 2 | 3 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Diagnostics 4 | { 5 | class PingTest : IDiagnosticTest 6 | { 7 | public bool Execute(ITerminal terminal) 8 | { 9 | using (Ping ping = new Ping()) 10 | { 11 | try 12 | { 13 | terminal.WriteLine(string.Format("Attempt to Ping: {0} with timeout {1}", c_hostname, c_timeout)); 14 | PingReply pingreply = ping.Send(c_hostname, c_timeout); 15 | terminal.WriteLine(string.Format("Address: {0}", pingreply.Address)); 16 | terminal.WriteLine(string.Format("Status: {0}", pingreply.Status)); 17 | terminal.WriteLine(string.Format("Round trip time: {0}", pingreply.RoundtripTime)); 18 | 19 | if (pingreply.Status != IPStatus.Success) 20 | { 21 | terminal.WriteError(string.Format("Unsuccessful status response from {0}. Verify internet connection is working", c_hostname)); 22 | return false; 23 | } 24 | } 25 | catch (PingException ex) 26 | { 27 | terminal.WriteError(ex); 28 | return false; 29 | } 30 | } 31 | 32 | return true; 33 | } 34 | 35 | private const string c_hostname = "www.bing.com"; 36 | private const int c_timeout = 10000; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/DeploymentTarget.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class DeploymentTarget : IPhaseTarget 10 | { 11 | internal String ContinueOnError { get; set; } 12 | 13 | internal String Group { get; set; } 14 | 15 | internal String HealthOption { get; set; } 16 | 17 | internal String Percentage { get; set; } 18 | 19 | internal IList Tags { get; set; } 20 | 21 | internal String TimeoutInMinutes { get; set; } 22 | 23 | /// Number of retries for task failure 24 | internal String RetryCountOnTaskFailure { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/IPhase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 5 | { 6 | internal interface IPhase 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/IPhaseTarget.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal interface IPhaseTarget 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/ISimpleStep.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 5 | { 6 | internal interface ISimpleStep : IStep 7 | { 8 | ISimpleStep Clone(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/IStep.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | internal interface IStep 9 | { 10 | String Name { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/IVariable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 5 | { 6 | internal interface IVariable 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/Phase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal class Phase : IPhase 10 | { 11 | internal String Condition { get; set; } 12 | 13 | internal String ContinueOnError { get; set; } 14 | 15 | internal IList DependsOn { get; set; } 16 | 17 | internal String EnableAccessToken { get; set; } 18 | 19 | internal String Name { get; set; } 20 | 21 | internal IList Steps { get; set; } 22 | 23 | internal IPhaseTarget Target { get; set; } 24 | 25 | internal IList Variables { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/PhaseSelector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class PhaseSelector 10 | { 11 | internal String Name { get; set; } 12 | 13 | internal IDictionary> StepOverrides { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/PhasesTemplate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | // A phase template cannot reference other phase templates, but 10 | // steps within can reference templates. 11 | internal class PhasesTemplate : StepsTemplate 12 | { 13 | internal IList Phases { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/PhasesTemplateReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal class PhasesTemplateReference : StepsTemplateReference, IPhase 10 | { 11 | internal IList PhaseSelectors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/Process.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | internal sealed class Process : Phase 9 | { 10 | internal IList Phases { get; set; } 11 | 12 | internal IList Resources { get; set; } 13 | 14 | internal ProcessTemplateReference Template { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/ProcessResource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class ProcessResource 10 | { 11 | internal String Name { get; set; } 12 | 13 | internal String Type { get; set; } 14 | 15 | internal IDictionary Data 16 | { 17 | get 18 | { 19 | if (_data == null) 20 | { 21 | _data = new Dictionary(StringComparer.OrdinalIgnoreCase); 22 | } 23 | 24 | return _data; 25 | } 26 | } 27 | 28 | private IDictionary _data; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/ProcessTemplate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | // A process template cannot reference other process templates, but 9 | // phases/steps within can reference templates. 10 | internal sealed class ProcessTemplate : PhasesTemplate 11 | { 12 | internal IList Resources { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/ProcessTemplateReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 5 | { 6 | internal sealed class ProcessTemplateReference : PhasesTemplateReference 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/QueueTarget.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class QueueTarget : IPhaseTarget 10 | { 11 | internal String ContinueOnError { get; set; } 12 | 13 | internal IList Demands { get; set; } 14 | 15 | internal IDictionary> Matrix { get; set; } 16 | 17 | internal String Name { get; set; } 18 | 19 | internal String Parallel { get; set; } 20 | 21 | internal String TimeoutInMinutes { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/ServerTarget.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class ServerTarget : IPhaseTarget 10 | { 11 | internal String ContinueOnError { get; set; } 12 | 13 | internal IDictionary> Matrix { get; set; } 14 | 15 | internal String Parallel { get; set; } 16 | 17 | internal String TimeoutInMinutes { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/StepGroup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class StepGroup : IStep 10 | { 11 | public String Name { get; set; } 12 | 13 | internal IList Steps { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/StepsTemplate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | // A step template cannot reference other step templates (enforced during deserialization). 9 | internal class StepsTemplate 10 | { 11 | internal IList Steps { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/StepsTemplateReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal class StepsTemplateReference : IStep 10 | { 11 | public String Name { get; set; } 12 | 13 | internal IDictionary Parameters { get; set; } 14 | 15 | internal IDictionary> StepOverrides { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/TaskReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | internal sealed class TaskReference 9 | { 10 | internal String Name { get; set; } 11 | 12 | internal String Version { get; set; } 13 | 14 | internal TaskReference Clone() 15 | { 16 | return new TaskReference 17 | { 18 | Name = Name, 19 | Version = Version, 20 | }; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/Variable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | internal sealed class Variable : IVariable 9 | { 10 | internal String Name { get; set; } 11 | 12 | internal String Value { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/VariablesTemplate.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 7 | { 8 | internal sealed class VariablesTemplate 9 | { 10 | internal IList Variables { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/Contracts/VariablesTemplateReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml.Contracts 8 | { 9 | internal sealed class VariablesTemplateReference : IVariable 10 | { 11 | internal String Name { get; set; } 12 | 13 | internal IDictionary Parameters { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/FileData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml 8 | { 9 | [EditorBrowsable(EditorBrowsableState.Never)] 10 | public sealed class FileData 11 | { 12 | public String Name { get; set; } 13 | 14 | public String Directory { get; set; } 15 | 16 | public String Content { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/IFileProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml 8 | { 9 | [EditorBrowsable(EditorBrowsableState.Never)] 10 | public interface IFileProvider 11 | { 12 | FileData GetFile(String path); 13 | 14 | String ResolvePath(String defaultRoot, String path); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Agent.Listener/DistributedTask.Pipelines/Yaml/ITraceWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace Microsoft.TeamFoundation.DistributedTask.Orchestration.Server.Pipelines.Yaml 8 | { 9 | [EditorBrowsable(EditorBrowsableState.Never)] 10 | public interface ITraceWriter 11 | { 12 | void Info(String format, params Object[] args); 13 | 14 | void Verbose(String format, params Object[] args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Agent.Listener/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Agent.Listener/Telemetry/CustomerIntelligenceServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.VisualStudio.Services.Agent.Util; 6 | using Microsoft.VisualStudio.Services.CustomerIntelligence.WebApi; 7 | using Microsoft.VisualStudio.Services.WebApi; 8 | using Microsoft.VisualStudio.Services.WebPlatform; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Listener.Telemetry 11 | { 12 | [ServiceLocator(Default = typeof(CustomerIntelligenceServer))] 13 | public interface ICustomerIntelligenceServer : IAgentService 14 | { 15 | void Initialize(VssConnection connection); 16 | Task PublishEventsAsync(CustomerIntelligenceEvent[] ciEvents); 17 | } 18 | 19 | // This service is used for tracking task events which are applicable for VSTS internal tasks 20 | public class CustomerIntelligenceServer : AgentService, ICustomerIntelligenceServer 21 | { 22 | private CustomerIntelligenceHttpClient _ciClient; 23 | 24 | public void Initialize(VssConnection connection) 25 | { 26 | ArgUtil.NotNull(connection, nameof(connection)); 27 | _ciClient = connection.GetClient(); 28 | } 29 | 30 | public Task PublishEventsAsync(CustomerIntelligenceEvent[] ciEvents) 31 | { 32 | return _ciClient.PublishEventsAsync(events: ciEvents); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Agent.Listener/ValidationHelper/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.VisualStudio.Services.Agent.Listener 4 | { 5 | public class Utility 6 | { 7 | /// 8 | /// Checks if the OS version is win8 or above(doesn't check whether it is client or server) 9 | /// 10 | public static bool IsWin8OrAbove() 11 | { 12 | Version osVersion = Environment.OSVersion.Version; 13 | return (osVersion.Major >= 6 && osVersion.Minor >= 2); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Agent.Listener/ValidationHelper/VerificationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Listener 5 | { 6 | 7 | /// 8 | /// Represents errors that occur during validating intelligence pack signatures 9 | /// 10 | [SerializableAttribute] 11 | public class VerificationException : Exception 12 | { 13 | public VerificationException(string message) : base(message) 14 | { 15 | } 16 | 17 | public VerificationException(string message, Exception ex) 18 | : base(message, ex) 19 | { 20 | } 21 | 22 | #if NET6_0 23 | protected VerificationException(SerializationInfo info, StreamingContext context) 24 | : base(info, context) 25 | { 26 | } 27 | #endif 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Agent.PluginHost/Agent.PluginHost.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Exe 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Agent.Plugins/Agent.Plugins.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Library 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Agent.Plugins/Artifact/IArtifactProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Sdk; 5 | using BuildXL.Cache.ContentStore.Hashing; 6 | using Microsoft.TeamFoundation.Build.WebApi; 7 | using System.Collections.Generic; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace Agent.Plugins 12 | { 13 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1068: CancellationToken parameters must come last")] 14 | internal interface IArtifactProvider 15 | { 16 | Task DownloadSingleArtifactAsync( 17 | ArtifactDownloadParameters downloadParameters, 18 | BuildArtifact buildArtifact, 19 | CancellationToken cancellationToken, 20 | AgentTaskPluginExecutionContext context); 21 | 22 | Task DownloadMultipleArtifactsAsync( 23 | ArtifactDownloadParameters downloadParameters, 24 | IEnumerable buildArtifacts, 25 | CancellationToken cancellationToken, 26 | AgentTaskPluginExecutionContext context); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Agent.Plugins/Artifact/PipelineArtifactConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Plugins 5 | { 6 | // Use PipelineArtifactContants.cs from ADO, once the latest libs are available. 7 | public class PipelineArtifactConstants 8 | { 9 | public const string AzurePipelinesAgent = "AzurePipelinesAgent"; 10 | public const string ArtifactSize = "artifactsize"; 11 | public const string BuildArtifactDownload = "BuildArtifactDownload"; 12 | public const string Container = "Container"; 13 | public const string PipelineArtifact = "PipelineArtifact"; 14 | public const string PipelineCache = "PipelineCache"; 15 | public const string ProofNodes = "ProofNodes"; 16 | public const string RestoreCache = "RestoreCache"; 17 | public const string RootId = "RootId"; 18 | public const string SaveCache = "SaveCache"; 19 | public const string FileShareArtifact = "filepath"; 20 | public const string CustomPropertiesPrefix = "user-"; 21 | public const string HashType = "HashType"; 22 | public const string DomainId = "DomainId"; 23 | } 24 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/ArtifactsTracer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Microsoft.TeamFoundation.Build.WebApi; 10 | using Microsoft.VisualStudio.Services.Common; 11 | using Microsoft.VisualStudio.Services.Agent.Util; 12 | using Agent.Sdk; 13 | using System.Text.RegularExpressions; 14 | using Microsoft.VisualStudio.Services.Content.Common.Tracing; 15 | 16 | namespace Agent.Plugins 17 | { 18 | public static class ArtifactsTracer 19 | { 20 | public static IAppTraceSource CreateArtifactsTracer(this AgentTaskPluginExecutionContext context) 21 | { 22 | ArgUtil.NotNull(context, nameof(context)); 23 | bool verbose = context.IsSystemDebugTrue(); 24 | return new CallbackAppTraceSource( 25 | (str, level) => 26 | { 27 | if (level == System.Diagnostics.SourceLevels.Warning) 28 | { 29 | context.Warning(str); 30 | } 31 | else 32 | { 33 | context.Output(str); 34 | } 35 | }, 36 | verbose 37 | ? System.Diagnostics.SourceLevels.Verbose 38 | : System.Diagnostics.SourceLevels.Information); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/BuildArtifact/BuildArtifactPluginConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Agent.Plugins.BuildArtifacts 7 | { 8 | public class BuildArtifactPluginConstants 9 | { 10 | public static readonly Guid DownloadBuildArtifactTaskId = new Guid("a433f589-fce1-4460-9ee6-44a624aeb1fb"); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/PipelineArtifact/PipelineArtifactPluginConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Agent.Plugins.PipelineArtifact 7 | { 8 | public static class PipelineArtifactPluginConstants 9 | { 10 | public static readonly Guid PublishPipelineArtifactTaskId = new Guid("ECDC45F6-832D-4AD9-B52B-EE49E94659BE"); 11 | public static readonly Guid DownloadPipelineArtifactTaskId = new Guid("61F2A582-95AE-4948-B34D-A1B3C4F6A737"); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/PipelineArtifact/PipelineArtifactPluginUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace Agent.Plugins.PipelineArtifact 9 | { 10 | public static class PipelineArtifactPathHelper 11 | { 12 | // This collection of invalid characters is based on the characters that are illegal in Windows/NTFS filenames. 13 | // Also prevent files (pipeline artifact names) from containing "/" or "\" due to the added complexity this introduces for file pattern matching on download. 14 | private static readonly char[] ForbiddenArtifactNameChars = 15 | new char[] { 16 | (char) 0, (char) 1, (char) 2, (char) 3, (char) 4, (char) 5, (char) 6, 17 | (char) 7, (char) 8, (char) 9, (char) 10, (char) 11, (char) 12, (char) 13, 18 | (char) 14, (char) 15, (char) 16, (char) 17, (char) 18, (char) 19, (char) 20, 19 | (char) 21, (char) 22, (char) 23, (char) 24, (char) 25, (char) 26, (char) 27, 20 | (char) 28, (char) 29, (char) 30, (char) 31, 21 | '"', ':', '<', '>', '|', '*', '?', '/', '\\' }; 22 | private static readonly HashSet ForbiddenArtifactNameCharsSet = new HashSet(ForbiddenArtifactNameChars); 23 | 24 | public static bool IsValidArtifactName(string artifactName) 25 | { 26 | return !artifactName.Any(c => ForbiddenArtifactNameCharsSet.Contains(c)); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/PipelineArtifact/Telemetry/PipelineArtifactActionRecord.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Agent.Sdk; 6 | using Microsoft.VisualStudio.Services.Agent.Blob; 7 | using Microsoft.VisualStudio.Services.Content.Common.Telemetry; 8 | using Microsoft.VisualStudio.Services.BlobStore.WebApi; 9 | 10 | namespace Agent.Plugins.PipelineArtifact.Telemetry 11 | { 12 | /// 13 | /// Generic telemetry record for use with Pipeline Artifact events. 14 | /// 15 | public class PipelineArtifactActionRecord : PipelineTelemetryRecord 16 | { 17 | public long FileCount { get; private set; } 18 | 19 | public PipelineArtifactActionRecord(TelemetryInformationLevel level, Uri baseAddress, string eventNamePrefix, string eventNameSuffix, AgentTaskPluginExecutionContext context, uint attemptNumber = 1) 20 | : base(level, baseAddress, eventNamePrefix, eventNameSuffix, context, attemptNumber) 21 | { 22 | } 23 | 24 | protected override void SetMeasuredActionResult(T value) 25 | { 26 | if (value is PublishResult) 27 | { 28 | PublishResult result = value as PublishResult; 29 | FileCount = result.FileCount; 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/PipelineCache/PipelineCachePluginConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Agent.Plugins.PipelineCache 7 | { 8 | public static class PipelineCachePluginConstants 9 | { 10 | public static readonly Guid CacheTaskId = new Guid("D53CCAB4-555E-4494-9D06-11DB043FB4A9"); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/PipelineCache/RestorePipelineCacheV0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Agent.Sdk; 9 | using Microsoft.VisualStudio.Services.PipelineCache.WebApi; 10 | 11 | namespace Agent.Plugins.PipelineCache 12 | { 13 | public class RestorePipelineCacheV0 : PipelineCacheTaskPluginBase 14 | { 15 | public override string Stage => "main"; 16 | 17 | protected override async Task ProcessCommandInternalAsync( 18 | AgentTaskPluginExecutionContext context, 19 | Fingerprint fingerprint, 20 | Func restoreKeysGenerator, 21 | string path, 22 | CancellationToken token) 23 | { 24 | context.SetTaskVariable(RestoreStepRanVariableName, RestoreStepRanVariableValue); 25 | context.SetTaskVariable(ResolvedFingerPrintVariableName, fingerprint.ToString()); 26 | 27 | var server = new PipelineCacheServer(context); 28 | Fingerprint[] restoreFingerprints = restoreKeysGenerator(); 29 | await server.DownloadAsync( 30 | context, 31 | (new[] { fingerprint }).Concat(restoreFingerprints).ToArray(), 32 | path, 33 | context.GetInput(PipelineCacheTaskPluginConstants.CacheHitVariable, required: false), 34 | token); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/ClientFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.WebApi; 5 | 6 | namespace Agent.Plugins.Log.TestFilePublisher 7 | { 8 | public interface IClientFactory 9 | { 10 | /// 11 | /// Access any pipeline client through factory 12 | /// 13 | T GetClient() where T : VssHttpClientBase; 14 | } 15 | 16 | public class ClientFactory : IClientFactory 17 | { 18 | public ClientFactory(VssConnection vssConnection) 19 | { 20 | _vssConnection = vssConnection; 21 | } 22 | 23 | /// 24 | public T GetClient() where T : VssHttpClientBase 25 | { 26 | return _vssConnection.GetClient(); 27 | } 28 | 29 | private readonly VssConnection _vssConnection; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/Finder/ITestFileFinder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Threading.Tasks; 6 | 7 | namespace Agent.Plugins.Log.TestFilePublisher 8 | { 9 | public interface ITestFileFinder 10 | { 11 | Task> FindAsync(IList patterns); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/PipelineConfig.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Agent.Plugins.Log.TestFilePublisher 8 | { 9 | public class PipelineConfig 10 | { 11 | public Guid ProjectGuid { get; set; } 12 | 13 | public string ProjectName { get; set; } 14 | 15 | public int BuildId { get; set; } 16 | 17 | public string BuildUri { get; set; } 18 | 19 | public IList SearchFolders { get; } = new List(); 20 | 21 | public IList Patterns { get; } = new List(); 22 | 23 | public string StageName { get; set; } 24 | 25 | public string PhaseName { get; set; } 26 | 27 | public string JobName { get; set; } 28 | 29 | public int StageAttempt { get; set; } 30 | 31 | public int PhaseAttempt { get; set; } 32 | 33 | public int JobAttempt { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/Telemetry/TelemetryConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Plugins.Log.TestFilePublisher 5 | { 6 | public class TelemetryConstants 7 | { 8 | public const string PluginInitialized = "PluginInitialized"; 9 | 10 | public const string PluginDisabled = "PluginDisabled"; 11 | 12 | public const string Exceptions = "Exceptions"; 13 | 14 | public const string FinalizeAsync = "FinalizeAsync"; 15 | 16 | public const string FindTestFilesAsync = "FindTestFilesAsync"; 17 | 18 | public const string InitializeFailed = "InitializeFailed"; 19 | 20 | public const string PublishTestRunDataAsync = "PublishTestRunDataAsync"; 21 | 22 | public const string ParseTestResultFiles = "ParseTestResultFiles"; 23 | 24 | public const string StageName = "StageName"; 25 | 26 | public const string StageAttempt = "StageAttempt"; 27 | 28 | public const string PhaseName = "PhaseName"; 29 | 30 | public const string PhaseAttempt = "PhaseAttempt"; 31 | 32 | public const string JobName = "JobName"; 33 | 34 | public const string JobAttempt = "JobAttempt"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/Telemetry/TelemetryDataWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Plugins.Log.TestResultParser.Contracts; 5 | 6 | namespace Agent.Plugins.Log.TestFilePublisher 7 | { 8 | public class TelemetryDataWrapper 9 | { 10 | public TelemetryDataWrapper(ITelemetryDataCollector telemetry, string telemetryEventName, string telemetrySubArea = null) 11 | { 12 | telemetryDataCollector = telemetry; 13 | this.telemetryEventName = telemetryEventName; 14 | this.telemetrySubArea = telemetrySubArea; 15 | } 16 | 17 | public void AddAndAggregate(object value) 18 | { 19 | telemetryDataCollector.AddAndAggregate(telemetryEventName, value, telemetrySubArea); 20 | } 21 | 22 | private string telemetrySubArea; 23 | 24 | public string telemetryEventName; 25 | 26 | public ITelemetryDataCollector telemetryDataCollector; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/TraceListener.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Diagnostics; 5 | using Agent.Sdk; 6 | 7 | namespace Agent.Plugins.Log.TestFilePublisher 8 | { 9 | public class TestFileTraceListener : TraceListener 10 | { 11 | private readonly IAgentLogPluginContext _context; 12 | 13 | public TestFileTraceListener(IAgentLogPluginContext context) 14 | { 15 | _context = context; 16 | } 17 | 18 | public override void Write(string message) 19 | { 20 | //ignoring this as this contains trash info 21 | } 22 | 23 | public override void WriteLine(string message) 24 | { 25 | _context.Output(message); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestFilePublisher/TraceLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Plugins.Log.TestResultParser.Contracts; 5 | using Agent.Sdk; 6 | 7 | namespace Agent.Plugins.Log.TestFilePublisher 8 | { 9 | public class TraceLogger : ITraceLogger 10 | { 11 | public TraceLogger(IAgentLogPluginContext context) 12 | { 13 | _context = context; 14 | 15 | _context.Variables.TryGetValue("system.debug", out var systemDebug); 16 | if (string.Equals(systemDebug?.Value, "true", System.StringComparison.OrdinalIgnoreCase)) 17 | { 18 | _debug = true; 19 | } 20 | } 21 | 22 | #region interface implementation 23 | 24 | /// 25 | void ITraceLogger.Warning(string text) 26 | { 27 | _context.Output($"Warning: {text}"); 28 | } 29 | 30 | /// 31 | void ITraceLogger.Error(string error) 32 | { 33 | _context.Output($"Error: {error}"); 34 | } 35 | 36 | /// 37 | void ITraceLogger.Verbose(string text) 38 | { 39 | if (_debug) 40 | { 41 | _context.Output($"Debug: {text}"); 42 | } 43 | } 44 | 45 | /// 46 | void ITraceLogger.Info(string text) 47 | { 48 | _context.Output(text); 49 | } 50 | 51 | #endregion 52 | 53 | private readonly IAgentLogPluginContext _context; 54 | private readonly bool _debug; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/Bus/IBus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Agent.Plugins.Log.TestResultParser.Plugin 7 | { 8 | public interface IBus 9 | { 10 | /// 11 | /// Subscribe to Message Bus to receive messages via Pub-Sub model 12 | /// 13 | Guid Subscribe(Action handlerAction); 14 | 15 | /// 16 | /// Unsubscribe to Message Bus so that subscriber no longer receives messages 17 | /// 18 | void Unsubscribe(Guid subscriptionId); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/ClientFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.WebApi; 5 | 6 | namespace Agent.Plugins.Log.TestResultParser.Plugin 7 | { 8 | public interface IClientFactory 9 | { 10 | /// 11 | /// Access any pipeline client through factory 12 | /// 13 | T GetClient() where T : VssHttpClientBase; 14 | } 15 | 16 | public class ClientFactory : IClientFactory 17 | { 18 | public ClientFactory(VssConnection vssConnection) 19 | { 20 | _vssConnection = vssConnection; 21 | } 22 | 23 | /// 24 | public T GetClient() where T : VssHttpClientBase 25 | { 26 | return _vssConnection.GetClient(); 27 | } 28 | 29 | private readonly VssConnection _vssConnection; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/Gateway/ILogParserGateway.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Agent.Plugins.Log.TestResultParser.Contracts; 6 | 7 | namespace Agent.Plugins.Log.TestResultParser.Plugin 8 | { 9 | public interface ILogParserGateway 10 | { 11 | /// 12 | /// Register all parsers which needs to parse the task console stream 13 | /// 14 | Task InitializeAsync(IClientFactory clientFactory, IPipelineConfig pipelineConfig, ITraceLogger traceLogger, ITelemetryDataCollector telemetry); 15 | 16 | /// 17 | /// Process the task output data 18 | /// 19 | Task ProcessDataAsync(string data); 20 | 21 | /// 22 | /// Complete parsing the data 23 | /// 24 | Task CompleteAsync(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/Gateway/ILogPreProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Plugins.Log.TestResultParser.Plugin 5 | { 6 | public interface ILogPreProcessor 7 | { 8 | /// 9 | /// Pre processes the data performing sanitization operations if any before 10 | /// sending it over to the parsers 11 | /// 12 | string ProcessData(string data); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/IEnumerableExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace Agent.Plugins.Log.TestResultParser.Plugin 8 | { 9 | public static class EnumerableExtension 10 | { 11 | public static IEnumerable> Batch(this IEnumerable source, int size) 12 | { 13 | TSource[] bucket = null; 14 | var count = 0; 15 | 16 | foreach (var item in source) 17 | { 18 | if (bucket == null) 19 | bucket = new TSource[size]; 20 | 21 | bucket[count++] = item; 22 | if (count != size) 23 | continue; 24 | 25 | yield return bucket; 26 | 27 | bucket = null; 28 | count = 0; 29 | } 30 | 31 | if (bucket != null && count > 0) 32 | yield return bucket.Take(count); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/PipelineConfig.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Agent.Plugins.Log.TestResultParser.Contracts; 6 | 7 | namespace Agent.Plugins.Log.TestResultParser.Plugin 8 | { 9 | public class PipelineConfig : IPipelineConfig 10 | { 11 | public Guid Project { get; set; } 12 | 13 | public int BuildId { get; set; } 14 | 15 | public String StageName { get; set; } 16 | 17 | public int StageAttempt { get; set; } 18 | 19 | public String PhaseName { get; set; } 20 | 21 | public int PhaseAttempt { get; set; } 22 | 23 | public String JobName { get; set; } 24 | 25 | public int JobAttempt { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/PipelineTestRun.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Plugins.Log.TestResultParser.Contracts; 5 | 6 | namespace Agent.Plugins.Log.TestResultParser.Plugin 7 | { 8 | public class PipelineTestRun : TestRun 9 | { 10 | public PipelineTestRun(string parserUri, string runNamePrefix, int testRunId, int tcmTestRunId) : base(parserUri, runNamePrefix, testRunId) 11 | { 12 | TcmTestRunId = tcmTestRunId; 13 | } 14 | 15 | public int TcmTestRunId { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/Telemetry/TelemetryDataWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Plugins.Log.TestResultParser.Contracts; 5 | 6 | namespace Agent.Plugins.Log.TestResultParser.Plugin 7 | { 8 | public class TelemetryDataWrapper 9 | { 10 | public TelemetryDataWrapper(ITelemetryDataCollector telemetry, string telemetryEventName, string telemetrySubArea = null) 11 | { 12 | telemetryDataCollector = telemetry; 13 | this.telemetryEventName = telemetryEventName; 14 | this.telemetrySubArea = telemetrySubArea; 15 | } 16 | 17 | public void AddAndAggregate(object value) 18 | { 19 | telemetryDataCollector.AddAndAggregate(telemetryEventName, value, telemetrySubArea); 20 | } 21 | 22 | private string telemetrySubArea; 23 | 24 | public string telemetryEventName; 25 | 26 | public ITelemetryDataCollector telemetryDataCollector; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Agent.Plugins/TestResultParser/TraceLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Agent.Plugins.Log.TestResultParser.Contracts; 5 | using Agent.Sdk; 6 | 7 | namespace Agent.Plugins.Log.TestResultParser.Plugin 8 | { 9 | public class TraceLogger : ITraceLogger 10 | { 11 | public TraceLogger(IAgentLogPluginContext context) 12 | { 13 | _context = context; 14 | 15 | _context.Variables.TryGetValue("system.debug", out var systemDebug); 16 | if (string.Equals(systemDebug?.Value, "true", System.StringComparison.OrdinalIgnoreCase)) 17 | { 18 | _debug = true; 19 | } 20 | } 21 | 22 | #region interface implementation 23 | 24 | /// 25 | void ITraceLogger.Warning(string text) 26 | { 27 | _context.Output($"Warning: {text}"); 28 | } 29 | 30 | /// 31 | void ITraceLogger.Error(string error) 32 | { 33 | _context.Output($"Error: {error}"); 34 | } 35 | 36 | /// 37 | void ITraceLogger.Verbose(string text) 38 | { 39 | if (_debug) 40 | { 41 | _context.Output($"Debug: {text}"); 42 | } 43 | } 44 | 45 | /// 46 | void ITraceLogger.Info(string text) 47 | { 48 | _context.Output(text); 49 | } 50 | 51 | #endregion 52 | 53 | private readonly IAgentLogPluginContext _context; 54 | private readonly bool _debug; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Agent.Sdk/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("Test")] 4 | -------------------------------------------------------------------------------- /src/Agent.Sdk/DockerVersion.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Agent.Sdk 7 | { 8 | public class DockerVersion 9 | { 10 | public DockerVersion() 11 | { 12 | 13 | } 14 | 15 | public DockerVersion(Version serverVersion, Version clientVersion) 16 | { 17 | this.ServerVersion = serverVersion; 18 | this.ClientVersion = clientVersion; 19 | } 20 | 21 | public Version ServerVersion { get; set; } 22 | public Version ClientVersion { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Agent.Sdk/ExecutionTargetInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk 5 | { 6 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1715: Identifiers should have correct prefix")] 7 | public interface ExecutionTargetInfo 8 | { 9 | PlatformUtil.OS ExecutionOS { get; } 10 | string CustomNodePath { get; set; } 11 | string ResultNodePath { get; set; } 12 | 13 | string TranslateContainerPathForImageOS(PlatformUtil.OS runningOs, string path); 14 | string TranslateToContainerPath(string path); 15 | string TranslateToHostPath(string path); 16 | } 17 | 18 | public class HostInfo : ExecutionTargetInfo 19 | { 20 | public PlatformUtil.OS ExecutionOS => PlatformUtil.HostOS; 21 | public string CustomNodePath { get; set; } 22 | public string ResultNodePath { get; set; } 23 | 24 | public string TranslateToContainerPath(string path) 25 | { 26 | return path; 27 | } 28 | 29 | public string TranslateToHostPath(string path) 30 | { 31 | return path; 32 | } 33 | 34 | public string TranslateContainerPathForImageOS(PlatformUtil.OS runningOs, string path) 35 | { 36 | return path; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Agent.Sdk/ITraceWriter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk 5 | { 6 | public interface ITraceWriter 7 | { 8 | void Info(string message); 9 | void Verbose(string message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/BuiltInDefaultKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob 5 | { 6 | public class BuiltInDefaultKnobSource : IKnobSource 7 | { 8 | private string _value; 9 | 10 | public BuiltInDefaultKnobSource(string value) 11 | { 12 | _value = value; 13 | } 14 | 15 | public KnobValue GetValue(IKnobValueContext context) 16 | { 17 | return new KnobValue(_value, this); 18 | } 19 | 20 | public string GetDisplayString() 21 | { 22 | return "Default"; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/EnvironmentKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using Microsoft.VisualStudio.Services.Agent.Util; 4 | 5 | namespace Agent.Sdk.Knob 6 | { 7 | 8 | public class EnvironmentKnobSource : IEnvironmentKnobSource 9 | { 10 | private string _envVar; 11 | 12 | public EnvironmentKnobSource(string envVar) 13 | { 14 | _envVar = envVar; 15 | } 16 | 17 | public KnobValue GetValue(IKnobValueContext context) 18 | { 19 | ArgUtil.NotNull(context, nameof(context)); 20 | var scopedEnvironment = context.GetScopedEnvironment(); 21 | var value = scopedEnvironment.GetEnvironmentVariable(_envVar); 22 | if (!string.IsNullOrEmpty(value)) 23 | { 24 | return new KnobValue(value, this); 25 | } 26 | return null; 27 | } 28 | 29 | public string GetDisplayString() 30 | { 31 | return $"${{{_envVar}}}"; 32 | } 33 | 34 | public string GetEnvironmentVariableName() 35 | { 36 | return _envVar; 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/ICompositeKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob 5 | { 6 | public interface ICompositeKnobSource : IKnobSource 7 | { 8 | bool HasSourceWithTypeEnvironmentByName(string name); 9 | 10 | KnobValue GetValue(IKnobValueContext context); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/IEnvironmentKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob 5 | { 6 | public interface IEnvironmentKnobSource : IKnobSource 7 | { 8 | string GetEnvironmentVariableName(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/IKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob 5 | { 6 | public interface IKnobSource 7 | { 8 | KnobValue GetValue(IKnobValueContext context); 9 | 10 | string GetDisplayString(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/IKnobValueContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob 5 | { 6 | public interface IKnobValueContext 7 | { 8 | string GetVariableValueOrDefault(string variableName); 9 | 10 | IScopedEnvironment GetScopedEnvironment(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/KnobValue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System; 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | 6 | namespace Agent.Sdk.Knob 7 | { 8 | public class KnobValue 9 | { 10 | public IKnobSource Source { get; private set; } 11 | private string _value; 12 | 13 | public KnobValue(string value, IKnobSource source) 14 | { 15 | _value = value; 16 | Source = source; 17 | } 18 | 19 | public string AsString() 20 | { 21 | return _value; 22 | } 23 | 24 | public bool AsBoolean() 25 | { 26 | return StringUtil.ConvertToBoolean(_value); 27 | } 28 | 29 | public bool AsBooleanStrict() 30 | { 31 | return StringUtil.ConvertToBooleanStrict(_value); 32 | } 33 | 34 | public int AsInt() 35 | { 36 | return Int32.Parse(_value); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/PipelineFeatureSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk.Knob; 5 | 6 | /// 7 | /// Wrapper knob source for runtime feature flags. 8 | /// 9 | public class PipelineFeatureSource : RuntimeKnobSource 10 | { 11 | public PipelineFeatureSource(string featureName) : base($"DistributedTask.Agent.{featureName}") 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Knob/RuntimeKnobSource.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | using System; 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | 6 | namespace Agent.Sdk.Knob 7 | { 8 | public class RuntimeKnobSource : IKnobSource 9 | { 10 | private readonly string _runTimeVar; 11 | 12 | public RuntimeKnobSource(string runTimeVar) 13 | { 14 | _runTimeVar = runTimeVar; 15 | } 16 | 17 | public KnobValue GetValue(IKnobValueContext context) 18 | { 19 | ArgUtil.NotNull(context, nameof(context)); 20 | string value = null; 21 | try 22 | { 23 | value = context.GetVariableValueOrDefault(_runTimeVar); 24 | } 25 | catch (NotSupportedException) 26 | { 27 | throw new NotSupportedException($"{GetType().Name} not supported for context type {context.GetType()}"); 28 | } 29 | 30 | if (!string.IsNullOrEmpty(value)) 31 | { 32 | return new KnobValue(value, this); 33 | } 34 | return null; 35 | } 36 | 37 | public string GetDisplayString() 38 | { 39 | return $"$({_runTimeVar})"; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Agent.Sdk/PortMapping.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Agent.Sdk 5 | { 6 | public class PortMapping 7 | { 8 | 9 | public PortMapping() 10 | { 11 | 12 | } 13 | 14 | public PortMapping(string hostPort, string containerPort, string protocol) 15 | { 16 | this.HostPort = hostPort; 17 | this.ContainerPort = containerPort; 18 | this.Protocol = protocol; 19 | } 20 | 21 | public string HostPort { get; set; } 22 | public string ContainerPort { get; set; } 23 | public string Protocol { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Agent.Sdk/SecretMasking/ILoggedSecretMasker.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | using Microsoft.TeamFoundation.DistributedTask.Logging; 7 | 8 | namespace Agent.Sdk.SecretMasking 9 | { 10 | /// 11 | /// Extended ISecretMasker interface that adds support for logging the origin of 12 | /// regexes, encoders and literal secret values. 13 | /// 14 | public interface ILoggedSecretMasker : ISecretMasker, IDisposable 15 | { 16 | static int MinSecretLengthLimit { get; } 17 | 18 | void AddRegex(String pattern, string origin); 19 | void AddValue(String value, string origin); 20 | void AddValueEncoder(ValueEncoder encoder, string origin); 21 | void SetTrace(ITraceWriter trace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Util/ArgUtil/IArgUtilInstanced.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Microsoft.VisualStudio.Services.Agent.Util 6 | { 7 | public interface IArgUtilInstanced 8 | { 9 | public void Directory([ValidatedNotNull] string directory, string name); 10 | 11 | public void Equal(T expected, T actual, string name); 12 | 13 | public void File(string fileName, string name); 14 | 15 | public void NotNull([ValidatedNotNull] object value, string name); 16 | 17 | public void NotNullOrEmpty([ValidatedNotNull] string value, string name); 18 | 19 | public void ListNotNullOrEmpty([ValidatedNotNull] IEnumerable value, string name); 20 | public void NotEmpty(Guid value, string name); 21 | public void Null(object value, string name); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Util/ExceptionsUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Net.Sockets; 6 | using Microsoft.VisualStudio.Services.Agent.Util; 7 | 8 | namespace Agent.Sdk.Util 9 | { 10 | public class ExceptionsUtil 11 | { 12 | public static void HandleAggregateException(AggregateException e, Action traceErrorAction) 13 | { 14 | traceErrorAction("One or several exceptions have been occurred."); 15 | 16 | foreach (var ex in ((AggregateException)e).Flatten().InnerExceptions) 17 | { 18 | traceErrorAction(ex.ToString()); 19 | } 20 | } 21 | 22 | public static void HandleSocketException(SocketException e, string url, Action traceErrorAction) 23 | { 24 | traceErrorAction("SocketException occurred."); 25 | traceErrorAction(e.Message); 26 | traceErrorAction($"Verify whether you have (network) access to {url}"); 27 | traceErrorAction($"URLs the agent need communicate with - {BlobStoreWarningInfoProvider.GetAllowListLinkForCurrentPlatform()}"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Util/NullTraceWriter.cs: -------------------------------------------------------------------------------- 1 | namespace Agent.Sdk.Util 2 | { 3 | internal class NullTraceWriter : ITraceWriter 4 | { 5 | public void Info(string message) 6 | { 7 | } 8 | 9 | public void Verbose(string message) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Util/UrlUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Util 7 | { 8 | public static class UrlUtil 9 | { 10 | public static Uri GetCredentialEmbeddedUrl(Uri baseUrl, string username, string password) 11 | { 12 | ArgUtil.NotNull(baseUrl, nameof(baseUrl)); 13 | 14 | // return baseurl when there is no username and password 15 | if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password)) 16 | { 17 | return baseUrl; 18 | } 19 | 20 | UriBuilder credUri = new UriBuilder(baseUrl); 21 | 22 | // ensure we have a username, uribuild will throw if username is empty but password is not. 23 | if (string.IsNullOrEmpty(username)) 24 | { 25 | username = "emptyusername"; 26 | } 27 | 28 | // escape chars in username for uri 29 | credUri.UserName = Uri.EscapeDataString(username); 30 | 31 | // escape chars in password for uri 32 | if (!string.IsNullOrEmpty(password)) 33 | { 34 | credUri.Password = Uri.EscapeDataString(password); 35 | } 36 | 37 | return credUri.Uri; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Agent.Sdk/Util/UtilKnobValueContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Agent.Sdk; 3 | using Agent.Sdk.Knob; 4 | 5 | namespace Microsoft.VisualStudio.Services.Agent.Util 6 | { 7 | public class UtilKnobValueContext : IKnobValueContext 8 | { 9 | private static UtilKnobValueContext _instance; 10 | 11 | protected UtilKnobValueContext() 12 | { 13 | } 14 | 15 | public static UtilKnobValueContext Instance() 16 | { 17 | if (_instance == null) 18 | { 19 | _instance = new UtilKnobValueContext(); 20 | } 21 | 22 | return _instance; 23 | } 24 | 25 | public string GetVariableValueOrDefault(string variableName) 26 | { 27 | throw new NotSupportedException("Method not supported for Microsoft.VisualStudio.Services.Agent.Util.UtilKnobValueContext"); 28 | } 29 | 30 | public IScopedEnvironment GetScopedEnvironment() 31 | { 32 | return new SystemEnvironment(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Agent.Service/Windows/AgentService.Designer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace AgentService 5 | { 6 | partial class AgentService 7 | { 8 | /// 9 | /// Required designer variable. 10 | /// 11 | private System.ComponentModel.IContainer components = null; 12 | 13 | /// 14 | /// Clean up any resources being used. 15 | /// 16 | /// true if managed resources should be disposed; otherwise, false. 17 | protected override void Dispose(bool disposing) 18 | { 19 | if (disposing && (components != null)) 20 | { 21 | components.Dispose(); 22 | } 23 | base.Dispose(disposing); 24 | } 25 | 26 | #region Component Designer generated code 27 | 28 | /// 29 | /// Required method for Designer support - do not modify 30 | /// the contents of this method with the code editor. 31 | /// 32 | private void InitializeComponent() 33 | { 34 | components = new System.ComponentModel.Container(); 35 | this.ServiceName = "Service1"; 36 | } 37 | 38 | #endregion 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Agent.Service/Windows/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Agent.Service/Windows/FinalPublicKey.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/azure-pipelines-agent/5453c1a1915722b10e6017bbb9f041d620591b25/src/Agent.Service/Windows/FinalPublicKey.snk -------------------------------------------------------------------------------- /src/Agent.Service/Windows/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("AgentService")] 12 | [assembly: AssemblyDescription("")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("")] 15 | [assembly: AssemblyProduct("AgentService")] 16 | [assembly: AssemblyCopyright("Copyright © 2016")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("d12ebd71-0464-46d0-8394-40bcfba0a6f2")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Build and Revision Numbers 36 | // by using the '*' as shown below: 37 | // [assembly: AssemblyVersion("1.0.*")] 38 | [assembly: AssemblyVersion("1.0.0.0")] 39 | [assembly: AssemblyFileVersion("1.0.0.0")] 40 | -------------------------------------------------------------------------------- /src/Agent.Worker/Agent.Worker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Exe 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Agent.Worker/Build/Enums.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Build 5 | { 6 | public enum BuildCleanOption 7 | { 8 | None, 9 | Source, 10 | Binary, 11 | All, 12 | } 13 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Build/TopLevelTrackingConfig.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Globalization; 7 | using Newtonsoft.Json; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Build 10 | { 11 | public sealed class TopLevelTrackingConfig 12 | { 13 | [JsonIgnore] 14 | public DateTimeOffset? LastBuildDirectoryCreatedOn { get; set; } 15 | 16 | [JsonProperty("lastBuildFolderCreatedOn")] 17 | [EditorBrowsableAttribute(EditorBrowsableState.Never)] 18 | public string LastBuildDirectoryCreatedOnString 19 | { 20 | get 21 | { 22 | return string.Format(CultureInfo.InvariantCulture, "{0}", LastBuildDirectoryCreatedOn); 23 | } 24 | 25 | set 26 | { 27 | if (string.IsNullOrEmpty(value)) 28 | { 29 | LastBuildDirectoryCreatedOn = null; 30 | return; 31 | } 32 | 33 | LastBuildDirectoryCreatedOn = DateTimeOffset.Parse(value, CultureInfo.InvariantCulture); 34 | } 35 | } 36 | 37 | [JsonProperty("lastBuildFolderNumber")] 38 | public int LastBuildDirectoryNumber { get; set; } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Build/TrackingConfigBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Build 5 | { 6 | public abstract class TrackingConfigBase 7 | { 8 | protected static readonly string BuildSystem = "build"; 9 | 10 | public string CollectionId { get; set; } 11 | 12 | public string DefinitionId { get; set; } 13 | 14 | public string HashKey { get; set; } 15 | 16 | public string RepositoryUrl { get; set; } 17 | 18 | public string System { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Build/UploadResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using Microsoft.VisualStudio.Services.Agent.Util; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Build 8 | { 9 | public class UploadResult 10 | { 11 | public UploadResult() 12 | { 13 | FailedFiles = new List(); 14 | TotalFileSizeUploaded = 0; 15 | } 16 | 17 | public UploadResult(List failedFiles, long totalFileSizeUploaded) 18 | { 19 | FailedFiles = failedFiles; 20 | TotalFileSizeUploaded = totalFileSizeUploaded; 21 | } 22 | public List FailedFiles { get; set; } 23 | 24 | public long TotalFileSizeUploaded { get; set; } 25 | 26 | public void AddUploadResult(UploadResult resultToAdd) 27 | { 28 | ArgUtil.NotNull(resultToAdd, nameof(resultToAdd)); 29 | 30 | this.FailedFiles.AddRange(resultToAdd.FailedFiles); 31 | this.TotalFileSizeUploaded += resultToAdd.TotalFileSizeUploaded; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Agent.Worker/CodeCoverage/FeatureFlagUtility.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | using Microsoft.VisualStudio.Services.FeatureAvailability.WebApi; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Text; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Worker.CodeCoverage 11 | { 12 | public static class FeatureFlagUtility 13 | { 14 | public static bool GetFeatureFlagState(FeatureAvailabilityHttpClient featureAvailabilityHttpClient, string FFName, IAsyncCommandContext context) 15 | { 16 | ArgUtil.NotNull(context, nameof(context)); 17 | 18 | try 19 | { 20 | var featureFlag = featureAvailabilityHttpClient?.GetFeatureFlagByNameAsync(FFName).Result; 21 | if (featureFlag != null && featureFlag.EffectiveState.Equals("Off", StringComparison.OrdinalIgnoreCase)) 22 | { 23 | return false; 24 | } 25 | } 26 | catch 27 | { 28 | context.Debug(StringUtil.Format("Failed to get FF {0} Value. By default, publishing data to TCM.", FFName)); 29 | return true; 30 | } 31 | return true; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Agent.Worker/CodeCoverage/ICodeCoverageSummaryReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.TeamFoundation.TestManagement.WebApi; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Worker.CodeCoverage 8 | { 9 | public interface ICodeCoverageSummaryReader : IExtension 10 | { 11 | /// 12 | /// Get CodeCoverageStatistics from summary file 13 | /// 14 | /// coverage summary file 15 | /// 16 | IEnumerable GetCodeCoverageSummary(IExecutionContext context, string summaryFileLocation); 17 | 18 | /// 19 | /// Result reader name 20 | /// 21 | string Name { get; } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Container/DockerUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text.RegularExpressions; 7 | using Agent.Sdk; 8 | using Microsoft.VisualStudio.Services.Agent.Util; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Container 11 | { 12 | public class DockerUtil 13 | { 14 | public static List ParseDockerPort(IList portMappingLines) 15 | { 16 | ArgUtil.NotNull(portMappingLines, nameof(portMappingLines)); 17 | 18 | const string targetPort = "targetPort"; 19 | const string proto = "proto"; 20 | const string host = "host"; 21 | const string hostPort = "hostPort"; 22 | 23 | //"TARGET_PORT/PROTO -> HOST:HOST_PORT" 24 | string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$"; 25 | 26 | List portMappings = new List(); 27 | foreach (var line in portMappingLines) 28 | { 29 | Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1)); 30 | if (m.Success) 31 | { 32 | portMappings.Add(new PortMapping( 33 | m.Groups[hostPort].Value, 34 | m.Groups[targetPort].Value, 35 | m.Groups[proto].Value 36 | )); 37 | } 38 | } 39 | return portMappings; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Agent.Worker/Handlers/ProcessHandler/Exceptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Handlers 7 | { 8 | public class InvalidScriptArgsException : Exception 9 | { 10 | public InvalidScriptArgsException(string message) : base(message) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Agent.Worker/JobExtensionRunner.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading.Tasks; 6 | using Microsoft.TeamFoundation.DistributedTask.Expressions; 7 | using Pipelines = Microsoft.TeamFoundation.DistributedTask.Pipelines; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Worker 10 | { 11 | public sealed class JobExtensionRunner : IStep 12 | { 13 | private readonly object _data; 14 | private readonly Func _runAsync; 15 | 16 | public JobExtensionRunner( 17 | Func runAsync, 18 | IExpressionNode condition, 19 | string displayName, 20 | object data) 21 | { 22 | _runAsync = runAsync; 23 | Condition = condition; 24 | DisplayName = displayName; 25 | _data = data; 26 | } 27 | 28 | public IExpressionNode Condition { get; set; } 29 | public bool ContinueOnError => false; 30 | public string DisplayName { get; private set; } 31 | public bool Enabled => true; 32 | public IExecutionContext ExecutionContext { get; set; } 33 | public TimeSpan? Timeout => null; 34 | public Pipelines.StepTarget Target => null; 35 | 36 | public async Task RunAsync() 37 | { 38 | await _runAsync(ExecutionContext, _data); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Agent.Worker/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/AgentUtilities.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using Microsoft.VisualStudio.Services.Agent.Util; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release 11 | { 12 | public static class AgentUtilities 13 | { 14 | // Move this to Agent.Common.Util 15 | public static string GetPrintableEnvironmentVariables(IEnumerable variables) 16 | { 17 | StringBuilder builder = new StringBuilder(); 18 | 19 | if (variables != null) 20 | { 21 | var sortedVariables = variables.OrderBy(x => x.Name, StringComparer.OrdinalIgnoreCase); 22 | foreach (var variable in sortedVariables) 23 | { 24 | string varName = VarUtil.ConvertToEnvVariableFormat(variable.Name, variable.PreserveCase); 25 | builder.AppendFormat( 26 | "{0}\t\t\t\t[{1}] --> [{2}]", 27 | Environment.NewLine, 28 | varName, 29 | variable.Value); 30 | } 31 | } 32 | 33 | return builder.ToString(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/ArtifactDirectoryCreationFailedException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // 9 | // Defines the ArtifactDirectoryCreationFailedException type. 10 | // 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | using System; 14 | 15 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts 16 | { 17 | public class ArtifactDirectoryCreationFailedException : Exception 18 | { 19 | public ArtifactDirectoryCreationFailedException() 20 | { 21 | } 22 | 23 | public ArtifactDirectoryCreationFailedException(string message) : base(message) 24 | { 25 | } 26 | 27 | public ArtifactDirectoryCreationFailedException(string message, Exception innerException) : base(message, innerException) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/ArtifactDownloadException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // 9 | // Defines the ArtifactDownloadException type. 10 | // 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | using System; 14 | 15 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts 16 | { 17 | public class ArtifactDownloadException : Exception 18 | { 19 | public ArtifactDownloadException() 20 | { 21 | } 22 | 23 | public ArtifactDownloadException(string message) : base(message) 24 | { 25 | } 26 | 27 | public ArtifactDownloadException(string message, Exception innerException) : base(message, innerException) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/CommitsDownloadException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts 7 | { 8 | 9 | public class CommitsDownloadException : Exception 10 | { 11 | public CommitsDownloadException() 12 | { 13 | } 14 | 15 | public CommitsDownloadException(string message) : base(message) 16 | { 17 | } 18 | 19 | public CommitsDownloadException(string message, Exception innerException) : base(message, innerException) 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/ArtifactDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // 9 | // Defines the ArtifactDefinition type. 10 | // 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts; 14 | 15 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 16 | { 17 | public class ArtifactDefinition 18 | { 19 | public string Name { get; set; } 20 | 21 | public string Version { get; set; } 22 | 23 | public AgentArtifactType ArtifactType { get; set; } 24 | 25 | public IArtifactDetails Details { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/BuildArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // 9 | // Defines the BuildArtifactDetails type. 10 | // 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | using System; 14 | 15 | using Microsoft.VisualStudio.Services.Common; 16 | 17 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 18 | { 19 | public class BuildArtifactDetails : IArtifactDetails 20 | { 21 | public string RelativePath { get; set; } 22 | 23 | public Uri TfsUrl { get; set; } 24 | 25 | public VssCredentials Credentials { get; set; } 26 | 27 | public string Project { get; set; } 28 | 29 | public string AccessToken { get; set; } 30 | 31 | public int DefintionId { get; set; } 32 | 33 | public string DefinitionName { get; set; } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/CustomArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | 6 | using Microsoft.TeamFoundation.DistributedTask.WebApi; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 9 | { 10 | public class CustomArtifactDetails : IArtifactDetails 11 | { 12 | public string ArtifactsUrl { get; set; } 13 | 14 | public string ResultSelector { get; set; } 15 | 16 | public string ResultTemplate { get; set; } 17 | 18 | public ServiceEndpoint Endpoint { get; set; } 19 | 20 | public string RelativePath { get; set; } 21 | 22 | public Dictionary ArtifactVariables { get; set; } 23 | 24 | public List AuthorizationHeaders { get; set; } 25 | 26 | public IDictionary ArtifactTypeStreamMapping { get; set; } 27 | 28 | public string VersionsUrl { get; set; } 29 | 30 | public string VersionsResultSelector { get; set; } 31 | 32 | public string VersionsResultTemplate { get; set; } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/CustomArtifactDownloadDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 5 | { 6 | public class CustomArtifactDownloadDetails 7 | { 8 | public string Name { get; set; } 9 | 10 | public string DownloadUrl { get; set; } 11 | 12 | public string FileShareLocation { get; set; } 13 | 14 | public string StreamType { get; set; } 15 | 16 | public string RelativePath { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/CustomArtifactVersionDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 5 | { 6 | public class CustomArtifactVersionDetails 7 | { 8 | public string DisplayName { get; set; } 9 | 10 | public string Value { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/GitHubArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 7 | { 8 | public class GitHubArtifactDetails : IArtifactDetails 9 | { 10 | public string RelativePath { get; set; } 11 | 12 | public Uri CloneUrl { get; set; } 13 | 14 | public string Branch { get; set; } 15 | 16 | public string ConnectionName { get; set; } 17 | 18 | public string CheckoutNestedSubmodules { get; set; } 19 | 20 | public string CheckoutSubmodules { get; set; } 21 | 22 | public string GitLfsSupport { get; set; } 23 | 24 | public string FetchDepth { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/IArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // 9 | // Defines the IArtifactDetails type. 10 | // 11 | // -------------------------------------------------------------------------------------------------------------------- 12 | 13 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 14 | { 15 | public interface IArtifactDetails 16 | { 17 | // TODO: We may not need this, server may return / always, check and remove it 18 | string RelativePath { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/JenkinsArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | // -------------------------------------------------------------------------------------------------------------------- 5 | // 6 | // 2012-2023, All rights reserved. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | using System; 11 | 12 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 13 | { 14 | public class JenkinsArtifactDetails : IArtifactDetails 15 | { 16 | public string RelativePath { get; set; } 17 | 18 | public Uri Url { get; set; } 19 | 20 | public string AccountName { get; set; } 21 | 22 | public string AccountPassword { get; set; } 23 | 24 | public string JobName { get; set; } 25 | 26 | public int BuildId { get; set; } 27 | 28 | public bool AcceptUntrustedCertificates { get; set; } 29 | 30 | public string StartCommitArtifactVersion { get; set; } 31 | 32 | public string EndCommitArtifactVersion { get; set; } 33 | 34 | public string Alias { get; set; } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/TfsGitArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 5 | { 6 | public class TfsGitArtifactDetails : IArtifactDetails 7 | { 8 | public string RelativePath { get; set; } 9 | 10 | public string ProjectId { get; set; } 11 | 12 | public string RepositoryId { get; set; } 13 | 14 | public string Branch { get; set; } 15 | 16 | public string CheckoutNestedSubmodules { get; set; } 17 | 18 | public string CheckoutSubmodules { get; set; } 19 | 20 | public string GitLfsSupport { get; set; } 21 | 22 | public string FetchDepth { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/TfsVCArtifactDetails.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 5 | { 6 | public class TfsVCArtifactDetails : IArtifactDetails 7 | { 8 | public string RelativePath { get; set; } 9 | 10 | public string ProjectId { get; set; } 11 | 12 | public string RepositoryId { get; set; } 13 | 14 | public string Mappings { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/Artifacts/Definition/WellKnownStreamTypes.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition 5 | { 6 | public static class WellKnownStreamTypes 7 | { 8 | public static readonly string Zip = "Zip"; 9 | public static readonly string FileShare = "FileShare"; 10 | } 11 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/ContainerFetchEngine.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 9 | { 10 | public class ContainerFetchEngine : FetchEngine 11 | { 12 | public ContainerFetchEngine( 13 | IContainerProvider containerProvider, 14 | string rootItemPath, 15 | string rootDestinationDir) 16 | : base(containerProvider, rootItemPath, rootDestinationDir) 17 | { 18 | } 19 | 20 | public async Task FetchAsync(CancellationToken cancellationToken) 21 | { 22 | IEnumerable containerItems = await Provider.GetItemsAsync().ConfigureAwait(false); 23 | 24 | await FetchItemsAsync(containerItems, cancellationToken).ConfigureAwait(false); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/ContainerFetchEngineDefaultOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 7 | { 8 | public static class ContainerFetchEngineDefaultOptions 9 | { 10 | public static readonly TimeSpan RetryInterval = TimeSpan.FromSeconds(5); 11 | public const int ParallelDownloadLimit = 4; 12 | public const int RetryLimit = 5; 13 | public const int DownloadBufferSize = 8192; 14 | } 15 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/ContainerFetchEngineOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 8 | { 9 | public class ContainerFetchEngineOptions 10 | { 11 | public int RetryLimit { get; set; } 12 | public TimeSpan RetryInterval { get; set; } 13 | public TimeSpan GetFileAsyncTimeout { get; set; } 14 | public int ParallelDownloadLimit { get; set; } 15 | public int DownloadBufferSize { get; set; } 16 | 17 | public ContainerFetchEngineOptions() 18 | { 19 | RetryLimit = ContainerFetchEngineDefaultOptions.RetryLimit; 20 | ParallelDownloadLimit = ContainerFetchEngineDefaultOptions.ParallelDownloadLimit; 21 | RetryInterval = ContainerFetchEngineDefaultOptions.RetryInterval; 22 | DownloadBufferSize = ContainerFetchEngineDefaultOptions.DownloadBufferSize; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/ContainerItem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 7 | { 8 | public class ContainerItem 9 | { 10 | public ItemType ItemType { get; set; } 11 | public string Path { get; set; } 12 | public long FileLength { get; set; } 13 | 14 | // TODO(omeshp): Figure a way to remove these dependencies with server drop artifact 15 | public long ContainerId { get; set; } 16 | public Guid ScopeIdentifier { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/IConatinerFetchEngineLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 5 | { 6 | [ServiceLocator(Default = typeof(NullExecutionLogger))] 7 | // NOTE: FetchEngine specific interface shouldn't take dependency on Agent code. 8 | public interface IConatinerFetchEngineLogger 9 | { 10 | void Warning(string message); 11 | void Output(string message); 12 | void Debug(string message); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/IContainerProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 10 | { 11 | // NOTE: FetchEngine specific interface shouldn't take dependency on Agent code. 12 | public interface IContainerProvider 13 | { 14 | Task> GetItemsAsync(); 15 | Task GetFileTask(ContainerItem ticketedItem, CancellationToken token); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/ItemType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 5 | { 6 | public enum ItemType 7 | { 8 | Any, 9 | Folder, 10 | File 11 | } 12 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerFetchEngine/NullExecutionLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine 5 | { 6 | public class NullExecutionLogger : IConatinerFetchEngineLogger 7 | { 8 | public void Warning(string message) 9 | { 10 | } 11 | 12 | public void Output(string message) 13 | { 14 | } 15 | 16 | public void Debug(string message) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerProvider/Helpers/AsyncLazy.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerProvider.Helpers 9 | { 10 | // http://blogs.msdn.com/b/pfxteam/archive/2011/01/15/10116210.aspx 11 | public class AsyncLazy : Lazy> 12 | { 13 | public AsyncLazy(Func valueFactory) : 14 | base(() => Task.Factory.StartNew(valueFactory)) 15 | { } 16 | 17 | public AsyncLazy(Func> taskFactory) : 18 | base(() => Task.Factory.StartNew(() => taskFactory()).Unwrap()) 19 | { } 20 | 21 | public TaskAwaiter GetAwaiter() { return Value.GetAwaiter(); } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Agent.Worker/Release/ContainerProvider/Helpers/ExecutionLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerFetchEngine; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release.ContainerProvider.Helpers 7 | { 8 | public class ExecutionLogger : IConatinerFetchEngineLogger 9 | { 10 | private readonly IExecutionContext _executionContext; 11 | 12 | public ExecutionLogger(IExecutionContext executionContext) 13 | { 14 | this._executionContext = executionContext; 15 | } 16 | 17 | public void Warning(string message) 18 | { 19 | this._executionContext.Warning(message); 20 | } 21 | 22 | public void Output(string message) 23 | { 24 | this._executionContext.Output(message); 25 | } 26 | 27 | public void Debug(string message) 28 | { 29 | this._executionContext.Debug(message); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/DeploymentJobExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release 5 | { 6 | public sealed class DeploymentJobExtension : ReleaseJobExtension 7 | { 8 | public override HostTypes HostType => HostTypes.Deployment; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/IArtifactExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | 6 | using Microsoft.VisualStudio.Services.Agent.Worker.Release.Artifacts.Definition; 7 | using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release 10 | { 11 | public interface IArtifactExtension : IExtension 12 | { 13 | AgentArtifactType ArtifactType { get; } 14 | 15 | Task DownloadAsync(IExecutionContext executionContext, ArtifactDefinition artifactDefinition, string downloadFolderPath); 16 | 17 | IArtifactDetails GetArtifactDetails(IExecutionContext context, AgentArtifactDefinition agentArtifactDefinition); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Release/IReleaseDirectoryManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Release 5 | { 6 | [ServiceLocator(Default = typeof(ReleaseDirectoryManager))] 7 | public interface IReleaseDirectoryManager : IAgentService 8 | { 9 | ReleaseTrackingConfig PrepareArtifactsDirectory( 10 | string workingDirectory, 11 | string collectionId, 12 | string projectId, 13 | string releaseDefinition); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Agent.Worker/Telemetry/CustomerIntelligenceServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | using Microsoft.VisualStudio.Services.CustomerIntelligence.WebApi; 6 | using Microsoft.VisualStudio.Services.WebApi; 7 | using Microsoft.VisualStudio.Services.WebPlatform; 8 | using Microsoft.VisualStudio.Services.Common; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Net.Http; 12 | using System.Threading; 13 | using System.Threading.Tasks; 14 | 15 | namespace Microsoft.VisualStudio.Services.Agent.Worker.Telemetry 16 | { 17 | [ServiceLocator(Default = typeof(CustomerIntelligenceServer))] 18 | public interface ICustomerIntelligenceServer : IAgentService 19 | { 20 | void Initialize(VssConnection connection); 21 | Task PublishEventsAsync(CustomerIntelligenceEvent[] ciEvents); 22 | } 23 | 24 | // This service is used for tracking task events which are applicable for VSTS internal tasks 25 | public class CustomerIntelligenceServer : AgentService, ICustomerIntelligenceServer 26 | { 27 | private CustomerIntelligenceHttpClient _ciClient; 28 | 29 | public void Initialize(VssConnection connection) 30 | { 31 | ArgUtil.NotNull(connection, nameof(connection)); 32 | _ciClient = connection.GetClient(); 33 | } 34 | 35 | public Task PublishEventsAsync(CustomerIntelligenceEvent[] ciEvents) 36 | { 37 | return _ciClient.PublishEventsAsync(events: ciEvents); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/CommandTraceListener.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.TestResults 7 | { 8 | class CommandTraceListener : TraceListener 9 | { 10 | private readonly IExecutionContext _context; 11 | 12 | public CommandTraceListener(IExecutionContext executionContext) 13 | { 14 | _context = executionContext; 15 | } 16 | 17 | public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) 18 | { 19 | switch (eventType) 20 | { 21 | case TraceEventType.Warning: 22 | _context.Warning(message); 23 | break; 24 | case TraceEventType.Information: 25 | _context.Output(message); 26 | break; 27 | case TraceEventType.Error: 28 | _context.Error(message); 29 | break; 30 | default: 31 | _context.Debug(message); 32 | break; 33 | } 34 | } 35 | 36 | public override void Write(string message) 37 | { 38 | _context.Debug(message); 39 | } 40 | 41 | public override void WriteLine(string message) 42 | { 43 | _context.Debug(message); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/Legacy/AttachmentData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Worker.LegacyTestResults 8 | { 9 | /// 10 | /// This class is used to contain attachments list for the test run and the attachments for sub results. 11 | /// 12 | public class AttachmentData 13 | { 14 | /// 15 | /// List of Filepaths of attachments associated with the TestRun. 16 | /// 17 | public IList AttachmentsFilePathList { get; set; } 18 | 19 | /// 20 | /// Console log of the Test Run. 21 | /// 22 | public string ConsoleLog { get; set; } 23 | 24 | /// 25 | /// Standard Error of the Test Run. 26 | /// 27 | public string StandardError { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/Legacy/IConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Worker.LegacyTestResults 5 | { 6 | public interface IConverter 7 | { 8 | void Convert(TResultData resultData, TResultWebApi webApiData); 9 | } 10 | } -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/Legacy/IResultReader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using TestRunContext = Microsoft.TeamFoundation.TestClient.PublishTestResults.TestRunContext; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Worker.LegacyTestResults 7 | { 8 | public interface IResultReader : IExtension 9 | { 10 | /// 11 | /// Reads a test results file from disk, converts it into a TestCaseResultData array 12 | /// 13 | /// File path 14 | /// TestCaseResultData Array 15 | TestRunData ReadResults(IExecutionContext executionContext, string filePath, TestRunContext runContext); 16 | 17 | /// 18 | /// Should the run level attachments be uploaded 19 | /// 20 | bool AddResultsFileToRunLevelAttachments { get; set; } 21 | 22 | /// 23 | /// Result reader name 24 | /// 25 | string Name { get; } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/Legacy/TestCaseSubResultData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Microsoft.TeamFoundation.TestManagement.WebApi; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Worker.LegacyTestResults 9 | { 10 | public class TestCaseSubResultData 11 | { 12 | public int Id; 13 | 14 | public TestCaseResultIdentifier TestResult { get; set; } 15 | 16 | public int ParentId; 17 | 18 | public int SequenceId; 19 | 20 | public string DisplayName; 21 | 22 | public ResultGroupType ResultGroupType; 23 | 24 | public string Outcome; 25 | 26 | public string Comment; 27 | 28 | public string ErrorMessage; 29 | 30 | public DateTime StartedDate; 31 | 32 | public DateTime CompletedDate; 33 | 34 | public long DurationInMs; 35 | 36 | public ShallowReference Configuration; 37 | 38 | public DateTime LastUpdatedDate; 39 | 40 | public string ComputerName; 41 | 42 | public string StackTrace; 43 | 44 | public List CustomFields; 45 | 46 | public string Url; 47 | 48 | public List SubResultData { get; set; } 49 | 50 | public AttachmentData AttachmentData { get; set; } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Agent.Worker/TestResults/Legacy/TestRunContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/AgentService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Microsoft.VisualStudio.Services.Agent.Util; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent 8 | { 9 | 10 | [AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] 11 | public sealed class ServiceLocatorAttribute : Attribute 12 | { 13 | public Type Default { get; set; } 14 | public Type PreferredOnWindows { get; set; } 15 | public Type PreferredOnMacOS { get; set; } 16 | public Type PreferredOnLinux { get; set; } 17 | } 18 | 19 | public interface IAgentService 20 | { 21 | void Initialize(IHostContext context); 22 | } 23 | 24 | public abstract class AgentService 25 | { 26 | protected IHostContext HostContext { get; private set; } 27 | protected Tracing Trace { get; private set; } 28 | 29 | public string TraceName 30 | { 31 | get 32 | { 33 | return GetType().Name; 34 | } 35 | } 36 | 37 | public virtual void Initialize(IHostContext hostContext) 38 | { 39 | ArgUtil.NotNull(hostContext, nameof(hostContext)); 40 | 41 | HostContext = hostContext; 42 | Trace = HostContext.GetTrace(TraceName); 43 | Trace.Entering(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/AsyncManualResetEvent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent 8 | { 9 | //Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2012/02/11/10266920.aspx 10 | 11 | public class AsyncManualResetEvent 12 | { 13 | private volatile TaskCompletionSource m_tcs = new TaskCompletionSource(); 14 | 15 | public Task WaitAsync() { return m_tcs.Task; } 16 | 17 | public void Set() 18 | { 19 | var tcs = m_tcs; 20 | Task.Factory.StartNew(s => ((TaskCompletionSource)s).TrySetResult(true), 21 | tcs, CancellationToken.None, TaskCreationOptions.PreferFairness, TaskScheduler.Default); 22 | tcs.Task.Wait(); 23 | } 24 | 25 | public void Reset() 26 | { 27 | while (true) 28 | { 29 | var tcs = m_tcs; 30 | if (!tcs.Task.IsCompleted || 31 | Interlocked.CompareExchange(ref m_tcs, new TaskCompletionSource(), tcs) == tcs) 32 | return; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Blob/BlobFileInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using BuildXL.Cache.ContentStore.Hashing; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Blob 7 | { 8 | public class BlobFileInfo 9 | { 10 | public DedupNode Node { get; set; } 11 | public string Path { get; set; } 12 | public DedupIdentifier DedupId 13 | { 14 | get 15 | { 16 | return Node.GetDedupIdentifier(); 17 | } 18 | } 19 | public bool Success { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Blob/BuildArtifactActionRecord.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Agent.Sdk.Knob; 6 | using Microsoft.VisualStudio.Services.Content.Common.Telemetry; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Blob 9 | { 10 | /// 11 | /// Telemetry record for use with Build Artifact events. 12 | /// 13 | public class BuildArtifactActionRecord : PipelineTelemetryRecord 14 | { 15 | public BuildArtifactActionRecord( 16 | TelemetryInformationLevel level, 17 | Uri baseAddress, 18 | string eventNamePrefix, 19 | string eventNameSuffix, 20 | IKnobValueContext context, 21 | uint attemptNumber = 1) 22 | : base(level, baseAddress, eventNamePrefix, eventNameSuffix, context, attemptNumber) 23 | { 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Blob/IDedupRecord.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.BlobStore.Common.Telemetry; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent.Blob 7 | { 8 | public interface IDedupRecord 9 | { 10 | DedupUploadStatistics UploadStatistics { get; } 11 | 12 | DedupDownloadStatistics DownloadStatistics { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Blob/TimelineRecordAttachmentTelemetryRecord.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Agent.Sdk.Knob; 6 | using Microsoft.VisualStudio.Services.Content.Common.Telemetry; 7 | using Microsoft.VisualStudio.Services.BlobStore.Common.Telemetry; 8 | using Microsoft.TeamFoundation.DistributedTask.WebApi; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Blob 11 | { 12 | /// 13 | /// Generic telemetry record for use with timeline record events. 14 | /// 15 | public class TimelineRecordAttachmentTelemetryRecord : PipelineTelemetryRecord 16 | { 17 | public TimelineRecordAttachmentTelemetryRecord( 18 | TelemetryInformationLevel level, 19 | Uri baseAddress, 20 | string eventNamePrefix, 21 | string eventNameSuffix, 22 | Guid planId, 23 | Guid jobId, 24 | Guid taskInstanceId, 25 | uint attemptNumber = 1) 26 | : base(level, baseAddress, eventNamePrefix, eventNameSuffix, planId, jobId, taskInstanceId, attemptNumber) 27 | { 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/CredentialData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent 8 | { 9 | public sealed class CredentialData 10 | { 11 | public string Scheme { get; set; } 12 | 13 | public Dictionary Data 14 | { 15 | get 16 | { 17 | if (_data == null) 18 | { 19 | _data = new Dictionary(StringComparer.OrdinalIgnoreCase); 20 | } 21 | return _data; 22 | } 23 | } 24 | 25 | private Dictionary _data; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Exceptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent 7 | { 8 | public class NonRetryableException : Exception 9 | { 10 | public NonRetryableException() 11 | : base() 12 | { } 13 | 14 | public NonRetryableException(string message) 15 | : base(message) 16 | { } 17 | 18 | public NonRetryableException(string message, Exception inner) 19 | : base(message, inner) 20 | { } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Extensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent 9 | { 10 | //this code is documented on http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx 11 | public static class Extensions 12 | { 13 | public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) 14 | { 15 | var tcs = new TaskCompletionSource(); 16 | using (cancellationToken.Register( 17 | s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) 18 | if (task != await Task.WhenAny(task, tcs.Task)) 19 | throw new OperationCanceledException(cancellationToken); 20 | return await task; 21 | } 22 | 23 | public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) 24 | { 25 | var tcs = new TaskCompletionSource(); 26 | using (cancellationToken.Register( 27 | s => ((TaskCompletionSource)s).TrySetResult(true), tcs)) 28 | if (task != await Task.WhenAny(task, tcs.Task)) 29 | throw new OperationCanceledException(cancellationToken); 30 | await task; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/IAgentCredentialStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Net; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent 7 | { 8 | // Store and retrieve user's credential for agent configuration. 9 | [ServiceLocator( 10 | PreferredOnWindows = typeof(WindowsAgentCredentialStore), 11 | PreferredOnMacOS = typeof(MacOSAgentCredentialStore), 12 | PreferredOnLinux = typeof(LinuxAgentCredentialStore), 13 | Default = typeof(NoOpAgentCredentialStore) 14 | )] 15 | public interface IAgentCredentialStore : IAgentService 16 | { 17 | NetworkCredential Write(string target, string username, string password); 18 | 19 | // throw exception when target not found from cred store 20 | NetworkCredential Read(string target); 21 | 22 | // throw exception when target not found from cred store 23 | void Delete(string target); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/IExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | 6 | namespace Microsoft.VisualStudio.Services.Agent 7 | { 8 | public interface IExtension : IAgentService 9 | { 10 | Type ExtensionType { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Microsoft.VisualStudio.Services.Agent.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Library 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Util/EnumUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.VisualStudio.Services.Agent.Util 5 | { 6 | using System; 7 | 8 | public static class EnumUtil 9 | { 10 | public static T? TryParse(string value) where T : struct 11 | { 12 | T val; 13 | if (Enum.TryParse(value ?? string.Empty, ignoreCase: true, result: out val)) 14 | { 15 | return val; 16 | } 17 | 18 | return null; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Microsoft.VisualStudio.Services.Agent/Util/PlanUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Globalization; 7 | using System.Net.Http; 8 | using Microsoft.TeamFoundation.DistributedTask.WebApi; 9 | using Microsoft.VisualStudio.Services.Common; 10 | using Microsoft.VisualStudio.Services.WebApi; 11 | using System.Net.Http.Headers; 12 | using System.Runtime.InteropServices; 13 | 14 | namespace Microsoft.VisualStudio.Services.Agent.Util 15 | { 16 | public static class PlanUtil 17 | { 18 | public static PlanFeatures GetFeatures(TaskOrchestrationPlanReference plan) 19 | { 20 | ArgUtil.NotNull(plan, nameof(plan)); 21 | PlanFeatures features = PlanFeatures.None; 22 | if (plan.Version >= 8) 23 | { 24 | features |= PlanFeatures.JobCompletedPlanEvent; 25 | } 26 | 27 | return features; 28 | } 29 | } 30 | 31 | [Flags] 32 | public enum PlanFeatures 33 | { 34 | None = 0, 35 | JobCompletedPlanEvent = 1, 36 | } 37 | } -------------------------------------------------------------------------------- /src/Misc/BuildConstants.ch: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // DO NOT CHECKIN THE GENERATED .cs version of this file 4 | // 5 | /////////////////////////////////////////////////////////////////////////////////////////////////// 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent 8 | { 9 | public static class BuildConstants 10 | { 11 | public static class Source 12 | { 13 | public static readonly string CommitHash = "_COMMIT_HASH_"; 14 | } 15 | 16 | public static class AgentPackage 17 | { 18 | public static readonly string PackageName = "_PACKAGE_NAME_"; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Misc/check-symlinks.sh: -------------------------------------------------------------------------------- 1 | cd $(dirname $0)/../../_layout 2 | brokenSymlinks=$(find . -type l ! -exec test -e {} \; -print) 3 | if [[ $brokenSymlinks != "" ]]; then 4 | printf "Broken symlinks exist in the agent build:\n$brokenSymlinks\n" 5 | exit 1 6 | fi 7 | echo "Broken symlinks not found in the agent build." 8 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-AntCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | Add-CapabilityFromEnvironment -Name 'ant' -VariableName 'ANT_HOME' 5 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-ApplicationCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | Add-CapabilityFromApplication -Name 'npm' -ApplicationName 'npm' 5 | Add-CapabilityFromApplication -Name 'gulp' -ApplicationName 'gulp' 6 | Add-CapabilityFromApplication -Name 'node.js' -ApplicationName 'node' 7 | Add-CapabilityFromApplication -Name 'bower' -ApplicationName 'bower' 8 | Add-CapabilityFromApplication -Name 'grunt' -ApplicationName 'grunt' 9 | Add-CapabilityFromApplication -Name 'svn' -ApplicationName 'svn' 10 | Add-CapabilityFromApplication -Name 'cmake' -ApplicationName 'cmake' 11 | Add-CapabilityFromApplication -Name 'docker' -ApplicationName 'docker' 12 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-AzureGuestAgentCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | @(Get-Process -Name 'WindowsAzureGuestAgent' -ErrorAction Ignore) | Select-Object -First 1 | ForEach-Object { Write-Capability -Name 'AzureGuestAgent' -Value $_.Path } -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-Capabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | Import-Module -Name 'Microsoft.PowerShell.Management' 5 | Import-Module -Name 'Microsoft.PowerShell.Utility' 6 | $ErrorActionPreference = 'Stop' 7 | Import-Module -Name $PSScriptRoot\CapabilityHelpers 8 | 9 | # Run each capability script. 10 | foreach ($item in (Get-ChildItem -LiteralPath "$PSScriptRoot" -Filter "Add-*Capabilities.ps1")) { 11 | if ($item.Name -eq ([System.IO.Path]::GetFileName($PSCommandPath))) { 12 | continue; 13 | } 14 | 15 | Write-Host "& $($item.FullName)" 16 | try { 17 | & $item.FullName 18 | } catch { 19 | Write-Host ($_ | Out-String) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-MavenCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | Write-Host "Checking: env:JAVA_HOME" 5 | if (!$env:JAVA_HOME) { 6 | Write-Host "Value not found or empty." 7 | return 8 | } 9 | 10 | if($env:M2_HOME) { 11 | Add-CapabilityFromEnvironment -Name 'maven' -VariableName 'M2_HOME' 12 | } else { 13 | Write-Host "M2_HOME not set. Checking in PATH" 14 | Add-CapabilityFromApplication -Name 'maven' -ApplicationName 'mvn' 15 | } -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-PowerShellCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | Write-Capability -Name 'PowerShell' -Value $PSVersionTable.PSVersion 5 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-ScvmmAdminConsoleCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | foreach ($view in @('Registry64', 'Registry32')) { 5 | if ((Add-CapabilityFromRegistry -Name 'SCVMMAdminConsole' -Hive 'LocalMachine' -View $view -KeyName 'Software\Microsoft\Microsoft System Center Virtual Machine Manager Administrator Console\Setup' -ValueName 'InstallPath')) { 6 | break 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-WindowsKitCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | $rootsKeyName = 'Software\Microsoft\Windows Kits\Installed Roots' 5 | $valueNames = Get-RegistryValueNames -Hive 'LocalMachine' -View 'Registry32' -KeyName $rootsKeyName 6 | $versionInfos = @( ) 7 | foreach ($valueName in $valueNames) { 8 | if (!"$valueName".StartsWith('KitsRoot', 'OrdinalIgnoreCase')) { 9 | continue 10 | } 11 | 12 | $installDirectory = Get-RegistryValue -Hive 'LocalMachine' -View 'Registry32' -KeyName $rootsKeyName -ValueName $valueName 13 | $splitInstallDirectory = 14 | "$installDirectory".Split(@( ([System.IO.Path]::DirectorySeparatorChar) ) ) | 15 | ForEach-Object { "$_".Trim() } | 16 | Where-Object { $_ } 17 | $splitInstallDirectory = @( $splitInstallDirectory ) 18 | if ($splitInstallDirectory.Length -eq 0) { 19 | continue 20 | } 21 | 22 | $version = $null 23 | if (!([System.Version]::TryParse($splitInstallDirectory[-1], [ref]$version))) { 24 | continue 25 | } 26 | 27 | Write-Capability -Name "WindowsKit_$($version.Major).$($version.Minor)" -Value $installDirectory 28 | $versionInfos += @{ 29 | Version = $version 30 | InstallDirectory = $installDirectory 31 | } 32 | } 33 | 34 | if ($versionInfos.Length) { 35 | $maxInfo = 36 | $versionInfos | 37 | Sort-Object -Descending -Property Version | 38 | Select-Object -First 1 39 | Write-Capability -Name "WindowsKit" -Value $maxInfo.InstallDirectory 40 | } 41 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/Add-XamarinAndroidCapabilities.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | if (!(Add-CapabilityFromRegistry -Name 'Xamarin.Android' -Hive 'LocalMachine' -View 'Registry32' -KeyName 'Software\Novell\Mono for Android' -ValueName 'InstalledVersion')) { 5 | foreach ($vsver in @(17, 16, 15)) { 6 | $vs = Get-VisualStudio -MajorVersion $vsver 7 | if ($vs -and $vs.installationPath) { 8 | # End with "\" for consistency with old ShellFolder values. 9 | $shellFolder = $vs.installationPath.TrimEnd('\'[0]) + "\" 10 | $xamarinAndroidDir = ([System.IO.Path]::Combine($shellFolder, 'MSBuild', 'Xamarin', 'Android')) + '\' 11 | if ((Test-Container -LiteralPath $xamarinAndroidDir)) { 12 | # Xamarin.Android 7 has a Version file, and this file is renamed to Version.txt in Xamarin.Android 8.x 13 | $found = $false 14 | foreach ($file in @('Version', 'Version.txt')) { 15 | $versionFile = ([System.IO.Path]::Combine($xamarinAndroidDir, $file)) 16 | $version = Get-Content -ErrorAction ignore -TotalCount 1 -LiteralPath $versionFile 17 | if ($version) { 18 | Write-Capability -Name 'Xamarin.Android' -Value $version.trim() 19 | $found = $true 20 | break 21 | } 22 | } 23 | if ($found) { 24 | break 25 | } 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/CapabilityHelpers/CapabilityHelpers.psm1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | $ErrorActionPreference = 'Stop' 5 | 6 | # Import the helper functions. 7 | . $PSScriptRoot\CapabilityFunctions 8 | . $PSScriptRoot\PathFunctions 9 | . $PSScriptRoot\RegistryFunctions 10 | . $PSScriptRoot\VisualStudioFunctions 11 | . $PSScriptRoot\VersionFunctions 12 | 13 | # Export the public functions. 14 | Export-ModuleMember -Function @( 15 | # Capability functions. 16 | 'Add-CapabilityFromApplication' 17 | 'Add-CapabilityFromEnvironment' 18 | 'Add-CapabilityFromRegistry' 19 | 'Add-CapabilityFromRegistryWithLastVersionAvailable' 20 | 'Write-Capability' 21 | # File system functions with tracing built-in. 22 | 'Test-Container' 23 | 'Test-Leaf' 24 | # Registry functions. 25 | 'Get-RegistrySubKeyNames' 26 | 'Get-RegistryValue' 27 | 'Get-RegistryValueNames' 28 | # Visual Studio functions. 29 | 'Get-VisualStudio' 30 | ) 31 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/CapabilityHelpers/PathFunctions.ps1: -------------------------------------------------------------------------------- 1 | function Test-Container { 2 | [CmdletBinding()] 3 | param( 4 | [Parameter(Mandatory = $true)] 5 | [string]$LiteralPath) 6 | 7 | Write-Host "Testing container: '$LiteralPath'" 8 | if ((Test-Path -LiteralPath $LiteralPath -PathType Container)) { 9 | Write-Host 'Exists.' 10 | return $true 11 | } 12 | 13 | Write-Host 'Does not exist.' 14 | return $false 15 | } 16 | 17 | function Test-Leaf { 18 | [CmdletBinding()] 19 | param( 20 | [Parameter(Mandatory = $true)] 21 | [string]$LiteralPath) 22 | 23 | Write-Host "Testing leaf: '$LiteralPath'" 24 | if ((Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { 25 | Write-Host 'Exists.' 26 | return $true 27 | } 28 | 29 | Write-Host 'Does not exist.' 30 | return $false 31 | } 32 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/powershell/CapabilityHelpers/VersionFunctions.ps1: -------------------------------------------------------------------------------- 1 | function Parse-Version { 2 | <# 3 | .SYNOPSIS 4 | Parses version from provided. Allows incomplete versions like 16.0. Returns empty string if there is more than 4 numbers divided by dot or string is not in semver format 5 | 6 | .EXAMPLE 7 | Parse-Version -Version "1.3.5" 8 | 9 | #> 10 | [CmdletBinding()] 11 | param( 12 | [Parameter(Mandatory = $true)] 13 | [string]$Version) 14 | 15 | if ($Version.IndexOf(".") -lt 0) { 16 | return [System.Version]::Parse("$($Version).0") 17 | } 18 | try { 19 | $res = [System.Version]::Parse($Version) 20 | 21 | return $res 22 | } catch { 23 | return "" 24 | } 25 | } -------------------------------------------------------------------------------- /src/Misc/layoutbin/runsvc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # convert SIGTERM signal to SIGINT 4 | # for more info on how to propagate SIGTERM to a child process see: http://veithen.github.io/2014/11/16/sigterm-propagation.html 5 | trap 'kill -INT $PID' TERM INT 6 | 7 | if [ -f ".path" ]; then 8 | # configure 9 | export PATH=`cat .path` 10 | echo ".path=${PATH}" 11 | fi 12 | 13 | # insert anything to setup env when running as a service 14 | 15 | # fallback on Node16 if Node20 is not supported by the host 16 | ./externals/node20_1/bin/node --version 17 | if [ $? == 0 ]; then 18 | NODE_VER="node20_1" 19 | else 20 | NODE_VER="node16" 21 | fi 22 | 23 | # run the host process which keep the listener alive 24 | ./externals/"$NODE_VER"/bin/node ./bin/AgentService.js & 25 | PID=$! 26 | wait $PID 27 | trap - TERM INT 28 | wait $PID 29 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/tasks-exception-list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "769D88CB-515B-4456-A045-D9A4E11C90E3", 3 | "B832BEC5-8C27-4FEF-9FB8-6BEC8524AD8A", 4 | "B832BEC5-8C27-4FEF-9FB8-6BEC8524AD8A", 5 | "B832BEC5-8C27-4FEF-9FB8-6BEC8524AD8A", 6 | "AD5CD22A-BE4E-48BB-ADCE-181A32432DA5", 7 | "1d876d40-9aa7-11e7-905d-f541cc882994", 8 | "39bc2c9b-55b7-4835-89cd-6cc699ef7220", 9 | "5BFB729A-A7C8-4A78-A7C3-8D717BB7C13C", 10 | "E3CF3806-AD30-4EC4-8F1E-8ECD98771AA0", 11 | "97411e3d-0241-4b1f-9607-2d2c04b4df51", 12 | "9fac244b-8d7c-4d8e-a003-2097daa3270f", 13 | "263abc27-4582-4174-8789-af599697778e", 14 | "86c37a92-59a7-444b-93c7-220fcf91e29c", 15 | "ad884ca2-732e-4b85-b2d3-ed71bcbd2788", 16 | "333b11bd-d341-40d9-afcf-b32d5ce6f23b", 17 | "333b11bd-d341-40d9-afcf-b32d5ce6f23b", 18 | "333b11bd-d341-40d9-afcf-b32d5ce6f25b", 19 | "333b11bd-d341-40d9-afcf-b32d5ce6f23b", 20 | "2C65196A-54FD-4A02-9BE8-D9D1837B7C5D", 21 | "2C65196A-54FD-4A02-9BE8-D9D1837B7C5D", 22 | "2661B7E5-00F9-4DE1-BA41-04E68D70B528", 23 | "50817E39-E160-45E1-A825-1C746B7D2EB2", 24 | "5e3feff0-c5ae-11e8-a7d0-4bd3b8229800", 25 | "5e3feff0-c5ae-11e8-a7d0-4bd3b8229800", 26 | "2A7EBC54-C13E-490E-81A5-D7561AB7CD97", 27 | "0B0F01ED-7DDE-43FF-9CBB-E48954DAF9B1", 28 | "2d8a1d60-8ccd-11e7-a792-11ac56e9f553", 29 | "e4d58330-c771-11e8-8f8f-81fbb42e2824", 30 | "e4d58330-c771-11e8-8f8f-81fbb42e2824", 31 | "e0b79640-8625-11e8-91be-db2878ff888a", 32 | "2C65196A-54FD-4A02-9BE8-D9D1837B7111", 33 | "EF087383-EE5E-42C7-9A53-AB56C98420F9", 34 | "049918CB-1488-48EB-85E8-C318ECCAAA74" 35 | ] -------------------------------------------------------------------------------- /src/Misc/layoutbin/vsts.agent.plist.template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | {{SvcName}} 7 | ProgramArguments 8 | 9 | {{AgentRoot}}/runsvc.sh 10 | 11 | UserName 12 | {{User}} 13 | WorkingDirectory 14 | {{AgentRoot}} 15 | RunAtLoad 16 | 17 | StandardOutPath 18 | {{UserHome}}/Library/Logs/{{SvcName}}/stdout.log 19 | StandardErrorPath 20 | {{UserHome}}/Library/Logs/{{SvcName}}/stderr.log 21 | EnvironmentVariables 22 | 23 | VSTS_AGENT_SVC 24 | 1 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Misc/layoutbin/vsts.agent.service.template: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description={{Description}} 3 | After=network.target 4 | 5 | [Service] 6 | ExecStart={{AgentRoot}}/runsvc.sh 7 | User={{User}} 8 | WorkingDirectory={{AgentRoot}} 9 | KillMode=process 10 | KillSignal=SIGTERM 11 | TimeoutStopSec=5min 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /src/Misc/layoutroot/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | varCheckList=( 4 | 'LANG' 5 | 'JAVA_HOME' 6 | 'ANT_HOME' 7 | 'M2_HOME' 8 | 'ANDROID_HOME' 9 | 'GRADLE_HOME' 10 | 'NVM_BIN' 11 | 'NVM_PATH' 12 | 'VSTS_HTTP_PROXY' 13 | 'VSTS_HTTP_PROXY_USERNAME' 14 | 'VSTS_HTTP_PROXY_PASSWORD' 15 | 'LD_LIBRARY_PATH' 16 | 'PERL5LIB' 17 | 'AGENT_TOOLSDIRECTORY' 18 | ) 19 | 20 | envContents="" 21 | 22 | if [ -f ".env" ]; then 23 | envContents=`cat .env` 24 | else 25 | touch .env 26 | fi 27 | 28 | function writeVar() 29 | { 30 | checkVar="$1" 31 | checkDelim="${1}=" 32 | if test "${envContents#*$checkDelim}" = "$envContents" 33 | then 34 | if [ ! -z "${!checkVar}" ]; then 35 | echo "${checkVar}=${!checkVar}">>.env 36 | fi 37 | fi 38 | } 39 | 40 | echo $PATH>.path 41 | 42 | for var_name in ${varCheckList[@]} 43 | do 44 | writeVar "${var_name}" 45 | done 46 | -------------------------------------------------------------------------------- /src/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Test/CodeCoverage.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | .*buildxl.* 12 | .*ncrontab.* 13 | .*runtimecontracts\.dll 14 | .*test\.dll 15 | .*system\.identitymodel\.tokens\.jwt\.dll 16 | .*microsoft\..*\.dll 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Test/L0/Listener/Configuration/AgentCredentialL0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Listener; 5 | using Microsoft.VisualStudio.Services.Agent.Listener.Configuration; 6 | using Microsoft.VisualStudio.Services.Client; 7 | using Microsoft.VisualStudio.Services.Common; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Tests.Listener.Configuration 10 | { 11 | public class TestAgentCredential : CredentialProvider 12 | { 13 | public TestAgentCredential() : base("TEST") { } 14 | 15 | public override VssCredentials GetVssCredentials(IHostContext context) 16 | { 17 | Tracing trace = context.GetTrace("PersonalAccessToken"); 18 | trace.Info("GetVssCredentials()"); 19 | 20 | VssBasicCredential loginCred = new VssBasicCredential("test", "password"); 21 | VssCredentials creds = new VssClientCredentials(federatedCredential: loginCred); 22 | trace.Verbose("cred created"); 23 | 24 | return creds; 25 | } 26 | 27 | public override void EnsureCredential(IHostContext context, CommandSettings command, string serverUrl) 28 | { 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Test/L0/Listener/Configuration/Mocks/MockNativeWindowsServiceHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.Services.Agent.Listener.Configuration; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Test.L0.Listener.Configuration.Mocks 7 | { 8 | /// 9 | /// Mock class for NativeWindowsServiceHelper 10 | /// Use this to mock any functions of this class 11 | /// 12 | public class MockNativeWindowsServiceHelper : NativeWindowsServiceHelper 13 | { 14 | public bool ShouldAccountBeManagedService { get; set; } 15 | public bool ShouldErrorHappenDuringManagedServiceAccoutCheck { get; set; } 16 | public override uint CheckNetIsServiceAccount(string ServerName, string AccountName, out bool isServiceAccount) 17 | { 18 | isServiceAccount = this.ShouldAccountBeManagedService; 19 | if (ShouldErrorHappenDuringManagedServiceAccoutCheck) 20 | { 21 | return 1; 22 | } 23 | else 24 | { 25 | return 0; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Test/L0/Plugin/TarUtilsL0.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Xunit; 4 | using System.Threading; 5 | using Agent.Sdk; 6 | using Agent.Plugins.PipelineCache; 7 | using System.Diagnostics; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Tests.PipelineCaching 10 | { 11 | public class TarUtilsL0 12 | { 13 | [Fact] 14 | [Trait("Level", "L0")] 15 | [Trait("Category", "Plugin")] 16 | public async Task UnavailableProcessDependency_ThrowsNiceError() 17 | { 18 | var startInfo = new ProcessStartInfo(); 19 | startInfo.FileName = "ThisProcessObviouslyWillFail"; 20 | await Assert.ThrowsAsync(async () => await TarUtils.RunProcessAsync(new AgentTaskPluginExecutionContext(), startInfo, (p, ct) => null, () => { }, new CancellationToken())); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Test/L0/Plugin/TestGitCliManager/MockAgentTaskPluginExecutionContext.cs: -------------------------------------------------------------------------------- 1 | using Agent.Sdk; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Test.L0.Plugin.TestGitCliManager 7 | { 8 | public class MockAgentTaskPluginExecutionContext : AgentTaskPluginExecutionContext 9 | { 10 | public MockAgentTaskPluginExecutionContext(ITraceWriter trace) : base(trace) { } 11 | 12 | public override void PrependPath(string directory) { } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Test/L0/Plugin/TestGitSourceProvider/MockAgentTaskPluginExecutionContext.cs: -------------------------------------------------------------------------------- 1 | using Agent.Plugins.Repository; 2 | using Agent.Sdk; 3 | using Moq; 4 | using System.Collections.Generic; 5 | 6 | namespace Test.L0.Plugin.TestGitSourceProvider 7 | { 8 | public class MockAgentTaskPluginExecutionContext : AgentTaskPluginExecutionContext 9 | { 10 | public MockAgentTaskPluginExecutionContext(ITraceWriter trace) : base(trace) { } 11 | 12 | public override void PrependPath(string directory) { } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Test/L0/Util/TelemetryPropsUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.TeamFoundation.DistributedTask.WebApi; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Xunit; 9 | 10 | namespace Test.L0.Util 11 | { 12 | class TelemetryPropsUtil 13 | { 14 | public static void AssertPipelineData(Dictionary telemetryProps) 15 | { 16 | Assert.True((string)(telemetryProps["StageName"]) == "Stage1"); 17 | Assert.True((string)(telemetryProps["PhaseName"]) == "Phase1"); 18 | Assert.True((string)(telemetryProps["JobName"]) == "Job1"); 19 | Assert.True((int)(telemetryProps["StageAttempt"]) == 1); 20 | Assert.True((int)(telemetryProps["PhaseAttempt"]) == 1); 21 | Assert.True((int)(telemetryProps["JobAttempt"]) == 1); 22 | } 23 | 24 | public static void AddPipelineDataIntoAgentContext(Dictionary agentContextVariable) 25 | { 26 | agentContextVariable.Add("system.stageName", new VariableValue("Stage1")); 27 | agentContextVariable.Add("system.stageAttempt", new VariableValue("1")); 28 | agentContextVariable.Add("system.phaseName", new VariableValue("Phase1")); 29 | agentContextVariable.Add("system.phaseAttempt", new VariableValue("1")); 30 | agentContextVariable.Add("system.jobName", new VariableValue("Job1")); 31 | agentContextVariable.Add("system.jobAttempt", new VariableValue("1")); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Test/L0/Util/VarUtilL0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Util; 5 | using Xunit; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Tests.Util 8 | { 9 | public class VarUtilL0 10 | { 11 | [Theory] 12 | [InlineData("test.value1", "TEST_VALUE1", false)] 13 | [InlineData("test value2", "TEST_VALUE2", false)] 14 | [InlineData("tesT vaLue.3", "TEST_VALUE_3", false)] 15 | [InlineData(".tesT vaLue 4", "_TEST_VALUE_4", false)] 16 | [InlineData("TEST_VALUE_5", "TEST_VALUE_5", false)] 17 | [InlineData(".. TEST VALUE. 6", "___TEST___VALUE__6", false)] 18 | [InlineData(null, "", false)] 19 | [InlineData("", "", false)] 20 | [InlineData(" ", "_", false)] 21 | [InlineData(".", "_", false)] 22 | [InlineData("TestValue", "TestValue", true)] 23 | [InlineData("Test.Value", "Test_Value", true)] 24 | public void TestConverterToEnvVariableFormat(string input, string expected, bool preserveCase) 25 | { 26 | var result = VarUtil.ConvertToEnvVariableFormat(input, preserveCase); 27 | 28 | Assert.Equal(expected, result); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Test/L0/Worker/Build/TfsVCCommandManagerL0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Microsoft.VisualStudio.Services.Agent.Worker.Build; 7 | using Xunit; 8 | 9 | namespace Microsoft.VisualStudio.Services.Agent.Tests.Worker.Build 10 | { 11 | public sealed class TfsVCCommandManagerL0 12 | { 13 | [Fact] 14 | [Trait("Level", "L0")] 15 | [Trait("Category", "Worker")] 16 | public void FeaturesEnumHasCorrectValues() 17 | { 18 | var hashtable = new HashSet(); 19 | foreach (int val in Enum.GetValues(typeof(TfsVCFeatures))) 20 | { 21 | Assert.True(hashtable.Add(val), $"Duplicate value detected: {val}"); 22 | Assert.True(val >= 0, $"Must be greater than or equal to zero: {val}"); 23 | if (val > 0) 24 | { 25 | double log = Math.Log(val, 2); 26 | Assert.True(log - Math.Floor(log) == 0, $"Must be a power of 2: {val}"); 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Test/L0/Worker/CodeCoverage/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Coverage Report 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <body> 19 | <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a frame-incapable web client.</p> 20 | <p><a href="frame-summary.html">Click here to view a non-frame version.</a></p> 21 | </body> 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Test/L0/Worker/GitManagerL0.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using Microsoft.VisualStudio.Services.Agent.Worker; 7 | using Moq; 8 | using Xunit; 9 | 10 | namespace Microsoft.VisualStudio.Services.Agent.Tests.Worker 11 | { 12 | public sealed class GitManagerL0 13 | { 14 | [Fact] 15 | [Trait("Level", "L0")] 16 | [Trait("Category", "Worker")] 17 | [Trait("SkipOn", "darwin")] 18 | [Trait("SkipOn", "linux")] 19 | public async void DownloadAsync() 20 | { 21 | using var tokenSource = new CancellationTokenSource(); 22 | using var hostContext = new TestHostContext(this); 23 | GitManager gitManager = new(); 24 | gitManager.Initialize(hostContext); 25 | var executionContext = new Mock(); 26 | executionContext.Setup(x => x.CancellationToken).Returns(tokenSource.Token); 27 | await gitManager.DownloadAsync(executionContext.Object); 28 | 29 | var externalsPath = hostContext.GetDirectory(WellKnownDirectory.Externals); 30 | 31 | Assert.True(Directory.Exists(Path.Combine(externalsPath, "git-2.39.4"))); 32 | Assert.True(File.Exists(Path.Combine(externalsPath, "git-2.39.4", "cmd", "git.exe"))); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Test/L1/L1HostContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.IO; 6 | using System.Reflection; 7 | 8 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 9 | { 10 | public class L1HostContext : HostContext 11 | { 12 | public L1HostContext(HostType hostType, string logFile = null) 13 | : base(hostType, logFile) 14 | { 15 | } 16 | 17 | public T SetupService(Type target) where T : class, IAgentService 18 | { 19 | if (!typeof(T).IsAssignableFrom(target)) 20 | { 21 | throw new ArgumentException("The target type must implement the specified interface"); 22 | } 23 | ServiceTypes.TryAdd(typeof(T), target); 24 | return GetService(); 25 | } 26 | 27 | public override string GetDirectory(WellKnownDirectory directory) 28 | { 29 | if (directory == WellKnownDirectory.Bin) 30 | { 31 | return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 32 | } 33 | return base.GetDirectory(directory); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeAgentPluginManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Microsoft.VisualStudio.Services.Agent.Worker; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 8 | { 9 | public class FakeAgentPluginManager : AgentPluginManager 10 | { 11 | public override void Initialize(IHostContext hostContext) 12 | { 13 | // Inject any plugin mocks here. 14 | // Each injection should be paired with a removal of the plugin being mocked. 15 | ReplacePlugin("Agent.Plugins.Repository.CheckoutTask, Agent.Plugins", "Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker.FakeCheckoutTask, Test"); 16 | base.Initialize(hostContext); 17 | } 18 | 19 | private void ReplacePlugin(string existingPlugin, string fakePlugin) 20 | { 21 | if (!_taskPlugins.Contains(existingPlugin)) 22 | { 23 | throw new Exception($"{existingPlugin} must exist in _taskPlugins in order to be replaced"); 24 | } 25 | if (_taskPlugins.Contains(fakePlugin)) 26 | { 27 | throw new Exception($"{fakePlugin} already exists in _taskPlugins"); 28 | } 29 | _taskPlugins.Remove(existingPlugin); 30 | _taskPlugins.Add(fakePlugin); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeCustomerIntelligenceServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Worker.Telemetry; 5 | using Microsoft.VisualStudio.Services.Common; 6 | using Microsoft.VisualStudio.Services.WebApi; 7 | using Microsoft.VisualStudio.Services.WebPlatform; 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | 11 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 12 | { 13 | public class FakeCustomerIntelligenceServer : AgentService, ICustomerIntelligenceServer 14 | { 15 | public IList events = new List(); 16 | 17 | public void Initialize(VssConnection connection) 18 | { 19 | } 20 | 21 | public Task PublishEventsAsync(CustomerIntelligenceEvent[] ciEvents) 22 | { 23 | events.AddRange(ciEvents); 24 | return Task.CompletedTask; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeReleaseServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using System.Collections.Generic; 7 | using System; 8 | using Microsoft.VisualStudio.Services.WebApi; 9 | using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts; 10 | using Microsoft.VisualStudio.Services.Agent.Worker.Release; 11 | using RMContracts = Microsoft.VisualStudio.Services.ReleaseManagement.WebApi; 12 | 13 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 14 | { 15 | public class FakeReleaseServer : AgentService, IReleaseServer 16 | { 17 | public string ReleaseName { get; internal set; } 18 | 19 | public Task ConnectAsync(VssConnection jobConnection) 20 | { 21 | return Task.CompletedTask; 22 | } 23 | 24 | public IEnumerable GetReleaseArtifactsFromService( 25 | int releaseId, 26 | Guid projectId, 27 | CancellationToken cancellationToken = default(CancellationToken)) 28 | { 29 | return new List(); 30 | } 31 | public Task UpdateReleaseName( 32 | string releaseId, 33 | Guid projectId, 34 | string releaseName, 35 | CancellationToken cancellationToken = default(CancellationToken)) 36 | { 37 | ReleaseName = releaseName; 38 | return Task.FromResult(new RMContracts.Release 39 | { 40 | Name = releaseName 41 | }); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeResourceMetricsManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Threading.Tasks; 5 | using Microsoft.VisualStudio.Services.Agent.Worker; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 8 | { 9 | public sealed class FakeResourceMetricsManager : AgentService, IResourceMetricsManager 10 | { 11 | public Task RunDebugResourceMonitorAsync() { return Task.CompletedTask; } 12 | public Task RunMemoryUtilizationMonitorAsync() { return Task.CompletedTask; } 13 | public Task RunDiskSpaceUtilizationMonitorAsync() { return Task.CompletedTask; } 14 | public Task RunCpuUtilizationMonitorAsync(string taskId) { return Task.CompletedTask; } 15 | public void SetContext(IExecutionContext context) { } 16 | 17 | public void Dispose() { } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeTaskManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.Agent.Worker; 5 | using Pipelines = Microsoft.TeamFoundation.DistributedTask.Pipelines; 6 | 7 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 8 | { 9 | public class FakeTaskManager : TaskManager 10 | { 11 | public override Definition Load(Pipelines.TaskStep task) 12 | { 13 | Definition d = base.Load(task); 14 | if (task.Reference.Id == Pipelines.PipelineConstants.CheckoutTask.Id && task.Reference.Version == Pipelines.PipelineConstants.CheckoutTask.Version) 15 | { 16 | AgentPluginHandlerData checkoutHandlerData = new AgentPluginHandlerData(); 17 | checkoutHandlerData.Target = "Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker.FakeCheckoutTask, Test"; 18 | d.Data.Execution = new ExecutionData() 19 | { 20 | AgentPlugin = checkoutHandlerData 21 | }; 22 | } 23 | 24 | return d; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Test/L1/Mock/FakeTaskServer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Microsoft.TeamFoundation.DistributedTask.WebApi; 8 | using System; 9 | using Microsoft.VisualStudio.Services.WebApi; 10 | 11 | namespace Microsoft.VisualStudio.Services.Agent.Tests.L1.Worker 12 | { 13 | public class FakeTaskServer : AgentService, ITaskServer 14 | { 15 | public Task ConnectAsync(VssConnection jobConnection) 16 | { 17 | return Task.CompletedTask; 18 | } 19 | 20 | public Task GetTaskContentZipAsync(Guid taskId, TaskVersion taskVersion, CancellationToken token) 21 | { 22 | String taskZip = Path.Join(HostContext.GetDirectory(WellKnownDirectory.Externals), "Tasks", taskId.ToString() + ".zip"); 23 | if (File.Exists(taskZip)) 24 | { 25 | return Task.FromResult(new FileStream(taskZip, FileMode.Open, FileAccess.Read, FileShare.Read)); 26 | } 27 | else 28 | { 29 | throw new Exception("A step specified a task which does not exist in the L1 test framework. Any tasks used by L1 tests must be added manually."); 30 | } 31 | } 32 | 33 | public Task TaskDefinitionEndpointExist() 34 | { 35 | return Task.FromResult(true); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Test/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/agentversion: -------------------------------------------------------------------------------- 1 | 3.999.999 -------------------------------------------------------------------------------- /src/dev.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | rem Check if SH_PATH is defined. 4 | if defined SH_PATH ( 5 | goto run 6 | ) 7 | 8 | rem Attempt to resolve sh.exe from the PATH. 9 | where sh.exe 1>"%TEMP%\where_sh" 2>nul 10 | set /p SH_PATH= < "%TEMP%\where_sh" 11 | del "%TEMP%\where_sh" 12 | if defined SH_PATH ( 13 | goto run 14 | ) 15 | 16 | rem Check well-known locations. 17 | set SH_PATH=C:\Program Files\Git\bin\sh.exe 18 | if exist "%SH_PATH%" ( 19 | goto run 20 | ) 21 | 22 | echo Unable to resolve location of sh.exe. 1>&2 23 | exit /b 1 24 | 25 | :run 26 | echo on 27 | "%SH_PATH%" "%~dp0dev.sh" %* 28 | -------------------------------------------------------------------------------- /tools/FindPipelinesUsingRetiredImages/readme.md: -------------------------------------------------------------------------------- 1 | # Finding Pipelines Targeting Retired Images 2 | 3 | The scripts in this directory are intended to help customers identify Pipelines that depend on deprecated images. Customers can then navigate to and update those Pipelines. 4 | 5 | ## QueryJobHistoryForRetiredImages.ps1 6 | usage: 7 | `.\QueryJobHistoryForRetiredImages.ps1 ` 8 | 9 | or optionally, you can pass in a continuation token from a previous run in case you need to pick up where you left off: 10 | `.\QueryJobHistoryForRetiredImages.ps1 ` 11 | 12 | This script will query the "Azure Pipelines" Agent Pool's Job History and output unique Pipelines that targeted any of the retired images. It will query the jobs 200 at a time, as this is the REST API query limit, and prompt for continuation. This is to avoid account throttling in case of a large job history. It will output the current list of distinct Pipelines each iteration, with the URL to edit that Pipeline. It will also output once it has reached the end of the job history. --------------------------------------------------------------------------------