Skip to content

chore(deps): update tailscale 1.98.3 -> 1.98.9 #1259

chore(deps): update tailscale 1.98.3 -> 1.98.9

chore(deps): update tailscale 1.98.3 -> 1.98.9 #1259

Workflow file for this run

name: actionadon
# actionadon — Dakota's community next-action bot.
# Posts one short comment each time an issue moves to a new lifecycle stage.
# Handles /claim, /unclaim, and /ready. Sweeps stale claimed issues daily.
#
# Lifecycle:
# opened → status/discussing
# status/approved (maintainer) → needs spec comment
# status/queued (maintainer) → queue announcement
# /claim comment → status/claimed + assigned
# /ready comment (wrangler) → queued for agents
# /unclaim comment → back in queue
# daily sweep → unclaim issues idle > 7 days
on:
issues:
types: [opened, labeled]
issue_comment:
types: [created]
schedule:
- cron: '0 9 * * *'
permissions:
issues: write
pull-requests: write
contents: read
env:
WORKFLOW_NAME: "Raptor Current"
# Maintainers are implicit wranglers via their repo permissions.
# This list is for additional low-barrier operators who can steer the queue.
# Keep this list in sync with AGENTS.md and files/hive/hive-project.yaml.example.
WRANGLERS: "castrojo,ahmedadan,alatiera,hanthor,coxde,renner0e"
jobs:
# ── Ensure lifecycle labels exist ─────────────────────────────────────────
# Idempotent. Runs before any job that writes labels.
ensure-labels:
if: >-
github.event_name == 'issues' ||
github.event_name == 'schedule' ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request == null &&
(startsWith(github.event.comment.body, '/claim') ||
startsWith(github.event.comment.body, '/unclaim') ||
startsWith(github.event.comment.body, '/ready')))
runs-on: ubuntu-24.04
steps:
- name: Create lifecycle labels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
label() {
gh label create "$1" --color "$2" --description "$3" --repo "$REPO" 2>/dev/null \
|| gh label edit "$1" --color "$2" --description "$3" --repo "$REPO" 2>/dev/null \
|| true
}
label "status/discussing" "7c83fd" "Structured issue flow in progress; not ready for the agent queue yet."
label "status/approved" "2ea44f" "Approved for queue preparation; add acceptance criteria before /ready."
label "status/claimed" "e8b86d" "Actively being worked by a human or agent."
label "agent/blocked" "e74c3c" "Blocked and needs human input before work can continue."
label "status/queued" "a467dc" "Structured issue is ready for a human or agent to claim."
label "needs-human/agent-oops" "f795fe" "Agent mistake or bad automation outcome; Hive must not touch."
label "flow/agent-donation" "1b7f83" "Donate agent time for a repo, issue, or PR review/report request."
label "flow/project-report" "0e8a16" "Agent flow: produce a sourced project report."
label "flow/issue-review" "5319e7" "Agent flow: review a linked issue and produce a sourced report."
label "flow/pr-review" "fbca04" "Agent flow: review a linked pull request and produce a sourced report."
label "status/triage" "e4e669" "Issue needs maintainer triage."
label "pr/needs-review" "e4e669" "PR needs a maintainer review before it can move forward."
label "hold" "8b949e" "Do not touch; intentionally held by humans."
label "do-not-merge" "b60205" "Do not merge or automate this item."
# ── New issue opened ───────────────────────────────────────────────────────
# Templates stamp labels directly (e.g. kind/bug, flow/agent-donation).
# Route by those labels rather than scanning free-text body markers.
on-issue-opened:
if: github.event_name == 'issues' && github.event.action == 'opened'
needs: ensure-labels
runs-on: ubuntu-24.04
steps:
- name: Label as discussing if not already labelled
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
LABELS=$(gh issue view "$ISSUE_URL" --json labels --jq '[.labels[].name] | join(",")' 2>/dev/null || echo "")
# Skip if already has a lifecycle label (template stamped it)
if echo "$LABELS" | grep -qE "status/|flow/agent-donation"; then
exit 0
fi
gh issue edit "$ISSUE_URL" --add-label "status/discussing"
- name: Welcome comment (bug/feature reports)
if: >-
!contains(github.event.issue.labels.*.name, 'flow/agent-donation')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
WORKFLOW_NAME: ${{ env.WORKFLOW_NAME }}
run: |
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oP '\d+$')
cat > /tmp/comment.md << EOF
**${WORKFLOW_NAME}** — thanks for the report.
A maintainer will triage this and assign it to the right area. Once a fix ships in nightly, confirm it works on your machine:
\`\`\`bash
ujust verify ${ISSUE_NUMBER}
\`\`\`
Your confirmation is what closes the loop.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
- name: Fast-track donated agent work
if: contains(github.event.issue.labels.*.name, 'flow/agent-donation')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
# Detect flow from the dropdown value in the body
BODY=$(gh issue view "$ISSUE_URL" --json body --jq '.body // ""')
FLOW_LABEL="flow/project-report"
if printf '%s\n' "$BODY" | grep -Eq 'https://[^[:space:])>]+/pull/[0-9]+'; then
FLOW_LABEL="flow/pr-review"
elif printf '%s\n' "$BODY" | grep -Eq 'https://[^[:space:])>]+/issues/[0-9]+'; then
FLOW_LABEL="flow/issue-review"
fi
gh issue edit "$ISSUE_URL" \
--add-label "status/queued" \
--add-label "$FLOW_LABEL"
# ── Label transitions ──────────────────────────────────────────────────────
on-labeled:
if: github.event_name == 'issues' && github.event.action == 'labeled'
needs: ensure-labels
runs-on: ubuntu-24.04
steps:
- name: Comment on status/approved
if: github.event.label.name == 'status/approved'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
cat << 'EOF' > /tmp/comment.md
✅ Approved. The community has found its way here.
Before this goes to the build queue it needs **acceptance criteria** — the spec a contributor or agent will implement against. Add it to the issue body, then apply `status/queued` to open it up.
**Wranglers:** write acceptance criteria, then comment `/ready`.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
- name: Comment on status/queued
if: github.event.label.name == 'status/queued'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
run: |
LABELS=$(gh issue view "$ISSUE_URL" --json labels --jq '[.labels[].name] | join(",")')
if echo "$LABELS" | grep -q "flow/agent-donation"; then
cat << 'EOF' > /tmp/comment.md
🐝 In the queue! Hive now has the instructions it needs for this donated agent request.
**Agent workflow:**
```bash
just validate # check element graph
just build default # build the image
just lint # bootc container lint
just boot-test # confirm desktop boots
```
The issue body defines the flow: project report, issue review, or PR review. Post a sourced report comment when done, then close this issue.
EOF
else
cat << 'EOF' > /tmp/comment.md
🐟 In the queue! This issue has a spec and is ready to build.
**Contributors:** comment `/claim` to take it, then:
```bash
git checkout upstream/main -b fix/this-issue
# make your changes
just validate # check element graph
just build default # build the image
just boot-test # automated smoke test (exits 0/1)
just lint # bootc container lint
```
Open a PR with `Closes #NNN` when ready.
**Reviewers:** after the PR merges and ships in nightly:
```bash
ujust verify <issue-number> # confirm the fix on your machine
```
Read [AGENTS.md](../../blob/main/AGENTS.md) for the full workflow.
EOF
fi
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
# ── /claim, /unclaim, and /ready ──────────────────────────────────────────
claim-handler:
if: >-
github.event_name == 'issue_comment' &&
github.event.issue.pull_request == null &&
(startsWith(github.event.comment.body, '/claim') ||
startsWith(github.event.comment.body, '/unclaim') ||
startsWith(github.event.comment.body, '/ready'))
needs: ensure-labels
runs-on: ubuntu-24.04
steps:
- name: Resolve wrangler status
id: wrangler
env:
COMMENTER: ${{ github.event.comment.user.login }}
WRANGLERS: ${{ env.WRANGLERS }}
run: |
IS_WRANGLER=false
for user in $(echo "$WRANGLERS" | tr ',' ' '); do
if [ "$COMMENTER" = "$user" ]; then
IS_WRANGLER=true
break
fi
done
echo "is_wrangler=$IS_WRANGLER" >> "$GITHUB_OUTPUT"
- name: Handle /claim
if: startsWith(github.event.comment.body, '/claim')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
COMMENTER: ${{ github.event.comment.user.login }}
run: |
LABELS=$(gh issue view "$ISSUE_URL" --json labels --jq '[.labels[].name] | join(",")')
# Already claimed
if echo "$LABELS" | grep -q "status/claimed"; then
ASSIGNEE=$(gh issue view "$ISSUE_URL" --json assignees --jq '.assignees[0].login // "someone"')
cat << EOF > /tmp/comment.md
Already claimed by @${ASSIGNEE}. If they've gone quiet, a maintainer can \`/unclaim\` to return it to the queue.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
# Not in queue
if ! echo "$LABELS" | grep -q "status/queued"; then
cat << 'EOF' > /tmp/comment.md
This issue isn't in the agent queue yet — it needs `status/queued` before it can be claimed.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
gh issue edit "$ISSUE_URL" --add-label "status/claimed" --remove-label "status/queued" --add-assignee "$COMMENTER"
if echo "$LABELS" | grep -q "flow/agent-donation"; then
cat << EOF > /tmp/comment.md
🎣 @${COMMENTER} has this one! Follow the workflow embedded in the issue, post a sourced report comment when you're done, and close this issue so Hive can move on.
EOF
else
cat << EOF > /tmp/comment.md
🎣 @${COMMENTER} has this one!
**Your workflow:**
\`\`\`bash
git checkout upstream/main -b fix/issue-${ISSUE_NUMBER}
# implement the acceptance criteria
just validate # fast graph check
just build default # build the image (~1hr first time)
just boot-test # confirm desktop boots (exits 0/1)
just lint # bootc container lint
\`\`\`
Open a PR with \`Closes #${ISSUE_NUMBER}\` in the description when ready. Hit a blocker? Add \`agent/blocked\` and describe what you need.
EOF
fi
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
- name: Handle /ready
if: startsWith(github.event.comment.body, '/ready')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
COMMENTER: ${{ github.event.comment.user.login }}
IS_WRANGLER: ${{ steps.wrangler.outputs.is_wrangler }}
REPO: ${{ github.repository }}
run: |
PERMISSION=$(gh api "repos/${REPO}/collaborators/${COMMENTER}/permission" \
--jq '.permission' 2>/dev/null || echo "none")
HAS_WRITE=false
case "$PERMISSION" in admin|maintain|write) HAS_WRITE=true ;; esac
if [ "$IS_WRANGLER" != "true" ] && [ "$HAS_WRITE" = "false" ]; then
cat << 'EOF' > /tmp/comment.md
Only a wrangler or maintainer can move an issue into the queue with `/ready`.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
LABELS=$(gh issue view "$ISSUE_URL" --json labels --jq '[.labels[].name] | join(",")')
BODY=$(gh issue view "$ISSUE_URL" --json body --jq '.body // ""')
if ! echo "$LABELS" | grep -q "status/approved"; then
cat << 'EOF' > /tmp/comment.md
This issue needs `status/approved` before it can enter the queue.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
ACCEPTANCE_SECTION=$(
printf '%s\n' "$BODY" | awk '
/^###[[:space:]]/ {
if (in_section) exit
if ($0 ~ /^###[[:space:]]+.*Acceptance criteria[[:space:]]*$/) {
in_section=1
print
next
}
}
in_section { print }
'
)
if [ -z "$ACCEPTANCE_SECTION" ]; then
cat << 'EOF' > /tmp/comment.md
This issue needs a dedicated `### Acceptance criteria` section in the body before it can enter the queue.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
if ! printf '%s\n' "$ACCEPTANCE_SECTION" | grep -Eq '^[[:space:]]*-[[:space:]]\[( |x|X)\][[:space:]]+'; then
cat << 'EOF' > /tmp/comment.md
This issue needs at least one real checklist item under `### Acceptance criteria` before it can enter the queue.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
if echo "$LABELS" | grep -q "status/queued"; then
cat << 'EOF' > /tmp/comment.md
This issue is already in the queue and ready for a human or agent to `/claim`.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
gh issue edit "$ISSUE_URL" --add-label "status/queued"
cat << 'EOF' > /tmp/comment.md
In the queue. Comment `/claim` to take it.
**Build and test loop:**
```bash
git checkout upstream/main -b fix/this-issue
just validate # element graph check
just build default # build the image
just boot-test # automated smoke test (exits 0 = pass)
just lint # bootc container lint
```
Open a PR with `Closes #NNN` in the description. Read [AGENTS.md](../../blob/main/AGENTS.md) for the full workflow.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
- name: Handle /unclaim
if: startsWith(github.event.comment.body, '/unclaim')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_URL: ${{ github.event.issue.html_url }}
COMMENTER: ${{ github.event.comment.user.login }}
REPO: ${{ github.repository }}
IS_WRANGLER: ${{ steps.wrangler.outputs.is_wrangler }}
run: |
ASSIGNEE=$(gh issue view "$ISSUE_URL" --json assignees --jq '.assignees[0].login // ""')
# Allow assignee, wrangler, or repo collaborators with write+ to unclaim
PERMISSION=$(gh api "repos/${REPO}/collaborators/${COMMENTER}/permission" \
--jq '.permission' 2>/dev/null || echo "none")
HAS_WRITE=false
case "$PERMISSION" in admin|maintain|write) HAS_WRITE=true ;; esac
if [ "$COMMENTER" != "$ASSIGNEE" ] && [ "$HAS_WRITE" = "false" ] && [ "$IS_WRANGLER" != "true" ]; then
cat << EOF > /tmp/comment.md
Only @${ASSIGNEE}, a wrangler, or a maintainer can unclaim this issue.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
exit 0
fi
gh issue edit "$ISSUE_URL" --remove-label "status/claimed" --add-label "status/queued"
if [ -n "$ASSIGNEE" ]; then
gh issue edit "$ISSUE_URL" --remove-assignee "$ASSIGNEE"
fi
cat << 'EOF' > /tmp/comment.md
Back in the queue. Comment `/claim` to pick it up. Start with `just validate` to confirm the graph is sound.
EOF
gh issue comment "$ISSUE_URL" --body-file /tmp/comment.md
# ── Stale claim sweep ──────────────────────────────────────────────────────
# Daily: find claimed issues with no update in 7 days, return to queue.
stale-claim-sweep:
if: github.event_name == 'schedule'
needs: ensure-labels
runs-on: ubuntu-24.04
steps:
- name: Unclaim stale issues
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
CUTOFF=$(date -u -d '7 days ago' '+%Y-%m-%dT%H:%M:%SZ')
gh issue list --repo "$REPO" \
--label "status/claimed" \
--json number,url,updatedAt,assignees \
--jq ".[] | select(.updatedAt < \"$CUTOFF\") | .number" \
| while read -r NUMBER; do
ASSIGNEE=$(gh issue view "$NUMBER" --repo "$REPO" \
--json assignees --jq '.assignees[0].login // ""')
gh issue edit "$NUMBER" --repo "$REPO" --remove-label "status/claimed" --add-label "status/queued"
if [ -n "$ASSIGNEE" ]; then
gh issue edit "$NUMBER" --repo "$REPO" --remove-assignee "$ASSIGNEE"
cat << EOF > /tmp/comment.md
This issue has been claimed for 7 days with no PR activity, so it's back in the queue.
@${ASSIGNEE} — if you're still working on it, just \`/claim\` again and it's yours. Otherwise anyone can pick it up:
\`\`\`bash
git checkout upstream/main -b fix/issue-${NUMBER}
just validate && just build default && just boot-test && just lint
\`\`\`
EOF
else
cat << 'EOF' > /tmp/comment.md
This issue has been claimed for 7 days with no PR activity, so it's back in the queue. Comment `/claim` to take it.
EOF
fi
gh issue comment "$NUMBER" --repo "$REPO" --body-file /tmp/comment.md
done