fix: feat: versioned releases — vault-gated tag, image build, and deploy (#112)
This commit is contained in:
parent
0455040d02
commit
a7ad6eb32a
4 changed files with 406 additions and 5 deletions
126
bin/disinto
126
bin/disinto
|
|
@ -40,6 +40,7 @@ Usage:
|
|||
disinto status Show factory status
|
||||
disinto secrets <subcommand> Manage encrypted secrets
|
||||
disinto run <action-id> Run action in ephemeral runner container
|
||||
disinto release <version> Create vault PR for release (e.g., v1.2.0)
|
||||
disinto hire-an-agent <agent-name> <role> [--formula <path>]
|
||||
Hire a new agent (create user + .profile repo)
|
||||
|
||||
|
|
@ -232,7 +233,6 @@ services:
|
|||
volumes:
|
||||
- agent-data:/home/agent/data
|
||||
- project-repos:/home/agent/repos
|
||||
- ./:/home/agent/disinto:ro
|
||||
- ${HOME}/.claude:/home/agent/.claude
|
||||
- ${HOME}/.claude.json:/home/agent/.claude.json:ro
|
||||
- CLAUDE_BIN_PLACEHOLDER:/usr/local/bin/claude:ro
|
||||
|
|
@ -261,9 +261,7 @@ services:
|
|||
security_opt:
|
||||
- apparmor=unconfined
|
||||
volumes:
|
||||
- ./vault:/home/agent/disinto/vault
|
||||
- ./lib:/home/agent/disinto/lib:ro
|
||||
- ./formulas:/home/agent/disinto/formulas:ro
|
||||
- agent-data:/home/agent/data
|
||||
environment:
|
||||
FORGE_URL: http://forgejo:3000
|
||||
DISINTO_CONTAINER: "1"
|
||||
|
|
@ -2613,6 +2611,125 @@ EOF
|
|||
echo " Formula: ${role}.toml"
|
||||
}
|
||||
|
||||
# ── release command ───────────────────────────────────────────────────────────
|
||||
#
|
||||
# Creates a vault PR for the release. This is a convenience wrapper that
|
||||
# creates the vault item TOML and submits it as a PR to the ops repo.
|
||||
#
|
||||
# Usage: disinto release <version>
|
||||
# Example: disinto release v1.2.0
|
||||
|
||||
disinto_release() {
|
||||
local version="${1:-}"
|
||||
local formula_path="${FACTORY_ROOT}/formulas/release.toml"
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
echo "Error: version required" >&2
|
||||
echo "Usage: disinto release <version>" >&2
|
||||
echo "Example: disinto release v1.2.0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate version format (must start with 'v' followed by semver)
|
||||
if ! echo "$version" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "Error: version must be in format v1.2.3 (semver with 'v' prefix)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check formula exists
|
||||
if [ ! -f "$formula_path" ]; then
|
||||
echo "Error: release formula not found at ${formula_path}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the ops repo root
|
||||
local ops_root="${FACTORY_ROOT}/../disinto-ops"
|
||||
if [ ! -d "${ops_root}/.git" ]; then
|
||||
echo "Error: ops repo not found at ${ops_root}" >&2
|
||||
echo " Run 'disinto init' to set up the ops repo first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate a unique ID for the vault item
|
||||
local id="release-${version//./}"
|
||||
local vault_toml="${ops_root}/vault/pending/${id}.toml"
|
||||
|
||||
# Create vault TOML with the specific version
|
||||
cat > "$vault_toml" <<EOF
|
||||
# vault/pending/${id}.toml
|
||||
# Release vault item for ${version}
|
||||
# Auto-generated by disinto release
|
||||
|
||||
id = "${id}"
|
||||
formula = "release"
|
||||
context = "Release ${version}"
|
||||
secrets = []
|
||||
EOF
|
||||
|
||||
echo "Created vault item: ${vault_toml}"
|
||||
|
||||
# Create a PR to submit the vault item to the ops repo
|
||||
local branch_name="release/${version//./}"
|
||||
local pr_title="release: ${version}"
|
||||
local pr_body="Release ${version}
|
||||
|
||||
This PR creates a vault item for the release of version ${version}.
|
||||
|
||||
## Changes
|
||||
- Added vault item: ${id}.toml
|
||||
|
||||
## Next Steps
|
||||
1. Review this PR
|
||||
2. Approve and merge
|
||||
3. The vault runner will execute the release formula
|
||||
"
|
||||
|
||||
# Create branch
|
||||
cd "$ops_root"
|
||||
git checkout -B "$branch_name" 2>/dev/null || git checkout "$branch_name"
|
||||
|
||||
# Add and commit
|
||||
git add -A
|
||||
git commit -m "$pr_title" -m "$pr_body" 2>/dev/null || true
|
||||
|
||||
# Push branch
|
||||
git push -u origin "$branch_name" 2>/dev/null || {
|
||||
echo "Error: failed to push branch" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Create PR
|
||||
local pr_response
|
||||
pr_response=$(curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_URL}/api/v1/repos/${PROJECT_REPO}/pulls" \
|
||||
-d "{\"title\":\"${pr_title}\",\"head\":\"${branch_name}\",\"base\":\"main\",\"body\":\"$(echo "$pr_body" | sed ':a;N;$!ba;s/\n/\\n/g')\"}" 2>/dev/null) || {
|
||||
echo "Error: failed to create PR" >&2
|
||||
echo "Response: ${pr_response}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
local pr_number
|
||||
pr_number=$(echo "$pr_response" | jq -r '.number')
|
||||
|
||||
local pr_url="${FORGE_URL}/${PROJECT_REPO}/pulls/${pr_number}"
|
||||
|
||||
echo ""
|
||||
echo "Release PR created: ${pr_url}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Review the PR"
|
||||
echo " 2. Approve and merge (requires 2 reviewers for vault items)"
|
||||
echo " 3. The vault runner will execute the release formula"
|
||||
echo ""
|
||||
echo "After merge, the release will:"
|
||||
echo " 1. Tag Forgejo main with ${version}"
|
||||
echo " 2. Push tag to mirrors (Codeberg, GitHub)"
|
||||
echo " 3. Build and tag the agents Docker image"
|
||||
echo " 4. Restart agent containers"
|
||||
}
|
||||
|
||||
# ── Main dispatch ────────────────────────────────────────────────────────────
|
||||
|
||||
case "${1:-}" in
|
||||
|
|
@ -2624,6 +2741,7 @@ case "${1:-}" in
|
|||
status) shift; disinto_status "$@" ;;
|
||||
secrets) shift; disinto_secrets "$@" ;;
|
||||
run) shift; disinto_run "$@" ;;
|
||||
release) shift; disinto_release "$@" ;;
|
||||
hire-an-agent) shift; disinto_hire_an_agent "$@" ;;
|
||||
-h|--help) usage ;;
|
||||
*) usage ;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue