예제 #1
0
        public async Task <string> ExecuteAsync(string collectionUrl, Guid projectId, string projectName, string personalAccessToken, int workItemId, WorkItemTrackingHttpClientBase witClient, CancellationToken cancellationToken)
        {
            if (State == EngineState.Error)
            {
                return(string.Empty);
            }

            var context = new EngineContext(witClient, projectId, projectName, personalAccessToken, logger);
            var store   = new WorkItemStore(context);
            var self    = store.GetWorkItem(workItemId);

            logger.WriteInfo($"Initial WorkItem {workItemId} retrieved from {collectionUrl}");

            var globals = new Globals
            {
                self  = self,
                store = store
            };

            logger.WriteInfo($"Executing Rule...");
            var result = await roslynScript.RunAsync(globals, cancellationToken);

            if (result.Exception != null)
            {
                logger.WriteError($"Rule failed with {result.Exception}");
                State = EngineState.Error;
            }
            else if (result.ReturnValue != null)
            {
                logger.WriteInfo($"Rule succeeded with {result.ReturnValue}");
            }
            else
            {
                logger.WriteInfo($"Rule succeeded, no return value");
            }

            State = EngineState.Success;

            logger.WriteVerbose($"Post-execution, save any change (mode {saveMode})...");
            var saveRes = await store.SaveChanges(saveMode, !DryRun, cancellationToken);

            if (saveRes.created + saveRes.updated > 0)
            {
                logger.WriteInfo($"Changes saved to Azure DevOps (mode {saveMode}): {saveRes.created} created, {saveRes.updated} updated.");
            }
            else
            {
                logger.WriteInfo($"No changes saved to Azure DevOps.");
            }

            return(result.ReturnValue);
        }
예제 #2
0
        public async Task <string> ExecuteAsync(Guid projectId, WorkItemData workItemPayload, IClientsContext clients, CancellationToken cancellationToken)
        {
            if (State == EngineState.Error)
            {
                return(string.Empty);
            }

            var workItem    = workItemPayload.WorkItem;
            var context     = new EngineContext(clients, projectId, workItem.GetTeamProject(), logger);
            var store       = new WorkItemStore(context, workItem);
            var self        = store.GetWorkItem(workItem.Id.Value);
            var selfChanges = new WorkItemUpdateWrapper(workItemPayload.WorkItemUpdate);

            logger.WriteInfo($"Initial WorkItem {self.Id} retrieved from {clients.WitClient.BaseAddress}");

            var globals = new Globals
            {
                self        = self,
                selfChanges = selfChanges,
                store       = store,
                logger      = logger
            };

            logger.WriteInfo($"Executing Rule...");
            var result = await roslynScript.RunAsync(globals, cancellationToken);

            if (result.Exception != null)
            {
                logger.WriteError($"Rule failed with {result.Exception}");
                State = EngineState.Error;
            }
            else
            {
                logger.WriteInfo($"Rule succeeded with {result.ReturnValue ?? "no return value"}");
                State = EngineState.Success;
            }

            logger.WriteVerbose($"Post-execution, save any change (mode {saveMode})...");
            var saveRes = await store.SaveChanges(saveMode, !DryRun, cancellationToken);

            if (saveRes.created + saveRes.updated > 0)
            {
                logger.WriteInfo($"Changes saved to Azure DevOps (mode {saveMode}): {saveRes.created} created, {saveRes.updated} updated.");
            }
            else
            {
                logger.WriteInfo($"No changes saved to Azure DevOps.");
            }

            return(result.ReturnValue);
        }
예제 #3
0
        protected RuleExecutionContext CreateRuleExecutionContext(Guid projectId, WorkItemData workItemPayload, IClientsContext clients)
        {
            var workItem    = workItemPayload.WorkItem;
            var context     = new EngineContext(clients, projectId, workItem.GetTeamProject(), logger);
            var store       = new WorkItemStore(context, workItem);
            var self        = store.GetWorkItem(workItem.Id.Value);
            var selfChanges = new WorkItemUpdateWrapper(workItemPayload.WorkItemUpdate);

            logger.WriteInfo($"Initial WorkItem {self.Id} retrieved from {clients.WitClient.BaseAddress}");

            var globals = new RuleExecutionContext
            {
                self        = self,
                selfChanges = selfChanges,
                store       = store,
                logger      = logger
            };

            return(globals);
        }
예제 #4
0
        internal async Task <string> Execute(string aggregatorVersion, dynamic data)
        {
            if (string.IsNullOrEmpty(aggregatorVersion))
            {
                aggregatorVersion = "0.1";
            }

            string collectionUrl = data.resourceContainers.collection.baseUrl;
            int    workItemId    = data.resource.id;

            logger.WriteVerbose($"Connecting to VSTS using {configuration.VstsTokenType}...");
            var clientCredentials = default(VssCredentials);

            if (configuration.VstsTokenType == VstsTokenType.PAT)
            {
                clientCredentials = new VssBasicCredential(configuration.VstsTokenType.ToString(), configuration.VstsToken);
            }
            else
            {
                logger.WriteError($"VSTS Token type {configuration.VstsTokenType} not supported!");
                throw new ArgumentOutOfRangeException(nameof(configuration.VstsTokenType));
            }
            var vsts = new VssConnection(new Uri(collectionUrl), clientCredentials);
            await vsts.ConnectAsync();

            logger.WriteInfo($"Connected to VSTS");
            var witClient = vsts.GetClient <WorkItemTrackingHttpClient>();
            var context   = new Engine.EngineContext(witClient);
            var store     = new Engine.WorkItemStore(context);
            var self      = store.GetWorkItem(workItemId);

            logger.WriteInfo($"Initial WorkItem retrieved");

            string ruleFilePath = Path.Combine(functionDirectory, $"{ruleName}.rule");

            if (!File.Exists(ruleFilePath))
            {
                logger.WriteError($"Rule code not found at {ruleFilePath}");
                return("Rule file not found!");
            }

            logger.WriteVerbose($"Rule code found at {ruleFilePath}");
            string ruleCode = File.ReadAllText(ruleFilePath);

            logger.WriteInfo($"Executing Rule...");
            var globals = new Engine.Globals {
                self  = self,
                store = store
            };

            var types = new List <Type>()
            {
                typeof(object),
                typeof(System.Linq.Enumerable),
                typeof(System.Collections.Generic.CollectionExtensions)
            };
            var references = types.ConvertAll(t => t.Assembly);

            var scriptOptions = ScriptOptions.Default
                                .WithEmitDebugInformation(true)
                                .WithReferences(references)
                                // Add namespaces
                                .WithImports("System")
                                .WithImports("System.Linq")
                                .WithImports("System.Collections.Generic");
            var result = await CSharpScript.EvaluateAsync <string>(
                code : ruleCode,
                options : scriptOptions,
                globals : globals, globalsType : typeof(Engine.Globals));

            logger.WriteInfo($"Rule returned {result}");

            logger.WriteVerbose($"Post-execution, save all changes...");
            context.SaveChanges();
            logger.WriteInfo($"Changes saved to VSTS");

            return(result);
        }