Skip to content

psake build script review #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rkeithhill opened this issue Oct 6, 2016 · 27 comments
Closed

psake build script review #145

rkeithhill opened this issue Oct 6, 2016 · 27 comments

Comments

@rkeithhill
Copy link
Collaborator

rkeithhill commented Oct 6, 2016

TL;DR - skim through and look at the bolded questions/issues. FYI, I'm in the midst of making changes to build.psake.ps1 so please hold off on making changes to this file.

Currently our build script has the following tasks:

Task PreBuild {
Task PostBuild {
Task PreBuildHelp {
Task PostBuildHelp {
Task PreInstall {
Task PostInstall {
Task PrePublish {
Task PostPublish {
Task default -depends Build
Task Init -requiredVariables PublishDir {
Task Clean -requiredVariables PublishRootDir {
Task Sign -depends PostCopySource -requiredVariables SettingsPath, SignScripts {
Task Build -depends BuildImpl, Sign, PostBuild {
Task BuildImpl -depends Init, Clean, PreBuild -requiredVariables SourceRootDir, PublishDir {
Task GenerateMarkdown -depends Build, PreBuildHelp -requiredVariables DefaultLocale, DocsRootDir, ModuleName, PublishDir {
Task BuildHelp -depends BuildHelpImpl, PostBuildHelp {
Task BuildHelpImpl -depends GenerateMarkdown -requiredVariables DocsRootDir, PublishDir {
Task Install -depends InstallImpl, PostInstall {
Task InstallImpl -depends BuildHelp, PreInstall -requiredVariables InstallPath, PublishDir {
Task Test -depends Build {
Task Publish -depends Test, PrePublish, PublishImpl, PostPublish {
Task PublishImpl -requiredVariables SettingsPath, PublishDir {
Task ? -description 'Lists the available tasks' {
Task RemoveApiKey -requiredVariables SettingsPath {
Task StoreApiKey -requiredVariables SettingsPath {
Task ShowApiKey -requiredVariables SettingsPath {
Task ShowFullApiKey -requiredVariables SettingsPath {
Task RemoveCertSubjectName -requiredVariables SettingsPath {
Task StoreCertSubjectName -requiredVariables SettingsPath {
Task ShowCertSubjectName -requiredVariables SettingsPath {

The default task is Build. The primary build flow is:

 Init -> Clean -> PreBuild -> BuildImpl -> Sign -> PostBuild

The two simple user extension points are:

# Executes before the BuidImpl phase of the Build task.
Task PreBuild {
}

# Executes after the Sign phase of the Build task.
Task PostBuild {
}

The BuildHelp flow is:

<Build flow> -> PreBuildHelp -> GenerateMarkdown -> BuildHelpImpl -> PostBuildHelp

BTW since we usually refer to docs as "help" in PowerShell, shouldn't these be called GenerateHelp or better yet, GenerateMarkdown and BuildHelp? GenerateFoo and BuildFoo sound a bit like they would do the same thing, at least to me. Update: I've temporarily made this change.

The install task flow is:

<BuildHelp flow> -> PreInstall -> InstallImpl -> PostInstall

BTW, I think we need an option (property) on the Install task to allow it to "clean" the destination before copying over the module. The default should probably be to not clean the destination first.

The test task flow is:

<Build flow> -> test

And the publish flow is:

<Test flow> -> PrePublish -> PublishImpl ->PostPublish

This provides two more empty, task extension points for the user: Pre/PostPublish.

# Executes before publishing occurs.
Task PrePublish {
}

# Executes after publishing occurs.
Task PostPublish {
}

Hmm, forgot that I had used this "impl" pattern before. I like that and may convert PreCopySource/PostCopySource (never liked those names) to more of PreBuild/PostBuild where these would fit in like so:

 Init -> Clean -> PreBuild ->BuildImpl -> Sign -> PostBuild

In fact, I might do the same for Install (Pre/PostInstall). These are simple to add and give the user easy ways to hook into the build flow without having to drop down and modify the common code. Update: I've temporarily made this change.

OK this has me thinking (given something @daviwil mentioned a few days ago), we should look into splitting up the build.psake.ps1 file and putting the things the user is going to change in one file and the fixed stuff in another file (perhaps module-build.psake.ps1).

Finally, in testing the build script I found some cases where a newly created module wouldn't build without failures. When we are creating build steps like the help build for instance, we need to be sure we tolerate conditions like no exported commands.

@rkeithhill
Copy link
Collaborator Author

OK, I've fleshed out more extension points and renamed Pre/PostCopy. The only one missing that I can think of is Pre/PostTest. Anybody think we need that?

###############################################################################
# Customize these tasks for performing operations before and/or after Build.
###############################################################################

# Executes before the BuildImpl phase of the Build task.
Task PreBuild {
}

# Executes after the Sign phase of the Build task.
Task PostBuild {
}

###############################################################################
# Customize these tasks for performing operations before and/or after BuildHelp.
###############################################################################

# Executes before the GenerateMarkdown phase of the BuildHelp task.
Task PreBuildHelp {
}

# Executes after the BuildHelpImpl phase of the BuildHelp task.
Task PostBuildHelp {
}

###############################################################################
# Customize these tasks for performing operations before and/or after Install.
###############################################################################

# Executes before the InstallImpl phase of the Install task.
Task PreInstall {
}

# Executes after the InstallImpl phase of the Install task.
Task PostInstall {
}

###############################################################################
# Customize these tasks for performing operations before and/or after Publish.
###############################################################################

# Executes before publishing occurs.
Task PrePublish {
}

# Executes after publishing occurs.
Task PostPublish {
}

@daviwil
Copy link
Contributor

daviwil commented Oct 6, 2016

Nice! I like it so far. Some feedback:

  • Definitely agree on updated GenerateMarkdown and BuildHelp naming
  • Agreed on not blowing away the contents of the install folder unless absolutely desired, that could be risky
  • I don't think Pre/PostTest is needed, but we can add it later if someone comes up with a use case

@davegreen
Copy link
Collaborator

Nice,

  • GenerateMarkdown and BuildHelp is much better.
  • Also agreed on not deleting stuff by default.
  • Splitting the build.psake.ps1 into plaster and user maintained files is good.
  • The only thing I can think someone might want a pre/post test step for is to run script analyzer, but it's probably better building in a task to do that anyway.

@rkeithhill
Copy link
Collaborator Author

Good point on PSSA. You do get the benefit of real-time PSSA in VSCode but yeah, being a configurable/optional part of the build pipeline is a good idea. That way, you could run the build from the command line and (optionally) have PSSA fail the build if there are rule errors.

rkeithhill added a commit that referenced this issue Oct 7, 2016
This separates out the user customizations into a separate file build.settings.ps1.  Also made changes related to the discussion in issue #145. Fixed some bugs with the build script as well after a fair bit of testing.  Too bad my code-signing cert expired last month. Hopefully DigiCert will come through with a new cert so I can test the Sign task.
rkeithhill added a commit that referenced this issue Oct 7, 2016
* Refactored psake build script.

This separates out the user customizations into a separate file build.settings.ps1.  Also made changes related to the discussion in issue #145. Fixed some bugs with the build script as well after a fair bit of testing.  Too bad my code-signing cert expired last month. Hopefully DigiCert will come through with a new cert so I can test the Sign task.

* Eliminate 28 script analyzer warnings.
@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 9, 2016

Information only:

After @davegreen has added an Analyze step (using PSScriptAnalyzer), here is the current task list:

Task default -depends Build
Task Init -requiredVariables OutDir {
Task Clean -requiredVariables ReleaseDir {
Task Build -depends BuildImpl, Analyze, Sign, PostBuild {
Task BuildImpl -depends Init, Clean, PreBuild -requiredVariables SrcRootDir, OutDir {
Task Analyze -depends BuildImpl -requiredVariables ScriptAnalysisAction, OutDir {
Task Sign -depends BuildImpl -requiredVariables SettingsPath, SignScripts {
Task GenerateMarkdown -depends Build, PreBuildHelp -requiredVariables DocsRootDir, ModuleName, OutDir {
Task BuildHelp -depends BuildHelpImpl, PostBuildHelp {
Task BuildHelpImpl -depends GenerateMarkdown -requiredVariables DocsRootDir, OutDir {
Task Install -depends InstallImpl, PostInstall {
Task InstallImpl -depends BuildHelp, PreInstall -requiredVariables OutDir {
Task Test -depends Analyze -requiredVariables TestRootDir, ModuleName {
Task Publish -depends Test, PrePublish, PublishImpl, PostPublish {
Task PublishImpl -requiredVariables SettingsPath, OutDir {
Task ? -description 'Lists the available tasks' {
Task RemoveApiKey -requiredVariables SettingsPath {
Task StoreApiKey -requiredVariables SettingsPath {
Task ShowApiKey -requiredVariables SettingsPath {
Task ShowFullApiKey -requiredVariables SettingsPath {
Task RemoveCertSubjectName -requiredVariables SettingsPath {
Task StoreCertSubjectName -requiredVariables SettingsPath {
Task ShowCertSubjectName -requiredVariables SettingsPath {

The default build flow is now:

Init -> Clean -> PreBuild -> BuildImpl -> Analyze -> Sign -> PostBuild

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 9, 2016

Input required:

Right now the newly added Analyze task is enabled by default and will fail a build. I'm not sure that should be the default. Perhaps I'm just used to VS requiring me to enable CodeAnalysis if I want it.

Perhaps the default ScriptAnalysisAction should be Skip or maybe that should be called None? Thoughts @davegreen @daviwil ?

Also, I think I'd like to allow for script analysis customization via the NewModule template by adding this file to the src dir of a newly created PowerShell module project - ScriptAnalyzerSettings.psd1:

# The PowerShell Script Analyzer will generate a warning
# diagnostic record for this file due to a bug -
# https://github.com/PowerShell/PSScriptAnalyzer/issues/472
@{
    # Only diagnostic records of the specified severity will be generated.
    # Uncomment the following line if you only want Errors and Warnings but
    # not Information diagnostic records.
    #Severity = @('Error','Warning')

    # Analyze **only** the following rules. Use IncludeRules when you want
    # to invoke only a small subset of the defualt rules.
    IncludeRules = @('PSAvoidDefaultValueSwitchParameter',
                     'PSMissingModuleManifestField',
                     'PSReservedCmdletChar',
                     'PSReservedParams',
                     'PSShouldProcess',
                     'PSUseApprovedVerbs',
                     'PSUseDeclaredVarsMoreThanAssigments')

    # Do not analyze the following rules. Use ExcludeRules when you have
    # commented out the IncludeRules settings above and want to include all
    # the default rules except for those you exclude below.
    # Note: if a rule is in both IncludeRules and ExcludeRules, the rule
    # will be excluded.
    #ExcludeRules = @('PSAvoidUsingWriteHost')
}

This would give the user an obvious way to configure PSSA. Then we would add a .vscode\settings.json file if the user has chosen VSCode (or we figure out a way to determine that at runtime e.g. existence of an env var like VSCODE_PID):

{
    //  Use a custom PowerShell Script Analyzer settings file for this workspace.
    //  Relative paths for this setting are always relative to the workspace root dir.
    "powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1"
}
That said, we should only do this *if* we think this setting will be around for a while. I believe there has been talk on PSSA of just adopting a conventional filename then we wouldn't need this setting in vscode-powershell anymore.  Thoughts?  @kapilmb @daviwil

I also like the settings.json idea because I would probably drop this into the workspace settings file as well:

    //-------- Files configuration --------

    // When enabled, will trim trailing whitespace when you save a file.
    "files.trimTrailingWhitespace": true,

This should be a mandatory setting for PowerShell script authoring IMO given the issues with whitespace trailing a line continuation char.

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 9, 2016

Also, we need to update the NewModule plasterManifest.xml file to indicate if PSScriptAnalyzer is a required module with an appropriate message to the user. Right now, PSSA appears to be required because if I try to build a newly scaffolded "NewModule" I get an error if I don't have PSSA installed:

The term 'Invoke-ScriptAnalyzer' is not recognized as the name of a cmdlet, function, script file, or operable program.

I think the module probably should not require PSSA and the build script should tolerate not having the module. Simple emit a message about "Skipping Analyze task" if PSSA is not installed (or ScriptAnalyisAction is set None). Although, if it's the case of PSSA not installed AND they have ScriptAnalysisAction set to something other than None, then we should let the user know that the Analyze task is being skipped because they haven't installed the PSSA module.

In the NewModule manifest then we would probably want to add a <requireModule> directive with the message that without PSScriptAnalyzer module installed, the build system will not perform script analysis during the "Build". Thoughts? Update: Done

@davegreen
Copy link
Collaborator

I didn't think about users not having PSSA at all, I'm not sure why. We can always detect on the module existence and skip based on that. I set the initial default to Error, mostly because I feel like you have to do some potentially quite bad things to get an error severity out of it. There is currently a 'None' setting which essentially gets you a 'report only' output with no fail, so that would probably be the way forward if the module is present.

The ScriptAnalyzerSettings.psd1 is a good idea, as it gives the user an easy route into customization if they need it.

I definitely agree on the settings.json for VSCode, with a default inclusion like that. That setting is nice :).

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 9, 2016

I set the initial default to Error, mostly because I feel like you have to do some potentially quite bad things to get an error severity out of it.

Good point. I could go either way on "enabled by default or not". Let's think about that a bit. I'm in the process of adding in the ScriptAnalysisSettings.psd1 / settings.json. Let me submit that PR in a few minutes - have you look it over. After we merge that in, perhaps you can fix the Analyze task to handle PSSA not being installed. Also, if you wouldn't mind, update plasterManifest.xml to put in a <requireModule> directive letting them know what they don't get without the module. Same as you did for platyPS.

RE None vs Skip - any chance we can rename that. I know coming from the VS space, I would consider "None" to be what you currently mean by "Skip". Perhaps the current None behavior could be renamed to "ReportOnly" (can't think of a better name ATM)? Thanks man!

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 9, 2016

Input required:

Also, the current "editor-based" PSSA ruleset is different (more limited) than the current build script that ships with the NewModule template. It uses the default ruleset with just one rule disabled: PSMissingModuleManifestField. That is to prevent a warning on the ScriptAnalyzerSettings.psd1 file. We don't need this rules as we verify the module's manifest file with a Pester test.

All that said, is this going to be confusing for users of the template within VSCode?

@davegreen
Copy link
Collaborator

RE None vs Skip, That would make more sense with the altered variable names, with None being ReportOnly and Skip becoming None.

Sure, I can do the Analyze task skip if the module isn't installed and the manifest requiremodule directive.

I'm unsure about how to deal with the differences in PSSA between editor based and running the module. I imagine the goal is to eventually get to parity?

@rkeithhill
Copy link
Collaborator Author

Sounds good. I've merged by PR so you have the floor. :-) WRT to the ruleset difference, hopefully @daviwil will weigh in on that.

@rkeithhill
Copy link
Collaborator Author

After using the latest build script I'm beginning to wonder about a couple of things. First, script analysis is slow. Should we put this in a later build step? Second, should we be doing anything with New-FileCatalog on system that have this cmdlet installed? We could be creating a .cat file for a module and if script signing is enabled, Authenticode sign the .cat file.

Also, I find this name $CodeCoverageStop and tristate use unintuitive. I think we should have a simple "$CodeCoverageEnabled" bool. I don't think we need to fail a build for lack of code coverage. I've never seen that out in the real world (well, at least where I work). :-) Plus that might be getting a bit too opinionated. Most IDE/build systems tend to just "report" code coverage.

Similarly for $ScriptAnalysisAction, I'd like to break that tristate up into a $ScriptAnalysisEnabled bool and a $ScriptAnalysisFailBuildOnSeverityLevel [string](defaults to Error but could be Warning or Information or None). There are not many PSSA error rules and the ones that exist should probably break the build if the user has enabled ScriptAnalysis. The user has several ways to mitigate the build error. They can add the rules to the list of exclusions in the PSSA settings file or they can suppress the message in the source. This has the benefit of removing the error from VSCode's problems window. I also propose we eliminate $SkipScriptAnalysisHost. PSSA still runs in VSCode because A) the terminal name is ConsoleHost. Besides, if I have ScriptAnalyis set up to fail my build, I definitely want it to run. BTW we've been using the general term ScriptAnalysis. I wonder if we should just called it $ScriptAnalyzer*?

Finally, for consistency I'd like to change the $SignScripts to $ScriptSigningEnabled.

I'll take a whack at the build script bits and submit a PR today so we have some code to look at.

@rkeithhill
Copy link
Collaborator Author

I had other work to do so I went ahead and merged this PR. If we decide we want the "fail build on lack of code coverage", let me know. If we do then I would add a new variable called something like $CodeCoverageFailBuildUnderPercentage and default it to 0. Then folks that want this can up the percentage to whatever they want.

Yeah I know, long variable name but I figure folks won't need to go into the settings very often. So when they do, we want variable names to be pretty obvious.

@davegreen
Copy link
Collaborator

OK, that sounds good. I don't use code coverage in the things I write, so I thought if I included the option, it could be used or not, so that's fine. That's probably a better way to control it as well if we were to re-add it.

The script analyzer bits sound great too. the variable format $ScriptAnalyzer* for all of the PSSA settings would be nice, it sets us up for each section to have nice organised variable names for the settings.

@davegreen
Copy link
Collaborator

I didn't know VS code used ConsoleHost, I obviously didn't dig deep enough there, sorry!

@rkeithhill
Copy link
Collaborator Author

I dithered on the ScriptAnalyzer* names. I changed all three variables to ScriptAnalyzer* and looked at it and didn't like it. Mainly for the variable that controls build failure severity level as that isn't a ScriptAnalyzer thing, it is purely a construct of our build script. OTOH the settings files is definitely ScriptAnalyzer specific file, so I did change that variable to ScriptAnalyzerSettingsPath. And ScriptAnalyzerEnabled seemed less idea than ScriptAnalysisEnabled. That said, I could be convinced to go either way as I'm kind of on the fence as it is on this. Naming is hard. :-)

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Oct 31, 2016

I didn't know VS code used ConsoleHost

Well the current implementation for the debugger host returns "Visual Studio Code Host" but users would rarely execute the build script under the debugger. Most of the time, from VSCode, you run build & test tasks via the Task Runner and it is configured to launch PowerShell.exe. So you get ConsoleHost.

@rkeithhill
Copy link
Collaborator Author

rkeithhill commented Nov 2, 2016

Should we try to tackle versioning at all? Or just leave it up to the user to change the version number in their .psd1 file (and anywhere else it might need updating)?

Should we try to tackle combining individual .ps1 script files into the module's .psm1 file (perhaps as an option)? Does having separate scripts to dot source from within a .psm1 really impact load time that much?

@gerane
Copy link
Contributor

gerane commented Nov 17, 2016

@rkeithhill There is a module called BuildHelpers that is used as a Helper Module for PSDeploy. It has functions to update the psd1 metadata, update functions to export and get/update the next module version etc. I have been using it in my build scripts to update functions to export(my exported functions are in a public folder), Formats to export (in a formats folder), Module version, and things like that. It has really made that very easy with only a few lines of code.

If the option to combine all functions into the psm1 were added, you could still update the functions to export prior to the merge. However, this still doesn't address some issues I have seen discussed in the community, which is how to adapt these types of processes to a CI/CD sort of platform like Appveyor or Teamcity.

Since these platforms are typically triggered at commit, how do you handle all of the steps that are generating markdown, building help, making updates to the psd1, signing, publishing etc that are now out of sync with git and your local build. This is an issue that I hear people talk about very often. I have had multiple people message me asking about how to handle this problem, and I don't know the answer and have not be able to find anyone that had a clear solution.

The template still doesn't answer that question for people, and I wonder how you would adapt the psake build script to work in that scenario.

@dbroeglin
Copy link

@gerane
About:

Since these platforms are typically triggered at commit, how do you handle all of the steps that are generating markdown, building help, making updates to the psd1, signing, publishing

Maybe the issues arise from the fact that some of those steps should not be in the build process. For instance, updating the functions to export is a step taken by the developer. It is a conscious decision when adding the new function. Which means that it should be part of the source code, not the build process. If the building tools like PSake offer a way to automate repetitive tasks, it does not mean they should all end in the automated build.

To me, changing the version number is one of those. You can automate the various steps, tag, change version number, generate release notes. But obviously, you would not like to release each time a build is launched. If you use a git workflow you could rig the build so that a release happens automatically when you commit to a particular branch. However, I cannot see how the build process could automatically increment the version number. This is a decision the release manager has to make: do i increment patch, minor or major ?

Maybe I did not get the question correctly, but it reminded me a lot of a colleague of mine I was helping releasing his module so I thought I would add my 2c.

@rkeithhill
Copy link
Collaborator Author

I agree that a "publish" step shouldn't be part of a "normal" build.

If the building tools like PSake offer a way to automate repetitive tasks, it does not mean they should all end in the automated build.

That's the key. You can have many build steps that are not part of what you would run as an "automated" Travis/AppVeyor build. But they are there when you need to run them manually or via a Task Runner like the one in VSCode.

As for updating version numbers, it is actually quite common to update version numbers automatically during a build. It is just that the major & minor version (and sometimes the patch version) are specified in a config file or build variable somewhere so you still have that control. The rest of the version number (typically build metadata) gets auto-generated based on that static info. Checkout GitVersion.

@dbroeglin
Copy link

@rkeithhill

Yes your are correct, I was referring to version number changes that occur in case of a release, build numbers should be changed by the build. I did not know GitVersion, I will look into it.Thanks for mentioning it.

About :

Should we try to tackle combining individual .ps1 script files into the module's .psm1 file (perhaps as an option)? Does having separate scripts to dot source from within a .psm1 really impact load time that much?

For small modules it may not matter much, but as soon as things get a bit bigger you need a way to split things up. I contribute to the Netscaler module https://github.com/devblackops/NetScaler where we have more than a hundred functions. It would be completely unmanageable if they were not organised by file. I did not consider the performance impact. That could be an issue but did not see a really noticeable impact for the 135 files we currently have.

In the Netscaler module we use the following loading pattern, because Public and Private functions are separated into distinct directories:

# Load public functions
$publicFunctions = Get-ChildItem -Path "$PSScriptRoot\Public" -Recurse -Include *.ps1 -Exclude *.tests.ps1
foreach ($function in $publicFunctions) {
    . $function.FullName
}

# Load private functions
$privateFunctions = Get-ChildItem -Path "$PSScriptRoot\Private" -Recurse -Include *.ps1 -Exclude *.tests.ps1
foreach ($function in $privateFunctions) {
    . $function.FullName
}

In Forge and in all modules with more than 1 public function that I did during the last months I use the following pattern:

$functions = Get-ChildItem -Path $PSScriptRoot -Recurse -Include *.ps1
$functions | ForEach-Object { . $_.FullName }

In any case, even if the template generates the loading code, it is very easy for the module developer to just remove it if he does not like it.

From my point of view that way of doing things has two other advantages:

  1. It allows for generating module functions (after the module has already been generated and development is ongoing). That generator can then generate both the function scaffold and the pester test scaffold.
  2. If things are laid out like that, it also allows for the test to load just the code it needs and make things more "atomic". At first I was always loading the full module to run a unit test but it has the disadvantage of forcing a full load of the module and it hides private functions from the tests. Pester can circumvent that but it brings unnecessary complexity to the tests. Usually I use following pattern:
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$PSScriptRoot\..\MyModule\$sut"

What do you think ?

@ngetchell
Copy link

ngetchell commented Mar 10, 2017

I run my pester tests on the release folder since that is where the full module resides. That means code, help, formats, and manifest. Since I create pester tests to make sure the help is complete ( is it auto generated vs actually populated, do parameters have help, etc) I need the generated MAML file.

Shouldn't Build include generating the MAML file from the docs?

@LaurentDardenne
Copy link

Notes on the build :

The build tasks are implicitly linked to the structure of the project, that is not specified.

The order of execution of the tasks is not specified. See

Specify that the template is oriented mono-module.

The Apikey should be linked to the repository not to the template, if I change the key I have to change all projects using the same repository.
If I have a separate file I change it once.

Tasks to improve

CoreStagefiles:
The task creates the destination directory $ModuleOutDir, it is inaccessible in the 'beforeStageFile'

Move :

    New-Item $ModuleOutDir -ItemType Directory -Verbose:$VerbosePreference > $null

to the 'Clean' task :

 Get-ChildItem $OutDir | Remove-Item -Recurse -Force -Verbose:($VerbosePreference -eq 'Continue')
  #NewDirectory is a function to create directory
 NewDirectory -Path $ModuleOutDir -TaskName $psake.context.currentTaskName

CorePublish :
The first declaration seem duplicate :

    $publishParams = @{
        Path        = $ModuleOutDir
        NuGetApiKey = $NuGetApiKey
    }

When I want publish inside a CI (Appveyor) or execute the build inside a Job, the function 'PromptUserForCredentialAndStorePassword' is not appropriate.

Analyze :
The task does not use the external rule modules. See PowerShell/PSScriptAnalyzer#675

Settings
May be add this variables :

 $ProjectName= 'PROJECTNAME'
 $ProjectUrl= 'https://github.com/USER/Project.git'

Name of the Modules for additionnal custom rule :

    [String[]]$PSSACustomRules=@(
       #GetModulePath return the full path of the module
      GetModulePath -Name OptimizationRules
      GetModulePath -Name ParameterSetRules
    )

ApiKey setting file name :

    # Path to encrypted APIKey file(s).
    $NuGetApiKeyPath = "$env:LOCALAPPDATA\Plaster\SecuredBuildSettings\$PublishRepository-ApiKey.clixml"

Template can targeted many projects
May be change :

   $SettingsPath = "$env:LOCALAPPDATA\Plaster\NewModuleTemplate\SecuredBuildSettings.clixml"

to

   $SettingsPath = "$env:LOCALAPPDATA\Plaster\SecuredBuildSettings\$ProjectName.clixml"

Add BuildConfiguration : 'Release' or 'Debug'

    $BuildConfiguration='Release'

I can deploy a module with trace (DEBUG) or without trace (RELEASE)

bug :

-Verbose:$Verboseprefrence

to

-Verbose:($VerbosePreference -eq 'Continue')

During the execution of the 'Publish" task, I get this Warning :

WARNING: ReleaseNotes is now supported in the module manifest file (.psd1). Update the module manifest file of module
'Template' in 'G:\PS\Template\Release\Template' with the newest ReleaseNotes changes. You can run Update-ModuleManifest
 -ReleaseNotes to update the manifest with ReleaseNotes.

Any idea (ps v5.1) ?

@LaurentDardenne
Copy link

The note on the export of the apikey in a separate file concerns the case where I want to use two repository, one for testing (MyGet) and one for the public (PSGallery).

@LaurentDardenne
Copy link

For information, inside a PS Job the $Profile variable do not exist, this statements fail :

 $InstallPath = Join-Path (Split-Path $profile.CurrentUserAllHosts -Parent) `
             "Modules\$ModuleName\$((Test-ModuleManifest -Path $SrcRootDir\$ModuleName.psd1).Version.ToString())"

I get this exception :

~~~ [<<==>>] Exception: Cannot bind argument to parameter 'Path' because it is null.

Test :

test-path variable:Profile
True
start-job {test-path variable:Profile}|Receive-Job -Wait -AutoRemoveJob
False

Same issue under Appveyor, possible workaround :

install:
  - ps: |

          PowerShell.exe -Command {
           Export-Clixml -InputObject $Profile -Path  $env:temp\PSProfile.xml }

build_script:
   - ps: |

         $Profile=Import-Clixml $env:temp\PSProfile.xml
         .\build.ps1 ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants