diff --git a/README.md b/README.md index 8c0230e..5faabae 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,24 @@ Small Dalamud plugins by Bep. +## Dalamud Custom Repository + +Add this URL under Dalamud Settings, Experimental, Custom Plugin Repositories: + +```text +https://git.bep.moe/verniy/xiv-plugins/raw/branch/main/pluginmaster.json +``` + ## Plugins - [Auto Fishing Stool](AutoFishingStool/README.md): automatically uses `/sit` after entering fishing mode. + +## Publishing a Plugin + +Increment the plugin version, then run this command from the repository root: + +```powershell +.\scripts\publish-plugin.cmd -Project AutoFishingStool -Changelog "Describe the update" +``` + +Commit and push the updated source, `pluginmaster.json`, and release ZIP. Future plugin projects can use the same command with their project directory name. diff --git a/pluginmaster.json b/pluginmaster.json new file mode 100644 index 0000000..aafa731 --- /dev/null +++ b/pluginmaster.json @@ -0,0 +1,25 @@ +[ + { + "Author": "Bep", + "Name": "Auto Fishing Stool", + "InternalName": "AutoFishingStool", + "AssemblyVersion": "1.1.3.0", + "TestingAssemblyVersion": null, + "Description": "Uses /sit once after fishing becomes active and the current fishing action finishes.", + "Punchline": "Automatically sits after entering fishing mode.", + "RepoUrl": "https://git.bep.moe/verniy/xiv-plugins", + "ApplicableVersion": "any", + "DalamudApiLevel": 15, + "IsHide": false, + "IsTestingExclusive": false, + "DownloadLinkInstall": "https://git.bep.moe/verniy/xiv-plugins/raw/branch/main/repo/AutoFishingStool/latest.zip", + "DownloadLinkUpdate": "https://git.bep.moe/verniy/xiv-plugins/raw/branch/main/repo/AutoFishingStool/latest.zip", + "LastUpdate": "1786068591", + "IconUrl": "https://git.bep.moe/verniy/xiv-plugins/raw/branch/main/AutoFishingStool/icon.png", + "Tags": [ + "fishing", + "utility" + ], + "Changelog": "Initial custom repository release." + } +] diff --git a/repo/AutoFishingStool/latest.zip b/repo/AutoFishingStool/latest.zip new file mode 100644 index 0000000..d9f9def Binary files /dev/null and b/repo/AutoFishingStool/latest.zip differ diff --git a/scripts/Publish-Plugin.ps1 b/scripts/Publish-Plugin.ps1 new file mode 100644 index 0000000..fed6371 --- /dev/null +++ b/scripts/Publish-Plugin.ps1 @@ -0,0 +1,91 @@ +param( + [Parameter(Mandatory = $true)] + [string]$Project, + + [string]$Changelog +) + +$ErrorActionPreference = 'Stop' + +$repositoryRoot = Split-Path -Parent $PSScriptRoot +$projectDirectory = Join-Path $repositoryRoot $Project + +if (-not (Test-Path -LiteralPath $projectDirectory -PathType Container)) { + throw "Plugin project directory not found: $projectDirectory" +} + +$projectFiles = @(Get-ChildItem -LiteralPath $projectDirectory -Filter '*.csproj' -File) +if ($projectFiles.Count -ne 1) { + throw "Expected exactly one project file in $projectDirectory" +} + +$projectFile = $projectFiles[0] +$internalName = [System.IO.Path]::GetFileNameWithoutExtension($projectFile.Name) + +dotnet build $projectFile.FullName -c Release --no-restore +if ($LASTEXITCODE -ne 0) { + throw "Release build failed for $internalName" +} + +$packageDirectory = Join-Path $projectDirectory "bin\Release\$internalName" +$manifestPath = Join-Path $packageDirectory "$internalName.json" +$zipPath = Join-Path $packageDirectory 'latest.zip' + +if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) { + throw "Release manifest not found: $manifestPath" +} + +if (-not (Test-Path -LiteralPath $zipPath -PathType Leaf)) { + throw "Release package not found: $zipPath" +} + +$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json +$repositoryBaseUrl = 'https://git.bep.moe/verniy/xiv-plugins' +$downloadUrl = "$repositoryBaseUrl/raw/branch/main/repo/$internalName/latest.zip" +$destinationDirectory = Join-Path $repositoryRoot "repo\$internalName" +$pluginMasterPath = Join-Path $repositoryRoot 'pluginmaster.json' + +New-Item -ItemType Directory -Path $destinationDirectory -Force | Out-Null +Copy-Item -LiteralPath $zipPath -Destination (Join-Path $destinationDirectory 'latest.zip') -Force + +$entry = [ordered]@{ + Author = $manifest.Author + Name = $manifest.Name + InternalName = $manifest.InternalName + AssemblyVersion = $manifest.AssemblyVersion + TestingAssemblyVersion = $null + Description = $manifest.Description + Punchline = $manifest.Punchline + RepoUrl = $manifest.RepoUrl + ApplicableVersion = $manifest.ApplicableVersion + DalamudApiLevel = $manifest.DalamudApiLevel + IsHide = $false + IsTestingExclusive = $false + DownloadLinkInstall = $downloadUrl + DownloadLinkUpdate = $downloadUrl + LastUpdate = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds().ToString() + IconUrl = $manifest.IconUrl + Tags = @($manifest.Tags) +} + +if ($Changelog) { + $entry.Changelog = $Changelog +} elseif ($manifest.Changelog) { + $entry.Changelog = $manifest.Changelog +} + +$entries = @() +if (Test-Path -LiteralPath $pluginMasterPath -PathType Leaf) { + $existing = Get-Content -LiteralPath $pluginMasterPath -Raw | ConvertFrom-Json + $entries = @($existing | Where-Object { $_.InternalName -ne $internalName }) +} + +$entries += [PSCustomObject]$entry +$sortedEntries = @($entries | Sort-Object InternalName) +$json = ConvertTo-Json -InputObject $sortedEntries -Depth 10 +$utf8 = [System.Text.UTF8Encoding]::new($false) +[System.IO.File]::WriteAllText($pluginMasterPath, $json + [Environment]::NewLine, $utf8) + +Write-Output "Published $internalName $($manifest.AssemblyVersion)" +Write-Output "Repository index: $pluginMasterPath" +Write-Output "Package: $(Join-Path $destinationDirectory 'latest.zip')" diff --git a/scripts/publish-plugin.cmd b/scripts/publish-plugin.cmd new file mode 100644 index 0000000..c538848 --- /dev/null +++ b/scripts/publish-plugin.cmd @@ -0,0 +1 @@ +@powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0Publish-Plugin.ps1" %*