How-to Guides

Know whether you need pack, upload, publish, or release

NovaModuleTools gives you four different delivery commands because they solve four different problems. This page shows you what each command does, what it does not do, and how to configure the related workflow safely.

Choose the right command

Command What it does What it does not do Use it when…
New-NovaModulePackage / % nova package Builds, tests, and creates package artifacts such as .nupkg and .zip. Does not upload or publish the package anywhere. You need artifacts in artifacts/packages/.
Deploy-NovaPackage / % nova deploy Uploads existing artifacts to a raw HTTP endpoint. Does not build, test, or create the package first. You already have artifacts and need to push them to Nexus, Artifactory, or another raw endpoint.
Publish-NovaModule / % nova publish Builds, tests, and publishes the module locally or to a PowerShell repository. Does not create generic raw HTTP uploads. You want the PowerShell module itself published, not just an arbitrary artifact.
Invoke-NovaRelease / % nova release Builds, tests, bumps the version, rebuilds, and then publishes. Does not replace New-NovaModulePackage or raw upload as a generic artifact workflow. You want one orchestrated release command instead of separate steps.
Most confusion comes from this difference:

New-NovaModulePackage creates files. Deploy-NovaPackage sends those files to a raw endpoint. Publish-NovaModule publishes the module itself to a PowerShell repository. Invoke-NovaRelease coordinates versioning plus publishing.

Create package artifacts

Use New-NovaModulePackage or % nova package when you want a package artifact generated from the built module output.

What happens

  1. Nova builds the project.
  2. Nova runs the test workflow.
  3. Nova creates one or more package artifacts under Package.OutputDirectory.Path, which defaults to artifacts/packages/.
CI/CD shortcut:

Use -SkipTests, --skip-tests, or -s when tests already ran earlier in your pipeline. Nova still rebuilds before packaging; it only skips Invoke-NovaTest and Test-NovaBuild.

Common examples

Create package artifacts

Showing: PowerShell

PS> New-NovaModulePackage
PS> New-NovaModulePackage -SkipTests

This creates a .nupkg by default when Package.Types is omitted.

{
  "Package": {
    "Types": ["Zip"]
  }
}

This creates only a .zip.

{
  "Package": {
    "Types": ["NuGet", "Zip"],
    "Latest": "stable",
    "OutputDirectory": {
      "Path": "artifacts/packages",
      "Clean": true
    }
  }
}

This creates both formats and, for stable versions, also adds latest aliases, such as:

MyModule.2.0.0.nupkg
MyModule.latest.nupkg
MyModule.2.0.0.zip
MyModule.latest.zip

What metadata is reused

  • top-level ProjectName, Description, and Version
  • Manifest.Author
  • Manifest.Tags
  • Manifest.ProjectUri
  • Manifest.ReleaseNotes
  • Manifest.LicenseUri

See package settings in the configuration reference

Upload package artifacts to a raw endpoint

Use Deploy-NovaPackage or % nova deploy when you already have package files and you need to push them to a raw HTTP endpoint.

Upload works on existing files only.

If you have not run New-NovaModulePackage yet, upload has nothing to send unless you explicitly point it at existing package files with -PackagePath.

Common ways to target artifacts

Upload to a named repository target

Showing: PowerShell

PS> Deploy-NovaPackage -Repository LocalNexus

Use a named repository from Package.Repositories.

Upload to a direct URL target

Showing: PowerShell

PS> Deploy-NovaPackage -Url 'https://packages.example/raw/' -Token $env:NOVA_PACKAGE_TOKEN

Use a direct URL when CI or a one-off script already knows the endpoint.

Filter upload to one package type

Showing: PowerShell

PS> Deploy-NovaPackage -PackageType Zip -Repository LocalNexus

Filter to only one package type.

Upload explicit package files

Showing: PowerShell

PS> Deploy-NovaPackage -PackagePath @(
  'artifacts/packages/MyModule.2.0.0.zip',
  'artifacts/packages/MyModule.latest.zip'
) -Url 'https://packages.example/raw/releases/'

Use explicit file paths when you do not want Nova to discover package files from the configured output directory.

