feat(HAI-079): add cross-platform matrix builds for release workflows
- Convert release.yml and test-release.yml to matrix strategy with Linux, macOS (arm64/x64), and Windows runners - Add platform-specific checksum generation (sha256sum, shasum, Get-FileHash) - Split release into build and release jobs with artifact upload/download - Add matrix build assertion tests for both workflow files - Update README with supported platforms table and binary details
This commit is contained in:
85
.github/workflows/release.yml
vendored
85
.github/workflows/release.yml
vendored
@@ -9,9 +9,25 @@ permissions:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
build:
|
||||||
name: Build & Release
|
name: Build (${{ matrix.binary }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
target: bun-linux-x64
|
||||||
|
binary: hai-linux-x64
|
||||||
|
- os: macos-latest
|
||||||
|
target: bun-darwin-arm64
|
||||||
|
binary: hai-darwin-arm64
|
||||||
|
- os: macos-13
|
||||||
|
target: bun-darwin-x64
|
||||||
|
binary: hai-darwin-x64
|
||||||
|
- os: windows-latest
|
||||||
|
target: bun-windows-x64
|
||||||
|
binary: hai-windows-x64.exe
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -36,28 +52,57 @@ jobs:
|
|||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Build standalone binary
|
- name: Build standalone binary
|
||||||
run: pnpm build:exe
|
run: pnpm --filter hai build:exe -- --target ${{ matrix.target }}
|
||||||
|
|
||||||
- name: Rename binary with platform and arch
|
- name: Generate checksum (Linux)
|
||||||
run: |
|
if: runner.os == 'Linux'
|
||||||
PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
case "$ARCH" in
|
|
||||||
x86_64) ARCH="x64" ;;
|
|
||||||
aarch64) ARCH="arm64" ;;
|
|
||||||
esac
|
|
||||||
cp packages/cli/dist/hai packages/cli/dist/hai-${PLATFORM}-${ARCH}
|
|
||||||
|
|
||||||
- name: Generate checksums
|
|
||||||
run: |
|
run: |
|
||||||
cd packages/cli/dist
|
cd packages/cli/dist
|
||||||
for file in hai-*; do
|
sha256sum ${{ matrix.binary }} > ${{ matrix.binary }}.sha256
|
||||||
sha256sum "$file" > "${file}.sha256"
|
|
||||||
done
|
- name: Generate checksum (macOS)
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
cd packages/cli/dist
|
||||||
|
shasum -a 256 ${{ matrix.binary }} > ${{ matrix.binary }}.sha256
|
||||||
|
|
||||||
|
- name: Generate checksum (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
cd packages/cli/dist
|
||||||
|
$hash = (Get-FileHash -Algorithm SHA256 "${{ matrix.binary }}").Hash.ToLower()
|
||||||
|
"$hash ${{ matrix.binary }}" | Out-File -Encoding ascii "${{ matrix.binary }}.sha256"
|
||||||
|
|
||||||
|
- name: Upload binary artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.binary }}
|
||||||
|
path: |
|
||||||
|
packages/cli/dist/${{ matrix.binary }}
|
||||||
|
packages/cli/dist/${{ matrix.binary }}.sha256
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Create Release
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
|
||||||
|
- name: Collect release files
|
||||||
|
run: |
|
||||||
|
mkdir -p release
|
||||||
|
find artifacts -type f -exec cp {} release/ \;
|
||||||
|
ls -la release/
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: |
|
files: release/*
|
||||||
packages/cli/dist/hai-*
|
|
||||||
|
|||||||
89
.github/workflows/test-release.yml
vendored
89
.github/workflows/test-release.yml
vendored
@@ -4,9 +4,25 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-release:
|
build:
|
||||||
name: Test Build & Package
|
name: Test Build (${{ matrix.binary }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
target: bun-linux-x64
|
||||||
|
binary: hai-linux-x64
|
||||||
|
- os: macos-latest
|
||||||
|
target: bun-darwin-arm64
|
||||||
|
binary: hai-darwin-arm64
|
||||||
|
- os: macos-13
|
||||||
|
target: bun-darwin-x64
|
||||||
|
binary: hai-darwin-x64
|
||||||
|
- os: windows-latest
|
||||||
|
target: bun-windows-x64
|
||||||
|
binary: hai-windows-x64.exe
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -31,32 +47,59 @@ jobs:
|
|||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Build standalone binary
|
- name: Build standalone binary
|
||||||
run: pnpm build:exe
|
run: pnpm --filter hai build:exe -- --target ${{ matrix.target }}
|
||||||
|
|
||||||
- name: Rename binary with platform and arch
|
- name: Generate checksum (Linux)
|
||||||
run: |
|
if: runner.os == 'Linux'
|
||||||
PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
||||||
ARCH=$(uname -m)
|
|
||||||
case "$ARCH" in
|
|
||||||
x86_64) ARCH="x64" ;;
|
|
||||||
aarch64) ARCH="arm64" ;;
|
|
||||||
esac
|
|
||||||
cp packages/cli/dist/hai packages/cli/dist/hai-${PLATFORM}-${ARCH}
|
|
||||||
|
|
||||||
- name: Generate checksums
|
|
||||||
run: |
|
run: |
|
||||||
cd packages/cli/dist
|
cd packages/cli/dist
|
||||||
for file in hai-*; do
|
sha256sum ${{ matrix.binary }} > ${{ matrix.binary }}.sha256
|
||||||
sha256sum "$file" > "${file}.sha256"
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Smoke test
|
- name: Generate checksum (macOS)
|
||||||
|
if: runner.os == 'macOS'
|
||||||
run: |
|
run: |
|
||||||
chmod +x packages/cli/dist/hai
|
cd packages/cli/dist
|
||||||
packages/cli/dist/hai --help
|
shasum -a 256 ${{ matrix.binary }} > ${{ matrix.binary }}.sha256
|
||||||
|
|
||||||
|
- name: Generate checksum (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
cd packages/cli/dist
|
||||||
|
$hash = (Get-FileHash -Algorithm SHA256 "${{ matrix.binary }}").Hash.ToLower()
|
||||||
|
"$hash ${{ matrix.binary }}" | Out-File -Encoding ascii "${{ matrix.binary }}.sha256"
|
||||||
|
|
||||||
|
- name: Smoke test (Unix)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
chmod +x packages/cli/dist/${{ matrix.binary }}
|
||||||
|
packages/cli/dist/${{ matrix.binary }} --help
|
||||||
|
|
||||||
|
- name: Smoke test (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
run: .\packages\cli\dist\${{ matrix.binary }} --help
|
||||||
|
|
||||||
- name: Upload binary artifact
|
- name: Upload binary artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: hai-binary
|
name: ${{ matrix.binary }}
|
||||||
path: packages/cli/dist/hai-*
|
path: |
|
||||||
|
packages/cli/dist/${{ matrix.binary }}
|
||||||
|
packages/cli/dist/${{ matrix.binary }}.sha256
|
||||||
|
|
||||||
|
collect:
|
||||||
|
name: Collect Artifacts
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
|
||||||
|
- name: Upload combined archive
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: hai-all-platforms
|
||||||
|
path: artifacts/**/*
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -203,10 +203,16 @@ Pre-built standalone binaries are published automatically via GitHub Actions.
|
|||||||
|
|
||||||
### Downloading binaries
|
### Downloading binaries
|
||||||
|
|
||||||
Download the latest binary from the [GitHub Releases](../../releases) page. Each release includes:
|
Download the latest binary from the [GitHub Releases](../../releases) page. Each release includes platform-specific binaries and SHA256 checksum files for verification.
|
||||||
|
|
||||||
- Platform-specific binaries (e.g., `hai-linux-x64`)
|
#### Supported platforms
|
||||||
- SHA256 checksum files for verification
|
|
||||||
|
| Platform | Binary | Runner |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| Linux x64 | `hai-linux-x64` | `ubuntu-latest` |
|
||||||
|
| macOS arm64 (Apple Silicon) | `hai-darwin-arm64` | `macos-latest` |
|
||||||
|
| macOS x64 (Intel) | `hai-darwin-x64` | `macos-13` |
|
||||||
|
| Windows x64 | `hai-windows-x64.exe` | `windows-latest` |
|
||||||
|
|
||||||
### Triggering a release
|
### Triggering a release
|
||||||
|
|
||||||
@@ -217,7 +223,7 @@ git tag v0.1.0
|
|||||||
git push origin v0.1.0
|
git push origin v0.1.0
|
||||||
```
|
```
|
||||||
|
|
||||||
The release workflow will automatically build the binary and create a GitHub Release with the artifact attached.
|
The release workflow will automatically build native binaries for all supported platforms and create a GitHub Release with all artifacts attached.
|
||||||
|
|
||||||
### CI pipeline
|
### CI pipeline
|
||||||
|
|
||||||
|
|||||||
@@ -88,13 +88,50 @@ describe("Release workflow (.github/workflows/release.yml)", () => {
|
|||||||
expect(content).toContain("pnpm build");
|
expect(content).toContain("pnpm build");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes pnpm build:exe step", () => {
|
it("includes build:exe step", () => {
|
||||||
expect(content).toContain("pnpm build:exe");
|
expect(content).toContain("build:exe");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("generates SHA256 checksums", () => {
|
it("generates SHA256 checksums", () => {
|
||||||
expect(content).toContain("sha256sum");
|
expect(content).toContain("sha256sum");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("matrix build strategy", () => {
|
||||||
|
it("has a build job with strategy.matrix including at least 4 entries", () => {
|
||||||
|
const buildJob = workflow.jobs.build;
|
||||||
|
expect(buildJob).toBeDefined();
|
||||||
|
expect(buildJob.strategy?.matrix?.include?.length).toBeGreaterThanOrEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes all required OS runners", () => {
|
||||||
|
const runners = workflow.jobs.build.strategy.matrix.include.map((e: any) => e.os);
|
||||||
|
expect(runners).toContain("ubuntu-latest");
|
||||||
|
expect(runners).toContain("macos-latest");
|
||||||
|
expect(runners).toContain("macos-13");
|
||||||
|
expect(runners).toContain("windows-latest");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes all required Bun targets", () => {
|
||||||
|
const targets = workflow.jobs.build.strategy.matrix.include.map((e: any) => e.target);
|
||||||
|
expect(targets).toContain("bun-linux-x64");
|
||||||
|
expect(targets).toContain("bun-darwin-arm64");
|
||||||
|
expect(targets).toContain("bun-darwin-x64");
|
||||||
|
expect(targets).toContain("bun-windows-x64");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has a release job that needs the build job", () => {
|
||||||
|
const releaseJob = workflow.jobs.release;
|
||||||
|
expect(releaseJob).toBeDefined();
|
||||||
|
const needs = Array.isArray(releaseJob.needs) ? releaseJob.needs : [releaseJob.needs];
|
||||||
|
expect(needs).toContain("build");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("generates checksums on all platforms", () => {
|
||||||
|
expect(content).toContain("sha256sum");
|
||||||
|
expect(content).toContain("shasum -a 256");
|
||||||
|
expect(content).toContain("Get-FileHash");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Test Release workflow (.github/workflows/test-release.yml)", () => {
|
describe("Test Release workflow (.github/workflows/test-release.yml)", () => {
|
||||||
@@ -124,8 +161,8 @@ describe("Test Release workflow (.github/workflows/test-release.yml)", () => {
|
|||||||
expect(content).toContain("pnpm build");
|
expect(content).toContain("pnpm build");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes pnpm build:exe step", () => {
|
it("includes build:exe step", () => {
|
||||||
expect(content).toContain("pnpm build:exe");
|
expect(content).toContain("build:exe");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes smoke test with --help", () => {
|
it("includes smoke test with --help", () => {
|
||||||
@@ -135,4 +172,34 @@ describe("Test Release workflow (.github/workflows/test-release.yml)", () => {
|
|||||||
it("uploads artifact", () => {
|
it("uploads artifact", () => {
|
||||||
expect(content).toContain("actions/upload-artifact");
|
expect(content).toContain("actions/upload-artifact");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("matrix build strategy", () => {
|
||||||
|
it("has a build job with strategy.matrix including at least 4 entries", () => {
|
||||||
|
const buildJob = workflow.jobs.build;
|
||||||
|
expect(buildJob).toBeDefined();
|
||||||
|
expect(buildJob.strategy?.matrix?.include?.length).toBeGreaterThanOrEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes all required OS runners", () => {
|
||||||
|
const runners = workflow.jobs.build.strategy.matrix.include.map((e: any) => e.os);
|
||||||
|
expect(runners).toContain("ubuntu-latest");
|
||||||
|
expect(runners).toContain("macos-latest");
|
||||||
|
expect(runners).toContain("macos-13");
|
||||||
|
expect(runners).toContain("windows-latest");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("includes all required Bun targets", () => {
|
||||||
|
const targets = workflow.jobs.build.strategy.matrix.include.map((e: any) => e.target);
|
||||||
|
expect(targets).toContain("bun-linux-x64");
|
||||||
|
expect(targets).toContain("bun-darwin-arm64");
|
||||||
|
expect(targets).toContain("bun-darwin-x64");
|
||||||
|
expect(targets).toContain("bun-windows-x64");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("generates checksums on all platforms", () => {
|
||||||
|
expect(content).toContain("sha256sum");
|
||||||
|
expect(content).toContain("shasum -a 256");
|
||||||
|
expect(content).toContain("Get-FileHash");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user