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
File renamed without changes.
121 changes: 121 additions & 0 deletions .github/workflows/python.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Python

on:
push:
tags: ["v*"]
pull_request:
paths:
- "src/python.rs"
- "python/**"
- "pyproject.toml"
- "murk.pyi"
- "Cargo.toml"

env:
PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: astral-sh/ruff-action@4919ec5cf1f49eff0871dbcea0da843445b837e6 # v3
with:
src: python/

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2

- name: Build release binary (for test fixture)
run: cargo build --release

- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6

- name: Install and test
run: |
uv venv
source .venv/bin/activate
uv pip install maturin pytest
maturin develop --features python
pytest python/tests -v

wheels:
name: Build wheels (${{ matrix.os }})
if: startsWith(github.ref, 'refs/tags/v')
needs: [lint, test]
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64
- os: ubuntu-latest
target: aarch64
- os: macos-14
target: x86_64
- os: macos-latest
target: aarch64
- os: windows-latest
target: x64
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"

- name: Build wheels
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
target: ${{ matrix.target }}
args: --release --out dist --features python
manylinux: auto

- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: wheels-${{ matrix.os }}-${{ matrix.target }}
path: dist/

sdist:
name: Build sdist
if: startsWith(github.ref, 'refs/tags/v')
needs: [lint, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Build sdist
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
with:
command: sdist
args: --out dist

- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: wheels-sdist
path: dist/

publish:
name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
needs: [wheels, sdist]
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: wheels-*
merge-multiple: true
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
with:
skip-existing: true
File renamed without changes.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
AGENTS.md
CLAUDE.md
.DS_Store
.venv/
__pycache__/
*.pyc
.pytest_cache/
100 changes: 100 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ constant_time_eq = "0.4"
tempfile = "3.27.0"
clap_complete = "4.6.0"
fs2 = "0.4.3"
pyo3 = { version = "0.24", features = ["extension-module"], optional = true }

[features]
default = []
python = ["pyo3"]

[dev-dependencies]
assert_cmd = "2"
Expand Down
20 changes: 17 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ SHELL := /bin/bash
MURK := $(CURDIR)/target/release/murk
MUSL_TARGET := x86_64-unknown-linux-musl

.PHONY: build test test-demos test-hero test-team test-offboard test-eve test-recovery test-github test-direnv test-mallory test-vhs
.PHONY: build test test-demos test-hero test-team test-offboard test-eve test-recovery test-github test-direnv test-mallory test-ssh test-vhs

build:
cargo build --release

test:
cargo nextest run

test-demos: build test-hero test-team test-offboard test-eve test-recovery test-github test-direnv test-mallory
test-demos: build test-hero test-team test-offboard test-eve test-recovery test-github test-direnv test-mallory test-ssh
@echo "\nall demo tests passed"

test-hero: build
Expand Down Expand Up @@ -163,11 +163,25 @@ test-mallory: build
! $(MURK) export >/dev/null 2>&1 && \
echo "ok"

test-ssh: build
@printf " %-12s" "ssh" && \
set -e && \
export PATH="$(CURDIR)/target/release:$$PATH" && \
source demo/setup.sh && \
demo_init_dirs alice bob && \
trap "demo_cleanup" EXIT && \
demo_alice_vault && \
ssh-keygen -t ed25519 -f "$$BOB_DIR/id_ed25519" -N "" -q && \
cd $$ALICE_DIR && export MURK_KEY=$$ALICE_KEY && \
murk circle authorize "ssh:$$BOB_DIR/id_ed25519.pub" --name bob >/dev/null 2>&1 && \
murk circle 2>/dev/null | grep -q "bob" && \
echo "ok"

test-vhs:
@command -v cross >/dev/null 2>&1 || { echo "error: cross not found — install with: cargo install cross --locked"; exit 1; }
cross build --release --target $(MUSL_TARGET)
@printf 'FROM ghcr.io/charmbracelet/vhs\nRUN apt-get update --allow-releaseinfo-change && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*\n' | docker build -t vhs-git -
@for tape in hero team offboard eve recovery github direnv mallory; do \
@for tape in hero team offboard eve recovery github direnv mallory ssh; do \
printf " %-12s" "$$tape" && \
docker run --rm -v $(CURDIR):/vhs -e PATH="/vhs/target/$(MUSL_TARGET)/release:$$PATH" vhs-git demo/$$tape.tape && \
echo "ok"; \
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# murk

[![CI](https://github.com/iicky/murk/actions/workflows/ci.yml/badge.svg)](https://github.com/iicky/murk/actions/workflows/ci.yml)
[![CI](https://github.com/iicky/murk/actions/workflows/ci.yaml/badge.svg)](https://github.com/iicky/murk/actions/workflows/ci.yaml)
[![codecov](https://codecov.io/gh/iicky/murk/graph/badge.svg)](https://codecov.io/gh/iicky/murk)
[![Crates.io](https://img.shields.io/crates/v/murk-cli)](https://crates.io/crates/murk-cli)
[![License](https://img.shields.io/crates/l/murk-cli)](LICENSE-MIT)
Expand Down Expand Up @@ -195,6 +195,7 @@ murk restore
| `murk rotate --all` | Rotate all secrets (prompts for each) |
| `murk rm KEY` | Remove a secret |
| `murk get KEY` | Print a single decrypted value |
| `murk edit [KEY] [--scoped]` | Edit secrets in `$EDITOR` |
| `murk ls` | List key names |
| `murk export` | Print all secrets as shell exports |
| `murk exec CMD...` | Run a command with secrets in the environment |
Expand All @@ -203,7 +204,7 @@ murk restore
| `murk describe KEY "..."` | Set description for a key |
| `murk info` | Show public schema (no key required) |
| `murk circle` | List recipients |
| `murk circle authorize PUBKEY [--name NAME]` | Add a recipient |
| `murk circle authorize PUBKEY [--name NAME]` | Add a recipient (age key, `ssh:path`, or `github:user`) |
| `murk circle revoke RECIPIENT` | Remove a recipient |
| `murk restore` | Recover key from BIP39 phrase |
| `murk recover` | Show recovery phrase for current key |
Expand Down
Loading
Loading