Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- `Package.Latest` now supports policy values: `"never"`, `"stable"`, and `"always"`.
- `"stable"` keeps the floating `latest` alias pinned to stable package versions.
- Legacy boolean values still work for now and map to `"always"` / `"never"` for backward compatibility.

### Deprecated

- Boolean `Package.Latest` values are deprecated and will be removed in the next major version.

### Removed

### Fixed
Expand Down Expand Up @@ -74,9 +80,8 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma
### Deprecated

- `Invoke-NovaRelease` parameters that differ from `Publish-NovaModule` and `% nova release` such as `-Local`,
`-Repository`,
`-ModuleDirectoryPath`, and `-ApiKey` are now the primary PowerShell release parameters, while `-PublishOption` is
deprecated.
`-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` are now the primary PowerShell release parameters, while
`-PublishOption` is deprecated and will be removed in the next major version.

### Fixed

Expand Down Expand Up @@ -385,4 +390,3 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma
[0.0.6]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.5...Version_0.0.6
[0.0.5]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.4...Version_0.0.5
[0.0.4]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.3...Version_0.0.4

12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ Use this `project.json` shape when you want to control the package types and out
"PackageFileName": "AgentInstaller",
"AddVersionToFileName": true,
"Types": ["NuGet", "Zip"],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
Expand All @@ -326,14 +326,16 @@ Use this `project.json` shape when you want to control the package types and out
- `Types` is optional. When it is missing, empty, or null, Nova defaults to `NuGet` and creates a `.nupkg`.
- Supported `Types` values are `NuGet`, `Zip`, `.nupkg`, and `.zip`, and matching is case-insensitive.
- Use `Types = ["Zip"]` when you only want a `.zip`, or `Types = ["NuGet", "Zip"]` when you want both files.
- `Latest` is optional and defaults to `false`. When set to `true`, Nova also creates a companion `*.latest.*`
artifact for each selected package type, such as `NovaModuleTools.latest.nupkg` next to the normal versioned file.
- `Latest` is optional and defaults to `"never"`.
- Set `Latest` to `"stable"` when only stable versions should also create companion `*.latest.*` artifacts.
- Set `Latest` to `"always"` when both stable and preview versions should also create companion `*.latest.*` artifacts.
- Set `Latest` to `"never"` when you only want versioned package files.
- `PackageFileName` lets you override the base artifact name.
- `AddVersionToFileName` defaults to `false`. When set to `true`, Nova appends `.<Version>` from `project.json` to the
configured `PackageFileName`, so `AgentInstaller` becomes `AgentInstaller.2.3.4` before the package
extension is applied.
- When both `AddVersionToFileName` and `Latest` are enabled, the companion artifact substitutes that appended version
suffix with `.latest`, such as `AgentInstaller.latest.nupkg`.
- When `AddVersionToFileName` is enabled and `Latest` is `"stable"` or `"always"`, the companion artifact substitutes
the appended version suffix with `.latest`, such as `AgentInstaller.latest.nupkg`.
- `Path` selects where the package artifact(s) are written.
- `Clean` defaults to `true` and removes that output directory before a new package is created.
- Set `Clean` to `false` when you want to keep existing files in the package output directory.
Expand Down
2 changes: 1 addition & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ coverage:
target: auto
patch:
default:
target: 100%
target: 99%
2 changes: 1 addition & 1 deletion docs/NovaModuleTools/en-US/Deploy-NovaPackage.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Uploads only the matching `.zip` artifacts for the current project.
### EXAMPLE 5

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

Uploads the explicitly selected package files instead of discovering them from the configured package output directory.
Expand Down
20 changes: 13 additions & 7 deletions docs/NovaModuleTools/en-US/New-NovaModulePackage.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Use this `project.json` shape when you want to control package types and the pac
"NuGet",
"Zip"
],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
Expand All @@ -62,16 +62,22 @@ a `.nupkg` file.

Supported `Package.Types` values are `NuGet`, `Zip`, `.nupkg`, and `.zip`, and matching is case-insensitive.

`Package.Latest` is optional and defaults to `false`. When set to `true`, `New-NovaModulePackage` also writes a
companion `*.latest.*` artifact for each selected package type while keeping the normal versioned file.
`Package.Latest` is optional and defaults to `"never"`.

Set `Package.Latest` to `"stable"` when only stable versions should also write companion `*.latest.*` artifacts.

Set `Package.Latest` to `"always"` when both stable and preview versions should also write companion `*.latest.*`
artifacts.

Set `Package.Latest` to `"never"` when only the versioned package file(s) should be written.

`Package.PackageFileName` lets you override the base package file name.

