From da4c614667080839c72aa84129489fc815f1ab7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 06:32:00 +0000 Subject: [PATCH 1/3] Add GitHub Actions release workflow with workflow_dispatch trigger Agent-Logs-Url: https://github.com/Halcyonhal9/ghcp-powershell/sessions/f1647c8e-d34e-4244-a383-10524338cad5 Co-authored-by: Halcyonhal9 <123903683+Halcyonhal9@users.noreply.github.com> --- .github/workflows/release.yml | 174 ++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6472786 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,174 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version_bump: + description: "Version bump type" + required: true + type: choice + options: + - patch + - minor + - major + default: patch + publish_to_gallery: + description: "Publish to PowerShell Gallery" + required: true + type: boolean + default: true + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + environment: CopilotCmldetsEnv + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: "9.0.x" + + - name: Determine new version + id: version + shell: pwsh + run: | + # Find latest release tag to compute the next version + $tag = git describe --tags --abbrev=0 2>$null + if ($LASTEXITCODE -ne 0 -or -not $tag) { + $major = 0; $minor = 0; $patch = 0 + } elseif ($tag -match '^v?(\d+)\.(\d+)\.(\d+)$') { + $major = [int]$Matches[1]; $minor = [int]$Matches[2]; $patch = [int]$Matches[3] + } else { + Write-Error "Could not parse version from tag '$tag'" + exit 1 + } + + switch ('${{ inputs.version_bump }}') { + 'major' { $newVersion = "$($major + 1).0.0" } + 'minor' { $newVersion = "$major.$($minor + 1).0" } + default { $newVersion = "$major.$minor.$($patch + 1)" } + } + + Write-Host "Version: $major.$minor.$patch -> $newVersion" + "version=$newVersion" >> $env:GITHUB_OUTPUT + "tag=v$newVersion" >> $env:GITHUB_OUTPUT + + - name: Update module manifest version + shell: pwsh + run: | + $manifest = Join-Path $env:GITHUB_WORKSPACE 'CopilotCmdlets.psd1' + $content = Get-Content $manifest -Raw + $updated = $content -replace "ModuleVersion\s*=\s*'\d+\.\d+\.\d+'", "ModuleVersion = '${{ steps.version.outputs.version }}'" + Set-Content -Path $manifest -Value $updated -NoNewline + Write-Host "Updated manifest to ${{ steps.version.outputs.version }}" + + - name: Build all platforms + shell: pwsh + run: | + $project = Join-Path $env:GITHUB_WORKSPACE 'src/CopilotCmdlets.csproj' + $outDir = Join-Path $env:GITHUB_WORKSPACE 'out' + $runtimes = @('win-x64', 'linux-x64', 'linux-arm64', 'osx-arm64') + + foreach ($rid in $runtimes) { + $ridOut = Join-Path $outDir $rid + Write-Host "Publishing $rid -> $ridOut" + dotnet publish $project -c Release -r $rid --self-contained false -o $ridOut + if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed for $rid" } + } + + # RID-neutral gallery build + $galleryDir = Join-Path $outDir 'gallery' + Write-Host "Publishing RID-neutral gallery build -> $galleryDir" + dotnet publish $project -c Release -o $galleryDir + if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed for gallery build" } + + - name: Stage module files and create release zips + id: artifacts + shell: pwsh + run: | + $root = $env:GITHUB_WORKSPACE + $outDir = Join-Path $root 'out' + $manifest = Join-Path $root 'CopilotCmdlets.psd1' + $runtimes = @('win-x64', 'linux-x64', 'linux-arm64', 'osx-arm64') + $version = '${{ steps.version.outputs.version }}' + $galleryDir = Join-Path $outDir 'gallery' + + # Stage per-RID builds and create zips + $zipPaths = @() + foreach ($rid in $runtimes) { + $ridOut = Join-Path $outDir $rid + $ridStage = Join-Path $ridOut 'CopilotCmdlets' + + if (Test-Path $ridStage) { Remove-Item $ridStage -Recurse -Force } + New-Item -ItemType Directory -Force -Path $ridStage | Out-Null + + Get-ChildItem -Path $ridOut -Force | + Where-Object { $_.FullName -ne $ridStage } | + Copy-Item -Destination $ridStage -Recurse -Force + Copy-Item $manifest -Destination $ridStage -Force + + $zipPath = Join-Path $root "CopilotCmdlets-$version-$rid.zip" + if (Test-Path $zipPath) { Remove-Item $zipPath -Force } + Compress-Archive -Path (Join-Path $ridStage '*') -DestinationPath $zipPath -Force + Write-Host "Created $zipPath" + $zipPaths += $zipPath + } + + # Stage gallery build + $galleryStage = Join-Path $galleryDir 'CopilotCmdlets' + if (Test-Path $galleryStage) { Remove-Item $galleryStage -Recurse -Force } + New-Item -ItemType Directory -Force -Path $galleryStage | Out-Null + Get-ChildItem -Path $galleryDir -Force | + Where-Object { $_.FullName -ne $galleryStage } | + Copy-Item -Destination $galleryStage -Recurse -Force + Copy-Item $manifest -Destination $galleryStage -Force + + # Output zip paths (newline-separated) for the release step + $joined = $zipPaths -join "`n" + # Use a delimiter for multi-line output + $delimiter = "EOF_$(Get-Random)" + "zip_paths<<$delimiter" >> $env:GITHUB_OUTPUT + $joined >> $env:GITHUB_OUTPUT + $delimiter >> $env:GITHUB_OUTPUT + + - name: Commit version bump + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add CopilotCmdlets.psd1 + git diff --cached --quiet || git commit -m "Release ${{ steps.version.outputs.tag }}" + git tag "${{ steps.version.outputs.tag }}" + git push origin HEAD "${{ steps.version.outputs.tag }}" + + - name: Create GitHub Release + shell: pwsh + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + $tag = '${{ steps.version.outputs.tag }}' + $version = '${{ steps.version.outputs.version }}' + $zipPaths = '${{ steps.artifacts.outputs.zip_paths }}' -split "`n" | Where-Object { $_ } + + Write-Host "Creating release $tag with assets:" + $zipPaths | ForEach-Object { Write-Host " $_" } + + gh release create $tag @zipPaths --title $tag --notes "Release $tag" + + - name: Publish to PowerShell Gallery + if: ${{ inputs.publish_to_gallery }} + shell: pwsh + env: + POWERSHELL_GALLERY_API_KEY: ${{ secrets.POWERSHELL_GALLERY_API_KEY }} + run: | + $galleryStage = Join-Path $env:GITHUB_WORKSPACE 'out/gallery/CopilotCmdlets' + Write-Host "Publishing CopilotCmdlets ${{ steps.version.outputs.version }} to PowerShell Gallery" + Publish-Module -Path $galleryStage -NuGetApiKey $env:POWERSHELL_GALLERY_API_KEY + Write-Host "Successfully published to PowerShell Gallery" From b5db4734eb877ab130c76888251dafe86cb1bea7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 06:38:14 +0000 Subject: [PATCH 2/3] Simplify code for clarity and consistency - Fix typo in environment name (CopilotCmldetsEnv -> CopilotCmdletsEnv) - Remove unused $version variable in Create GitHub Release step - Remove redundant zip pre-delete (Compress-Archive -Force handles overwrite) - Simplify if: expression by removing unnecessary ${{ }} wrapper Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Halcyonhal9 <123903683+Halcyonhal9@users.noreply.github.com> --- .github/workflows/release.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6472786..29f67ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ permissions: jobs: release: runs-on: ubuntu-latest - environment: CopilotCmldetsEnv + environment: CopilotCmdletsEnv steps: - name: Checkout repository uses: actions/checkout@v4 @@ -116,7 +116,6 @@ jobs: Copy-Item $manifest -Destination $ridStage -Force $zipPath = Join-Path $root "CopilotCmdlets-$version-$rid.zip" - if (Test-Path $zipPath) { Remove-Item $zipPath -Force } Compress-Archive -Path (Join-Path $ridStage '*') -DestinationPath $zipPath -Force Write-Host "Created $zipPath" $zipPaths += $zipPath @@ -154,7 +153,6 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | $tag = '${{ steps.version.outputs.tag }}' - $version = '${{ steps.version.outputs.version }}' $zipPaths = '${{ steps.artifacts.outputs.zip_paths }}' -split "`n" | Where-Object { $_ } Write-Host "Creating release $tag with assets:" @@ -163,7 +161,7 @@ jobs: gh release create $tag @zipPaths --title $tag --notes "Release $tag" - name: Publish to PowerShell Gallery - if: ${{ inputs.publish_to_gallery }} + if: inputs.publish_to_gallery shell: pwsh env: POWERSHELL_GALLERY_API_KEY: ${{ secrets.POWERSHELL_GALLERY_API_KEY }} From 356d0734d604d6044109f2157cde60ec4db0a6e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 06:50:44 +0000 Subject: [PATCH 3/3] Add concurrency control, unit test step, and idempotent tag/release handling Agent-Logs-Url: https://github.com/Halcyonhal9/ghcp-powershell/sessions/83b64ebb-7640-42d9-b239-c810240e10a0 Co-authored-by: Halcyonhal9 <123903683+Halcyonhal9@users.noreply.github.com> --- .github/workflows/release.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 29f67ee..b241aa7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,10 @@ on: permissions: contents: write +concurrency: + group: release + cancel-in-progress: false + jobs: release: runs-on: ubuntu-latest @@ -70,6 +74,9 @@ jobs: Set-Content -Path $manifest -Value $updated -NoNewline Write-Host "Updated manifest to ${{ steps.version.outputs.version }}" + - name: Run unit tests + run: dotnet test tests/CopilotCmdlets.Tests.csproj --filter "Category=Unit" + - name: Build all platforms shell: pwsh run: | @@ -144,7 +151,9 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" git add CopilotCmdlets.psd1 git diff --cached --quiet || git commit -m "Release ${{ steps.version.outputs.tag }}" - git tag "${{ steps.version.outputs.tag }}" + if ! git tag --list "${{ steps.version.outputs.tag }}" | grep -q .; then + git tag "${{ steps.version.outputs.tag }}" + fi git push origin HEAD "${{ steps.version.outputs.tag }}" - name: Create GitHub Release @@ -158,7 +167,13 @@ jobs: Write-Host "Creating release $tag with assets:" $zipPaths | ForEach-Object { Write-Host " $_" } - gh release create $tag @zipPaths --title $tag --notes "Release $tag" + $existing = gh release view $tag --json tagName 2>$null + if ($existing) { + Write-Host "Release $tag already exists — uploading assets" + gh release upload $tag @zipPaths --clobber + } else { + gh release create $tag @zipPaths --title $tag --notes "Release $tag" + } - name: Publish to PowerShell Gallery if: inputs.publish_to_gallery