Skip to content

[codex] add portable binary release validation#56

Draft
johnnyhuy wants to merge 1 commit intomainfrom
codex/portable-binary-validation
Draft

[codex] add portable binary release validation#56
johnnyhuy wants to merge 1 commit intomainfrom
codex/portable-binary-validation

Conversation

@johnnyhuy
Copy link
Contributor

Summary

  • add CI coverage that smoke-tests compiled Bun artifacts across native runners, QEMU arm64 emulation, Wine, Docker multi-arch images, and packaging syntax checks
  • add a release workflow that uploads compiled binaries to GitHub Releases and then verifies Homebrew, Chocolatey, and winget installs against the same release URLs used by packaging metadata
  • switch the winget installer manifest to portable so release verification exercises the portable .exe flow end to end, and add renderer/package validation helpers for generated packaging assets

Why

The distribution assets added in #45, #46, #47, #48, and #49 depended on compiled Bun binaries being portable, but the repository only smoke-tested host builds and did not verify that release assets were uploaded and consumable through package-manager flows. That left a gap where packaging metadata could look correct while real installs from release URLs still failed.

What changed

  • extended scripts/smoke-artifact.ts so one smoke path can validate arbitrary artifacts and wrapper runners like wine64
  • added scripts/validate-packaging.ts and a mise run package-validate task to verify rendered packaging output and manifest structure from current build checksums
  • expanded build-matrix.yaml with QEMU arm64 binary checks, Wine Windows binary checks, Docker amd64/arm64 image checks, and packaging validation jobs
  • added release-binaries.yaml to build release artifacts, upload them to the GitHub release, and verify Homebrew, Chocolatey, and winget installation from those release-backed assets
  • updated winget manifests/rendering to use the portable installer type for the compiled Windows binary

Validation

  • bun scripts/build-release.ts --targets=darwin-arm64,darwin-x64,windows-x64,linux-x64-gnu,linux-x64-musl,linux-arm64-gnu,linux-arm64-musl
  • bun scripts/write-checksums.ts
  • bun scripts/smoke-artifact.ts
  • bun scripts/validate-packaging.ts
  • bunx vitest run tests/distribution/homebrew.test.ts tests/distribution/chocolatey.test.ts tests/distribution/winget.test.ts tests/distribution/npm-package.test.ts tests/build/targets.test.ts

Follow-up context

Comment on lines +81 to +119
needs: build
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Setup QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e8

- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
path: dist
merge-multiple: true

- name: Make Linux artifacts executable
shell: bash
run: |
set -euo pipefail
chmod +x dist/skillet-linux-*

- name: Smoke test arm64 musl artifact under emulation
shell: bash
run: |
set -euo pipefail
OUTPUT=$(docker run --rm --platform linux/arm64/v8 -v "$PWD/dist:/artifacts:ro" alpine:3.22 /artifacts/skillet-linux-arm64-musl --version)
printf '%s\n' "$OUTPUT"
grep -F "sklt/" <<< "$OUTPUT"

- name: Smoke test arm64 gnu artifact under emulation
shell: bash
run: |
set -euo pipefail
OUTPUT=$(docker run --rm --platform linux/arm64/v8 -v "$PWD/dist:/artifacts:ro" ubuntu:24.04 /artifacts/skillet-linux-arm64-gnu --version)
printf '%s\n' "$OUTPUT"
grep -F "sklt/" <<< "$OUTPUT"

wine-smoke:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

In general, to fix this issue you add a permissions: block to the workflow (either at the root level so it applies to all jobs, or per job) and set it to the minimum scopes required. For CI workflows that only read the code and upload artifacts (using actions that do not require repo writes), contents: read is a good minimal starting point.

For this specific workflow, the steps use:

  • actions/checkout to read the repository
  • jdx/mise-action, docker/setup-qemu-action, actions/upload-artifact, and actions/download-artifact
    All of these operate with the GITHUB_TOKEN at most needing read access to repository contents (and the artifact actions typically work without additional repo write permissions). There is no indication of any step that pushes commits, creates releases, or modifies issues/PRs.

The single best fix is therefore:

  • Add a root-level permissions: block after the on: section (e.g., after line 8) setting contents: read. This will apply to all jobs (build, checksums, qemu-smoke, wine-smoke, docker-integration, packaging-validate, etc.) unless they override it.
  • No other imports, methods, or definitions are needed since this is purely a workflow configuration change.

