Skip to content

docs(1.0): promote org-SSO to a supported 1.0 feature (revises #325 s… #814

docs(1.0): promote org-SSO to a supported 1.0 feature (revises #325 s…

docs(1.0): promote org-SSO to a supported 1.0 feature (revises #325 s… #814

Workflow file for this run

name: ci
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --all-targets
# Force single-threaded test execution to keep the heavy real-process
# e2e binaries (e.g. e2e_detached_pair, with real daemons + a SAS
# handshake under a tight deadline) from self-contending under default
# parallelism on the 2-core ubuntu-latest runner. Lib + non-heavy e2e
# cost is negligible serialized; heavy e2e is where the wins are. See
# feedback/heavy-e2e-subprocess-contention. (The UDS round-trip
# Broken-pipe/os-error-32 flake this also used to mask was root-caused +
# fixed in #241 — the canned test server's single-read racing
# uds_request's two-write — so serialization now stands on heavy-e2e
# contention alone, not a live flake.)
- run: cargo test --all-targets -- --test-threads=1
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets -- -D warnings
demo-invite:
# Runs demo-invite.sh end-to-end: local relay + paul + willard + one-paste
# invite-URL pair + bidirectional signed send/recv. Catches regressions in
# the v0.4.0 pair_drop hook, daemon-pull cursor persist, and CLI wiring.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y jq
- run: cargo build --release --bin wire
- run: WIRE=./target/release/wire bash demo-invite.sh
demo-command:
# Runs the shipped `wire demo` verb end-to-end: it self-execs to boot an
# ephemeral local relay, mint two identities, pair them, and verify a
# signed round-trip — then tears it all down. Guards the one-command
# try-before-you-install path (and its self-exec orchestration).
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --release --bin wire
- run: ./target/release/wire demo --json | tee /dev/stderr | grep -q '"ok":true'
hello-world:
# The canonical FIRST-CONNECTION round-trip gate (ROAD_TO_1.0 §3 lifecycle
# hardening). Reproduces the README "60-second local demo" exactly — local
# relay + two independent `wire up` agents + dial-by-persona + receive +
# autonomous reply — across several fresh-box iterations to catch the
# intermittent daemon-survival / first-connection regressions a single-shot
# `wire demo` or install-smoke wouldn't. This is the harness that caught the
# #263 daemon-self-abort + one-directional-pin bugs; it must stay green.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y bc
- run: cargo build --release --bin wire
- run: WIRE_BIN=./target/release/wire bash scripts/hello-world-validate.sh 5
demo-hotline:
# Runs demo-hotline.sh end-to-end: local relay + 5 agents with vibes +
# full mesh via `wire add` + signed ring-send. Validates the v0.5
# handle directory, .well-known/wire/agent resolver, pair_drop +
# pair_drop_ack flow, profile fields, and 5-way mesh under one daemon.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y jq
- run: cargo build --release --bin wire
- run: WIRE=./target/release/wire bash demo-hotline.sh
integration-tests:
# Real end-to-end CLI tests (tests/it/): each boots actual relay processes
# and drives the shipped binary like a user/script would — zero-paste
# pairing + bidirectional signed messages, the on-box sister mesh,
# `wire up` onboarding (+ --offline), nuke/recovery, and group join-by-code
# with cross-member verified read. Covers the CLI seams `cargo test`'s
# library-level tests don't (arg parsing, process lifecycle, multi-agent
# connections). See tests/it/README.md.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y jq
- run: cargo build --release --bin wire
- run: WIRE=./target/release/wire tests/it/run-all.sh
docs-lint:
# Catch deprecated command phrases drifting back into docs. Per the
# swift-harbor / dthoma1 #145 audit: README + AGENTS + INSTALL had
# several stale shapes (`wire add bob@`, `wire init <nick>`, `wire
# daemon start`, `wire.slancha.ai`, `wire up <nick>@<relay>`) that
# contradicted the canonical v0.12+ surface. Lint blocks regression.
#
# Legacy sections explicitly named "Legacy" or "Legacy flows" are
# allowed to mention deprecated verbs — the lint scopes its grep
# exclusions to those headers (handled inline via `grep -v`).
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: deprecated phrases (canonical surface drift)
run: |
set -e
FILES="README.md AGENTS.md INSTALL.md docs/integrations/*.md docs/AGENT_INTEGRATION.md"
fail=0
check() {
local pattern="$1"
local description="$2"
# Exclude lines inside Legacy sections (best-effort: grep -v on
# the line itself contains 'Legacy' marker; deeper context
# exclusion would need a real parser).
hits=$(grep -nE "$pattern" $FILES 2>/dev/null \
| grep -v -iE '(legacy|deprecated|removed|v1\.0 removes)' \
|| true)
if [ -n "$hits" ]; then
echo "::error::Deprecated phrase '$description' found in docs:"
echo "$hits"
fail=1
fi
}
# The shapes swift-harbor's audit (#145) called out:
check 'wire add [a-z][a-z-]*@' 'wire add <peer>@<relay> (use `wire dial`)'
check 'wire init <nick>' 'wire init <nick> (use `wire up`)'
check 'wire daemon start' 'wire daemon start (no subcommand; use `wire daemon`)'
check 'wire up <nick>@' 'wire up <nick>@<relay> (handle is DID-derived; use `wire up @<relay>`)'
check 'wire\.slancha\.ai' 'wire.slancha.ai (use wireup.net)'
check 'relay\.slancha\.ai' 'relay.slancha.ai (use wireup.net)'
if [ "$fail" -ne 0 ]; then
echo ""
echo "Lint failed: deprecated command phrase(s) drifted back into docs."
echo "Fix the lines above or move them under a 'Legacy' header if intentional."
exit 1
fi
echo "docs-lint: clean."
install-smoke:
# Fresh-user first-run path. Builds the binary THIS PR produces, puts it
# on PATH the way an install leaves it, and — from a clean cwd with an
# empty WIRE_HOME — runs the offline out-of-the-box sequence. Catches
# changes that compile + pass tests but break the new-user experience
# (first-run offline identity, --json shape, basic subcommands). Also
# This is the "test-env in CI" smoke; the demos cover deeper e2e flows.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y jq
- run: cargo build --release --bin wire
- name: fresh-user smoke (offline, clean WIRE_HOME)
run: |
set -euo pipefail
sudo install -m 0755 target/release/wire /usr/local/bin/wire
export WIRE_HOME="$(mktemp -d)/home" WIRE_QUIET_AUTOSESSION=1
cd "$(mktemp -d)" # clean cwd — no repo, no existing state
wire --version
wire --help >/dev/null
wire whoami --json | jq -e '.initialized == false' # pre-init
# `wire up --no-local` creates the local identity but also tries to
# claim its DID-derived handle on the shared relay — that claim can
# 409 if the random persona is already taken (non-fatal). The real
# check is the local identity, so tolerate a nonzero exit and assert
# via whoami.
wire up --no-local || true
wire whoami --json | jq -e '.did | startswith("did:wire:")'
wire here >/dev/null
echo "install-smoke: fresh-user offline path OK"
- name: nuke smoke (dry-run changes nothing; --force resets; re-up works)
run: |
set -euo pipefail
export WIRE_HOME="$(mktemp -d)/home" WIRE_QUIET_AUTOSESSION=1
wire up --no-local || true
wire whoami --json | jq -e '.did | startswith("did:wire:")' # identity created
wire nuke --dry-run # lists, must change nothing
wire whoami --json | jq -e '.did | startswith("did:wire:")' # dry-run kept it
wire nuke --force --json | jq -e 'has("removed_paths")'
wire whoami --json | jq -e '.initialized == false' # state wiped
wire up --no-local || true # fresh again
wire whoami --json | jq -e '.did | startswith("did:wire:")'
echo "install-smoke: nuke + re-up OK"
install-smoke-windows:
# Windows leg of the cross-platform gate: build wire.exe and run the
# fresh-user + nuke smoke in PowerShell from a clean WIRE_HOME. Windows
# can't be exercised on the maintainer's mac/linux hosts, so this CI
# job is the primary Windows signal (plus an operator confirm on a real
# box before merge).
runs-on: windows-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --release --bin wire
- name: fresh-user + nuke smoke (PowerShell)
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$PSNativeCommandUseErrorActionPreference = $true # native non-zero exit → throw
$wire = ".\target\release\wire.exe"
$env:WIRE_HOME = Join-Path $env:RUNNER_TEMP ("wh-" + [guid]::NewGuid().ToString("N"))
$env:WIRE_QUIET_AUTOSESSION = "1"
& $wire --version
& $wire --help | Out-Null
$pre = (& $wire whoami --json | ConvertFrom-Json)
if ($pre.initialized -ne $false) { throw "expected initialized:false pre-init" }
# `wire up --no-local` creates the local identity but also tries to
# claim its handle on the shared relay; that claim can 409 (handle
# already taken) which is non-fatal. Tolerate a nonzero exit and
# assert the real outcome (local DID) via whoami.
try { & $wire up --no-local } catch { Write-Host "wire up claim non-fatal: $_" }
$post = (& $wire whoami --json | ConvertFrom-Json)
if (-not $post.did.StartsWith("did:wire:")) { throw "expected a did:wire: DID" }
& $wire here | Out-Null
& $wire nuke --dry-run
$afterDry = (& $wire whoami --json | ConvertFrom-Json)
if (-not $afterDry.did.StartsWith("did:wire:")) { throw "dry-run must not wipe state" }
& $wire nuke --force --json | ConvertFrom-Json | Out-Null
$afterNuke = (& $wire whoami --json | ConvertFrom-Json)
if ($afterNuke.initialized -ne $false) { throw "nuke --force should wipe state" }
try { & $wire up --no-local } catch { Write-Host "wire up claim non-fatal: $_" }
$fresh = (& $wire whoami --json | ConvertFrom-Json)
if (-not $fresh.did.StartsWith("did:wire:")) { throw "re-up should recreate identity" }
Write-Host "install-smoke-windows: fresh-user + nuke OK"
install-script-smoke:
# The REAL installer, end-to-end. `install-smoke` copies the binary
# straight onto PATH and never touches install.sh — so the path a user
# actually runs (`curl … | sh`: triple detection → download → SHA-256
# verify → --prefix install → PATH/next-steps) is untested. This serves a
# locally-built binary as a release asset over http and runs install.sh
# against it (WIRE_DIST_URL override — no real GitHub Release needed),
# then drives the fresh-user onboarding through the installed binary.
# Catches installer bugs (wrong triple/asset name, broken verify, bad
# install dir) that compile + pass tests but break first-touch install.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update && sudo apt-get install -y jq
- run: cargo build --release --bin wire
- name: install.sh from a clean machine, then fresh-user onboarding
# Serve + install + assert in ONE step so the http server's lifetime is
# controlled (a background server from an earlier step isn't guaranteed
# to survive into the next).
run: |
set -euo pipefail
DIST="$(mktemp -d)"
# Resolve the SAME triple install.sh will request on this runner, so
# the served asset name matches (mirrors install.sh's Linux branch).
case "$(uname -m)" in
x86_64|amd64) triple="x86_64-unknown-linux-musl" ;;
aarch64|arm64) triple="aarch64-unknown-linux-musl" ;;
*) echo "unsupported arch $(uname -m)" >&2; exit 1 ;;
esac
cp target/release/wire "$DIST/wire-$triple"
( cd "$DIST" && sha256sum "wire-$triple" > "wire-$triple.sha256" )
# Serve over http so install.sh's curl exercises the real download +
# SHA-256-sibling verify path (not a file:// shortcut, which would let
# install.sh silently cargo-fall-back to the crates.io release).
# Background the subshell itself (not `& )` inside it) so $! captures
# the server PID — `& )` backgrounds within the subshell and leaves $!
# unset, which is fatal under `set -u`.
( cd "$DIST" && exec python3 -m http.server 8099 >/dev/null 2>&1 ) &
SRV=$!; trap 'kill "$SRV" 2>/dev/null || true' EXIT
for i in $(seq 1 20); do curl -fsS "http://127.0.0.1:8099/wire-$triple.sha256" -o /dev/null && break; sleep 0.5; done
PFX="$(mktemp -d)/bin"
WIRE_DIST_URL="http://127.0.0.1:8099" sh install.sh --prefix "$PFX"
test -x "$PFX/wire" # landed where --prefix said
"$PFX/wire" --version
export WIRE_HOME="$(mktemp -d)/home" WIRE_QUIET_AUTOSESSION=1
cd "$(mktemp -d)" # clean cwd, no repo
"$PFX/wire" whoami --json | jq -e '.initialized == false' # pre-init
# up --offline is PR-only — if install.sh had cargo-fallen-back to the
# crates.io release, this flag wouldn't exist, so it also proves the
# SERVED binary was the one installed.
"$PFX/wire" up --offline
"$PFX/wire" whoami --json | jq -e '.did | startswith("did:wire:")'
echo "install-script-smoke: install.sh + fresh onboarding OK"