How upload target resolution works

  1. If you pass -Url, Nova uses it.
  2. Otherwise, if you pass -Repository, Nova resolves the matching entry from Package.Repositories.
  3. Otherwise, Nova falls back to package-level defaults such as Package.RepositoryUrl.

If no target can be resolved, upload fails fast with a clear error telling you to provide -Url or configure package-level upload settings.

Headers and auth

Upload uses a generic auth model so you can target many raw repository types without turning the command into a vendor-specific integration.

Scenario Recommended configuration
Bearer token HeaderName = "Authorization", Scheme = "Bearer", TokenEnvironmentVariable = "NOVA_PACKAGE_TOKEN"
Custom API key header HeaderName = "X-Api-Key", TokenEnvironmentVariable = "NOVA_PACKAGE_API_KEY"
HTTP Basic auth HeaderName = "Authorization", Scheme = "Basic", and an environment variable whose value is the Base64-encoded username:password

When multiple matching files exist, Nova uploads all matching artifacts for the selected type or configured types. That includes versioned and latest artifacts.

See upload auth troubleshooting

Publish to a PowerShell repository

Use Publish-NovaModule or % nova publish when you want to publish the built module itself either locally or to a PowerShell repository.

Local publish

Publish locally

Showing: PowerShell

PS> Publish-NovaModule -Local

Local publish is useful when you want to validate a realistic install/import cycle without pushing to a shared repository. After a successful local publish, Nova reloads the published module from the local install path into the current PowerShell session.

Repository publish

Publish to a PowerShell repository

Showing: PowerShell

PS> Publish-NovaModule -Repository PSGallery -ApiKey $env:PSGALLERY_API
PS> Publish-NovaModule -Repository PSGallery -ApiKey $env:PSGALLERY_API -SkipTests
PS> Publish-NovaModule -Repository PSGallery -ApiKey $env:PSGALLERY_API -ContinuousIntegration

Repository mode is for registered PowerShell repositories such as PowerShell Gallery.

Custom local path

Publish locally to a custom module path

Showing: PowerShell

PS> Publish-NovaModule -Local -ModuleDirectoryPath ~/Modules

Use this when you want local publishing to target a custom module directory.

CI/CD shortcut:

Use -SkipTests, --skip-tests, or -s when tests already ran earlier in the pipeline. Publish still rebuilds before copying or repository publishing.

CI/self-hosting activation:

Use -ContinuousIntegration, --continuous-integration, or -i when later commands in the same session must switch back to the built dist/ module after publish completes.

What -WhatIf means here

When you preview local publish, Nova does not build, test, copy, or import the module. The preview is safe and side-effect free.

Run the release workflow

Use Invoke-NovaRelease or % nova release when you want one command to coordinate build, test, version bump, rebuild, and publish.

What happens

  1. Build the module.
  2. Run the tests.
  3. Calculate and write the next semantic version.
  4. Build again so the output reflects the new version.
  5. Publish locally or to a repository.
CI/CD shortcut:

Use -SkipTests, --skip-tests, or -s when tests already ran earlier in your pipeline. Release still runs both build steps; it only skips the pre-release Invoke-NovaTest and Test-NovaBuild steps.

Examples

Run the release workflow

Showing: PowerShell

PS> Invoke-NovaRelease -Local
PS> Invoke-NovaRelease -Repository PSGallery -ApiKey $env:PSGALLERY_API
PS> Invoke-NovaRelease -Repository PSGallery -ApiKey $env:PSGALLERY_API -SkipTests
PS> Invoke-NovaRelease -Repository PSGallery -ApiKey $env:PSGALLERY_API -ContinuousIntegration

Important difference from local publish

Local release does not import the published module into your current session afterward. That behavior is specific to Publish-NovaModule -Local.

When you use the continuous-integration form, Nova still restores the built dist/ module after the CI-sensitive release boundaries so later commands in the same session keep using the built module state.

When to prefer release over separate steps

  • Use release when your version bump and publish should happen together.
  • Use separate commands when you want to inspect artifacts, review versioning, or pause between steps.

See how version bump selection works