Concretely:

  • Edit .github/workflows/build-matrix.yaml.

  • Insert:

    permissions:
      contents: read

    between the on: block and the jobs: key.

Suggested changeset 1
.github/workflows/build-matrix.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml
--- a/.github/workflows/build-matrix.yaml
+++ b/.github/workflows/build-matrix.yaml
@@ -7,6 +7,9 @@
   pull_request:
   workflow_dispatch:
 
+permissions:
+  contents: read
+
 jobs:
   build:
     strategy:
EOF
@@ -7,6 +7,9 @@
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
build:
strategy:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +120 to +149
needs: build
runs-on: ubuntu-latest

env:
WINEDEBUG: -all

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Setup mise
uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac

- name: Install Wine
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y wine64

- name: Download build artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
path: dist
merge-multiple: true

- name: Smoke test Windows artifact with Wine
run: bun scripts/smoke-artifact.ts --target=windows-x64 --artifact-dir=dist --runner=wine64

docker-integration:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

To fix the problem, explicitly define restricted GITHUB_TOKEN permissions in the workflow. Since none of the shown jobs perform any GitHub write operations (they check out code, download artifacts, build and smoke‑test binaries/images), they only require read access to repository contents and, optionally, to packages if images are pushed (not shown here). The best minimal fix is to add a top‑level permissions block with contents: read, which applies to all jobs that do not override it.

Concretely, in .github/workflows/build-matrix.yaml, add a root‑level permissions: section right after the name: Build Matrix line (before on:). This will ensure that build, checksums, qemu-smoke, wine-smoke, docker-integration, packaging-validate, windows-packaging-validate, and any other jobs inherit contents: read and do not get broader defaults. No additional methods, imports, or definitions are needed—this is a pure YAML configuration change.

Suggested changeset 1
.github/workflows/build-matrix.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml
--- a/.github/workflows/build-matrix.yaml
+++ b/.github/workflows/build-matrix.yaml
@@ -1,5 +1,8 @@
 name: Build Matrix
 
+permissions:
+  contents: read
+
 on:
   push:
     branches:
EOF
@@ -1,5 +1,8 @@
name: Build Matrix

permissions:
contents: read

on:
push:
branches:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +150 to +181
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Setup mise
uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac

- name: Setup QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e8

- name: Build musl binaries
run: mise run build -- --targets=linux-x64-musl,linux-arm64-musl

- name: Smoke test amd64 Docker image
shell: bash
run: |
set -euo pipefail
docker buildx create --name skillet-smoke-builder --use || docker buildx use skillet-smoke-builder
docker buildx build --platform linux/amd64 --load -t skillet:amd64 .
docker run --rm --platform linux/amd64 skillet:amd64 --help

- name: Smoke test arm64 Docker image
shell: bash
run: |
set -euo pipefail
docker buildx use skillet-smoke-builder
docker buildx build --platform linux/arm64 --load -t skillet:arm64 .
docker run --rm --platform linux/arm64 skillet:arm64 --help

packaging-validate:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

In general, fix this by adding an explicit permissions: block that grants only the minimal required scopes (usually contents: read) either at the workflow root (affecting all jobs) or on specific jobs. This prevents the workflow from inheriting potentially broader default permissions from the repository or organization.

For this workflow, the safest and simplest change without altering functionality is to define a workflow-level permissions block immediately after the name: (or after on:), setting contents: read. None of the shown jobs perform write operations to the repository or other resources via GITHUB_TOKEN; they mostly check out code, download artifacts, build, and run tests. actions/checkout operates fine with contents: read. Therefore, we can add:

permissions:
  contents: read

near the top of .github/workflows/build-matrix.yaml. This will apply to all jobs, including docker-integration (line 150) where CodeQL reported the issue, and will remove the warning while preserving existing behavior.

Concretely:

  • Edit .github/workflows/build-matrix.yaml.
  • Insert a workflow-level permissions: block between line 1 (name: Build Matrix) and line 3 (on:), or between on: and jobs:. I’ll place it right after the name: for clarity.
  • No imports or additional methods are needed since this is a YAML configuration change only.
Suggested changeset 1
.github/workflows/build-matrix.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml
--- a/.github/workflows/build-matrix.yaml
+++ b/.github/workflows/build-matrix.yaml
@@ -1,5 +1,8 @@
 name: Build Matrix
 
+permissions:
+  contents: read
+
 on:
   push:
     branches:
EOF
@@ -1,5 +1,8 @@
name: Build Matrix

