Skip to content

Commit ef4543b

Browse files
committed
home brow, other install options
1 parent 6f8b5c2 commit ef4543b

File tree

26 files changed

+1022
-58
lines changed

26 files changed

+1022
-58
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Haisdk < Formula
2+
include Language::Python::Virtualenv
3+
4+
desc "HAI SDK CLI for JACS registration and attestation workflows"
5+
homepage "https://github.com/HumanAssisted/haisdk"
6+
url "__HAISDK_SDIST_URL__"
7+
sha256 "__HAISDK_SHA256__"
8+
license "MIT"
9+
10+
depends_on "python@3.12"
11+
depends_on "httpx"
12+
depends_on "cryptography"
13+
depends_on "jacs"
14+
15+
def install
16+
python = Formula["python@3.12"].opt_bin/"python3.12"
17+
venv = virtualenv_create(libexec, python, system_site_packages: true)
18+
venv.pip_install buildpath
19+
bin.install_symlink libexec/"bin/haisdk"
20+
end
21+
22+
test do
23+
assert_match "HAI SDK CLI", shell_output("#{bin}/haisdk --help")
24+
assert_match "jacs version:", shell_output("#{Formula["jacs"].opt_bin}/jacs version")
25+
end
26+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Jacs < Formula
2+
desc "JSON Agent Communication Standard command-line interface"
3+
homepage "https://github.com/HumanAssisted/JACS"
4+
url "https://crates.io/api/v1/crates/jacs/__JACS_VERSION__/download"
5+
sha256 "__JACS_SHA256__"
6+
license "Apache-2.0"
7+
8+
depends_on "rust" => :build
9+
10+
def install
11+
system "cargo", "install", *std_cargo_args(path: "."), "--features", "cli", "--locked"
12+
end
13+
14+
test do
15+
assert_match "jacs version: #{version}", shell_output("#{bin}/jacs version")
16+
assert_match "Usage: jacs [COMMAND]", shell_output("#{bin}/jacs --help")
17+
end
18+
end

.github/workflows/homebrew.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Homebrew Install Smoke Tests
2+
3+
on:
4+
push:
5+
branches: ["master"]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
macos-brew-install:
11+
runs-on: macos-latest
12+
env:
13+
HOMEBREW_NO_AUTO_UPDATE: "1"
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Install JACS formula
18+
run: brew install --formula ./Formula/jacs.rb
19+
20+
- name: Smoke test JACS CLI + MCP helpers
21+
run: |
22+
jacs version
23+
jacs mcp --help
24+
25+
- name: Install HAISDK formula
26+
run: brew install --formula --HEAD ./Formula/haisdk.rb
27+
28+
- name: Smoke test HAISDK CLI
29+
run: |
30+
haisdk --help
31+
haisdk register --help

.github/workflows/nodejs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ name: Node.js (jacsnpm)
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: [ "master" ]
66
paths:
77
- 'jacsnpm/**'
88
- 'jacs/**' # jacsnpm depends on jacs
99
- 'binding-core/**' # jacsnpm verifyStandalone depends on binding-core
1010
- '.github/workflows/nodejs.yml'
1111
pull_request:
12-
branches: [ "main" ]
12+
branches: [ "master" ]
1313
paths:
1414
- 'jacsnpm/**'
1515
- 'jacs/**' # jacsnpm depends on jacs

.github/workflows/python.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Python (jacs)
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: [ "master" ]
66
pull_request:
7-
branches: [ "main" ]
7+
branches: [ "master" ]
88
workflow_dispatch: # Allows manual triggering
99

1010
env:

