mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
8557af71b7
Regenerates the `tend-*.yaml` workflows for tend 0.2.7 (from 0.2.6). The diff is the version comment and the `max-sixty/tend/claude@` action pin in all eight workflows; no job, trigger, or permission changed. What adopters get from the upgrade: - **The sandbox can write zsh here-documents again.** Scratch files for heredocs now go to the writable temp dir instead of a path the sandbox denies, so a session that shells out through zsh no longer fails on them (max-sixty/tend#1211). This run hit exactly that failure while composing this description. - **`review-runs` stops reporting paths that have since gone green.** It re-queries the closure read before calling a path still red, so a run fixed between the scan and the report is no longer written up as an outstanding failure (max-sixty/tend#1210). - **`review-runs` now checks open Dependabot alerts** as part of its live repository scan, so unaddressed security advisories surface in the daily sweep (max-sixty/tend#1214). - **Sessions load less bundled guidance.** `running-in-ci` and `review` keep the rules every session needs and move the rarer actions — opening a PR, pushing, monitoring CI, posting, draft mode — into `references/` files read on demand, dropping from 52 KB to 20 KB and 41 KB to 25 KB respectively. That leaves more of each session's context for the actual work (max-sixty/tend#1215). - **PR review decides its pre-approval check in a script** rather than re-deriving it from prose each session, which makes the approve/don't-approve call consistent run to run (max-sixty/tend#1217). Full comparison: https://github.com/max-sixty/tend/compare/0.2.6...0.2.7 `.config/tend.yaml` pins no model, so nothing there needed to move. Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
158 lines
6.2 KiB
YAML
158 lines
6.2 KiB
YAML
# Generated by tend 0.2.7. Regenerate with: uvx tend@latest init
|
|
#
|
|
# Do not edit this file directly — it will be overwritten on regeneration.
|
|
# To customize behavior, edit the relevant skill (for example,
|
|
# `running-tend`) in this repo's .claude/skills/ directory, or open an issue at
|
|
# https://github.com/max-sixty/tend/issues for changes that need to
|
|
# happen upstream in the tend-ci-runner plugin.
|
|
|
|
name: tend-review
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, synchronize, ready_for_review, reopened]
|
|
|
|
jobs:
|
|
review:
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
|
# Preserve pending PR events within GitHub's queue limit: a push must not
|
|
# replace a ready-for-review run. Runs stay serial so outward actions
|
|
# cannot race. An override setting `cancel-in-progress: true` must set
|
|
# `queue: null` too — GitHub rejects the pair as an invalid workflow file.
|
|
queue: max
|
|
cancel-in-progress: false
|
|
runs-on: ubuntu-24.04
|
|
environment:
|
|
name: tend
|
|
deployment: false
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
actions: read
|
|
issues: write
|
|
steps:
|
|
- name: Check whether tend is enabled
|
|
id: tend_enabled
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
gh api \
|
|
-H "Accept: application/vnd.github.raw+json" \
|
|
"repos/$GITHUB_REPOSITORY/contents/.config/tend.yaml" \
|
|
> "$RUNNER_TEMP/tend.yaml"
|
|
ruby - "$RUNNER_TEMP/tend.yaml" <<'RUBY' >> "$GITHUB_OUTPUT"
|
|
# Inspect the parsed YAML node so the extra YAML 1.1 boolean words (yes/no/on/off)
|
|
# do not diverge from the YAML 1.2 parser used by `tend init`.
|
|
require "psych"
|
|
|
|
path = ARGV.fetch(0)
|
|
documents = Psych.parse_stream(File.read(path, mode: "r:bom|utf-8")).children
|
|
unless documents.length == 1
|
|
abort "tend config must contain exactly one YAML document"
|
|
end
|
|
|
|
mapping = documents.first.root
|
|
unless mapping.is_a?(Psych::Nodes::Mapping)
|
|
abort "tend config must contain a YAML mapping"
|
|
end
|
|
|
|
def has_yaml_merge_key?(node)
|
|
case node
|
|
when Psych::Nodes::Mapping
|
|
node.children.each_slice(2).any? do |key, value|
|
|
(key.is_a?(Psych::Nodes::Scalar) && key.plain && key.value == "<<") ||
|
|
has_yaml_merge_key?(key) || has_yaml_merge_key?(value)
|
|
end
|
|
when Psych::Nodes::Sequence
|
|
node.children.any? { |value| has_yaml_merge_key?(value) }
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
if has_yaml_merge_key?(mapping)
|
|
abort "tend config: YAML merge keys (<<) are not supported"
|
|
end
|
|
|
|
matches = mapping.children.each_slice(2).select do |key, _value|
|
|
key.is_a?(Psych::Nodes::Scalar) && key.value == "enabled"
|
|
end
|
|
abort "tend config: enabled must appear at most once" if matches.length > 1
|
|
|
|
value = matches.dig(0, 1)
|
|
enabled = true
|
|
if value
|
|
bool_tag = value.respond_to?(:tag) && value.tag == "tag:yaml.org,2002:bool"
|
|
literal = value.value.downcase if value.is_a?(Psych::Nodes::Scalar)
|
|
unless value.is_a?(Psych::Nodes::Scalar) &&
|
|
(value.plain || bool_tag) &&
|
|
["true", "false"].include?(literal)
|
|
abort "tend config: enabled must be true or false"
|
|
end
|
|
enabled = literal == "true"
|
|
end
|
|
|
|
puts "enabled=#{enabled}"
|
|
|
|
unless enabled
|
|
warn "::notice title=Tend disabled::The tend config sets enabled: false; skipping this job"
|
|
end
|
|
RUBY
|
|
- name: React with eyes
|
|
if: steps.tend_enabled.outputs.enabled == 'true'
|
|
run: |
|
|
gh api "repos/$REPO/$TARGET/reactions" -f content=eyes --silent \
|
|
|| echo "::warning::could not add the eyes reaction"
|
|
env:
|
|
REPO: ${{ github.repository }}
|
|
TARGET: issues/${{ github.event.pull_request.number }}
|
|
GITHUB_TOKEN: ${{ secrets.TEND_BOT_TOKEN }}
|
|
|
|
# The runner checkout remains on the reviewed base tree for local setup
|
|
# actions and their POST chains. The harness creates and selects the PR
|
|
# topology in an independent disposable clone.
|
|
- uses: actions/checkout@v7
|
|
if: steps.tend_enabled.outputs.enabled == 'true'
|
|
with:
|
|
fetch-depth: 0
|
|
fetch-tags: true
|
|
token: ${{ secrets.TEND_BOT_TOKEN }}
|
|
|
|
- uses: ./.github/actions/tend-setup
|
|
if: steps.tend_enabled.outputs.enabled == 'true'
|
|
|
|
- uses: max-sixty/tend/claude@0.2.7
|
|
if: steps.tend_enabled.outputs.enabled == 'true'
|
|
with:
|
|
github_token: ${{ secrets.TEND_BOT_TOKEN }}
|
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
bot_name: worktrunk-bot
|
|
model: opus
|
|
checkout_mode: review
|
|
base_branch: ${{ github.event.pull_request.base.ref }}
|
|
sandbox_setup: |2
|
|
mkdir -p ~/.local/bin
|
|
uv tool install --quiet pre-commit
|
|
for t in cargo-insta cargo-nextest pre-commit nu nix; do command -v "$t" >/dev/null || { echo "::error::tend sandbox is missing $t; see Sandbox toolchain in .github/CLAUDE.md"; exit 1; }; done
|
|
prompt: |2
|
|
/tend-ci-runner:review ${{ github.event.pull_request.number }}
|
|
|
|
- name: Remove the eyes reaction
|
|
if: |
|
|
always()
|
|
&& (steps.tend_enabled.outputs.enabled == 'true')
|
|
run: |
|
|
REACTION_ID=$(gh api --paginate \
|
|
"repos/$REPO/$TARGET/reactions?content=eyes&per_page=100" \
|
|
--jq ".[] | select(.user.login == \"$BOT_NAME\") | .id" | head -n1)
|
|
if [ -n "$REACTION_ID" ]; then
|
|
gh api -X DELETE "repos/$REPO/$TARGET/reactions/$REACTION_ID" --silent \
|
|
|| echo "::warning::could not remove the eyes reaction"
|
|
fi
|
|
env:
|
|
REPO: ${{ github.repository }}
|
|
TARGET: issues/${{ github.event.pull_request.number }}
|
|
BOT_NAME: worktrunk-bot
|
|
GITHUB_TOKEN: ${{ secrets.TEND_BOT_TOKEN }}
|