permissions:
contents: read

on:
push:
branches:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +182 to +204
needs: checksums
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Setup mise
uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac

- name: Download checksum artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: skillet-checksums
path: dist

- name: Validate rendered packaging assets
run: mise run package-validate

- name: Validate Homebrew formula syntax
run: ruby -c packaging/homebrew/skillet.rb

windows-packaging-validate:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

To fix this, explicitly define permissions for the GITHUB_TOKEN in the workflow and scope them as narrowly as possible. The jobs shown (docker-integration, packaging-validate, windows-packaging-validate, and the referenced checksums job) only need to read the repository contents and artifacts; they do not push commits, create releases, or modify issues/PRs. Therefore, setting contents: read at the workflow (root) level is an appropriate minimal starting point and aligns with the CodeQL suggestion.

The best minimal fix without changing existing functionality is:

  • Add a permissions: block at the root of .github/workflows/build-matrix.yaml, alongside name and on, so it applies to all jobs that don’t override it.
  • Set contents: read within that block. This allows actions/checkout and other read-only operations to work, while preventing write operations via GITHUB_TOKEN.
  • Do not alter any job steps or add any additional scopes such as pull-requests or issues, since nothing in the provided snippet requires them.

Concretely, in .github/workflows/build-matrix.yaml, insert:

permissions:
  contents: read

between the name: Build Matrix line and the on: block (or immediately after on: if you prefer), ensuring indentation and YAML structure remain valid. No imports or external methods are needed.

Suggested changeset 1
.github/workflows/build-matrix.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml
--- a/.github/workflows/build-matrix.yaml
+++ b/.github/workflows/build-matrix.yaml
@@ -1,5 +1,8 @@
 name: Build Matrix
 
+permissions:
+  contents: read
+
 on:
   push:
     branches:
EOF
@@ -1,5 +1,8 @@
name: Build Matrix

permissions:
contents: read

on:
push:
branches:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +205 to +230
runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5

- name: Pack Chocolatey package
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path dist/choco | Out-Null
choco pack packaging/chocolatey/skillet.nuspec --outputdirectory dist/choco

- name: Validate Chocolatey PowerShell scripts
shell: pwsh
run: |
[scriptblock]::Create((Get-Content -Raw packaging/chocolatey/tools/chocolateyinstall.ps1)) | Out-Null
[scriptblock]::Create((Get-Content -Raw packaging/chocolatey/tools/chocolateyuninstall.ps1)) | Out-Null

- name: Validate winget manifests parse as YAML
shell: pwsh
run: |
$package = Get-Content package.json -Raw | ConvertFrom-Json
$wingetDir = Join-Path packaging/winget $package.version
Get-Content (Join-Path $wingetDir 'echohello-dev.skillet.yaml') -Raw | ConvertFrom-Yaml | Out-Null
Get-Content (Join-Path $wingetDir 'echohello-dev.skillet.installer.yaml') -Raw | ConvertFrom-Yaml | Out-Null
Get-Content (Join-Path $wingetDir 'echohello-dev.skillet.locale.en-US.yaml') -Raw | ConvertFrom-Yaml | Out-Null

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

In general, fix this issue by explicitly specifying a permissions: block that grants only the minimal required scopes for the GITHUB_TOKEN. This can be done at the workflow root (affecting all jobs that don’t override it) or per job. Here, all the shown jobs only read the repository (checkout, download artifacts, packaging/validation) and do not write to issues, PRs, or contents, so a minimal permissions: contents: read at the workflow root is appropriate.

The single best fix with no functional change is to add a top-level permissions: block right after the name: line (line 1) in .github/workflows/build-matrix.yaml. This will apply contents: read to all jobs, including windows-packaging-validate, and satisfies CodeQL’s recommendation. No additional imports or definitions are needed, and no existing steps/jobs need to be modified.

Specifically:

  • In .github/workflows/build-matrix.yaml, insert:
permissions:
  contents: read

after line 1 (name: Build Matrix) and before the on: block at line 3. No other lines need to change.

Suggested changeset 1
.github/workflows/build-matrix.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml
--- a/.github/workflows/build-matrix.yaml
+++ b/.github/workflows/build-matrix.yaml
@@ -1,4 +1,6 @@
 name: Build Matrix
+permissions:
+  contents: read
 
 on:
   push:
EOF
@@ -1,4 +1,6 @@
name: Build Matrix
permissions:
contents: read

on:
push:
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant