Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ jobs:
with:
path: dist
merge-multiple: true
- name: Checksums
run: cd dist && sha256sum studio-* | tee SHA256SUMS
- name: Publish GitHub release
# ref_name / repository come in through the environment, never
# interpolated into the script body, so a crafted tag can't inject shell.
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ reference are all pre-1.0, minor (0.x) releases may include breaking changes.

## [Unreleased]

### Added

- **macOS one-line installer** —
`curl -fsSL https://raw.githubusercontent.com/ocpp-debugkit/studio/main/scripts/install-macos.sh | bash`
downloads the latest release, verifies its SHA-256, installs the app to
Applications, and opens it. Releases now publish a `SHA256SUMS` checksums asset.

### Changed

- The README macOS install is now the one-liner; the manual download / quarantine
instructions were removed.

## [0.5.1] — 2026-07-12

### Changed
Expand Down
23 changes: 9 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,24 @@ The two share **no code**. They meet only at a *conformance contract*: the same

## Install

Download the latest build for your platform from the
[**Releases**](https://github.com/ocpp-debugkit/studio/releases) page.

### macOS (Apple silicon)

Open the `.dmg` and drag **OCPP DebugKit Studio** to Applications. The build is
**ad-hoc signed** (not notarized), so macOS quarantines the download and Gatekeeper
blocks the first launch. Clear it once with a single command:
Paste this into a terminal — it installs the latest **OCPP DebugKit Studio** into
Applications and opens it:

```sh
xattr -dr com.apple.quarantine "/Applications/OCPP DebugKit Studio.app"
curl -fsSL https://raw.githubusercontent.com/ocpp-debugkit/studio/main/scripts/install-macos.sh | bash
```

Prefer not to use the Terminal? Double-click the app, and when macOS refuses, open
**System Settings → Privacy & Security** and click **Open Anyway**, then launch it
again. The ad-hoc signature is what lets the app run once unquarantined;
notarization — which would remove this step entirely — is a deliberate tradeoff
we've deferred.
The script downloads the latest release, verifies its SHA-256, installs the app,
and launches it — no toolchain, no manual steps. (Prefer to read it first? See
[`scripts/install-macos.sh`](scripts/install-macos.sh).)

### Linux

Extract the `.tar.gz` and run the `studio` binary. Requires GTK 4 (`libgtk-4`,
`libwebkitgtk-6.0`).
Download the `.tar.gz` from the
[**Releases**](https://github.com/ocpp-debugkit/studio/releases) page, extract it,
and run the `studio` binary. Requires GTK 4 (`libgtk-4`, `libwebkitgtk-6.0`).

Studio is pre-1.0 (0.x) while Zig, the Native SDK, and the toolkit conformance
reference are all pre-1.0 — see the [roadmap](ROADMAP.md).
Expand Down
15 changes: 8 additions & 7 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ which builds and publishes a GitHub release with two artifacts:
| --- | --- | --- |
| macOS | `studio-X.Y.Z-macos-ReleaseFast.dmg` | A `.app` bundle, **ad-hoc signed** |
| Linux | `studio-X.Y.Z-linux-ReleaseFast.tar.gz` | The `studio` binary + resources |

**macOS Gatekeeper:** the ad-hoc build is not notarized, so macOS quarantines the
download and blocks first launch. Users clear it once with
`xattr -dr com.apple.quarantine "/Applications/OCPP DebugKit Studio.app"` (or
*System Settings → Privacy & Security → Open Anyway*) — see the README. This is a
deliberate tradeoff; notarization, which removes the prompt, needs an Apple
Developer identity and is out of scope for now.
| both | `SHA256SUMS` | Checksums of both packages; the installer verifies against it |

**macOS install:** users install with the one-line installer
([`scripts/install-macos.sh`](scripts/install-macos.sh); see the README), which
downloads the latest DMG, verifies its SHA-256 against `SHA256SUMS`, installs the
app, and clears the download quarantine. The build is ad-hoc signed, not notarized
(a deliberate tradeoff) — installing via `curl` sidesteps the browser-download
quarantine, so the first launch is clean.

## Cutting a release

Expand Down
69 changes: 69 additions & 0 deletions scripts/install-macos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
#
# One-line installer for OCPP DebugKit Studio (macOS, Apple silicon):
#
# curl -fsSL https://raw.githubusercontent.com/ocpp-debugkit/studio/main/scripts/install-macos.sh | bash
#
# Fetches the latest release DMG, verifies its SHA-256 against the release's
# published SHA256SUMS, installs the app to /Applications, clears the download
# quarantine, and opens it. No toolchain, no manual steps.
#
# The checksum and the DMG are both served from the GitHub release over HTTPS, so
# this verifies integrity (a corrupt or truncated download is rejected); it is not
# an independent code signature.
set -euo pipefail

repo="ocpp-debugkit/studio"
app="OCPP DebugKit Studio.app"
dest="/Applications/$app"
base="https://github.com/$repo/releases/latest/download"

note() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }

[ "$(uname -s)" = "Darwin" ] || fail "This installer is macOS-only. On Linux, grab the .tar.gz from https://github.com/$repo/releases."
[ "$(uname -m)" = "arm64" ] || fail "OCPP DebugKit Studio ships an Apple-silicon (arm64) build; this Mac is $(uname -m)."

mnt=""
tmp="$(mktemp -d)"
cleanup() {
[ -n "$mnt" ] && hdiutil detach "$mnt" >/dev/null 2>&1 || true
rm -rf "$tmp"
}
trap cleanup EXIT

note "Finding the latest release"
sums="$(curl -fsSL "$base/SHA256SUMS")" || fail "could not fetch release checksums"
line="$(printf '%s\n' "$sums" | grep 'macos-ReleaseFast\.dmg$')" || fail "the latest release has no macOS build"
sha="${line%% *}"
name="${line##* }"

note "Downloading $name"
curl -fSL --progress-bar -o "$tmp/$name" "$base/$name" || fail "download failed"

note "Verifying SHA-256"
got="$(shasum -a 256 "$tmp/$name" | awk '{ print $1 }')"
[ "$got" = "$sha" ] || fail "checksum mismatch — expected $sha, got $got (not installing)"

note "Mounting the disk image"
mnt="$(hdiutil attach "$tmp/$name" -nobrowse -readonly | grep -o '/Volumes/.*' | head -1)"
[ -n "$mnt" ] || fail "could not mount the disk image"

sudo=""
if [ ! -w /Applications ]; then
sudo="sudo"
note "/Applications needs administrator access — you may be prompted for your password"
fi

note "Installing to /Applications"
$sudo rm -rf "$dest"
$sudo ditto "$mnt/$app" "$dest"

# The app copied out of a curl-downloaded DMG normally has no quarantine flag
# (curl does not set one), but clear it defensively so the first launch never
# hits Gatekeeper. Harmless if the attribute is absent.
$sudo xattr -dr com.apple.quarantine "$dest" 2>/dev/null || true

note "Opening $app"
open "$dest"
note "Done — OCPP DebugKit Studio is installed in /Applications."
Loading