.github/workflows/release-cli.yml

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ jobs:
2222
TAG="${GITHUB_REF#refs/tags/cli/v}"
2323
echo "version=$TAG" >> $GITHUB_OUTPUT
2424
25-
- name: Check Cargo.toml version matches tag
25+
- name: Check Cargo.toml versions match tag
2626
run: |
2727
TAG_VERSION="${{ steps.extract.outputs.version }}"
28-
CARGO_VERSION=$(grep '^version = ' jacs/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
29-
echo "Cargo version: $CARGO_VERSION, tag: $TAG_VERSION"
30-
if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then
31-
echo "::error::Version mismatch! jacs/Cargo.toml has $CARGO_VERSION but tag is $TAG_VERSION"
28+
JACS_VERSION=$(grep '^version = ' jacs/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
29+
MCP_VERSION=$(grep '^version = ' jacs-mcp/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
30+
echo "jacs version: $JACS_VERSION, tag: $TAG_VERSION"
31+
echo "jacs-mcp version: $MCP_VERSION, tag: $TAG_VERSION"
32+
if [ "$JACS_VERSION" != "$TAG_VERSION" ]; then
33+
echo "::error::Version mismatch! jacs/Cargo.toml has $JACS_VERSION but tag is $TAG_VERSION"
34+
exit 1
35+
fi
36+
if [ "$MCP_VERSION" != "$TAG_VERSION" ]; then
37+
echo "::error::Version mismatch! jacs-mcp/Cargo.toml has $MCP_VERSION but tag is $TAG_VERSION"
3238
exit 1
3339
fi
3440
@@ -40,31 +46,30 @@ jobs:
4046
include:
4147
- os: macos-latest
4248
target: aarch64-apple-darwin
43-
artifact_name: jacs-cli
44-
asset_name: jacs-cli-${{ needs.verify-version.outputs.version }}-darwin-arm64
45-
archive: tar.gz
49+
asset_suffix: darwin-arm64
50+
archive_ext: tar.gz
4651
- os: macos-14
4752
target: x86_64-apple-darwin
48-
artifact_name: jacs-cli
49-
asset_name: jacs-cli-${{ needs.verify-version.outputs.version }}-darwin-x64
50-
archive: tar.gz
53+
asset_suffix: darwin-x64
54+
archive_ext: tar.gz
5155
- os: ubuntu-latest
5256
target: x86_64-unknown-linux-gnu
53-
artifact_name: jacs-cli
54-
asset_name: jacs-cli-${{ needs.verify-version.outputs.version }}-linux-x64
55-
archive: tar.gz
57+
asset_suffix: linux-x64
58+
archive_ext: tar.gz
5659
- os: ubuntu-24.04-arm
5760
target: aarch64-unknown-linux-gnu
58-
artifact_name: jacs-cli
59-
asset_name: jacs-cli-${{ needs.verify-version.outputs.version }}-linux-arm64
60-
archive: tar.gz
61+
asset_suffix: linux-arm64
62+
archive_ext: tar.gz
6163
- os: windows-latest
6264
target: x86_64-pc-windows-msvc
63-
artifact_name: jacs-cli.exe
64-
asset_name: jacs-cli-${{ needs.verify-version.outputs.version }}-windows-x64
65-
archive: zip
65+
asset_suffix: windows-x64
66+
archive_ext: zip
6667

6768
runs-on: ${{ matrix.os }}
69+
env:
70+
VERSION: ${{ needs.verify-version.outputs.version }}
71+
CLI_ASSET_NAME: jacs-cli-${{ needs.verify-version.outputs.version }}-${{ matrix.asset_suffix }}
72+
MCP_ASSET_NAME: jacs-mcp-${{ needs.verify-version.outputs.version }}-${{ matrix.asset_suffix }}
6873
steps:
6974
- uses: actions/checkout@v4
7075

@@ -73,37 +78,51 @@ jobs:
7378
toolchain: '1.93'
7479
targets: ${{ matrix.target }}
7580

76-
- name: Build CLI binary
77-
run: cargo build --release -p jacs --features cli --target ${{ matrix.target }}
81+
- name: Build binaries
82+
run: |
83+
cargo build --release -p jacs --features cli --target ${{ matrix.target }}
84+
cargo build --release -p jacs-mcp --target ${{ matrix.target }}
7885
7986
- name: Smoke test (Unix)
8087
if: runner.os != 'Windows'
81-
run: ./target/${{ matrix.target }}/release/jacs --version
88+
run: |
89+
./target/${{ matrix.target }}/release/jacs --version
90+
./target/${{ matrix.target }}/release/jacs-mcp --help > /dev/null
8291
8392
- name: Smoke test (Windows)
8493
if: runner.os == 'Windows'
85-
run: .\target\${{ matrix.target }}\release\jacs.exe --version
94+
shell: pwsh
95+
run: |
96+
.\target\${{ matrix.target }}\release\jacs.exe version
97+
.\target\${{ matrix.target }}\release\jacs-mcp.exe --help | Out-Null
8698
8799
- name: Package (Unix)
88100
if: runner.os != 'Windows'
89101
run: |
90102
cp target/${{ matrix.target }}/release/jacs jacs-cli
91-
tar czf ${{ matrix.asset_name }}.tar.gz jacs-cli
92-
shasum -a 256 ${{ matrix.asset_name }}.tar.gz > ${{ matrix.asset_name }}.tar.gz.sha256
103+
cp target/${{ matrix.target }}/release/jacs-mcp jacs-mcp
104+
tar czf ${CLI_ASSET_NAME}.tar.gz jacs-cli
105+
tar czf ${MCP_ASSET_NAME}.tar.gz jacs-mcp
106+
shasum -a 256 ${CLI_ASSET_NAME}.tar.gz > ${CLI_ASSET_NAME}.tar.gz.sha256
107+
shasum -a 256 ${MCP_ASSET_NAME}.tar.gz > ${MCP_ASSET_NAME}.tar.gz.sha256
93108
94109
- name: Package (Windows)
95110
if: runner.os == 'Windows'
96111
shell: pwsh
97112
run: |
98113
Copy-Item "target/${{ matrix.target }}/release/jacs.exe" "jacs-cli.exe"
99-
Compress-Archive -Path "jacs-cli.exe" -DestinationPath "${{ matrix.asset_name }}.zip"
100-
Get-FileHash "${{ matrix.asset_name }}.zip" -Algorithm SHA256 | ForEach-Object { "$($_.Hash.ToLower()) ${{ matrix.asset_name }}.zip" } | Out-File "${{ matrix.asset_name }}.zip.sha256" -Encoding ascii
114+
Copy-Item "target/${{ matrix.target }}/release/jacs-mcp.exe" "jacs-mcp.exe"
115+
Compress-Archive -Path "jacs-cli.exe" -DestinationPath "${env:CLI_ASSET_NAME}.zip"
116+
Compress-Archive -Path "jacs-mcp.exe" -DestinationPath "${env:MCP_ASSET_NAME}.zip"
117+
Get-FileHash "${env:CLI_ASSET_NAME}.zip" -Algorithm SHA256 | ForEach-Object { "$($_.Hash.ToLower()) ${env:CLI_ASSET_NAME}.zip" } | Out-File "${env:CLI_ASSET_NAME}.zip.sha256" -Encoding ascii
118+
Get-FileHash "${env:MCP_ASSET_NAME}.zip" -Algorithm SHA256 | ForEach-Object { "$($_.Hash.ToLower()) ${env:MCP_ASSET_NAME}.zip" } | Out-File "${env:MCP_ASSET_NAME}.zip.sha256" -Encoding ascii
101119
102120
- uses: actions/upload-artifact@v4
103121
with:
104-
name: ${{ matrix.asset_name }}
122+
name: binaries-${{ matrix.asset_suffix }}
105123
path: |
106-
${{ matrix.asset_name }}.*
124+
${{ env.CLI_ASSET_NAME }}.*
125+
${{ env.MCP_ASSET_NAME }}.*
107126
108127
release:
109128
needs: [verify-version, build]
@@ -128,7 +147,9 @@ jobs:
128147
body: |
129148
## JACS CLI v${{ needs.verify-version.outputs.version }}
130149
131-
Prebuilt CLI binaries for verifying and signing JACS documents.
150+
Prebuilt binaries for:
151+
- `jacs` (CLI)
152+
- `jacs-mcp` (MCP server)
132153
133154
### Install
134155
@@ -146,7 +167,12 @@ jobs:
146167
sudo mv jacs-cli /usr/local/bin/
147168
```
148169
149-
Or install via npm/pip (ships with `jacs`).
170+
Install MCP directly from the CLI (uses these platform assets by default):
171+
172+
```bash
173+
jacs mcp install
174+
jacs mcp run
175+
```
150176
151177
### Verify checksums
152178
```bash
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Sync Homebrew Tap
2+
3+
on:
4+
push:
5+
tags:
6+
- 'cli/v*'
7+
- 'crate/v*'
8+
workflow_dispatch:
9+
inputs:
10+
jacs_version:
11+
description: "JACS version for Formula/jacs.rb (defaults to tag or jacs/Cargo.toml)"
12+
required: false
13+
haisdk_version:
14+
description: "HAISDK version for Formula/haisdk.rb (defaults to latest on PyPI)"
15+
required: false
16+
haisdk_pypi_package:
17+
description: "PyPI package name for HAISDK"
18+
required: false
19+
default: "haisdk"
20+
tap_repository:
21+
description: "Homebrew tap repository (owner/repo)"
22+
required: false
23+
default: "HumanAssisted/homebrew-jacs"
24+
tap_branch:
25+
description: "Tap branch (stable branch is master)"
26+
required: false
27+
default: "master"
28+
29+
permissions:
30+
contents: read
31+
32+
jobs:
33+
sync-formulas:
34+
if: ${{ secrets.HOMEBREW_TAP_TOKEN != '' }}
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v4
38+
39+
- name: Resolve versions and artifact checksums
40+
id: resolve
41+
shell: bash
42+
run: |
43+
set -euo pipefail
44+
45+
ref_name="${GITHUB_REF_NAME:-}"
46+
jacs_version_input="${{ github.event.inputs.jacs_version }}"
47+
haisdk_version_input="${{ github.event.inputs.haisdk_version }}"
48+
haisdk_pkg_input="${{ github.event.inputs.haisdk_pypi_package }}"
49+
50+
if [[ -n "${jacs_version_input}" ]]; then
51+
jacs_version="${jacs_version_input}"
52+
elif [[ "${ref_name}" =~ ^cli/v(.+)$ ]]; then
53+
jacs_version="${BASH_REMATCH[1]}"
54+
elif [[ "${ref_name}" =~ ^crate/v(.+)$ ]]; then
55+
jacs_version="${BASH_REMATCH[1]}"
56+
else
57+
jacs_version="$(grep '^version = ' jacs/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')"
58+
fi
59+
60+
haisdk_pkg="${haisdk_pkg_input:-haisdk}"
61+
if [[ -z "${haisdk_pkg}" ]]; then
62+
haisdk_pkg="haisdk"
63+
fi
64+
65+
pypi_json="$(mktemp)"
66+
curl -fsSL "https://pypi.org/pypi/${haisdk_pkg}/json" -o "${pypi_json}"
67+
68+
if [[ -n "${haisdk_version_input}" ]]; then
69+
haisdk_version="${haisdk_version_input}"
70+
else
71+
haisdk_version="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1], encoding="utf-8"))["info"]["version"])' "${pypi_json}")"
72+
fi
73+
74+
read -r haisdk_sdist_url haisdk_sha256 < <(python3 -c 'import json,sys; data=json.load(open(sys.argv[1], encoding="utf-8")); version=sys.argv[2]; entry=next((f for f in data.get("releases", {}).get(version, []) if f.get("packagetype")=="sdist"), None); (entry is not None) or sys.exit(f"No sdist found for version {version}"); print(entry["url"], entry["digests"]["sha256"])' "${pypi_json}" "${haisdk_version}")
75+
76+
jacs_crate="$(mktemp)"
77+
curl -fsSL "https://crates.io/api/v1/crates/jacs/${jacs_version}/download" -o "${jacs_crate}"
78+
jacs_sha256="$(sha256sum "${jacs_crate}" | awk '{print $1}')"
79+
80+
echo "jacs_version=${jacs_version}" >> "${GITHUB_OUTPUT}"
81+
echo "jacs_sha256=${jacs_sha256}" >> "${GITHUB_OUTPUT}"
82+
echo "haisdk_version=${haisdk_version}" >> "${GITHUB_OUTPUT}"
83+
echo "haisdk_sdist_url=${haisdk_sdist_url}" >> "${GITHUB_OUTPUT}"
84+
echo "haisdk_sha256=${haisdk_sha256}" >> "${GITHUB_OUTPUT}"
85+
echo "haisdk_pypi_package=${haisdk_pkg}" >> "${GITHUB_OUTPUT}"
86+
87+
- name: Generate formula files
88+
shell: bash
89+
run: |
90+
set -euo pipefail
91+
mkdir -p generated/Formula
92+
93+
sed \
94+
-e "s|__JACS_VERSION__|${{ steps.resolve.outputs.jacs_version }}|g" \
95+
-e "s|__JACS_SHA256__|${{ steps.resolve.outputs.jacs_sha256 }}|g" \
96+
.github/homebrew-templates/jacs.rb.tmpl > generated/Formula/jacs.rb
97+
98+
sed \
99+
-e "s|__HAISDK_SDIST_URL__|${{ steps.resolve.outputs.haisdk_sdist_url }}|g" \
100+
-e "s|__HAISDK_SHA256__|${{ steps.resolve.outputs.haisdk_sha256 }}|g" \
101+
.github/homebrew-templates/haisdk.rb.tmpl > generated/Formula/haisdk.rb
102+
103+
- name: Checkout Homebrew tap repository
104+
uses: actions/checkout@v4
105+
with:
106+
repository: ${{ github.event.inputs.tap_repository || 'HumanAssisted/homebrew-jacs' }}
107+
ref: ${{ github.event.inputs.tap_branch || 'master' }}
108+
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
109+
path: tap
110+
111+
- name: Publish updated formulas to tap
112+
shell: bash
113+
run: |
114+
set -euo pipefail
115+
mkdir -p tap/Formula
116+
cp generated/Formula/jacs.rb tap/Formula/jacs.rb
117+
cp generated/Formula/haisdk.rb tap/Formula/haisdk.rb
118+
119+
cd tap
120+
if git diff --quiet -- Formula/jacs.rb Formula/haisdk.rb; then
121+
echo "No Homebrew formula changes to publish."
122+
exit 0
123+
fi
124+
125+
git config user.name "github-actions[bot]"
126+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
127+
git add Formula/jacs.rb Formula/haisdk.rb
128+
git commit -m "Update formulas: jacs v${{ steps.resolve.outputs.jacs_version }}, haisdk v${{ steps.resolve.outputs.haisdk_version }}"
129+
git push origin HEAD:${{ github.event.inputs.tap_branch || 'master' }}

0 commit comments

Comments
 (0)