# Release Tools Documentation

## Overview

Release tools manage the publishing workflow for Modyo Channels elements (templates, pages, widget definitions, and menus). In Modyo, changes to these elements are not immediately visible to end users - they must be published through a release.

## Publishing Workflow

Modyo uses a two-step publishing process:

1. **Get publishable elements** - Retrieve list of draft elements ready to be published
2. **Create release** - Publish selected elements making them live

## Tools

### release-get-elements-to-publish

Retrieves all elements that are ready to be published in a site.

**Use Cases:**
- Check what changes are pending publication
- See all unpublished widgets, templates, pages, and menus
- Prepare data for creating a release
- Audit draft content before publishing

**Parameters:**
- `platformSlug` (required): Platform identifier from platforms.json
- `siteId` (required): Numeric ID of the site

**Returns:**
```typescript
{
  template?: Array<{
    id: number;
    title: string;
    oid: string;
    type: "template";
    is_new: boolean;
    selected: boolean;
    publish_at?: string;
    unpublish_at?: string;
  }>;
  page?: Array<{...}>;  // Same structure
  widgetDefinition?: Array<{...}>;  // Same structure
  menu?: Array<{...}>;  // Same structure
}
```

**Notes:**
- For sites with team review enabled, only shows approved elements
- `is_new: true` indicates element has never been published
- `oid` is the element's unique identifier (OID/SHA hash, not UUID)
- Empty arrays mean no elements of that type are pending publication

**Example:**
```typescript
// Get all publishable elements for NeoBank site
{
  platformSlug: "fed-team",
  siteId: 4605
}

// Response shows 4 unpublished widgets:
{
  widgetDefinition: [
    { id: 86713, title: "Account Balance", is_new: true, ... },
    { id: 86714, title: "Transaction List", is_new: true, ... },
    { id: 86716, title: "Quick Transfer", is_new: true, ... },
    { id: 86717, title: "Product Cards", is_new: true, ... }
  ],
  template: [],
  page: [],
  menu: []
}
```

---

### release-create

Creates and immediately publishes a release with selected elements.

**Use Cases:**
- Publish multiple widgets at once
- Deploy template changes to production
- Update multiple pages simultaneously
- Schedule future publications
- Coordinate releases across element types

**Parameters:**
- `platformSlug` (required): Platform identifier from platforms.json
- `siteId` (required): Numeric ID of the site
- `data` (required): Object containing arrays of elements to publish:
  - `template?`: Array of `{id: number, selected: boolean}`
  - `page?`: Array of `{id: number, selected: boolean}`
  - `widgetDefinition?`: Array of `{id: number, selected: boolean}`
  - `menu?`: Array of `{id: number, selected: boolean}`
- `scheduled` (optional): Boolean, default false - whether this is a scheduled release
- `publish_at` (optional): ISO datetime string - schedule publication for future
- `unpublish_at` (optional): ISO datetime string - schedule automatic unpublication

**Returns:**
```typescript
{
  message: string;  // "All selected elements were successfully published"
}
```

**Important Notes:**
- Only elements with `selected: true` will be published
- Use element IDs from `release-get-elements-to-publish` response
- Publishing is immediate unless `scheduled: true` or `publish_at` is set
- Once published, widgets become available via `custom_widgets` endpoint
- Scheduled releases require both `scheduled: true` and `publish_at`
- `unpublish_at` must be after `publish_at`

**Examples:**

**Publish all widgets immediately:**
```typescript
{
  platformSlug: "fed-team",
  siteId: 4605,
  data: {
    widgetDefinition: [
      { id: 86713, selected: true },
      { id: 86714, selected: true },
      { id: 86716, selected: true },
      { id: 86717, selected: true }
    ]
  }
}
```

**Publish specific widgets and templates:**
```typescript
{
  platformSlug: "fed-team",
  siteId: 4605,
  data: {
    widgetDefinition: [
      { id: 86713, selected: true },
      { id: 86714, selected: false }  // Won't be published
    ],
    template: [
      { id: 12345, selected: true }
    ]
  }
}
```

**Schedule future publication:**
```typescript
{
  platformSlug: "fed-team",
  siteId: 4605,
  scheduled: true,
  publish_at: "2025-12-25T00:00:00.000Z",  // Christmas launch
  data: {
    widgetDefinition: [
      { id: 86717, selected: true }
    ]
  }
}
```

**Publish with automatic unpublication:**
```typescript
{
  platformSlug: "fed-team",
  siteId: 4605,
  publish_at: "2025-01-01T00:00:00.000Z",
  unpublish_at: "2025-01-31T23:59:59.999Z",  // Campaign runs for January only
  data: {
    page: [
      { id: 175255, selected: true }
    ]
  }
}
```

## Complete Workflow Example

### Publishing New Widgets to a Site

**Scenario:** You've created 4 banking widgets and want to publish them all.

**Step 1: Get publishable elements**
```typescript
release-get-elements-to-publish({
  platformSlug: "fed-team",
  siteId: 4605
})
```

**Step 2: Review response and note widget IDs**
```json
{
  "widgetDefinition": [
    {"id": 86713, "title": "Account Balance", "is_new": true},
    {"id": 86714, "title": "Transaction List", "is_new": true},
    {"id": 86716, "title": "Quick Transfer", "is_new": true},
    {"id": 86717, "title": "Product Cards", "is_new": true}
  ]
}
```

**Step 3: Publish all widgets**
```typescript
release-create({
  platformSlug: "fed-team",
  siteId: 4605,
  data: {
    widgetDefinition: [
      { id: 86713, selected: true },
      { id: 86714, selected: true },
      { id: 86716, selected: true },
      { id: 86717, selected: true }
    ]
  }
})
```

**Step 4: Verify publication**
Use `widget-get-custom-widgets` to confirm widgets are now published and available for use.

## Best Practices

1. **Always get elements first** - Use `release-get-elements-to-publish` before creating release
2. **Review before publishing** - Check titles and `is_new` flag to verify you're publishing the right elements
3. **Use selective publishing** - Set `selected: false` for elements you want to keep as draft
4. **Schedule important releases** - Use `publish_at` for coordinated launches
5. **Batch related changes** - Publish widgets, templates, and pages together when they depend on each other
6. **Test in staging** - Use separate platformSlug for staging environment before production
7. **Track IDs carefully** - Widget IDs may change after publishing; use OIDs/UUIDs for stable references

## Common Errors

**"Widget definition uuid can't be blank"**
- Attempting to add widget to page before publishing it
- Solution: Use release tools to publish widget first

**"No elements to publish"**
- All elements are already published or archived
- Solution: Make changes to elements or create new ones

**"Column must be included in [0]"**
- Trying to use invalid column number for page's grid type
- Solution: Check page's `grid_type` and use valid column numbers

## Related Tools

- `widget-get-custom-widgets` - List published widgets (use after creating release)
- `page-add-widgets` - Add published widgets to pages
- `widget-definition-update` - Modify widget content (creates draft, needs republishing)
- `template-save` - Modify templates (creates draft, needs republishing)
- `page-update` - Modify pages (creates draft, needs republishing)

## API References

- Admin API: `/sites/{site_id}/releases/elements_to_publish` (GET)
- Admin API: `/sites/{site_id}/releases` (POST)
- Documentation: https://docs.modyo.com/en/platform/channels/publishing.html