`Package.AddVersionToFileName` defaults to `false`. When you set it to `true`, Nova appends `.<Version>` from
`project.json` to the configured `Package.PackageFileName` before the package extension is applied.

When both `Package.AddVersionToFileName` and `Package.Latest` are enabled, `New-NovaModulePackage` replaces that
appended version suffix with `.latest` for the companion artifact.
When `Package.AddVersionToFileName` is enabled and `Package.Latest` is `"stable"` or `"always"`, `New-NovaModulePackage`
replaces that appended version suffix with `.latest` for the companion artifact.

`Package.OutputDirectory.Clean` defaults to `true`, which deletes the configured package output directory before a new
package is created. Set it to `false` when you want to keep existing files in that directory.
Expand Down Expand Up @@ -113,8 +119,8 @@ package output directory.
PS> New-NovaModulePackage
```

When `Package.Latest` is `true`, the command keeps the normal versioned package file and also writes a companion latest
file such as `NovaModuleTools.latest.nupkg`.
When `Package.Latest` is `"stable"` and the project version is stable, the command keeps the normal versioned package
file and also writes a companion latest file such as `NovaModuleTools.latest.nupkg`.

### EXAMPLE 5

Expand Down
4 changes: 2 additions & 2 deletions docs/packaging-and-delivery.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,14 @@ <h3>Common examples</h3>
<pre><code>{
"Package": {
"Types": ["NuGet", "Zip"],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
}
}
}</code></pre>
<p>This creates both formats and also adds <code>latest</code> aliases, such as:</p>
<p>This creates both formats and, for stable versions, also adds <code>latest</code> aliases, such as:</p>
<pre><code>MyModule.2.0.0.nupkg
MyModule.latest.nupkg
MyModule.2.0.0.zip
Expand Down
15 changes: 7 additions & 8 deletions docs/project-json-reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ <h2>Complete example</h2>
"Package": {
"Id": "NovaExampleModule",
"Types": ["NuGet", "Zip"],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
Expand Down Expand Up @@ -396,10 +396,9 @@ <h3>Package creation settings</h3>
</tr>
<tr>
<td><code>Latest</code></td>
<td><code>false</code></td>
<td>Whether to create companion <code>latest</code> artifacts for each selected type.</td>
<td>When <code>true</code>, Nova keeps the normal versioned artifact and adds a second file
such as <code>MyModule.latest.nupkg</code>.
<td><code>"never"</code></td>
<td>Controls whether Nova creates companion <code>latest</code> artifacts for each selected type.</td>
<td>Use <code>"stable"</code> to update <code>latest</code> only for stable versions, <code>"always"</code> for both stable and preview versions, or <code>"never"</code> to disable the floating alias.
</td>
</tr>
<tr>
Expand Down Expand Up @@ -650,15 +649,15 @@ <h3>Create both NuGet and Zip artifacts, plus latest aliases</h3>
<pre><code>{
"Package": {
"Types": ["NuGet", "Zip"],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
}
}
}</code></pre>
<p>This creates four files when both package types are selected: versioned and <code>latest</code>
variants for each format.</p>
<p>This creates four files for stable versions when both package types are selected: versioned and
<code>latest</code> variants for each format.</p>

<h3>Use named raw repositories with shared defaults</h3>
<pre><code>{
Expand Down
4 changes: 2 additions & 2 deletions docs/troubleshooting.html
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,10 @@ <h2>Raw upload auth does not work</h2>
<h2>Package output contains both versioned and <code>latest</code> artifacts</h2>
<p><strong>Likely cause:</strong> <code>Package.Latest</code> is enabled.</p>
<p><strong>Fix:</strong> if you only want versioned files, remove the setting or set it to
<code>false</code>.</p>
<code>"never"</code>.</p>
<pre><code>{
"Package": {
"Latest": false
"Latest": "never"
}
}</code></pre>
<p><strong>Success looks like:</strong> the next package run creates only the normal versioned
Expand Down
42 changes: 28 additions & 14 deletions src/private/package/GetNovaPackageMetadataList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function Get-NovaPackageMetadataList {
)

$packageTypeList = @(Get-NovaConfiguredPackageTypeList -PackageSettings $ProjectInfo.Package)
$includeLatest = Test-NovaPackageLatestEnabled -PackageSettings $ProjectInfo.Package
$includeLatest = Test-NovaPackageLatestEnabled -PackageSettings $ProjectInfo.Package -Version $ProjectInfo.Version

return @(
foreach ($packageType in $packageTypeList) {
Expand Down Expand Up @@ -42,24 +42,38 @@ function Get-NovaConfiguredPackageTypeList {
function Test-NovaPackageLatestEnabled {
[CmdletBinding()]
param(
[AllowNull()]$PackageSettings
[AllowNull()]$PackageSettings,
[Parameter(Mandatory)][string]$Version
)

if ($PackageSettings -is [System.Collections.IDictionary]) {
if ( $PackageSettings.Contains('Latest')) {
return [bool]$PackageSettings['Latest']
$latestPolicy = Get-NovaPackageLatestPolicy -PackageSettings $PackageSettings
switch ($latestPolicy) {
'always' {
return $true
}
'stable' {
return Test-NovaPackageVersionIsStable -Version $Version
}
default {
return $false
}

return $false
}
}

if ($null -eq $PackageSettings) {
return $false
}
function Get-NovaPackageLatestPolicy {
[CmdletBinding()]
param(
[AllowNull()]$PackageSettings
)

if ($PackageSettings.PSObject.Properties.Name -contains 'Latest') {
return [bool]$PackageSettings.Latest
}
return ConvertTo-NovaPackageLatestPolicy -Value (Get-NovaPackageSettingValue -InputObject $PackageSettings -Name 'Latest')
}

function Test-NovaPackageVersionIsStable {
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$Version
)

return $false
return [string]::IsNullOrWhiteSpace(([semver]$Version).PreReleaseLabel)
}
44 changes: 42 additions & 2 deletions src/private/shared/GetNovaResolvedProjectPackageSettings.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,56 @@ function Get-NovaResolvedProjectPackageSettings {
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'FileNamePattern' -Value "$( $packageSettings['Id'] )*" -TreatWhitespaceAsMissing
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Authors' -Value $ManifestSettings['Author']
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Description' -Value $ProjectData['Description'] -TreatWhitespaceAsMissing
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Latest' -Value $false
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Latest' -Value 'never'
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Repositories' -Value @()
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Headers' -Value ([ordered]@{})
Set-NovaPackageSettingDefault -PackageSettings $packageSettings -Name 'Auth' -Value ([ordered]@{})

$packageSettings['Latest'] = [bool]$packageSettings['Latest']
$packageSettings['Latest'] = ConvertTo-NovaPackageLatestPolicy -Value $packageSettings['Latest']
$packageSettings['AddVersionToFileName'] = [bool]$packageSettings['AddVersionToFileName']
$packageSettings['Repositories'] = @($packageSettings['Repositories'])
$packageSettings['Headers'] = [ordered]@{} + $packageSettings['Headers']
$packageSettings['Auth'] = [ordered]@{} + $packageSettings['Auth']

return $packageSettings
}

function ConvertTo-NovaPackageLatestPolicy {
[CmdletBinding()]
param(
[AllowNull()]$Value
)

if ($null -eq $Value) {
return 'never'
}

# TODO: Remove legacy boolean Package.Latest handling in the next major version.
if ($Value -is [bool]) {
if ($Value) {
return 'always'
}

return 'never'
}

$policy = "$Value".Trim()
if ([string]::IsNullOrWhiteSpace($policy)) {
return 'never'
}

switch -Regex ($policy) {
'^(?i)never$' {
return 'never'
}
'^(?i)stable$' {
return 'stable'
}
'^(?i)always$' {
return 'always'
}
default {
Stop-NovaOperation -Message "Invalid project.json Package.Latest value: $Value. Use one of: 'never', 'stable', 'always'." -ErrorId 'Nova.Validation.InvalidPackageLatestPolicy' -Category InvalidData -TargetObject $Value
}
}
}
10 changes: 9 additions & 1 deletion src/resources/Schema-Build.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,15 @@
}
},
"Latest": {
"type": "boolean"
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"enum": ["never", "stable", "always"]
}
]
},
"OutputDirectory": {
"anyOf": [
Expand Down
5 changes: 3 additions & 2 deletions src/resources/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ After `New-NovaModulePackage`, the package artifact is written to:
src/resources/example/artifacts/packages/
```

The example project sets `Package.Types` to `['NuGet', 'Zip']` and `Package.Latest` to `true`, so packing generates the
normal versioned `.nupkg` / `.zip` files plus companion `*.latest.*` files in the package output directory.
The example project sets `Package.Types` to `['NuGet', 'Zip']` and `Package.Latest` to `"stable"`, so stable packing
generates the normal versioned `.nupkg` / `.zip` files plus companion `*.latest.*` files in the package output
directory.

The example `project.json` also shows how to configure raw package upload settings such as:

Expand Down
2 changes: 1 addition & 1 deletion src/resources/example/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"NuGet",
"Zip"
],
"Latest": true,
"Latest": "stable",
"OutputDirectory": {
"Path": "artifacts/packages",
"Clean": true
Expand Down
Loading
Loading