Merge pull request 'fix: fix: seed missing ops repo directories on existing deployments (#425)' (#427) from fix/issue-425 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
commit
b544da603a
2 changed files with 128 additions and 2 deletions
|
|
@ -25,7 +25,7 @@ set -euo pipefail
|
||||||
|
|
||||||
FACTORY_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
FACTORY_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
source "${FACTORY_ROOT}/lib/env.sh"
|
source "${FACTORY_ROOT}/lib/env.sh"
|
||||||
source "${FACTORY_ROOT}/lib/ops-setup.sh"
|
source "${FACTORY_ROOT}/lib/ops-setup.sh" # setup_ops_repo, migrate_ops_repo
|
||||||
source "${FACTORY_ROOT}/lib/hire-agent.sh"
|
source "${FACTORY_ROOT}/lib/hire-agent.sh"
|
||||||
source "${FACTORY_ROOT}/lib/forge-setup.sh"
|
source "${FACTORY_ROOT}/lib/forge-setup.sh"
|
||||||
source "${FACTORY_ROOT}/lib/generators.sh"
|
source "${FACTORY_ROOT}/lib/generators.sh"
|
||||||
|
|
@ -662,6 +662,10 @@ p.write_text(text)
|
||||||
local ops_root="/home/${USER}/${project_name}-ops"
|
local ops_root="/home/${USER}/${project_name}-ops"
|
||||||
setup_ops_repo "$forge_url" "$ops_slug" "$ops_root" "$branch"
|
setup_ops_repo "$forge_url" "$ops_slug" "$ops_root" "$branch"
|
||||||
|
|
||||||
|
# Migrate ops repo to canonical structure (seed missing directories/files)
|
||||||
|
# This brings pre-#407 deployments up to date with the canonical structure
|
||||||
|
migrate_ops_repo "$ops_root" "$branch"
|
||||||
|
|
||||||
# Set up vault branch protection on ops repo (#77)
|
# Set up vault branch protection on ops repo (#77)
|
||||||
# This ensures admin-only merge to main, blocking bots from merging vault PRs
|
# This ensures admin-only merge to main, blocking bots from merging vault PRs
|
||||||
# Use HUMAN_TOKEN (disinto-admin) or FORGE_TOKEN (dev-bot) for admin operations
|
# Use HUMAN_TOKEN (disinto-admin) or FORGE_TOKEN (dev-bot) for admin operations
|
||||||
|
|
|
||||||
124
lib/ops-setup.sh
124
lib/ops-setup.sh
|
|
@ -14,9 +14,12 @@
|
||||||
# - Clone or initialize ops repo locally
|
# - Clone or initialize ops repo locally
|
||||||
# - Seed directory structure (vault, knowledge, evidence)
|
# - Seed directory structure (vault, knowledge, evidence)
|
||||||
# - Export _ACTUAL_OPS_SLUG for caller to use
|
# - Export _ACTUAL_OPS_SLUG for caller to use
|
||||||
|
# migrate_ops_repo <ops_root> [primary_branch]
|
||||||
|
# - Seed missing directories/files on existing ops repos (idempotent)
|
||||||
|
# - Creates .gitkeep files and template content for canonical structure
|
||||||
#
|
#
|
||||||
# Globals modified:
|
# Globals modified:
|
||||||
# _ACTUAL_OPS_SLUG - resolved ops repo slug after function completes
|
# _ACTUAL_OPS_SLUG - resolved ops repo slug after setup_ops_repo completes
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
@ -234,3 +237,122 @@ OPSEOF
|
||||||
# Export resolved slug for the caller to write back to the project TOML
|
# Export resolved slug for the caller to write back to the project TOML
|
||||||
_ACTUAL_OPS_SLUG="${actual_ops_slug}"
|
_ACTUAL_OPS_SLUG="${actual_ops_slug}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# migrate_ops_repo — Seed missing ops repo directories and files on existing deployments
|
||||||
|
#
|
||||||
|
# This function is idempotent — safe to run on every container start.
|
||||||
|
# It checks for missing directories/files and creates them with .gitkeep files
|
||||||
|
# or template content as appropriate.
|
||||||
|
#
|
||||||
|
# Called from entrypoint.sh after setup_ops_repo() to bring pre-#407 deployments
|
||||||
|
# up to date with the canonical ops repo structure.
|
||||||
|
migrate_ops_repo() {
|
||||||
|
local ops_root="${1:-}"
|
||||||
|
local primary_branch="${2:-main}"
|
||||||
|
|
||||||
|
# Validate ops_root argument
|
||||||
|
if [ -z "$ops_root" ]; then
|
||||||
|
# Try to determine ops_root from environment or project config
|
||||||
|
if [ -n "${OPS_REPO_ROOT:-}" ]; then
|
||||||
|
ops_root="${OPS_REPO_ROOT}"
|
||||||
|
elif [ -n "${PROJECT_TOML:-}" ] && [ -f "$PROJECT_TOML" ]; then
|
||||||
|
source "$(dirname "$0")/load-project.sh" "$PROJECT_TOML"
|
||||||
|
ops_root="${OPS_REPO_ROOT:-}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip if we still don't have an ops root
|
||||||
|
if [ -z "$ops_root" ]; then
|
||||||
|
echo "migrate_ops_repo: skipping — no ops repo root determined"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify it's a git repo
|
||||||
|
if [ ! -d "${ops_root}/.git" ]; then
|
||||||
|
echo "migrate_ops_repo: skipping — ${ops_root} is not a git repo"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "── Ops repo migration ───────────────────────────────────"
|
||||||
|
echo "Checking ${ops_root} for missing directories and files..."
|
||||||
|
|
||||||
|
local migrated=false
|
||||||
|
|
||||||
|
# Canonical ops repo structure (post #407)
|
||||||
|
# Directories to ensure exist with .gitkeep files
|
||||||
|
local -a dir_keepfiles=(
|
||||||
|
"${ops_root}/vault/pending/.gitkeep"
|
||||||
|
"${ops_root}/vault/approved/.gitkeep"
|
||||||
|
"${ops_root}/vault/fired/.gitkeep"
|
||||||
|
"${ops_root}/vault/rejected/.gitkeep"
|
||||||
|
"${ops_root}/knowledge/.gitkeep"
|
||||||
|
"${ops_root}/evidence/engagement/.gitkeep"
|
||||||
|
"${ops_root}/evidence/red-team/.gitkeep"
|
||||||
|
"${ops_root}/evidence/holdout/.gitkeep"
|
||||||
|
"${ops_root}/evidence/evolution/.gitkeep"
|
||||||
|
"${ops_root}/evidence/user-test/.gitkeep"
|
||||||
|
"${ops_root}/sprints/.gitkeep"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create missing directories and .gitkeep files
|
||||||
|
for keepfile in "${dir_keepfiles[@]}"; do
|
||||||
|
local dir
|
||||||
|
dir=$(dirname "$keepfile")
|
||||||
|
if [ ! -f "$keepfile" ]; then
|
||||||
|
mkdir -p "$dir"
|
||||||
|
touch "$keepfile"
|
||||||
|
echo " + Created: ${keepfile}"
|
||||||
|
migrated=true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Template files to create if missing (starter content)
|
||||||
|
local -a template_files=(
|
||||||
|
"${ops_root}/portfolio.md"
|
||||||
|
"${ops_root}/prerequisites.md"
|
||||||
|
"${ops_root}/RESOURCES.md"
|
||||||
|
)
|
||||||
|
|
||||||
|
for tfile in "${template_files[@]}"; do
|
||||||
|
if [ ! -f "$tfile" ]; then
|
||||||
|
local title
|
||||||
|
title=$(basename "$tfile" | sed 's/\.md$//; s/_/ /g' | sed 's/\b\(.\)/\u\1/g')
|
||||||
|
{
|
||||||
|
echo "# ${title}"
|
||||||
|
echo ""
|
||||||
|
echo "## Overview"
|
||||||
|
echo ""
|
||||||
|
echo "<!-- Add content here -->"
|
||||||
|
} > "$tfile"
|
||||||
|
echo " + Created: ${tfile}"
|
||||||
|
migrated=true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Commit and push changes if any were made
|
||||||
|
if [ "$migrated" = true ]; then
|
||||||
|
# Auto-configure repo-local git identity if missing
|
||||||
|
if [ -z "$(git -C "$ops_root" config user.name 2>/dev/null)" ]; then
|
||||||
|
git -C "$ops_root" config user.name "disinto-admin"
|
||||||
|
fi
|
||||||
|
if [ -z "$(git -C "$ops_root" config user.email 2>/dev/null)" ]; then
|
||||||
|
git -C "$ops_root" config user.email "disinto-admin@localhost"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git -C "$ops_root" add -A
|
||||||
|
if ! git -C "$ops_root" diff --cached --quiet 2>/dev/null; then
|
||||||
|
git -C "$ops_root" commit -m "chore: migrate ops repo structure to canonical layout" -q
|
||||||
|
# Push if remote exists
|
||||||
|
if git -C "$ops_root" remote get-url origin >/dev/null 2>&1; then
|
||||||
|
if git -C "$ops_root" push origin "${primary_branch}" -q 2>/dev/null; then
|
||||||
|
echo "Migrated: ops repo structure updated and pushed"
|
||||||
|
else
|
||||||
|
echo "Warning: failed to push migration to ops repo" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " (all directories and files already present)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue