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
6 changes: 5 additions & 1 deletion .github/workflows/check-upstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ jobs:
run: |
Import-Module ./.hub/module/LANCommander.Redistributables -Force

$payload = Resolve-RedistributablePayload -RepositoryPath . -StagingPath ./.payload
# -RefreshReference is a no-op unless Source.Mode is 'none', where it
# lets source.ps1 refresh the committed Reference/ config the schema is
# generated from. It never yields a payload.
$payload = Resolve-RedistributablePayload -RepositoryPath . -StagingPath ./.payload -RefreshReference
$schema = Update-OptionSchemaFile -RepositoryPath . -PayloadPath $payload.PayloadPath

# LastKnownVersion is what the next run compares against, so it has to
Expand Down Expand Up @@ -143,6 +146,7 @@ jobs:
OptionSchema.yml
redistributable.yml
Files/**
Reference/**
body: |
Upstream moved from `${{ steps.upstream.outputs.previous }}` to
`${{ steps.upstream.outputs.version }}`.
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "LANCommander.Redistributables.UmuLauncher"]
path = LANCommander.Redistributables.UmuLauncher
url = https://github.com/LANCommander/LANCommander.Redistributables.UmuLauncher.git
[submodule "LANCommander.Redistributables.dgVoodoo2"]
path = LANCommander.Redistributables.dgVoodoo2
url = https://github.com/LANCommander/LANCommander.Redistributables.dgVoodoo2.git
1 change: 1 addition & 0 deletions LANCommander.Redistributables.dgVoodoo2
13 changes: 9 additions & 4 deletions module/LANCommander.Redistributables/Private/Parsers/Ini.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
Section headers become group nodes; keys outside any section land at the root.

ChoiceCommentPattern lets a redistributable harvest valid values out of the
comments that sit above a key -- a very common convention (dgVoodoo.conf
documents its allowed values this way). The pattern must expose a named group
'choices'; the captured text is split on commas or pipes. This keeps odd
conventions declarative instead of requiring a bespoke parser.
comments that sit directly above a key -- a very common convention. The pattern
must expose a named group 'choices'; the captured text is split on commas or
pipes. This keeps odd conventions declarative instead of requiring a bespoke
parser.

It only reaches comments that survive the blank-line rule below, so it cannot
read a config that documents a whole section in one block above a blank line.
dgVoodoo.conf is the notable example, and it uses ConfigFormat 'custom' with a
repository-local Parse-Config.ps1 instead.
#>
function ConvertFrom-IniConfig {
[CmdletBinding()]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
upstream release into a staging directory and reports the version.
vendored Uses the committed Files/ directory. The version comes from
LastKnownVersion in redistributable.yml.
none No payload at all. The package ships scripts only and the Install
script fetches from the vendor on the client. This is the mode used
when the upstream license does not permit redistribution.
none No payload at all. The package ships scripts only and the files are
fetched from the vendor after import. This is the mode used when the
upstream license does not permit redistribution.

source.ps1 is still useful here: it tracks the upstream version, and
with -RefreshReference it refreshes the committed Reference/ config
the option schema is generated from. Neither path ever returns a
PayloadPath, so nothing can be bundled by accident.

source.ps1 contract:
-CheckOnly write the version to stdout and exit
Expand All @@ -23,6 +28,14 @@
Where a download-mode payload should be extracted. Defaults to a temp directory.
.PARAMETER CheckOnly
Resolve the version without downloading anything.
.PARAMETER RefreshReference
Only meaningful in 'none' mode. Lets source.ps1 refresh the repository's
committed Reference/ directory -- the config a redistributable that ships no
payload still needs in order to generate an option schema.

This is how the scheduled upstream check picks up options added upstream. It
is deliberately opt-in and Invoke-RedistributableBuild never passes it, so a
build can never acquire files it is not allowed to publish.
.OUTPUTS
An object with Version, Changelog, PayloadPath and Mode.
#>
Expand All @@ -31,7 +44,8 @@ function Resolve-RedistributablePayload {
param(
[Parameter(Mandatory)][string] $RepositoryPath,
[string] $StagingPath,
[switch] $CheckOnly
[switch] $CheckOnly,
[switch] $RefreshReference
)

$definition = Get-RedistributableDefinition -Path $RepositoryPath
Expand Down Expand Up @@ -117,9 +131,67 @@ function Resolve-RedistributablePayload {
}

'none' {
$hasSource = Test-Path -LiteralPath $sourceScript

# PayloadPath stays null in every branch below. That is the guarantee
# this mode exists to make: when the upstream license forbids
# redistribution there must be no way for a build to end up with
# bundleable files, however it was invoked.

if ($CheckOnly -and $hasSource) {
# Mirror 'download'. LastKnownVersion is what a *build* pins to, so
# letting it answer here too would make the scheduled upstream check
# compare a value against itself and never see upstream move.
$version = [string] (& $sourceScript -CheckOnly | Select-Object -Last 1)

if ([string]::IsNullOrWhiteSpace($version)) {
throw 'source.ps1 -CheckOnly produced no version'
}

return [pscustomobject] @{
Version = $version.Trim()
Changelog = $null
PayloadPath = $null
Mode = $mode
}
}

if ($RefreshReference -and $hasSource) {
# source.ps1 writes the reference config straight into the
# repository, because unlike a payload it is a committed artefact:
# it is the only thing the option schema can be generated from, and
# the upstream-update pull request has to carry it.
$reference = Join-Path $RepositoryPath 'Reference'

if (-not (Test-Path -LiteralPath $reference)) {
$null = New-Item -ItemType Directory -Path $reference -Force
}

$output = & $sourceScript -OutputPath $reference

$json = @($output) | Where-Object { $_ -is [string] -and $_.TrimStart().StartsWith('{') } | Select-Object -Last 1

if (-not $json) {
throw 'source.ps1 did not emit a JSON result object with a Version'
}

$result = $json | ConvertFrom-Json

if ([string]::IsNullOrWhiteSpace($result.Version)) {
throw 'source.ps1 emitted a result with no Version'
}

return [pscustomobject] @{
Version = ([string] $result.Version).Trim()
Changelog = $result.Changelog
PayloadPath = $null
Mode = $mode
}
}

$version = [string] $definition['LastKnownVersion']

if ([string]::IsNullOrWhiteSpace($version) -and (Test-Path -LiteralPath $sourceScript)) {
if ([string]::IsNullOrWhiteSpace($version) -and $hasSource) {
# Even with nothing to bundle, source.ps1 can still track the
# upstream version so releases stay aligned with it.
$version = [string] (& $sourceScript -CheckOnly | Select-Object -Last 1)
Expand Down
2 changes: 2 additions & 0 deletions template/.github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ on:
- 'OptionSchema.yml'
- 'Scripts/**'
- 'Files/**'
- 'Reference/**'
- 'source.ps1'
- 'Parse-Config.ps1'
pull_request:
Expand All @@ -25,6 +26,7 @@ on:
- 'OptionSchema.yml'
- 'Scripts/**'
- 'Files/**'
- 'Reference/**'
- 'source.ps1'
- 'Parse-Config.ps1'
workflow_dispatch:
Expand Down
27 changes: 22 additions & 5 deletions template/redistributable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ LastKnownVersion: "0.0.0"
Source:
# download source.ps1 fetches the upstream release at build time.
# vendored the payload is committed under Files/.
# none no payload is shipped; the Install script downloads on the client.
# This is the mode to use when the upstream license does not permit
# redistribution -- the SDK runs Install even with no archives.
# none no payload is shipped; the files are fetched from the vendor after
# import, by the Install script on the client or by the Package script
# on the server. This is the mode to use when the upstream license does
# not permit redistribution -- the SDK runs Install even with no
# archives.
#
# source.ps1 is still worth writing in this mode. It reports the
# upstream version so the scheduled check still fires, and it populates
# Reference/ (see ConfigPaths below). It is never allowed to yield a
# payload here, so keep it to the config file and the license text.
Mode: download

# Consumed by source.ps1. github-release and html both have helpers in the
Expand All @@ -47,6 +54,13 @@ Source:
# so an option added upstream appears automatically on the next scheduled run --
# no script change required.
#
# With Source.Mode 'none' there is no payload to resolve against, so the config has
# to be committed. The convention is Reference/, which the scheduled upstream check
# refreshes from source.ps1 and includes in its pull request:
#
# ConfigPaths:
# - Reference/upstream.conf
#
# Remove this section entirely for a plain runtime installer with no options.
ConfigPaths: []

Expand All @@ -55,8 +69,11 @@ ConfigPaths: []
# 'custom' requires a Parse-Config.ps1 in this repository.
# ConfigFormat: ini

# Optional. Harvests valid values out of the comment above each key, for configs
# that document their options inline. Must expose a named group 'choices'.
# Optional. Harvests valid values out of the comment directly above each key, for
# configs that document their options inline. Must expose a named group 'choices'.
#
# A blank line ends a comment block, so this cannot read a config that documents a
# whole section in one block above a blank line. Write a Parse-Config.ps1 for that.
# ChoiceCommentPattern: '(?i)(?:values?|options?)\s*:\s*(?<choices>.+)'

# Scripts ----------------------------------------------------------------------
Expand Down
Loading