Files
PSInfisicalAPI/.gitea/workflows/publish-psgallery.yml
T
GraceSolutions eaffeedf12 Add Gitea runner installer, proxy/SSO support, and release workflow
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.
2026-06-02 15:48:54 -04:00

297 lines
11 KiB
YAML

name: Publish to PowerShell Gallery
on:
pull_request:
types: [closed]
branches: [main]
jobs:
build:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Install PowerShell 7 (if not present)
shell: bash
run: |
set -euo pipefail
if command -v pwsh >/dev/null 2>&1; then
echo "pwsh already installed: $(pwsh --version)"
exit 0
fi
sudo apt-get update
sudo apt-get install -y --no-install-recommends wget ca-certificates apt-transport-https gnupg
source /etc/os-release
wget -q "https://packages.microsoft.com/config/ubuntu/${VERSION_ID}/packages-microsoft-prod.deb" -O /tmp/ms-prod.deb
sudo dpkg -i /tmp/ms-prod.deb
rm -f /tmp/ms-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
pwsh --version
- name: Build and test module
shell: pwsh
run: ./build.ps1 -RunTests
- name: Validate module manifest
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$manifestPath = Join-Path $PWD 'Module/PSInfisicalAPI/PSInfisicalAPI.psd1'
$manifest = Test-ModuleManifest -Path $manifestPath
Write-Host "Manifest OK: $($manifest.Name) $($manifest.Version)"
- name: Upload module artifact
uses: actions/upload-artifact@v4
with:
name: PSInfisicalAPI-module
path: Module/PSInfisicalAPI
if-no-files-found: error
retention-days: 7
release:
needs: build
if: ${{ success() && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
tag: ${{ steps.meta.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install PowerShell 7 (if not present)
shell: bash
run: |
set -euo pipefail
if command -v pwsh >/dev/null 2>&1; then
echo "pwsh already installed: $(pwsh --version)"
exit 0
fi
sudo apt-get update
sudo apt-get install -y --no-install-recommends wget ca-certificates apt-transport-https gnupg
source /etc/os-release
wget -q "https://packages.microsoft.com/config/ubuntu/${VERSION_ID}/packages-microsoft-prod.deb" -O /tmp/ms-prod.deb
sudo dpkg -i /tmp/ms-prod.deb
rm -f /tmp/ms-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
pwsh --version
- name: Download module artifact
uses: actions/download-artifact@v4
with:
name: PSInfisicalAPI-module
path: Module/PSInfisicalAPI
- name: Resolve module version and tag
id: meta
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$manifestPath = Join-Path $PWD 'Module/PSInfisicalAPI/PSInfisicalAPI.psd1'
$manifest = Test-ModuleManifest -Path $manifestPath
$version = $manifest.Version.ToString()
$tag = $version
Write-Host "Module version: $version"
Write-Host "Release tag: $tag"
"version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
- name: Package module as release asset
shell: pwsh
env:
VERSION: ${{ steps.meta.outputs.version }}
run: |
$ErrorActionPreference = 'Stop'
$zipPath = Join-Path $PWD "PSInfisicalAPI-$($env:VERSION).zip"
if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
Compress-Archive -Path 'Module/PSInfisicalAPI/*' -DestinationPath $zipPath -Force
Write-Host "Created: $zipPath ($([math]::Round((Get-Item $zipPath).Length / 1KB, 1)) KB)"
- name: Create Gitea release
shell: pwsh
env:
GITEA_TOKEN: ${{ github.token }}
API_URL: ${{ github.api_url }}
REPO: ${{ github.repository }}
TAG: ${{ steps.meta.outputs.tag }}
VERSION: ${{ steps.meta.outputs.version }}
COMMIT_SHA: ${{ github.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
SERVER_URL: ${{ github.server_url }}
RUN_ID: ${{ github.run_id }}
run: |
$ErrorActionPreference = 'Stop'
if ([string]::IsNullOrWhiteSpace($env:GITEA_TOKEN)) {
throw "github.token is not available; cannot call the Gitea release API."
}
$shortSha = $env:COMMIT_SHA.Substring(0, [Math]::Min(12, $env:COMMIT_SHA.Length))
$buildUtc = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
$runUrl = "$($env:SERVER_URL)/$($env:REPO)/actions/runs/$($env:RUN_ID)"
$prUrl = "$($env:SERVER_URL)/$($env:REPO)/pulls/$($env:PR_NUMBER)"
$changelogSection = ''
if (Test-Path 'CHANGELOG.md') {
$lines = [System.IO.File]::ReadAllLines('CHANGELOG.md')
$start = -1; $end = $lines.Length
for ($i = 0; $i -lt $lines.Length; $i++) {
if ($lines[$i] -match "^##\s+$([regex]::Escape($env:VERSION))\s*$") { $start = $i + 1; continue }
if ($start -ge 0 -and $lines[$i] -match '^##\s+') { $end = $i; break }
}
if ($start -ge 0) {
$changelogSection = ($lines[$start..($end - 1)] -join "`n").Trim()
}
}
$body = @"
**PSInfisicalAPI $($env:VERSION)**
| Field | Value |
| --- | --- |
| Version | ``$($env:VERSION)`` |
| Tag | ``$($env:TAG)`` |
| Commit | [``$shortSha``]($($env:SERVER_URL)/$($env:REPO)/commit/$($env:COMMIT_SHA)) |
| Built (UTC) | $buildUtc |
| Merged PR | [#$($env:PR_NUMBER) $($env:PR_TITLE)]($prUrl) by @$($env:PR_AUTHOR) |
| Workflow run | [$($env:RUN_ID)]($runUrl) |
## Changes
$(if ($changelogSection) { $changelogSection } else { '_No CHANGELOG section found for this version._' })
## Install
``````powershell
Install-Module -Name PSInfisicalAPI -RequiredVersion $($env:VERSION) -Scope CurrentUser
``````
"@
$headers = @{
Authorization = "token $($env:GITEA_TOKEN)"
Accept = 'application/json'
}
$createUri = "$($env:API_URL)/repos/$($env:REPO)/releases"
$existing = $null
try {
$existing = Invoke-RestMethod -Method Get -Headers $headers `
-Uri "$createUri/tags/$($env:TAG)" -ErrorAction Stop
} catch {
if ($_.Exception.Response.StatusCode.value__ -ne 404) { throw }
}
if ($existing) {
Write-Host "Release tag '$($env:TAG)' already exists (id=$($existing.id)); skipping release creation."
return
}
$payload = @{
tag_name = $env:TAG
target_commitish = $env:COMMIT_SHA
name = "PSInfisicalAPI $($env:VERSION)"
body = $body
draft = $false
prerelease = $false
} | ConvertTo-Json -Depth 4
$release = Invoke-RestMethod -Method Post -Uri $createUri -Headers $headers `
-ContentType 'application/json' -Body $payload
Write-Host "Created release id=$($release.id) at $($release.html_url)"
$assetPath = Join-Path $PWD "PSInfisicalAPI-$($env:VERSION).zip"
$uploadUri = "$createUri/$($release.id)/assets?name=PSInfisicalAPI-$($env:VERSION).zip"
$fileBytes = [System.IO.File]::ReadAllBytes($assetPath)
Invoke-RestMethod -Method Post -Uri $uploadUri -Headers $headers `
-ContentType 'application/zip' -Body $fileBytes | Out-Null
Write-Host "Uploaded asset: PSInfisicalAPI-$($env:VERSION).zip"
publish:
needs: release
if: ${{ success() && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
steps:
- name: Install PowerShell 7 (if not present)
shell: bash
run: |
set -euo pipefail
if command -v pwsh >/dev/null 2>&1; then
echo "pwsh already installed: $(pwsh --version)"
exit 0
fi
sudo apt-get update
sudo apt-get install -y --no-install-recommends wget ca-certificates apt-transport-https gnupg
source /etc/os-release
wget -q "https://packages.microsoft.com/config/ubuntu/${VERSION_ID}/packages-microsoft-prod.deb" -O /tmp/ms-prod.deb
sudo dpkg -i /tmp/ms-prod.deb
rm -f /tmp/ms-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
pwsh --version
- name: Download module artifact
uses: actions/download-artifact@v4
with:
name: PSInfisicalAPI-module
path: Module/PSInfisicalAPI
- name: Bootstrap PowerShellGet / NuGet provider
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
if (-not (Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue)) {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Scope CurrentUser | Out-Null
}
Get-PackageProvider -Name NuGet | Format-Table Name,Version
- name: Verify PowerShell Gallery API key is configured
shell: pwsh
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
run: |
if ([string]::IsNullOrWhiteSpace($env:PSGALLERY_API_KEY)) {
throw "Repository secret 'PSGALLERY_API_KEY' is not configured."
}
- name: Re-validate downloaded module manifest
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$manifestPath = Join-Path $PWD 'Module/PSInfisicalAPI/PSInfisicalAPI.psd1'
$manifest = Test-ModuleManifest -Path $manifestPath
Write-Host "Manifest OK: $($manifest.Name) $($manifest.Version)"
- name: Publish to PowerShell Gallery
shell: pwsh
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
run: |
$ErrorActionPreference = 'Stop'
$moduleDir = Join-Path $PWD 'Module/PSInfisicalAPI'
Write-Host "Publishing module from: $moduleDir"
Publish-Module `
-Path $moduleDir `
-NuGetApiKey $env:PSGALLERY_API_KEY `
-Verbose