Julmar.MSLearnDevOps
2.0.1-preview
dotnet add package Julmar.MSLearnDevOps --version 2.0.1-preview
NuGet\Install-Package Julmar.MSLearnDevOps -Version 2.0.1-preview
<PackageReference Include="Julmar.MSLearnDevOps" Version="2.0.1-preview" />
paket add Julmar.MSLearnDevOps --version 2.0.1-preview
#r "nuget: Julmar.MSLearnDevOps, 2.0.1-preview"
// Install Julmar.MSLearnDevOps as a Cake Addin #addin nuget:?package=Julmar.MSLearnDevOps&version=2.0.1-preview&prerelease // Install Julmar.MSLearnDevOps as a Cake Tool #tool nuget:?package=Julmar.MSLearnDevOps&version=2.0.1-preview&prerelease
MSLearnDevOps library
The MSLearnDevOps library extends the AzDOUtilities library and provides custom WorkItem wrappers for the primary WorkItems in the Microsoft Learn Azure DevOps project:
ModuleWorkItem
LearningPathWorkItem
AchievementWorkItem
BugWorkItem
(extends the base one to add custom fields)ContentPlanWorkItem
EpicWorkItem
(extends the base one to add custom fields)ModuleUpdateWorkItem
- UserStoryWorkItem` (extends the base one to add custom fields)
There is an unlisted NuGet package you can use to add the library to any .NET Core application.
Install-Package Julmar.MSLearnDevOps -Version 2.0.1-preview
The library also provides some helper functions to quickly pull data out of Azure DevOps. Almost all of these are on the MSLearnHelpers
class.
public static class MSLearnHelpers
{
// Constant for the MS Learn DevOps board
public const string Uri = "https://ceapex.visualstudio.com";
// Constant for the MS Learn project
public const string Project = "Microsoft Learn";
// Retrieve a typed LINQ class for all three WorkItems
public static IMSLearnDB Db(IAzureDevOpsService service = null);
// Wrapper around the AzureDevOpsFactory.Create method which can provide an access token
public static IAzureDevOpsService Create(string accessToken);
}
The two constants point to the Azure DevOps site and project. The two creation methods provide simpler alternatives to the AzureDevOpsFactory
methods.
The Create
method takes an access token, but you can pass null
unlike the underlying factory. If you don't supply the access token, the system will look in your documents folder for a file named vsts-rw-key.txt
. If that file is present, it will read the contents and use them as the access key. If the file doesn't exist, and no token was supplied, an exception is thrown.
The Db
method takes an IAzureDevOpsService
instance and retrieves a wrapper object around each of the custom WorkItem types:
public IAzureDevOpsService Service { get; }
public IOrderedQueryable<ModuleWorkItem> Modules { get; }
public IOrderedQueryable<LearningPathWorkItem> LearningPaths { get; }
public IOrderedQueryable<AchievementWorkItem> Achievements { get; }
public IOrderedQueryable<WorkItem> WorkItems { get; }
This can be used to easily query each type. For example:
var myModules = MSLearnHelpers.Db().Modules.Where(m => m.AssignedTo == "smmark@microsoft.com").ToList();
The WorkItems
property will pull from all registered types - for example, in the below code fragment, the library will return a mixture of ModuleWorkItem
and LearningPathWorkItem
objects. You can use obj is ModuleWorkItem
at runtime to see what got returned.
var closedModulesAndPaths = MSLearnHelpers.Db().WorkItems.Where(wi =>
(wi.WorkItemType == ModuleWorkItem.Type || wi.WorkItemType == LearningPathWorkItem.Type)
&& wi.State == WorkItemStatus.Closed).ToList();
Note: keep in mind these are
IQueryable
objects -- the query is built and executed when you enumerate the objects. This is important because if you enumerate it more than once, you will execute the query more than once. It's best to capture the results in a list or array unless you only plan to enumerate it a single time!
Notice a set of status constants are used above. These are also included in the library as simple string constants and define each of the allowed states for Modules, Paths, or Achievements. You can use strings as well, these just provide a nice Intellisense experience and avoid mistypes.
public static class WorkItemStatus
{
public const string New = "New";
public const string Proposed = "Proposed";
public const string Approved = "Approved";
public const string Design = "Design";
public const string InProgress = "In Progress";
public const string Blocked = "Blocked";
public const string InReview = "In Review";
public const string Test = "Test";
public const string PrePublish = "Pre-publish";
public const string Published = "Published";
public const string Closed = "Closed";
public const string Removed = "Removed";
public const string Canceled = "Canceled";
public const string Declined = "Declined";
}
LINQ helpers
The library also has a set of extension methods which can be applied to any query. These can be added as part of the fluent syntax to string together the query. The final AzDO query will be constructed with each of these constraints when it's executed.
// Ignore WorkItems that have the tag 'Needs Review' or 'Missing'
workItems.IgnoreMissing()
// Ignore modules or paths that have the Hidden flag set
workItems.IgnoreHidden()
// Ignore modules or paths in the learn-sandbox-pr or 'Other'
workItems.IgnoreTestRepos()
// Ignore the specified states
// If no states are supplied, it uses WorkItemStatus.Removed, WorkItemStatus.Canceled, WorkItemStatus.Declined
workItems.IgnoreStates("state1", "state2", ...)
// Return items ONLY in the given state(s)
workItems.OnlyStates("state1", "state2", ...)
Here's an example:
var db = MSLearnHelpers.Db();
var query = db.Modules.Where(m => m.AssignedTo.EndsWith("@microsoft.com"))
.OnlyStates(WorkItemStatus.Closed, WorkItemStatus.PrePublish)
.IgnoreMissing()
.IgnoreTestRepos();
// Build the query and execute it.
var modules = query.ToList();
// This sends:
// SELECT [System.Id] FROM [WorkItems] WHERE [System.TeamProject = 'Microsoft Learn']
// AND [System.AssignedTo] CONTAINS ('@microsoft.com')
// AND [System.State] IN ('Closed', 'Pre-Publish')
// AND NOT [System.Tags] CONTAINS ('Missing', 'Needs Review')
// AND NOT [Custom.Repo] CONTAINS ('learn-sandbox-pr', 'Other')
//
// Then the collection is filtered with Where(m => m.AssignedTo.EndsWith("@microsoft.com"))
// to filter out bad work items because AzDO doesn't support 'EndsWith'.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Julmar.AzDOUtilities (>= 1.8.4.1-preview)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.0.1-preview | 165 | 3/28/2022 |
1.0 Initial release