Top Posts & Pages
Error: Twitter did not respond. Please wait a few minutes and refresh this page.
Stephen Ritchie's offerings of ruthlessly helpful .NET practices.
I want to use NuGet to retrieve a set of content files that are needed for the build. For example, the TeamCity build configuration runs a runner.msbuild script, however, that script needs to import a Targets file, like this:
<Import Condition="$(BuildPath)\ImportTargets\MSBuild.Lender.Common.Targets" Project="$(BuildPath)\ImportTargets\MSBuild.Lender.Common.Targets" />
The plan is to create a local NuGet feed that has all the prerequisite files for the build script. Using the local NuGet feed, install the “global build” package as the first build task. After that, the primary build script can find the import file and proceed normally. Here is the basic solution strategy that I came up with.
To see an example, follow these steps:
1. Create a local NuGet feed. Read more information here: http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds
2. Write a NuGet spec file and name it Lender.Build.nuspec. This is simply an XML file. The schema is described here: http://docs.nuget.org/docs/reference/nuspec-reference
<?xml version="1.0"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>_globalBuild</id> <version>1.0.0</version> <authors>Lender Development</authors> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>Lender Build</description> </metadata> <files> <file src="ImportTargets\**" target="ImportTargets" /> </files> </package>
Notice the “file” element. It specifies the source files, which includes in the MSBuild.Lender.Common.Targets file when the ImportTargets folder is added.
3. Using the NuGet Package Explorer, I opened the Lender.Build.nuspec file and saved the package in the LocalNuGetFeed folder. Here’s how that looks:
4. Save the package to the local NuGet feeds folder. In this case, it is the C:\LocalNuGetFeeds folder.
5. Now let’s move on over to where this “_globalBuild” dependency is going to be used. For example, the C:\projects\Lender.Slos folder. In that folder, create a packages.config file and add it to version control. That config file looks like this:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="_globalBuild" version="1.0.0" /> </packages>
This references the package with the id of “_globalBuild”, which is found in the LocalNuGetFeeds package. It is one of the available package sources because it was added through Visual Studio, under Tools >> Library Package Manager >> Package Manager Settings.
6. From MSBuild, the CI server calls the “Kickstart” target before running the default script target. The Kickstart target uses the NuGet.exe command line to install the global build package. Here is the MSBuild script:
<Project DefaultTargets="Default" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" > <PropertyGroup> <RootPath>.</RootPath> <BuildPath>$(RootPath)\_globalBuild.1.0.0\ImportTargets</BuildPath> <CommonImportFile>$(BuildPath)\MSBuild.Lender.Common.Targets</CommonImportFile> </PropertyGroup> <Import Condition="Exists('$(CommonImportFile)')" Project="$(CommonImportFile)" /> <Target Name="Kickstart" > <PropertyGroup> <PackagesConfigFile>packages.config</PackagesConfigFile> <ReferencesPath>.</ReferencesPath> </PropertyGroup> <Exec Command="$(NuGetRoot)\nuget.exe i $(PackagesConfigFile) -o $(ReferencesPath)" /> </Target> <!-- The Rebuild or other targets belong here --> <Target Name="Default" > <PropertyGroup> <ProjectFullName Condition="$(ProjectFullName)==''">(undefined)</ProjectFullName> </PropertyGroup> <Message Text="Project name: '$(ProjectFullName)'" Importance="High" /> </Target> </Project>
7. In this way, the MSBuild script uses NuGet to bring down the ImportTargets files and places them under the _globalBuild.1.0.0 folder. This can happen on the CI server with multiple build steps. For the sake of simplicity here are the lines in a batch file that simulates these steps:
%MSBuildRoot%\msbuild.exe "runner.msbuild" /t:Kickstart %MSBuildRoot%\msbuild.exe "runner.msbuild"
With the kickstart bringing down the prerequisite files, the rest of the build script performs the automated build using the common Targets properly imported.
For those who would like an overview of Pro .NET Best Practices, here’s a rundown on the book.
The book presents each topic by keeping in mind two objectives: to provide reasonable breath and to go into depth on key practices. For example, the chapter on code analysis looks at both static and dynamic analysis, and it goes into depth with FxCop and StyleCop. The goal is to strike the balance between covering all the topics, discussing the widely-used tools and technologies, and having a reasonable chapter length.
Chapters 1 through 5 are focused on the context of new and different practices. Since adopting better practices is an initiative, it is important to know what practices to prioritize and where to uncover better practices within your organization and current circumstances.
This chapter shows how to choose new and different practices that are better practices for you, your team, and your organization.
This chapter draws out ways to uncover better practices in the areas of .NET and general software development that provide an opportunity to discover or learn and apply better practices.
This chapter presents practical advice on how to get team members to collaborate with each other and work toward a common purpose.
This chapter describes specific practices to help with quantifying the value of adopting better development practices.
This chapter provides you with practices to help you focus on strategy and the strategic implications of current practices.
Chapters 6 through 9 are focused on a developer’s individual practices. These chapters discuss guidelines and conventions to follow, effective approaches, and tips and tricks that are worth knowing. The overarching theme is that each developer helps the whole team succeed by being a more effective developer.
This chapter helps sort out the generalized statements, principles, practices, and procedures that best serve as .NET rules and regulations that support effective and innovative development.
This chapter is an informal review of the C# language’s power both to harness its own strengths and to recognize that effective development is a key part of following .NET practices.
This chapter describes many specific practices to improve test code, consistent with the principles behind effective development and automated testing.
This chapter discusses using build automation to remove error-prone steps, to establish repeatability and consistency, and to improve the build and deployment processes.
Chapters 10 through 12 are focused on supporting tools, products, and technologies. These chapters describe the purpose of various tool sets and present some recommendations on applications and products worth evaluating.
This chapter presents the continuous integration lifecycle with a description of the steps involved within each of the processes. Through effective continuous integration practices, the project can save time, improve team effectiveness, and provide early detection of problems.
This chapter provides an overview of many static and dynamic tools, technologies, and approaches with an emphasis on improvements that provide continuous, automated monitoring.
Chapter 12 is a comprehensive list of testing frameworks and tools with a blend of commercial and open-source alternatives.
The final chapter is about the aversions and biases that keep many individuals, teams, and organizations from adopting better practices. You may face someone’s reluctance to accept or acknowledge a new or different practice as potentially better. You may struggle against another’s tendency to hold a particular view of a new or different practice that undercuts and weakens its potential. Many people resist change even if it is for the better. This chapter helps you understand how aversions and biases impact change so that you can identify them, cope with them, and hopefully manage them.
I am a Microsoft .NET software developer. That explains why the book is about .NET best practices. That’s in my wheelhouse.
The more relevant question is, why a book about best practices?
When it comes right down to it, many best practices are the application of common sense approaches. However, there is something that blocks us from making the relatively simple changes in work habits that produce significant, positive results. I wanted to further explore that quandary. Unfortunately, common sense is not always common practice.
There is a gap between the reality that projects live with and the vision that the team members have for their processes and practices. They envision new and different practices that would likely yield better outcomes for their project. Yet, the project reality is slow to move or simply never moves toward the vision.
Many developers are discouraged by the simple fact that far too many projects compromise the vision instead of changing the reality. These two concepts are usually in tension. That tension is a source of great frustration and cynicism. I wanted to let people know that their project reality is not an immovable object, and the team members can be an irresistible force.
Part of moving your reality toward your vision is getting a handle on the barriers and objections and working to overcome them. Some of them are external to the team while others are internal to the team. I wanted to relate organizational behavior to following .NET best practices and to software development.
The team must know what to do. They need to know about the systematic approaches that help the individual and the team achieve the desired results. There are key practice areas that yield many benefits:
Of course, there is a lot of overlap in these areas. The management scientist might call that synergy. A common theme to these practice areas is the principle of automation. By acquiring knowledge in these practice areas you find ways to:
Know-how in these practice areas also raises awareness and understanding, creates an early warning system, and provides various stakeholders with a new level of visibility into the project’s progress. I wanted the reader to appreciate the significance and inter-relatedness of these key practice areas and the benefits each offers.
The team needs to know how to do it. Every new and different practice has a learning curve. Climbing that curve takes time and practice. The journey from newbie to expert has to be nurtured. There are no shortcuts that can sidestep the crawl-walk-run progression. Becoming skilled requires experience. Prototyping and building an archetype are two great ways to develop a skill. Code samples and structured walkthroughs are other ways to develop a skill. I wanted the book to offer an eclectic assortment of case studies, walkthroughs, and code samples.
Team members must want to adopt better practices. Managers need to know why the changes are for the better, in terms managers can appreciate. The bottom line, it is important to be able to quantify the benefits of following new and different practices. It is also important to understand what motivates and what doesn’t. It helps to understand human biases. Appreciate the underlying principle that software projects are materially impacted by how well individuals interact. I wanted to highlight and communicate the best practices that relate to the human factors that include persuasion, motivation, and commitment.
Here are the links to Pro .NET Best Practices: