Skip to content
Merged
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
39 changes: 36 additions & 3 deletions .github/workflows/build-windows-installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ jobs:
runs-on: windows-latest
permissions:
contents: read
outputs:
portable_artifact: ${{ steps.portable.outputs.name }}

steps:
- name: Checkout
Expand All @@ -111,6 +113,7 @@ jobs:
python -m pip install -r requirements-dev.txt

- name: Build exact portable release and SHA256 sidecar
id: portable
shell: pwsh
run: |
$versionLine = Get-Content agent\__init__.py | Where-Object { $_ -match '__version__\s*=\s*"([^"]+)"' } | Select-Object -First 1
Expand All @@ -124,6 +127,22 @@ jobs:
$sidecar = Get-Item "$($zip.FullName).sha256" -ErrorAction SilentlyContinue
if (-not $sidecar) { throw "Portable SHA256 sidecar was not produced" }
"HUMWATCH_PORTABLE_RELEASE_DIR=$output" >> $env:GITHUB_ENV
"name=humwatch-portable-v$version" >> $env:GITHUB_OUTPUT

# This job already builds the exact archive the updater expects and then
# threw it away, so the zip and its sidecar were attached to every release
# by hand. update-core.ps1 refuses to run when either is missing from the
# latest release, so a forgotten upload does not degrade the updater, it
# disables it on every portable install pointed at that release. Keep the
# tested bytes and let the release job attach them.
- name: Upload validated portable archive
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ steps.portable.outputs.name }}
path: |
${{ env.HUMWATCH_PORTABLE_RELEASE_DIR }}/HumWatch-v*.zip
${{ env.HUMWATCH_PORTABLE_RELEASE_DIR }}/HumWatch-v*.zip.sha256
if-no-files-found: error

- name: Test tampered archive rejection
shell: pwsh
Expand Down Expand Up @@ -265,7 +284,7 @@ jobs:
run: python -m pytest tests/test_linux_service_security.py -q

release:
name: Attach validated installer to release
name: Attach validated installer and portable archive to release
needs: [build, windows-service-security, windows-service-security-installed, windows-installation-behavior, linux-security]
if: ${{ inputs.release_tag != '' || startsWith(github.ref, 'refs/tags/v') }}
runs-on: windows-latest
Expand All @@ -279,6 +298,12 @@ jobs:
name: ${{ needs.build.outputs.installer_artifact }}
path: ${{ runner.temp }}\humwatch-release

- name: Download validated portable archive
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0, download-artifact@v4
with:
name: ${{ needs.windows-installation-behavior.outputs.portable_artifact }}
path: ${{ runner.temp }}\humwatch-release

- name: Attach to release
shell: pwsh
env:
Expand All @@ -289,9 +314,17 @@ jobs:
# "not a git repository" after every other gate has already passed.
GH_REPO: ${{ github.repository }}
run: |
$installer = Get-ChildItem "${{ runner.temp }}\humwatch-release" -Filter "HumWatch-Setup-v*.exe" | Select-Object -First 1
$staged = "${{ runner.temp }}\humwatch-release"
$installer = Get-ChildItem $staged -Filter "HumWatch-Setup-v*.exe" | Select-Object -First 1
if (-not $installer) { throw "Validated HumWatch installer artifact is missing" }
$portable = Get-ChildItem $staged -Filter "HumWatch-v*.zip" | Where-Object { $_.Name -notlike "*.sha256" } | Select-Object -First 1
if (-not $portable) { throw "Validated HumWatch portable archive is missing" }
# update-core.ps1 resolves the archive and its manifest by exact name
# on the latest release and throws when either is absent, so the
# sidecar is not optional decoration. Upload it or the updater dies.
$sidecar = Get-Item "$($portable.FullName).sha256" -ErrorAction SilentlyContinue
if (-not $sidecar) { throw "Portable SHA256 sidecar is missing" }
$tag = "${{ inputs.release_tag }}"
if (-not $tag) { $tag = "${{ github.ref_name }}" }
gh release upload $tag $installer.FullName --clobber
gh release upload $tag $installer.FullName $portable.FullName $sidecar.FullName --clobber

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject portable archives whose version differs from the target tag

When a manual dispatch supplies a release_tag that differs from the checked-out agent.__version__, this command uploads the build-version archive to the independently selected release鈥攆or example, HumWatch-v2.0.1.zip to v2.0.2. The checked gh release upload <tag> <files>... interface accepts arbitrary asset names, while scripts/update-core.ps1 looks only for HumWatch-v2.0.2.zip and its exact sidecar, so the workflow succeeds but leaves portable updating disabled for that release. Validate that the archive version equals $tag.Substring(1) before uploading, or build/name the archive from the target tag.

Useful? React with 馃憤聽/ 馃憥.

if ($LASTEXITCODE -ne 0) { throw "Release upload failed for $tag" }
Loading