fix: chore: remove dead lib files — profile.sh, tea-helpers.sh, file-action-issue.sh, parse-deps.sh, CODEBERG_* exports (#283)
This commit is contained in:
parent
6a05d8881b
commit
1a84e7204f
6 changed files with 7 additions and 403 deletions
25
lib/env.sh
25
lib/env.sh
|
|
@ -77,16 +77,11 @@ if [ -n "${PROJECT_TOML:-}" ] && [ -f "$PROJECT_TOML" ]; then
|
|||
source "${FACTORY_ROOT}/lib/load-project.sh" "$PROJECT_TOML"
|
||||
fi
|
||||
|
||||
# Forge token: new FORGE_TOKEN > legacy CODEBERG_TOKEN
|
||||
if [ -z "${FORGE_TOKEN:-}" ]; then
|
||||
FORGE_TOKEN="${CODEBERG_TOKEN:-}"
|
||||
fi
|
||||
export FORGE_TOKEN
|
||||
export CODEBERG_TOKEN="${FORGE_TOKEN}" # backwards compat
|
||||
# Forge token
|
||||
export FORGE_TOKEN="${FORGE_TOKEN:-}"
|
||||
|
||||
# Review bot token: FORGE_REVIEW_TOKEN > legacy REVIEW_BOT_TOKEN
|
||||
# Review bot token
|
||||
export FORGE_REVIEW_TOKEN="${FORGE_REVIEW_TOKEN:-${REVIEW_BOT_TOKEN:-}}"
|
||||
export REVIEW_BOT_TOKEN="${FORGE_REVIEW_TOKEN}" # backwards compat
|
||||
|
||||
# Per-agent tokens (#747): each agent gets its own Forgejo identity.
|
||||
# Falls back to FORGE_TOKEN for backwards compat with single-token setups.
|
||||
|
|
@ -97,18 +92,14 @@ export FORGE_SUPERVISOR_TOKEN="${FORGE_SUPERVISOR_TOKEN:-${FORGE_TOKEN}}"
|
|||
export FORGE_PREDICTOR_TOKEN="${FORGE_PREDICTOR_TOKEN:-${FORGE_TOKEN}}"
|
||||
export FORGE_ARCHITECT_TOKEN="${FORGE_ARCHITECT_TOKEN:-${FORGE_TOKEN}}"
|
||||
|
||||
# Bot usernames filter: FORGE_BOT_USERNAMES > legacy CODEBERG_BOT_USERNAMES
|
||||
export FORGE_BOT_USERNAMES="${FORGE_BOT_USERNAMES:-${CODEBERG_BOT_USERNAMES:-dev-bot,review-bot,planner-bot,gardener-bot,vault-bot,supervisor-bot,predictor-bot,architect-bot}}"
|
||||
export CODEBERG_BOT_USERNAMES="${FORGE_BOT_USERNAMES}" # backwards compat
|
||||
# Bot usernames filter
|
||||
export FORGE_BOT_USERNAMES="${FORGE_BOT_USERNAMES:-dev-bot,review-bot,planner-bot,gardener-bot,vault-bot,supervisor-bot,predictor-bot,architect-bot}"
|
||||
|
||||
# Project config (FORGE_* preferred, CODEBERG_* fallback)
|
||||
export FORGE_REPO="${FORGE_REPO:-${CODEBERG_REPO:-}}"
|
||||
export CODEBERG_REPO="${FORGE_REPO}" # backwards compat
|
||||
# Project config
|
||||
export FORGE_REPO="${FORGE_REPO:-}"
|
||||
export FORGE_URL="${FORGE_URL:-http://localhost:3000}"
|
||||
export FORGE_API="${FORGE_API:-${FORGE_URL}/api/v1/repos/${FORGE_REPO}}"
|
||||
export FORGE_WEB="${FORGE_WEB:-${FORGE_URL}/${FORGE_REPO}}"
|
||||
export CODEBERG_API="${FORGE_API}" # backwards compat
|
||||
export CODEBERG_WEB="${FORGE_WEB}" # backwards compat
|
||||
# tea CLI login name: derived from FORGE_URL (codeberg vs local forgejo)
|
||||
if [ -z "${TEA_LOGIN:-}" ]; then
|
||||
case "${FORGE_URL}" in
|
||||
|
|
@ -209,8 +200,6 @@ forge_api() {
|
|||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}${path}" "$@"
|
||||
}
|
||||
# Backwards-compat alias
|
||||
codeberg_api() { forge_api "$@"; }
|
||||
|
||||
# Paginate a Forge API GET endpoint and return all items as a merged JSON array.
|
||||
# Usage: forge_api_all /path (no existing query params)
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# file-action-issue.sh — File an action issue for a formula run
|
||||
#
|
||||
# Usage: source this file, then call file_action_issue.
|
||||
# Requires: forge_api() from lib/env.sh, jq, lib/secret-scan.sh
|
||||
#
|
||||
# file_action_issue <formula_name> <title> <body>
|
||||
# Sets FILED_ISSUE_NUM on success.
|
||||
# Returns: 0=created, 1=duplicate exists, 2=label not found, 3=API error, 4=secrets detected
|
||||
|
||||
# Load secret scanner
|
||||
# shellcheck source=secret-scan.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/secret-scan.sh"
|
||||
|
||||
file_action_issue() {
|
||||
local formula_name="$1" title="$2" body="$3"
|
||||
FILED_ISSUE_NUM=""
|
||||
|
||||
# Secret scan: reject issue bodies containing embedded secrets
|
||||
if ! scan_for_secrets "$body"; then
|
||||
echo "file-action-issue: BLOCKED — issue body for '${formula_name}' contains potential secrets. Use env var references instead." >&2
|
||||
return 4
|
||||
fi
|
||||
|
||||
# Dedup: skip if an open action issue for this formula already exists
|
||||
local open_actions
|
||||
open_actions=$(forge_api_all "/issues?state=open&type=issues&labels=action" 2>/dev/null || true)
|
||||
if [ -n "$open_actions" ] && [ "$open_actions" != "null" ]; then
|
||||
local existing
|
||||
existing=$(printf '%s' "$open_actions" | \
|
||||
jq --arg f "$formula_name" '[.[] | select(.title | test($f))] | length' 2>/dev/null || echo 0)
|
||||
if [ "${existing:-0}" -gt 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fetch 'action' label ID
|
||||
local action_label_id
|
||||
action_label_id=$(forge_api GET "/labels" 2>/dev/null | \
|
||||
jq -r '.[] | select(.name == "action") | .id' 2>/dev/null || true)
|
||||
if [ -z "$action_label_id" ]; then
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Create the issue
|
||||
local payload result
|
||||
payload=$(jq -nc \
|
||||
--arg title "$title" \
|
||||
--arg body "$body" \
|
||||
--argjson labels "[$action_label_id]" \
|
||||
'{title: $title, body: $body, labels: $labels}')
|
||||
|
||||
result=$(forge_api POST "/issues" -d "$payload" 2>/dev/null || true)
|
||||
FILED_ISSUE_NUM=$(printf '%s' "$result" | jq -r '.number // empty' 2>/dev/null || true)
|
||||
|
||||
if [ -z "$FILED_ISSUE_NUM" ]; then
|
||||
return 3
|
||||
fi
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
# PROJECT_CONTAINERS, CHECK_PRS, CHECK_DEV_AGENT,
|
||||
# CHECK_PIPELINE_STALL, CI_STALE_MINUTES,
|
||||
# MIRROR_NAMES, MIRROR_URLS, MIRROR_<NAME> (per configured mirror)
|
||||
# (plus backwards-compat aliases: CODEBERG_REPO, CODEBERG_API, CODEBERG_WEB)
|
||||
#
|
||||
# If no argument given, does nothing (allows poll scripts to work with
|
||||
# plain .env fallback for backwards compatibility).
|
||||
|
|
@ -103,10 +102,6 @@ if [ -n "$FORGE_REPO" ]; then
|
|||
# Extract repo owner (first path segment of owner/repo)
|
||||
export FORGE_REPO_OWNER="${FORGE_REPO%%/*}"
|
||||
fi
|
||||
# Backwards-compat aliases
|
||||
export CODEBERG_REPO="${FORGE_REPO}"
|
||||
export CODEBERG_API="${FORGE_API:-}"
|
||||
export CODEBERG_WEB="${FORGE_WEB:-}"
|
||||
|
||||
# Derive PROJECT_REPO_ROOT if not explicitly set
|
||||
if [ -z "${PROJECT_REPO_ROOT:-}" ] && [ -n "${PROJECT_NAME:-}" ]; then
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
# parse-deps.sh — Extract dependency issue numbers from an issue body
|
||||
#
|
||||
# Usage:
|
||||
# echo "$ISSUE_BODY" | bash lib/parse-deps.sh
|
||||
#
|
||||
# Output: one dep number per line, sorted and deduplicated
|
||||
#
|
||||
# Matches:
|
||||
# - Sections: ## Dependencies / ## Depends on / ## Blocked by
|
||||
# - Inline: "depends on #NNN" / "blocked by #NNN" anywhere
|
||||
# - Ignores: ## Related (safe for sibling cross-references)
|
||||
|
||||
BODY=$(cat)
|
||||
|
||||
{
|
||||
# Extract #NNN from dependency sections
|
||||
echo "$BODY" | awk '
|
||||
BEGIN { IGNORECASE=1 }
|
||||
/^##? *(Depends on|Blocked by|Dependencies)/ { capture=1; next }
|
||||
capture && /^##? / { capture=0 }
|
||||
capture { print }
|
||||
' | grep -oP '#\K[0-9]+' || true
|
||||
|
||||
# Also check inline deps on same line as keyword (skip fenced code blocks)
|
||||
echo "$BODY" | awk '
|
||||
BEGIN { IGNORECASE=1 }
|
||||
/^```/ { incode = !incode; next }
|
||||
incode { next }
|
||||
/blocked by|depends on/ { print }
|
||||
' | grep -oP '#\K[0-9]+' || true
|
||||
} | sort -un
|
||||
210
lib/profile.sh
210
lib/profile.sh
|
|
@ -1,210 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# profile.sh — Helpers for agent .profile repo management
|
||||
#
|
||||
# Source after lib/env.sh and lib/formula-session.sh:
|
||||
# source "$(dirname "$0")/../lib/env.sh"
|
||||
# source "$(dirname "$0")/lib/formula-session.sh"
|
||||
# source "$(dirname "$0")/lib/profile.sh"
|
||||
#
|
||||
# Required globals: FORGE_TOKEN, FORGE_URL, AGENT_IDENTITY, PROFILE_REPO_PATH
|
||||
#
|
||||
# Functions:
|
||||
# profile_propose_formula NEW_FORMULA CONTENT REASON — create PR to update formula.toml
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Internal log helper
|
||||
_profile_log() {
|
||||
if declare -f log >/dev/null 2>&1; then
|
||||
log "profile: $*"
|
||||
else
|
||||
printf '[%s] profile: %s\n' "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" "$*" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# profile_propose_formula — Propose a formula change via PR
|
||||
#
|
||||
# Creates a branch, writes updated formula.toml, opens a PR, and returns PR number.
|
||||
# Branch is protected (requires admin approval per #87).
|
||||
#
|
||||
# Args:
|
||||
# $1 - NEW_FORMULA_CONTENT: The complete new formula.toml content
|
||||
# $2 - REASON: Human-readable explanation of what changed and why
|
||||
#
|
||||
# Returns:
|
||||
# 0 on success, prints PR number to stdout
|
||||
# 1 on failure
|
||||
#
|
||||
# Example:
|
||||
# source "$(dirname "$0")/../lib/env.sh"
|
||||
# source "$(dirname "$0")/lib/formula-session.sh"
|
||||
# source "$(dirname "$0")/lib/profile.sh"
|
||||
# AGENT_IDENTITY="dev-bot"
|
||||
# ensure_profile_repo "$AGENT_IDENTITY"
|
||||
# profile_propose_formula "$new_formula" "Added new prompt pattern for code review"
|
||||
# -----------------------------------------------------------------------------
|
||||
profile_propose_formula() {
|
||||
local new_formula="$1"
|
||||
local reason="$2"
|
||||
|
||||
if [ -z "${AGENT_IDENTITY:-}" ]; then
|
||||
_profile_log "ERROR: AGENT_IDENTITY not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${PROFILE_REPO_PATH:-}" ]; then
|
||||
_profile_log "ERROR: PROFILE_REPO_PATH not set — ensure_profile_repo not called"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${FORGE_TOKEN:-}" ]; then
|
||||
_profile_log "ERROR: FORGE_TOKEN not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${FORGE_URL:-}" ]; then
|
||||
_profile_log "ERROR: FORGE_URL not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Generate short description from reason for branch name
|
||||
local short_desc
|
||||
short_desc=$(printf '%s' "$reason" | \
|
||||
tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/[^a-z0-9 ]//g' | \
|
||||
sed 's/ */ /g' | \
|
||||
sed 's/^ *//;s/ *$//' | \
|
||||
cut -c1-40 | \
|
||||
tr ' ' '-')
|
||||
|
||||
if [ -z "$short_desc" ]; then
|
||||
short_desc="formula-update"
|
||||
fi
|
||||
|
||||
local branch_name="formula/${short_desc}"
|
||||
local formula_path="${PROFILE_REPO_PATH}/formula.toml"
|
||||
|
||||
_profile_log "Proposing formula change: ${branch_name}"
|
||||
_profile_log "Reason: ${reason}"
|
||||
|
||||
# Ensure we're on main branch and up-to-date
|
||||
_profile_log "Fetching .profile repo"
|
||||
(
|
||||
cd "$PROFILE_REPO_PATH" || return 1
|
||||
|
||||
git fetch origin main --quiet 2>/dev/null || \
|
||||
git fetch origin master --quiet 2>/dev/null || true
|
||||
|
||||
# Reset to main/master
|
||||
if git checkout main --quiet 2>/dev/null; then
|
||||
git pull --ff-only origin main --quiet 2>/dev/null || true
|
||||
elif git checkout master --quiet 2>/dev/null; then
|
||||
git pull --ff-only origin master --quiet 2>/dev/null || true
|
||||
else
|
||||
_profile_log "ERROR: Failed to checkout main/master branch"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create and checkout new branch
|
||||
git checkout -b "$branch_name" 2>/dev/null || {
|
||||
_profile_log "Branch ${branch_name} may already exist"
|
||||
git checkout "$branch_name" 2>/dev/null || return 1
|
||||
}
|
||||
|
||||
# Write formula.toml
|
||||
printf '%s' "$new_formula" > "$formula_path"
|
||||
|
||||
# Commit the change
|
||||
git config user.name "${AGENT_IDENTITY}" || true
|
||||
git config user.email "${AGENT_IDENTITY}@users.noreply.codeberg.org" || true
|
||||
|
||||
git add "$formula_path"
|
||||
git commit -m "formula: ${reason}" --no-verify || {
|
||||
_profile_log "No changes to commit (formula unchanged)"
|
||||
# Check if branch has any commits
|
||||
if git rev-parse HEAD >/dev/null 2>&1; then
|
||||
: # branch has commits, continue
|
||||
else
|
||||
_profile_log "ERROR: Failed to create commit"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Push branch
|
||||
local remote="${FORGE_REMOTE:-origin}"
|
||||
git push --set-upstream "$remote" "$branch_name" --quiet 2>/dev/null || {
|
||||
_profile_log "ERROR: Failed to push branch"
|
||||
return 1
|
||||
}
|
||||
|
||||
_profile_log "Branch pushed: ${branch_name}"
|
||||
|
||||
# Create PR
|
||||
local forge_url="${FORGE_URL%/}"
|
||||
local api_url="${forge_url}/api/v1/repos/${AGENT_IDENTITY}/.profile"
|
||||
local primary_branch="main"
|
||||
|
||||
# Check if main or master is the primary branch
|
||||
if ! curl -sf -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${api_url}/git/branches/main" 2>/dev/null | grep -q "200"; then
|
||||
primary_branch="master"
|
||||
fi
|
||||
|
||||
local pr_title="formula: ${reason}"
|
||||
local pr_body="# Formula Update
|
||||
|
||||
**Reason:** ${reason}
|
||||
|
||||
---
|
||||
*This PR was auto-generated by ${AGENT_IDENTITY}.*
|
||||
"
|
||||
|
||||
local pr_response http_code
|
||||
local pr_json
|
||||
pr_json=$(jq -n \
|
||||
--arg t "$pr_title" \
|
||||
--arg b "$pr_body" \
|
||||
--arg h "$branch_name" \
|
||||
--arg base "$primary_branch" \
|
||||
'{title:$t, body:$b, head:$h, base:$base}') || {
|
||||
_profile_log "ERROR: Failed to build PR JSON"
|
||||
return 1
|
||||
}
|
||||
|
||||
pr_response=$(curl -s -w "\n%{http_code}" -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${api_url}/pulls" \
|
||||
-d "$pr_json" || true)
|
||||
|
||||
http_code=$(printf '%s\n' "$pr_response" | tail -1)
|
||||
pr_response=$(printf '%s\n' "$pr_response" | sed '$d')
|
||||
|
||||
if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then
|
||||
local pr_num
|
||||
pr_num=$(printf '%s' "$pr_response" | jq -r '.number')
|
||||
_profile_log "PR created: #${pr_num}"
|
||||
printf '%s' "$pr_num"
|
||||
return 0
|
||||
else
|
||||
# Check if PR already exists (409 conflict)
|
||||
if [ "$http_code" = "409" ]; then
|
||||
local existing_pr
|
||||
existing_pr=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${api_url}/pulls?state=open&head=${AGENT_IDENTITY}:formula/${short_desc}" 2>/dev/null | \
|
||||
jq -r '.[0].number // empty') || true
|
||||
if [ -n "$existing_pr" ]; then
|
||||
_profile_log "PR already exists: #${existing_pr}"
|
||||
printf '%s' "$existing_pr"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_profile_log "ERROR: Failed to create PR (HTTP ${http_code})"
|
||||
return 1
|
||||
fi
|
||||
)
|
||||
|
||||
return $?
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# tea-helpers.sh — Thin wrappers around tea CLI for forge issue operations
|
||||
#
|
||||
# Usage: source this file (after env.sh), then call tea_* functions.
|
||||
# Requires: tea binary in PATH, TEA_LOGIN and FORGE_REPO from env.sh,
|
||||
# scan_for_secrets from lib/secret-scan.sh
|
||||
#
|
||||
# tea_file_issue <title> <body> <labels...>
|
||||
# Sets FILED_ISSUE_NUM on success.
|
||||
# Returns: 0=created, 3=API/tea error, 4=secrets detected
|
||||
#
|
||||
# tea_relabel <issue_number> <labels...>
|
||||
# tea_comment <issue_number> <body>
|
||||
# tea_close <issue_number>
|
||||
|
||||
# Load secret scanner
|
||||
# shellcheck source=secret-scan.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/secret-scan.sh"
|
||||
|
||||
tea_file_issue() {
|
||||
local title="$1" body="$2"
|
||||
shift 2
|
||||
FILED_ISSUE_NUM=""
|
||||
|
||||
# Secret scan: reject issue bodies containing embedded secrets
|
||||
if ! scan_for_secrets "$body"; then
|
||||
echo "tea-helpers: BLOCKED — issue body contains potential secrets. Use env var references instead." >&2
|
||||
return 4
|
||||
fi
|
||||
|
||||
# Join remaining args as comma-separated label names
|
||||
local IFS=','
|
||||
local labels="$*"
|
||||
|
||||
local result
|
||||
result=$(tea issues create --login "$TEA_LOGIN" --repo "$FORGE_REPO" \
|
||||
--title "$title" --body "$body" --labels "$labels" \
|
||||
--output simple 2>&1) || {
|
||||
echo "tea-helpers: tea issues create failed: ${result}" >&2
|
||||
return 3
|
||||
}
|
||||
|
||||
# Parse issue number from tea output (e.g. "#42 Title")
|
||||
FILED_ISSUE_NUM=$(printf '%s' "$result" | grep -oE '#[0-9]+' | head -1 | tr -d '#')
|
||||
if [ -z "$FILED_ISSUE_NUM" ]; then
|
||||
# Fallback: extract any number
|
||||
FILED_ISSUE_NUM=$(printf '%s' "$result" | grep -oE '[0-9]+' | head -1)
|
||||
fi
|
||||
}
|
||||
|
||||
tea_relabel() {
|
||||
local issue_num="$1"
|
||||
shift
|
||||
|
||||
local IFS=','
|
||||
local labels="$*"
|
||||
|
||||
tea issues edit "$issue_num" --login "$TEA_LOGIN" --repo "$FORGE_REPO" \
|
||||
--labels "$labels"
|
||||
}
|
||||
|
||||
tea_comment() {
|
||||
local issue_num="$1" body="$2"
|
||||
|
||||
# Secret scan: reject comment bodies containing embedded secrets
|
||||
if ! scan_for_secrets "$body"; then
|
||||
echo "tea-helpers: BLOCKED — comment body contains potential secrets. Use env var references instead." >&2
|
||||
return 4
|
||||
fi
|
||||
|
||||
tea comment create "$issue_num" --login "$TEA_LOGIN" --repo "$FORGE_REPO" \
|
||||
--body "$body"
|
||||
}
|
||||
|
||||
tea_close() {
|
||||
local issue_num="$1"
|
||||
tea issues close "$issue_num" --login "$TEA_LOGIN" --repo "$FORGE_REPO"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue