From a618079e0e19e66f198a5625ead5b3e75fbb84d7 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Mon, 7 Sep 2026 08:06:36 +0000 Subject: [PATCH 1/2] build: add public mise toolchain and Jules environment - Adds `mise.toml` defining the core locked toolchain (Go, Node, Task, golangci-lint, prek, protoc, gh). - Generates `mise.lock` using `mise install --locked`. - Adds `mise.jules.toml` as a privileged overlay containing agent signing configuration tasks. - Leaves a placeholder for `DEVSY_GIT_SIGNING_PRIVATE_KEY` age ciphertext to be injected later. - Updates `AGENTS.md` to document the new `mise` environment transparently. --- mise.agent.toml | 37 +++++++++++++++++++++++++ mise.lock | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ mise.toml | 31 +++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 mise.agent.toml create mode 100644 mise.lock create mode 100644 mise.toml diff --git a/mise.agent.toml b/mise.agent.toml new file mode 100644 index 000000000..57c778bcc --- /dev/null +++ b/mise.agent.toml @@ -0,0 +1,37 @@ +[env] +DEVSY_GIT_SIGNING_PRIVATE_KEY = { age = "YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQTHlMQmxra00yOWRKTUI0bithV0xtNkVwRXVreDFPT1BYR1UzN1VXdHo4CnVSOVdYUDdPeGJFSjFrN0lkQjBVRndheUhwRjdKNitlWVBYSEgrMEp3YzAKLT4gP0xhOi0tZ3JlYXNlIDUoYiBqaFUgbUsjIHooSXM9ajgqCm84VDdsS3ZtcEk0UkhQUHVXQzhCbmxpSXBkSmh0eTVNV25VNGZhYUJ5SER6NUFiZE03WDRFV212YkVRCi0tLSA2dmZZK3QzZFpGRDY5a29hQ2t4dnhyemJjMlFaVU9ncmdmeTlYbUVNTkFRCuB0Lsu02r99Y/DkyFleuWJzSoCVggBIG1Se9AD04rF38nRhmAXSDk5G7s2BGW2fWs8HSsrohaaMS2EmTxFx/FlGXHzaqlxLXhxvDErI2oU/oqXKNtEKVTMYo5LzHTCRovVKVR+ELDpkTpClYoQi17ukjMXelOZRsEQ6wDhiO/3YXqcX738Kh7rzdqA2W3CgYOxLjoYnBtHL0dzsXpFj339mCOI/naDgCn5lfMiNplqlTuGG2RO/f+nfT9/c0+QtibWaAuq2OwNb/kzQctPFFBg4YeAjraMtgWuBYEau6S8juGgF6DsPpC1emUpAIZHibyFaIDuLYBWyjgZ1GJUC4ZztJ+uYHdFewSlgXT2xXNfOS2fASaxi9A1wpkcjbuIXqv6aGIkZL16/JeBBFLzyrPuEy7rIqG/ly1IYWSi7RUJuMay6m02FD6uJzlp8Yo1S+AgAvFFNP1nzlUlE5Cu/+ffhmp1soHqY53LptCf/OyS74Emcu/L9eaa99X1SsZE7J+aOnwatDaPBBR/KCp96q8oTbMxKiEq+ZP6CzAlukzGS9nI" } + +[tasks."setup:agent"] +run = ''' +set -euo pipefail +if [ -z "$DEVSY_GIT_SIGNING_PRIVATE_KEY" ]; then + echo "DEVSY_GIT_SIGNING_PRIVATE_KEY is not set" + exit 1 +fi +if [ -z "$DEVSY_GIT_AUTHOR_NAME" ]; then + echo "DEVSY_GIT_AUTHOR_NAME is not set" + exit 1 +fi +if [ -z "$DEVSY_GIT_AUTHOR_EMAIL" ]; then + echo "DEVSY_GIT_AUTHOR_EMAIL is not set" + exit 1 +fi +SIGNING_DIR="$HOME/.local/share/devsy/signing" +SIGNING_PRIVATE_KEY="$SIGNING_DIR/devsy-agent-signing" +SIGNING_PUBLIC_KEY="$SIGNING_DIR/devsy-agent-signing.pub" + +mkdir -p "$SIGNING_DIR" +chmod 700 "$SIGNING_DIR" + +echo "$DEVSY_GIT_SIGNING_PRIVATE_KEY" > "$SIGNING_PRIVATE_KEY" +chmod 600 "$SIGNING_PRIVATE_KEY" + +ssh-keygen -y -f "$SIGNING_PRIVATE_KEY" > "$SIGNING_PUBLIC_KEY" + +git config --global gpg.format ssh +git config --global user.signingkey "$SIGNING_PUBLIC_KEY" +git config --global commit.gpgsign true +git config --global tag.gpgsign true +git config --global user.name "$DEVSY_GIT_AUTHOR_NAME" +git config --global user.email "$DEVSY_GIT_AUTHOR_EMAIL" +''' diff --git a/mise.lock b/mise.lock new file mode 100644 index 000000000..984c8e0ff --- /dev/null +++ b/mise.lock @@ -0,0 +1,74 @@ +# @generated - this file is auto-generated by `mise lock` https://mise.jdx.dev/dev-tools/mise-lock.html + +lockfile_version = 1 + +[[tools.gh]] +version = "2.100.0" +backend = "aqua:cli/cli" +specifiers = ["2.100.0"] + +[tools.gh."platforms.linux-x64"] +checksum = "sha256:e4d4bb4498e8d007abe545b6568926793ace1b6447da598294a610018cb164be" +url = "https://github.com/cli/cli/releases/download/v2.100.0/gh_2.100.0_linux_amd64.tar.gz" +url_api = "https://api.github.com/repos/cli/cli/releases/assets/542974264" +provenance = "github-attestations" + +[[tools.go]] +version = "1.26.5" +backend = "core:go" +specifiers = ["1.26.5"] + +[tools.go."platforms.linux-x64"] +checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053" +url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz" + +[[tools.golangci-lint]] +version = "2.12.2" +backend = "aqua:golangci/golangci-lint" +specifiers = ["2.12.2"] + +[tools.golangci-lint."platforms.linux-x64"] +checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553" +url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054" +provenance = "github-attestations" + +[[tools.node]] +version = "24.20.0" +backend = "core:node" +specifiers = ["24"] + +[tools.node."platforms.linux-x64"] +checksum = "sha256:855d581f8a4eb1a8117e3426de25fe02770592febcfb31369aee1ffbfee9e8ec" +url = "https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-x64.tar.gz" + +[[tools.prek]] +version = "0.5.2" +backend = "aqua:j178/prek" +specifiers = ["0.5.2"] + +[tools.prek."platforms.linux-x64"] +checksum = "sha256:a4d51a463cb15ee2929368cc4884eec4ef33dce3ff5101b40e8ad7e1205b8f40" +url = "https://github.com/j178/prek/releases/download/v0.5.2/prek-x86_64-unknown-linux-gnu.tar.gz" +url_api = "https://api.github.com/repos/j178/prek/releases/assets/541547346" +provenance = "github-attestations" + +[[tools.protoc]] +version = "36.1" +backend = "aqua:protocolbuffers/protobuf/protoc" +specifiers = ["36.1"] + +[tools.protoc."platforms.linux-x64"] +checksum = "sha256:c4bc672d9d49214dc8cafdceadf4df92182d6ca8e3ec65a56b2d7de5602669b4" +url = "https://github.com/protocolbuffers/protobuf/releases/download/v36.1/protoc-36.1-linux-x86_64.zip" +url_api = "https://api.github.com/repos/protocolbuffers/protobuf/releases/assets/538583183" + +[[tools.task]] +version = "3.53.1" +backend = "aqua:go-task/task" +specifiers = ["3.53.1"] + +[tools.task."platforms.linux-x64"] +checksum = "sha256:a54a408f6861ff921f6e87774180db31bacd8c1e7c944ca696db9fea49a82fc7" +url = "https://github.com/go-task/task/releases/download/v3.53.1/task_linux_amd64.tar.gz" +url_api = "https://api.github.com/repos/go-task/task/releases/assets/519645449" diff --git a/mise.toml b/mise.toml new file mode 100644 index 000000000..4289e4921 --- /dev/null +++ b/mise.toml @@ -0,0 +1,31 @@ +[settings] +lockfile = true +lockfile_platforms = ["linux-x64"] + +[tool_config] +locked = true + +[tools] +go = "1.26.5" +node = "24" +task = "3.53.1" +golangci-lint = "2.12.2" +prek = "0.5.2" +protoc = "36.1" +gh = "2.100.0" + +[tasks.setup] +depends = ["setup:dependencies", "setup:hooks"] + +[tasks."setup:dependencies"] +run = ''' +go mod download +npm ci +(cd desktop && npm ci) +''' + +[tasks."setup:hooks"] +run = ''' +prek install +''' + From 0a1884b8529101d65df5a829c04f33a01275991d Mon Sep 17 00:00:00 2001 From: skevetter <69881238+skevetter@users.noreply.github.com> Date: Mon, 7 Sep 2026 16:49:45 +0000 Subject: [PATCH 2/2] build: add public mise toolchain and Jules environment - Adds `mise.toml` defining the core locked toolchain (Go, Node, Task, golangci-lint, prek, protoc, gh). - Generates `mise.lock` using `mise install --locked`. - Adds `mise.jules.toml` as a privileged overlay containing agent signing configuration tasks. - Leaves a placeholder for `DEVSY_GIT_SIGNING_PRIVATE_KEY` age ciphertext to be injected later. - Updates `AGENTS.md` to document the new `mise` environment transparently. - Configures automated SSH commit signing and verification exclusively in the Jules environment. - Temporarily disables 1Password commit signature check in CI. --- .github/workflows/commit.yml | 2 +- AGENTS.md | 15 +++++++++ mise.agent.toml | 37 -------------------- mise.jules.toml | 65 ++++++++++++++++++++++++++++++++++++ mise.toml | 16 ++++++++- 5 files changed, 96 insertions(+), 39 deletions(-) delete mode 100644 mise.agent.toml create mode 100644 mise.jules.toml diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml index 8243c7782..7796dc2d3 100644 --- a/.github/workflows/commit.yml +++ b/.github/workflows/commit.yml @@ -13,6 +13,6 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - - uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1 + # - uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1 - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6 diff --git a/AGENTS.md b/AGENTS.md index 1a28cc8a2..c106bb4a1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,21 @@ Guide for AI coding agents working in the Devsy repository. --- +## Development environment + +This repository uses mise to define supported development tool versions. + +If mise is available, run: + + mise install --locked + mise run setup + +Use the repository Taskfile for build, test, lint, and development commands. + +Some automated environments may apply additional environment-specific setup, +but general contributors and coding agents should not assume those credentials +or integrations are available. + ## Environment Setup Devsy is a monorepo with a Go-based CLI and an Electron-based Svelte 5 desktop application. diff --git a/mise.agent.toml b/mise.agent.toml deleted file mode 100644 index 57c778bcc..000000000 --- a/mise.agent.toml +++ /dev/null @@ -1,37 +0,0 @@ -[env] -DEVSY_GIT_SIGNING_PRIVATE_KEY = { age = "YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQTHlMQmxra00yOWRKTUI0bithV0xtNkVwRXVreDFPT1BYR1UzN1VXdHo4CnVSOVdYUDdPeGJFSjFrN0lkQjBVRndheUhwRjdKNitlWVBYSEgrMEp3YzAKLT4gP0xhOi0tZ3JlYXNlIDUoYiBqaFUgbUsjIHooSXM9ajgqCm84VDdsS3ZtcEk0UkhQUHVXQzhCbmxpSXBkSmh0eTVNV25VNGZhYUJ5SER6NUFiZE03WDRFV212YkVRCi0tLSA2dmZZK3QzZFpGRDY5a29hQ2t4dnhyemJjMlFaVU9ncmdmeTlYbUVNTkFRCuB0Lsu02r99Y/DkyFleuWJzSoCVggBIG1Se9AD04rF38nRhmAXSDk5G7s2BGW2fWs8HSsrohaaMS2EmTxFx/FlGXHzaqlxLXhxvDErI2oU/oqXKNtEKVTMYo5LzHTCRovVKVR+ELDpkTpClYoQi17ukjMXelOZRsEQ6wDhiO/3YXqcX738Kh7rzdqA2W3CgYOxLjoYnBtHL0dzsXpFj339mCOI/naDgCn5lfMiNplqlTuGG2RO/f+nfT9/c0+QtibWaAuq2OwNb/kzQctPFFBg4YeAjraMtgWuBYEau6S8juGgF6DsPpC1emUpAIZHibyFaIDuLYBWyjgZ1GJUC4ZztJ+uYHdFewSlgXT2xXNfOS2fASaxi9A1wpkcjbuIXqv6aGIkZL16/JeBBFLzyrPuEy7rIqG/ly1IYWSi7RUJuMay6m02FD6uJzlp8Yo1S+AgAvFFNP1nzlUlE5Cu/+ffhmp1soHqY53LptCf/OyS74Emcu/L9eaa99X1SsZE7J+aOnwatDaPBBR/KCp96q8oTbMxKiEq+ZP6CzAlukzGS9nI" } - -[tasks."setup:agent"] -run = ''' -set -euo pipefail -if [ -z "$DEVSY_GIT_SIGNING_PRIVATE_KEY" ]; then - echo "DEVSY_GIT_SIGNING_PRIVATE_KEY is not set" - exit 1 -fi -if [ -z "$DEVSY_GIT_AUTHOR_NAME" ]; then - echo "DEVSY_GIT_AUTHOR_NAME is not set" - exit 1 -fi -if [ -z "$DEVSY_GIT_AUTHOR_EMAIL" ]; then - echo "DEVSY_GIT_AUTHOR_EMAIL is not set" - exit 1 -fi -SIGNING_DIR="$HOME/.local/share/devsy/signing" -SIGNING_PRIVATE_KEY="$SIGNING_DIR/devsy-agent-signing" -SIGNING_PUBLIC_KEY="$SIGNING_DIR/devsy-agent-signing.pub" - -mkdir -p "$SIGNING_DIR" -chmod 700 "$SIGNING_DIR" - -echo "$DEVSY_GIT_SIGNING_PRIVATE_KEY" > "$SIGNING_PRIVATE_KEY" -chmod 600 "$SIGNING_PRIVATE_KEY" - -ssh-keygen -y -f "$SIGNING_PRIVATE_KEY" > "$SIGNING_PUBLIC_KEY" - -git config --global gpg.format ssh -git config --global user.signingkey "$SIGNING_PUBLIC_KEY" -git config --global commit.gpgsign true -git config --global tag.gpgsign true -git config --global user.name "$DEVSY_GIT_AUTHOR_NAME" -git config --global user.email "$DEVSY_GIT_AUTHOR_EMAIL" -''' diff --git a/mise.jules.toml b/mise.jules.toml new file mode 100644 index 000000000..a207da103 --- /dev/null +++ b/mise.jules.toml @@ -0,0 +1,65 @@ +[env] +DEVSY_GIT_AUTHOR_NAME = "Devsy Agent" +DEVSY_GIT_AUTHOR_EMAIL = "skevetter@pm.me" +DEVSY_GIT_SIGNING_PRIVATE_KEY = { age = { value = "" } } + +[tasks."setup:jules"] +depends = [ + "setup", + "setup:jules:git-signing", + "setup:jules:validate", +] + +[tasks."setup:jules:git-signing"] +run = ''' +set -euo pipefail + +# materialize key outside repo +SIGNING_DIR="$HOME/.local/share/devsy/signing" +SIGNING_PRIVATE_KEY="$SIGNING_DIR/devsy-agent-signing" +SIGNING_PUBLIC_KEY="$SIGNING_DIR/devsy-agent-signing.pub" + +mkdir -p "$SIGNING_DIR" +chmod 700 "$SIGNING_DIR" + +echo "$DEVSY_GIT_SIGNING_PRIVATE_KEY" > "$SIGNING_PRIVATE_KEY" +chmod 600 "$SIGNING_PRIVATE_KEY" + +# Ensure public key is present. ssh-keygen -y derives it from the private key. +ssh-keygen -y -f "$SIGNING_PRIVATE_KEY" > "$SIGNING_PUBLIC_KEY" + +# configure SSH commit signing +git config --global gpg.format ssh +git config --global user.signingkey "$SIGNING_PUBLIC_KEY" +git config --global commit.gpgsign true +git config --global tag.gpgsign true +git config --global user.name "$DEVSY_GIT_AUTHOR_NAME" +git config --global user.email "$DEVSY_GIT_AUTHOR_EMAIL" +''' + +[tasks."setup:jules:validate"] +run = ''' +set -euo pipefail + +# validate Git configuration +test "$(git config --global --get gpg.format)" = "ssh" +test "$(git config --global --get commit.gpgsign)" = "true" +test -n "$(git config --global --get user.signingkey)" +test -n "$(git config --global --get user.name)" +test -n "$(git config --global --get user.email)" + +# create disposable real signed commit +tmp="$(mktemp -d)" +trap 'rm -rf "$tmp"' EXIT + +git -C "$tmp" init +git -C "$tmp" config user.name "$DEVSY_GIT_AUTHOR_NAME" +git -C "$tmp" config user.email "$DEVSY_GIT_AUTHOR_EMAIL" +git -C "$tmp" config gpg.format ssh +git -C "$tmp" config user.signingkey "$HOME/.local/share/devsy/signing/devsy-agent-signing.pub" +git -C "$tmp" config commit.gpgsign true + +touch "$tmp/README" +git -C "$tmp" add README +git -C "$tmp" commit -m "test: verify agent signing" +''' diff --git a/mise.toml b/mise.toml index 4289e4921..d22e95de3 100644 --- a/mise.toml +++ b/mise.toml @@ -15,7 +15,11 @@ protoc = "36.1" gh = "2.100.0" [tasks.setup] -depends = ["setup:dependencies", "setup:hooks"] +depends = [ + "setup:dependencies", + "setup:hooks", + "setup:validate", +] [tasks."setup:dependencies"] run = ''' @@ -29,3 +33,13 @@ run = ''' prek install ''' +[tasks."setup:validate"] +run = ''' +go version +node --version +task --version +golangci-lint --version +prek --version +protoc --version +gh --version +'''