246 lines
9.8 KiB
TOML
246 lines
9.8 KiB
TOML
|
|
# formulas/release.toml — Release formula
|
||
|
|
#
|
||
|
|
# Defines the release workflow: tag Forgejo main, push to mirrors, build
|
||
|
|
# and tag the agents Docker image, and restart agents.
|
||
|
|
#
|
||
|
|
# Triggered by vault PR approval (human creates vault PR, approves it, then
|
||
|
|
# runner executes via `disinto run <id>`).
|
||
|
|
#
|
||
|
|
# Example vault item:
|
||
|
|
# id = "release-v1.2.0"
|
||
|
|
# formula = "release"
|
||
|
|
# context = "Tag v1.2.0 — includes vault redesign, .profile system, architect agent"
|
||
|
|
# secrets = []
|
||
|
|
#
|
||
|
|
# Steps: preflight → tag-main → push-mirrors → build-image → tag-image → restart-agents → commit-result
|
||
|
|
|
||
|
|
name = "release"
|
||
|
|
description = "Tag Forgejo main, push to mirrors, build and tag agents image, restart agents"
|
||
|
|
version = 1
|
||
|
|
|
||
|
|
[context]
|
||
|
|
files = ["docker-compose.yml"]
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 1: preflight
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "preflight"
|
||
|
|
title = "Validate release prerequisites"
|
||
|
|
description = """
|
||
|
|
Validate release prerequisites before proceeding.
|
||
|
|
|
||
|
|
1. Check that RELEASE_VERSION is set:
|
||
|
|
- Must be in format: v1.2.3 (semver with 'v' prefix)
|
||
|
|
- Validate with regex: ^v[0-9]+\\.[0-9]+\\.[0-9]+$
|
||
|
|
- If not set, exit with error
|
||
|
|
|
||
|
|
2. Check that FORGE_TOKEN and FORGE_URL are set:
|
||
|
|
- Required for Forgejo API calls
|
||
|
|
|
||
|
|
3. Check that DOCKER_HOST is accessible:
|
||
|
|
- Test with: docker info
|
||
|
|
- Required for image build
|
||
|
|
|
||
|
|
4. Check current branch is main:
|
||
|
|
- git rev-parse --abbrev-ref HEAD
|
||
|
|
- Must be 'main' or 'master'
|
||
|
|
|
||
|
|
5. Pull latest code:
|
||
|
|
- git fetch origin "$PRIMARY_BRANCH"
|
||
|
|
- git reset --hard origin/"$PRIMARY_BRANCH"
|
||
|
|
- Ensure working directory is clean
|
||
|
|
|
||
|
|
6. Check if tag already exists locally:
|
||
|
|
- git tag -l "$RELEASE_VERSION"
|
||
|
|
- If exists, exit with error
|
||
|
|
|
||
|
|
7. Check if tag already exists on Forgejo:
|
||
|
|
- curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
||
|
|
- "$FORGE_URL/api/v1/repos/johba/disinto/git/tags/$RELEASE_VERSION"
|
||
|
|
- If exists, exit with error
|
||
|
|
|
||
|
|
8. Export RELEASE_VERSION for subsequent steps:
|
||
|
|
- export RELEASE_VERSION (already set from vault action)
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 2: tag-main
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "tag-main"
|
||
|
|
title = "Create tag on Forgejo main via API"
|
||
|
|
description = """
|
||
|
|
Create the release tag on Forgejo main via the Forgejo API.
|
||
|
|
|
||
|
|
1. Get current HEAD SHA of main:
|
||
|
|
- curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
||
|
|
- "$FORGE_URL/api/v1/repos/johba/disinto/branches/$PRIMARY_BRANCH"
|
||
|
|
- Parse sha field from response
|
||
|
|
|
||
|
|
2. Create tag via Forgejo API:
|
||
|
|
- curl -sf -X POST \
|
||
|
|
- -H "Authorization: token $FORGE_TOKEN" \
|
||
|
|
- -H "Content-Type: application/json" \
|
||
|
|
- "$FORGE_URL/api/v1/repos/johba/disinto/tags" \
|
||
|
|
- -d "{\"tag\":\"$RELEASE_VERSION\",\"target\":\"$HEAD_SHA\",\"message\":\"Release $RELEASE_VERSION\"}"
|
||
|
|
- Parse response for success
|
||
|
|
|
||
|
|
3. Log the tag creation:
|
||
|
|
- echo "Created tag $RELEASE_VERSION on Forgejo (SHA: $HEAD_SHA)"
|
||
|
|
|
||
|
|
4. Store HEAD SHA for later verification:
|
||
|
|
- echo "$HEAD_SHA" > /tmp/release-head-sha
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 3: push-mirrors
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "push-mirrors"
|
||
|
|
title = "Push tag to mirrors (Codeberg, GitHub)"
|
||
|
|
description = """
|
||
|
|
Push the newly created tag to all configured mirrors.
|
||
|
|
|
||
|
|
1. Add mirror remotes if not already present:
|
||
|
|
- Codeberg: git remote add codeberg git@codeberg.org:johba/disinto.git
|
||
|
|
- GitHub: git remote add github git@github.com:disinto/disinto.git
|
||
|
|
- Check with: git remote -v
|
||
|
|
|
||
|
|
2. Push tag to Codeberg:
|
||
|
|
- git push codeberg "$RELEASE_VERSION" --tags
|
||
|
|
- Or push all tags: git push codeberg --tags
|
||
|
|
|
||
|
|
3. Push tag to GitHub:
|
||
|
|
- git push github "$RELEASE_VERSION" --tags
|
||
|
|
- Or push all tags: git push github --tags
|
||
|
|
|
||
|
|
4. Verify tags exist on mirrors:
|
||
|
|
- curl -sf -H "Authorization: token $GITHUB_TOKEN" \
|
||
|
|
- "https://api.github.com/repos/disinto/disinto/tags/$RELEASE_VERSION"
|
||
|
|
- curl -sf -H "Authorization: token $FORGE_TOKEN" \
|
||
|
|
- "$FORGE_URL/api/v1/repos/johba/disinto/git/tags/$RELEASE_VERSION"
|
||
|
|
|
||
|
|
5. Log success:
|
||
|
|
- echo "Tag $RELEASE_VERSION pushed to mirrors"
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 4: build-image
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "build-image"
|
||
|
|
title = "Build agents Docker image"
|
||
|
|
description = """
|
||
|
|
Build the new agents Docker image with the tagged code.
|
||
|
|
|
||
|
|
1. Build image without cache to ensure fresh build:
|
||
|
|
- docker compose build --no-cache agents
|
||
|
|
|
||
|
|
2. Verify image was created:
|
||
|
|
- docker images | grep disinto-agents
|
||
|
|
- Check image exists and has recent timestamp
|
||
|
|
|
||
|
|
3. Store image ID for later:
|
||
|
|
- docker images disinto-agents --format "{{.ID}}" > /tmp/release-image-id
|
||
|
|
|
||
|
|
4. Log build completion:
|
||
|
|
- echo "Built disinto-agents image"
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 5: tag-image
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "tag-image"
|
||
|
|
title = "Tag Docker image with version"
|
||
|
|
description = """
|
||
|
|
Tag the newly built agents image with the release version.
|
||
|
|
|
||
|
|
1. Get the untagged image ID:
|
||
|
|
- docker images disinto-agents --format "{{.ID}}" --no-trunc | head -1
|
||
|
|
|
||
|
|
2. Tag the image:
|
||
|
|
- docker tag disinto-agents disinto-agents:$RELEASE_VERSION
|
||
|
|
|
||
|
|
3. Verify tag:
|
||
|
|
- docker images disinto-agents
|
||
|
|
|
||
|
|
4. Log tag:
|
||
|
|
- echo "Tagged disinto-agents:$RELEASE_VERSION"
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 6: restart-agents
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "restart-agents"
|
||
|
|
title = "Restart agent containers with new image"
|
||
|
|
description = """
|
||
|
|
Restart agent containers to use the new image.
|
||
|
|
|
||
|
|
1. Pull the new image (in case it was pushed somewhere):
|
||
|
|
- docker compose pull agents
|
||
|
|
|
||
|
|
2. Stop and remove existing agent containers:
|
||
|
|
- docker compose down agents agents-llama 2>/dev/null || true
|
||
|
|
|
||
|
|
3. Start agents with new image:
|
||
|
|
- docker compose up -d agents agents-llama
|
||
|
|
|
||
|
|
4. Wait for containers to be healthy:
|
||
|
|
- for i in {1..30}; do
|
||
|
|
- if docker inspect --format='{{.State.Health.Status}}' agents | grep -q healthy; then
|
||
|
|
- echo "Agents container healthy"; break
|
||
|
|
- fi
|
||
|
|
- sleep 5
|
||
|
|
- done
|
||
|
|
|
||
|
|
5. Verify containers are running:
|
||
|
|
- docker compose ps agents agents-llama
|
||
|
|
|
||
|
|
6. Log restart:
|
||
|
|
- echo "Restarted agents containers"
|
||
|
|
"""
|
||
|
|
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
# Step 7: commit-result
|
||
|
|
# ─────────────────────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[[steps]]
|
||
|
|
id = "commit-result"
|
||
|
|
title = "Write release result"
|
||
|
|
description = """
|
||
|
|
Write the release result to a file for tracking.
|
||
|
|
|
||
|
|
1. Get the image ID:
|
||
|
|
- IMAGE_ID=$(cat /tmp/release-image-id)
|
||
|
|
|
||
|
|
2. Create result file:
|
||
|
|
- cat > /tmp/release-result.json <<EOF
|
||
|
|
- {
|
||
|
|
- "version": "$RELEASE_VERSION",
|
||
|
|
- "image_id": "$IMAGE_ID",
|
||
|
|
- "forgejo_tag_url": "$FORGE_URL/johba/disinto/src/$RELEASE_VERSION",
|
||
|
|
- "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||
|
|
- "status": "success"
|
||
|
|
- }
|
||
|
|
- EOF
|
||
|
|
|
||
|
|
3. Copy result to data directory:
|
||
|
|
- mkdir -p "$PROJECT_REPO_ROOT/release"
|
||
|
|
- cp /tmp/release-result.json "$PROJECT_REPO_ROOT/release/$RELEASE_VERSION.json"
|
||
|
|
|
||
|
|
4. Log result:
|
||
|
|
- cat /tmp/release-result.json
|
||
|
|
|
||
|
|
5. Clean up temp files:
|
||
|
|
- rm -f /tmp/release-head-sha /tmp/release-image-id /tmp/release-result.json
|
||
|
|
"""
|