@lead: externalize agent.yml inline scripts into .gitea/workflows/scripts/*.sh
Rebased onto the per-agent skill-scoping change so PR #25 carries both: - route.sh keeps the registry 'skills' allow-list and emits skills as a step output - install-opencode.sh writes the permission.skill block (deny-all + allow listed) Pure refactor otherwise: each step's shell moves to its own file, called via bash "$SCRIPTS/<name>.sh". The two extracted SKILL.md bodies are byte-identical to main; routing/config/publish behavior is unchanged. Because this is a reusable workflow (workflow_call) the runtime checkout is the caller's repo, so agent.yml now checks THIS repo out into .agents-workflow/ (pinned @main) and points $SCRIPTS there.
This commit is contained in:
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
# Set up read-only SSH alias `node1` (+ opencode skill so the agent actually knows about it).
|
||||
# 1) Writes the deploy key + an SSH config alias so the agent can run
|
||||
# `ssh node1 <read-only cmd>` (matches the homelab opencode.json allowlist).
|
||||
# 2) Emits a `node1-ssh` opencode Skill file under ~/.config/opencode/skills/ so any
|
||||
# downstream repo's dev agent discovers this capability via OpenCode's skill registry
|
||||
# rather than having to trial against the permission allowlist. Only emitted when the
|
||||
# swarm plumbing is actually wired for that caller (SWARM_HOST/SWARM_USER/SSH_PRIV_KEY).
|
||||
# All three secrets are passed via env and never inlined into shell — this shared workflow
|
||||
# runs in repos that don't have them and must not fail there.
|
||||
#
|
||||
# Required env (provided by the workflow step): SWARM_HOST SWARM_USER SSH_PRIV_KEY
|
||||
set -eu
|
||||
|
||||
if [ -z "$SWARM_HOST" ] || [ -z "$SWARM_USER" ] || [ -z "$SSH_PRIV_KEY" ]; then
|
||||
echo "swarm secrets not set in this repo — skipping node1 SSH alias + skill"
|
||||
exit 0
|
||||
fi
|
||||
mkdir -p ~/.ssh ~/.config/opencode/skills/node1-ssh && chmod 700 ~/.ssh ~/.config/opencode/skills/node1-ssh
|
||||
# Write the private key with 600 perms; never echo its contents.
|
||||
printf '%s\n' "$SSH_PRIV_KEY" > ~/.ssh/agent_node1
|
||||
chmod 600 ~/.ssh/agent_node1
|
||||
# SSH config alias `node1` — last-match-wins in the homelab opencode allowlist
|
||||
# (`deny ssh *` + specific `allow ssh node1 …`), so the alias name is fixed.
|
||||
cat > ~/.ssh/config <<EOF
|
||||
Host node1
|
||||
HostName $SWARM_HOST
|
||||
User $SWARM_USER
|
||||
IdentityFile ~/.ssh/agent_node1
|
||||
IdentitiesOnly yes
|
||||
StrictHostKeyChecking accept-new
|
||||
ConnectTimeout 10
|
||||
EOF
|
||||
chmod 600 ~/.ssh/config
|
||||
echo "node1 SSH alias configured (host=$SWARM_HOST user=$SWARM_USER)"
|
||||
|
||||
# Emit a reusable opencode Skill that surfaces the capability to downstream agents.
|
||||
# OpenCode's skill tool registers it via the <available_skills> block, so any dev agent
|
||||
# can discover "I am allowed to ssh node1" without trial-and-error against the allowlist.
|
||||
cat > ~/.config/opencode/skills/node1-ssh/SKILL.md <<'SKILLET'
|
||||
---
|
||||
name: node1-ssh
|
||||
description: Read-only diagnostics on the swarm host via `ssh node1 …` — use when debugging a deploy or checking a running service.
|
||||
domains: [swarm]
|
||||
tags: [ssh, swarm, diagnostics, docker]
|
||||
---
|
||||
|
||||
# `node1-ssh` Skill
|
||||
|
||||
Use this skill to run **read-only** commands against **node1** (the Docker Swarm host) when:
|
||||
- A deploy failed and you need to inspect running services.
|
||||
- You need to see a service's logs for debugging.
|
||||
- You want to check the state of the stack on the swarm.
|
||||
|
||||
## How it works
|
||||
|
||||
Commands run via `ssh node1 <cmd>`. The SSH alias is configured in `${HOME}/.ssh/config`
|
||||
during this workflow (only when swarm secrets are configured for the caller repo).
|
||||
|
||||
## What you're actually allowed to run — the allowlist is the source of truth
|
||||
|
||||
This skill does **not** define which commands are permitted, and you must not assume a fixed
|
||||
list here. The single source of truth for exactly which `ssh node1 …` commands are allowed is
|
||||
the **caller repo's own OpenCode permission config** (e.g. `opencode.json` in the homelab repo:
|
||||
a `deny "ssh *"` with specific `allow "ssh node1 …"` entries, last-match-wins).
|
||||
|
||||
- Only read-only diagnostics are permitted; any write/mutating command on node1 is denied.
|
||||
- The permission layer enforces this — if a command is not on the caller's allowlist it will be
|
||||
blocked, regardless of what this skill or any other allowlist says.
|
||||
- So: reach for `ssh node1 …` for read-only diagnostics, and treat the caller's `opencode.json`
|
||||
`ssh node1` allow-entries as the authoritative list of what will actually run.
|
||||
|
||||
## Example
|
||||
|
||||
> The frontend returned a 5xx after a deploy.
|
||||
>
|
||||
> Action (a read-only log inspection, subject to the caller's allowlist):
|
||||
> ```
|
||||
> ssh node1 "docker service logs --tail 100 --timestamps homelab_frontend"
|
||||
> ```
|
||||
SKILLET
|
||||
chmod -R o=rX ~/.config/opencode/skills/node1-ssh
|
||||
echo "opencode skill node1-ssh installed ($(wc -l < ~/.config/opencode/skills/node1-ssh/SKILL.md) lines)"
|
||||
Reference in New Issue
Block a user