mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-30 09:22:03 +00:00
Secret input: - Values that are secrets can now be read from stdin: `entry add key-value --stdin`, `entry add totp --secret-stdin`, `entry add document --stdin`, and `entry modify --value-stdin`. Arguments are visible in shell history and process listings, so the positional forms now warn (without echoing the secret they are warning about) rather than silently accepting. Packaging (the published package was broken): - `exports` pointed at src/index.ts while `files` shipped only dist/, so an installed package had no entry point; exports now points at the bundle. - A `workspace:*` runtime dependency would have failed any real install. The bundle inlines everything, so the package now declares no runtime dependencies at all. Verified by packing the tarball, installing it into a clean project and running the binary -- and CI now does the same on every change, because this class of mistake is invisible to build and test. - The workspace globs cover apps/* so a future extension cannot sit outside CI. - @types/node aligned with the advertised Node 22 runtime. Release and supply chain: - release-integrity now builds the CLI bundle into dist/ before checksums are generated and signed, so the executable TypeScript artifact is covered by the same manifest and cosign signature as the Python ones. - A new javascript-supply-chain job runs `pnpm audit` and produces a CycloneDX SBOM; the JS tree previously had neither. Also documents two findings that are protocol-level and shared with Python, where changing the port alone would break convergence: tombstone retention allowing deletion replay after the 2048-entry cap, and SSH/PGP sharing a derivation domain (same index yields the same Ed25519 key). Both need a versioned change in both implementations and are recorded in the compatibility matrix rather than silently patched here. 193 core + 70 CLI tests green; pnpm audit clean. Co-Authored-By: Claude Fable 5 <[email protected]>
158 lines
5.5 KiB
YAML
158 lines
5.5 KiB
YAML
name: TypeScript Parity
|
|
|
|
on:
|
|
push:
|
|
branches: ["**"]
|
|
paths:
|
|
- "js/**"
|
|
- "src/**"
|
|
- "scripts/generate_ts_port_fixtures.py"
|
|
- "scripts/cross_impl_check.py"
|
|
- ".github/workflows/ts-parity.yml"
|
|
pull_request:
|
|
branches: ["**"]
|
|
paths:
|
|
- "js/**"
|
|
- "src/**"
|
|
- "scripts/generate_ts_port_fixtures.py"
|
|
- "scripts/cross_impl_check.py"
|
|
- ".github/workflows/ts-parity.yml"
|
|
|
|
jobs:
|
|
parity:
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: js
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: Enable pnpm via corepack
|
|
run: corepack enable
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Typecheck
|
|
run: pnpm -r typecheck
|
|
- name: Parity tests (Node + jsdom)
|
|
run: pnpm -r test
|
|
- name: Build the distributable CLI
|
|
run: pnpm --filter @seedpass/cli build
|
|
- name: Smoke-test the bundle standalone
|
|
# Run from a directory with no node_modules to prove the bundle
|
|
# carries everything it needs.
|
|
run: |
|
|
set -eu
|
|
BIN="$PWD/packages/cli/dist/seedpass-js.mjs"
|
|
APP_DIR="$(mktemp -d)"
|
|
cd "$(mktemp -d)"
|
|
node "$BIN" --version
|
|
node "$BIN" capabilities > /dev/null
|
|
export SEEDPASS_APP_DIR="$APP_DIR"
|
|
export SEEDPASS_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
|
export SEEDPASS_PASSWORD="ci-smoke-password"
|
|
node "$BIN" fingerprint add --name ci > /dev/null
|
|
node "$BIN" entry add password ci-site --length 16 > /dev/null
|
|
test -n "$(node "$BIN" entry reveal ci-site)"
|
|
- name: Verify the packed npm tarball installs and runs
|
|
# `files`/`exports` mistakes only surface at install time: a package
|
|
# that omits its entry point still builds and tests fine here.
|
|
run: |
|
|
set -eu
|
|
pnpm --filter @seedpass/cli pack --pack-destination "$RUNNER_TEMP"
|
|
TARBALL="$(ls "$RUNNER_TEMP"/seedpass-cli-*.tgz)"
|
|
mkdir -p "$RUNNER_TEMP/packtest" && cd "$RUNNER_TEMP/packtest"
|
|
npm init -y > /dev/null
|
|
npm install "$TARBALL" > /dev/null
|
|
./node_modules/.bin/seedpass-js --version
|
|
- name: Upload CLI bundle
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: seedpass-js-cli
|
|
path: |
|
|
js/packages/cli/dist/seedpass-js.mjs
|
|
js/packages/cli/dist/seedpass-js.mjs.sha256
|
|
|
|
javascript-supply-chain:
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: js
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- name: Enable pnpm via corepack
|
|
run: corepack enable
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Audit dependencies
|
|
# The Python side has had a dependency audit for a while; the
|
|
# JavaScript tree had none.
|
|
run: pnpm audit --audit-level moderate
|
|
- name: Generate a CycloneDX SBOM
|
|
run: |
|
|
npx --yes @cyclonedx/cyclonedx-npm@latest \
|
|
--output-format JSON \
|
|
--output-file "$RUNNER_TEMP/seedpass-js-sbom.json" \
|
|
--package-lock-only || echo "SBOM generation failed (non-fatal)"
|
|
- name: Upload SBOM
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: seedpass-js-sbom
|
|
path: ${{ runner.temp }}/seedpass-js-sbom.json
|
|
if-no-files-found: warn
|
|
|
|
# Fixtures prove the two implementations compute the same values; this job
|
|
# proves they can read each other's on-disk profiles and backups.
|
|
cross-implementation:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
cache: pip
|
|
- name: Enable pnpm via corepack
|
|
run: corepack enable
|
|
- name: Install JS dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
working-directory: js
|
|
- name: Install Poetry
|
|
run: pipx install poetry
|
|
- name: Install Python dependencies
|
|
run: poetry install --no-interaction --no-ansi
|
|
- name: Cross-implementation compatibility
|
|
run: poetry run python scripts/cross_impl_check.py
|
|
|
|
# The fixtures are committed, so the parity job never regenerates them.
|
|
# This job proves the committed fixtures actually come from the committed
|
|
# generator: it regenerates from Python and fails on any drift.
|
|
fixture-drift:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
cache: pip
|
|
- name: Install Poetry
|
|
run: pipx install poetry
|
|
- name: Install dependencies
|
|
run: poetry install --no-interaction --no-ansi
|
|
- name: Regenerate fixtures
|
|
run: poetry run python scripts/generate_ts_port_fixtures.py
|
|
- name: Fail on drift
|
|
# manifest.json records the generating commit, which legitimately
|
|
# differs from the checked-out commit — everything else must match.
|
|
run: >
|
|
git diff --exit-code --
|
|
js/packages/test-vectors/fixtures
|
|
':(exclude)js/packages/test-vectors/fixtures/manifest.json'
|