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
85 changes: 84 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,29 @@ on:
permissions:
contents: write

env:
ORCASHELL_UPDATE_MANIFEST_PUBLIC_KEY: ${{ vars.ORCASHELL_UPDATE_MANIFEST_PUBLIC_KEY }}

jobs:
validate-release-config:
runs-on: ubuntu-latest
env:
ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64: ${{ secrets.ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64 }}
steps:
- name: Validate update manifest signing configuration
run: |
test -n "$ORCASHELL_UPDATE_MANIFEST_PUBLIC_KEY"
test -n "$ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64"
PUBLIC_KEY_BYTES="$(
printf '%s' "$ORCASHELL_UPDATE_MANIFEST_PUBLIC_KEY" \
| base64 --decode \
| wc -c \
| tr -d ' '
)"
test "$PUBLIC_KEY_BYTES" = "32"

build-macos:
needs: validate-release-config
runs-on: macos-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -105,6 +126,7 @@ jobs:
path: target/OrcaShell-${{ env.VERSION }}-macos-arm64.dmg

build-linux:
needs: validate-release-config
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -145,6 +167,7 @@ jobs:
path: target/orcashell-${{ env.VERSION }}-linux-x86_64.tar.gz

build-windows:
needs: validate-release-config
runs-on: windows-latest
steps:
- uses: actions/checkout@v5
Expand Down Expand Up @@ -192,13 +215,73 @@ jobs:
needs: [build-macos, build-linux, build-windows]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Derive version
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV"

- name: Download all artifacts
uses: actions/download-artifact@v5
with:
path: artifacts

- name: Generate signed update metadata
env:
ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64: ${{ secrets.ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64 }}
run: |
PUBLISHED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
python3 scripts/release/generate-update-manifest.py \
--artifacts-dir artifacts \
--version "$VERSION" \
--tag "$GITHUB_REF_NAME" \
--repo "$GITHUB_REPOSITORY" \
--published-at "$PUBLISHED_AT" \
--output release-metadata/latest.json

openssl version
openssl version | awk '{ print $2 }' | awk -F. '{ exit !($1 >= 3) }'
umask 077
printf '%s' "$ORCASHELL_UPDATE_MANIFEST_PRIVATE_KEY_PEM_B64" \
| base64 --decode > release-metadata/update-manifest-private-key.pem
DERIVED_PUBLIC_KEY="$(
openssl pkey \
-in release-metadata/update-manifest-private-key.pem \
-pubout \
-outform DER \
| tail -c 32 \
| base64 -w 0
)"
test "$DERIVED_PUBLIC_KEY" = "$ORCASHELL_UPDATE_MANIFEST_PUBLIC_KEY"
openssl pkey \
-in release-metadata/update-manifest-private-key.pem \
-pubout \
-out release-metadata/update-manifest-public-key.pem
openssl pkeyutl \
-sign \
-rawin \
-inkey release-metadata/update-manifest-private-key.pem \
-in release-metadata/latest.json \
-out release-metadata/latest.json.sig.raw
openssl pkeyutl \
-verify \
-rawin \
-pubin \
-inkey release-metadata/update-manifest-public-key.pem \
-sigfile release-metadata/latest.json.sig.raw \
-in release-metadata/latest.json
base64 -w 0 release-metadata/latest.json.sig.raw \
> release-metadata/latest.json.sig
printf '\n' >> release-metadata/latest.json.sig
rm -f \
release-metadata/update-manifest-private-key.pem \
release-metadata/update-manifest-public-key.pem \
release-metadata/latest.json.sig.raw

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: artifacts/**/*
files: |
artifacts/**/*
release-metadata/latest.json
release-metadata/latest.json.sig
31 changes: 19 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ ureq = { version = "3", default-features = false, features = ["rustls"] }
rusqlite = { version = "0.39", features = ["bundled"] }
dirs = "6"
raw-window-handle = "0.6"
base64 = "0.22"
ring = "0.17"
url = "2"
orcashell-ipc = { path = "crates/orcashell-ipc" }
orcashell-platform = { path = "crates/orcashell-platform" }

Expand Down
2 changes: 1 addition & 1 deletion crates/orcashell-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "orcashell-cli"
version = "0.3.3"
version = "0.3.4"
edition.workspace = true

[[bin]]
Expand Down
11 changes: 10 additions & 1 deletion crates/orcashell-cli/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::{bail, Context, Result};
use orcashell_ipc::{default_endpoint, IpcEndpoint, IpcStream};
use orcashell_protocol::framing::{read_frame, write_frame};
use orcashell_protocol::messages::{ClientCommand, DaemonResponse, Envelope};
use orcashell_protocol::messages::{ClientCommand, CommandAuth, DaemonResponse, Envelope};
use orcashell_protocol::version::CURRENT_PROTOCOL_VERSION;
use std::time::Duration;

Expand All @@ -15,9 +15,18 @@ pub fn send_command(command: ClientCommand) -> Result<DaemonResponse> {
pub fn send_command_to(endpoint: &IpcEndpoint, command: ClientCommand) -> Result<DaemonResponse> {
let mut stream = IpcStream::connect(endpoint, CONN_TIMEOUT)
.context("failed to connect to daemon - is the OrcaShell app running?")?;
let auth = if command.requires_auth() {
endpoint
.read_capability_token()
.context("failed to read IPC command capability")?
.map(|capability| CommandAuth { capability })
} else {
None
};

let envelope = Envelope {
protocol_version: CURRENT_PROTOCOL_VERSION,
auth,
payload: command,
};

Expand Down
4 changes: 3 additions & 1 deletion crates/orcashell-daemon-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "orcashell-daemon-core"
version = "0.3.3"
version = "0.3.4"
edition.workspace = true

[dependencies]
Expand All @@ -13,9 +13,11 @@ tracing.workspace = true
serde_json.workspace = true
crossbeam-channel.workspace = true
async-channel.workspace = true
base64.workspace = true
parking_lot.workspace = true
notify = "6.1"
orcashell-platform = { workspace = true }
ring.workspace = true
uuid = { version = "1", features = ["v4"] }

[dev-dependencies]
Expand Down
Loading