From 79332298318ec24df4cbb0c77bac9d7b32127858 Mon Sep 17 00:00:00 2001 From: Nathan Nutter Date: Wed, 4 Nov 2026 22:41:34 -0600 Subject: [PATCH 1/2] Grant each release job only the permission it needs A workflow-level `contents: write` lets the build jobs push commits and create releases, and the build restores a mise cache that a pull request can populate. jactionlint reports both when a workflow builds on a tag. The top level now grants nothing, the build jobs read the repository, and only the publish job writes, with the cache off so no cache entry from another branch can reach the published artifacts. --- .github/workflows/release.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 788b2e4..2c9df2b 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -2,13 +2,14 @@ name: Release on: push: tags: ["v*"] -permissions: - contents: write +permissions: {} concurrency: group: release cancel-in-progress: false jobs: build: + permissions: + contents: read runs-on: ubuntu-26.04 timeout-minutes: 20 strategy: @@ -32,6 +33,8 @@ jobs: uses: jdx/mise-action@6612f0ef07ed2a736cd1e00a94a065522dd41195 # v5.2.5 with: version: 2026.10.25 + # A cache from a pull request could reach the published artifacts. + cache: false - name: Build the archive env: GOOS: ${{ matrix.platform.os }} @@ -48,6 +51,8 @@ jobs: if-no-files-found: error publish: needs: build + permissions: + contents: write runs-on: ubuntu-26.04 timeout-minutes: 10 env: From c6e9ac9b4ee4476afec42885814e620fbf6dd37b Mon Sep 17 00:00:00 2001 From: Nathan Nutter Date: Wed, 4 Nov 2026 22:41:34 -0600 Subject: [PATCH 2/2] Take the hook steps and their order from hk-config The config listed every step and wrote the depends graph by hand, which repeats the order rules that hk-config now owns and drifts when a group gains a step. Hooks.all builds the 4 hooks from the groups it is given and orders their steps, so the config names go, toml, yaml, and agentskills and imports no builtin of its own. The hook defaults add a mise check and jactionlint, and the go group adds gohawk, so both tools join mise.toml. jactionlint reads the runner labels that the workflows name, so no extra label file is needed. --- hk.pkl | 67 +++++++++++-------------------------------------------- mise.lock | 45 +++++++++++++++++++++++++++++++++++++ mise.toml | 8 +++---- 3 files changed, 61 insertions(+), 59 deletions(-) diff --git a/hk.pkl b/hk.pkl index 16190d5..06b9c66 100644 --- a/hk.pkl +++ b/hk.pkl @@ -1,58 +1,17 @@ +// The hook templates from nnutter/hk-config, which amend hk's configuration. +// Both package paths name the same hk-config version, and that version must +// target the hk pin in mise.toml. The revision is the newest one released for +// that hk version. amends - "package://github.com/nnutter/hk-config/releases/download/v2.11.1-0/hk-config@2.11.1-0#/Config.pkl" + "package://github.com/nnutter/hk-config/releases/download/v2.11.1-2/hk-config@2.11.1-2#/Config.pkl" -import "package://github.com/jdx/hk/releases/download/v2.11.1/hk@2.11.1#/Builtins.pkl" as Hk import - "package://github.com/nnutter/hk-config/releases/download/v2.11.1-0/hk-config@2.11.1-0#/Builtins.pkl" - as Extra + "package://github.com/nnutter/hk-config/releases/download/v2.11.1-2/hk-config@2.11.1-2#/Hooks.pkl" + as Hooks -steps { - ["constable"] = Extra.constable - ["errcheck"] = Hk.err_check - ["gitleaks"] = Hk.gitleaks - ["go_check_sumtype"] = Extra.go_check_sumtype - ["go_fix"] = Hk.go_fix - ["go_fumpt"] = Hk.go_fumpt - ["go_imports"] = Extra.go_imports - ["go_sec"] = Extra.go_sec - ["go_vet"] = Hk.go_vet - ["go_vuln_check"] = Hk.go_vuln_check - ["gomod_tidy"] = Hk.gomod_tidy - ["mdlint"] = Extra.mdlint - ["newlines"] = Hk.newlines - ["nilaway"] = Extra.nilaway - ["pkl"] = Hk.pkl - ["pkl_format"] = Hk.pkl_format - ["skills_ref"] = Extra.skills_ref - ["staticcheck"] = Hk.staticcheck - ["testifylint"] = Extra.testifylint - ["tombi"] = Hk.tombi - ["tombi_format"] = Hk.tombi_format - ["trailing_whitespace"] = Hk.trailing_whitespace - ["yamlfmt"] = Hk.yamlfmt -} - -hooks { - ["commit-msg"] { - fix = true - steps { - ["change-id"] = Extra.timber_commit_msg - } - } - ["pre-commit"] { - fix = true - stage = true - stash = "git" - steps { - // No file filter: scan every staged change, including arbitrary types, - // binary files, deletions, and commits without Go or Markdown changes. - // The git-mode scan only sees text diffs, so staged binary bytes are - // checked out to a temporary directory and scanned explicitly. - ["gitleaks"] = (Hk.gitleaks) { - scan = "staged" - check = - "gitleaks git --redact --pre-commit --staged --verbose --no-banner && tmp=$(mktemp -d) || exit $?; trap 'rm -rf \"$tmp\"' EXIT INT TERM; git diff --cached --name-only -z --diff-filter=ACMRT > \"$tmp/list\" || exit $?; git checkout-index -z --stdin --prefix=\"$tmp/tree/\" < \"$tmp/list\" || exit $?; mkdir -p \"$tmp/tree\" || exit $?; gitleaks dir --redact --verbose --no-banner \"$tmp/tree\" || exit $?" - } - } - } -} +// The templates build the check, fix, pre-commit, and commit-msg hooks, and +// they order the steps of each hook that fixes: the steps that rewrite files +// run in the order their edits must land, and every step that only reads waits +// for the last fixer, so the readers run together. `check` sets no order. +// `go`, `toml`, `yaml`, and `agentskills` are the groups this repository needs. +hooks = Hooks.all(List("go", "toml", "yaml", "agentskills")) diff --git a/mise.lock b/mise.lock index 5bedd5b..ff9c8ea 100644 --- a/mise.lock +++ b/mise.lock @@ -269,6 +269,11 @@ version = "1.30.0" backend = "go:github.com/kisielk/errcheck" specifiers = ["latest"] +[[tools."go:github.com/kojah/gohawk"]] +version = "0.7.1" +backend = "go:github.com/kojah/gohawk" +specifiers = ["latest"] + [[tools."go:github.com/nnutter/testifylint"]] version = "0.0.0-20261101203540-577bf922d916" backend = "go:github.com/nnutter/testifylint" @@ -371,6 +376,46 @@ checksum = "sha256:60b925d9734cd6bec5fab78b9c825b39b2ad9b1c9d9f03b685423c2d21ae9 url = "https://github.com/jdx/hk/releases/download/v2.11.1/hk-x86_64-pc-windows-msvc.zip" signer = "sigstore-oidc:https://github.com/jdx/hk/.github/workflows/release.yml" +[[tools.jactionlint]] +version = "2.4.0" +backend = "packslip:github.com/jdx/jactionlint" +specifiers = ["latest"] + +[tools.jactionlint."platforms.linux-arm64"] +checksum = "sha256:42413391c248f99ff4550d6c866ee717d5ea4ca2b966d9d54ad1503af955e22f" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_linux_arm64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.linux-arm64-musl"] +checksum = "sha256:42413391c248f99ff4550d6c866ee717d5ea4ca2b966d9d54ad1503af955e22f" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_linux_arm64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.linux-x64"] +checksum = "sha256:26ddba81db28fffc51163175c070ee1a9d1150260de4b5232f01d9b749f32d8e" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_linux_amd64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.linux-x64-musl"] +checksum = "sha256:26ddba81db28fffc51163175c070ee1a9d1150260de4b5232f01d9b749f32d8e" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_linux_amd64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.macos-arm64"] +checksum = "sha256:349a13dbffdd25376898a256d195806afda08ba97ccc6378cbf2dd11a77ef8e7" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_darwin_arm64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.macos-x64"] +checksum = "sha256:4c21fce834f8267b65a65b32a527aaa2ec1c321c8f066d44b42d7f038835aa90" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_darwin_amd64.tar.gz" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + +[tools.jactionlint."platforms.windows-x64"] +checksum = "sha256:4e0c7b428a4faa35bb3b86af6fa65a0ac9797edcd4c64e4f7e16ca886437e172" +url = "https://github.com/jdx/jactionlint/releases/download/v2.4.0/jactionlint_2.4.0_windows_amd64.zip" +signer = "sigstore-oidc:https://github.com/jdx/jactionlint/.github/workflows/release.yaml" + [[tools.pkl]] version = "0.32.2" backend = "aqua:apple/pkl" diff --git a/mise.toml b/mise.toml index 43a2b3a..570fedd 100644 --- a/mise.toml +++ b/mise.toml @@ -2,6 +2,7 @@ minimum_release_age = "0" [tools] +jactionlint = "latest" "github:alecthomas/go-check-sumtype" = "latest" "github:nnutter/constable" = "latest" "github:nnutter/mdlint" = "latest" @@ -9,6 +10,7 @@ minimum_release_age = "0" gitleaks = "latest" go = "latest" "go:github.com/kisielk/errcheck" = "latest" +"go:github.com/kojah/gohawk" = "latest" "go:github.com/nnutter/testifylint" = "latest" "go:go.uber.org/nilaway/cmd/nilaway" = "latest" "go:golang.org/x/tools/cmd/goimports" = "latest" @@ -47,11 +49,7 @@ run = [{ task = "all" }] [tasks.on-stop] description = "Fix edited files, then test and check" usage = 'arg "[staged_files]" var=#true' -run = [ - "mise run fix ${usage_staged_files}", - "mise run test", - "mise run check", -] +run = ["mise run fix ${usage_staged_files}", "mise run test", "mise run check"] [tasks.ci-test] description = "Run tests (with the race detector)"