The release body was built solely from the CHANGELOG section, which is a
terse changelog entry rather than the account of what changed. Gitea's
pull_request webhook payload carries the description - PullRequest.Body is a
documented field on the API struct - so it is now passed to the release step as
PR_BODY and leads the release when present.
The CHANGELOG entry is kept behind a fold rather than dropped, so a release
records both the narrative and the versioned entry. With no description the
body falls back to the CHANGELOG exactly as before, and with neither it says so.
Co-author and generation trailers are stripped: they belong on the commit, not
on a published release page. The description supplies its own headings, so no
"## Changes" wrapper is added around it; the fallback branches emit one because
a bare changelog fragment needs it.
Verified by lifting the run: block straight out of the workflow and executing
it, so the test exercises the shipped code rather than a copy: a description
plus changelog produces the folded form, description-only omits the fold,
changelog-only falls back, neither produces the placeholder, and the trailers
are removed while the real content survives. Both workflows still parse as YAML
with the same three jobs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The publish job failed on PR #19 with a 409 for version 2026.7.30.2309, but
that version is live on the gallery (created 23:10:04) - the push landed and
the client still surfaced an error, so the retry collided with the upload that
had just succeeded. The run went red over a publish that actually worked.
The step now checks the gallery before pushing and skips when the version is
already there, and on a publish error it re-checks before failing. This mirrors
the release job, which already looks for an existing tag and skips.
Version comparison normalizes each segment the way NuGet does, since the
manifest carries zero-padded segments (2026.07.30.2309) while the gallery lists
the stripped form (2026.7.30.2309); comparing the raw strings would never match
and the guard would never fire.
Verified: both workflows still parse as YAML with the same three jobs, the
normalizer reproduces the gallery form for four published versions, and a live
lookup confirms the guard would have exited 0 on the run that failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All three jobs (build, release, publish) now target runs-on: powershell-linux, which maps to :host on the Gitea runner so steps execute directly on the host OS instead of inside a Docker container. Dropped the apt-get/sudo install blocks and actions/setup-dotnet in favor of a fast preflight that verifies pwsh (and dotnet for the build job) are present, failing loudly otherwise. Publish job migrated off the legacy PowerShellGet v2 path (Set-PSRepository / Install-PackageProvider NuGet / Publish-Module) to Microsoft.PowerShell.PSResourceGet (Set-PSResourceRepository / Publish-PSResource), which is bundled with PS 7.4+ on Linux and does not depend on the NuGet package provider.
Scripts:
- Add scripts/Install-GiteaRunner.ps1: cross-platform installer for the
Gitea act_runner daemon (systemd / launchd / Windows Service).
- PowerShell 7+ runtime guard (works under irm | iex).
- Explicit env var resolution (Process -> User -> Machine) for
InstanceUrl and RegistrationToken with named candidates.
- UTF-8 (no BOM) for every file write via [System.IO.File] APIs.
- System proxy + DefaultNetworkCredentials on all web calls.
- Optional -Labels; ServiceName/ServiceDisplayName split prevents
systemd 'Invalid unit name' errors caused by whitespace.
- config.yaml is always generated before the registration skip-check
so upgrades produce a config the daemon can load.
Module:
- InfisicalHttpClient: enable UseDefaultCredentials and attach the
system proxy with DefaultNetworkCredentials so requests work behind
authenticated corporate proxies / SSO.
- ExportInfisicalSecretsCmdlet: make the UTF-8 (no BOM) case explicit
in the encoding resolver.
CI/CD (.gitea/workflows/publish-psgallery.yml):
- Split into build -> release -> publish with hard `needs:` ordering
so publish never runs unless build and release both succeed.
- Build job uploads Module/PSInfisicalAPI as an artifact.
- Release job downloads the artifact, reads the version from the
manifest, zips the module, and creates a Gitea release tagged with
the bare version. Release notes include version, full + short commit
SHA, build timestamp, merged PR info, workflow run link, and any
matching CHANGELOG.md section. Skips cleanly when the tag already
exists.
- Publish job re-validates the downloaded manifest and runs
Publish-Module against PSGallery using PSGALLERY_API_KEY.