# Auto Publish on Merge
> Learn how to leverage Holistics Publish API to set up Auto Publish in CI/CD Workflow
## Introduction
If you connect your Holistics project to your own Git repository and make changes via a local IDE, this guide shows you how to automatically publish your Holistics project whenever changes are merged to the `master` branch.
:::info Choose your method
- **[GitHub Action](#option-1-github-action)**: Simple and straightforward integration with your Git workflow.
- **[Publish API](#option-2-publish-api)**: More customization and programmatic control over your publishing flow.
:::
## Prerequisites
To use our Publish API or GitHub Action, you need to set up the Holistics API first. See [Holistics API](/api) for setup instructions.
## Option 1: GitHub Action
We offer a [GitHub Action](https://github.com/holistics/publish-aml) that simplifies integrating the publishing process into your workflow.
Use the `holistics/publish-aml` action in your GitHub Action config:
```yaml
name: Publish AML
on:
push:
branches:
- master
pull_request:
branches:
- master
types:
- closed
jobs:
publish-aml:
if: github.event.pull_request.merged == true || github.event_name == 'push'
runs-on: ubuntu-latest
env:
HOLISTICS_API_KEY: ${{ secrets.HOLISTICS_API_KEY }}
HOLISTICS_HOST: "https://secure.holistics.io"
# https://eu.holistics.io
# https://us.holistics.io
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Publish AML
uses: holistics/publish-aml@v1.0
```
This GitHub Action uses the Publish API under the hood. See [Understanding the Response](#understanding-the-response) for interpreting the results.
## Option 2: Publish API
For programmatic control, use the Publish API directly. The flow involves two steps:
1. Submit a publish request and receive a Job ID.
2. Poll the Job API until the job completes.

See our [publish script example](https://github.com/holistics/deploy-aml/blob/master/src/index.ts) for a complete implementation.
### Submit publish request
:::info
POST `/api/v2/aml_studio/projects/submit_publish`
:::
Make sure to include the required headers:
```bash
curl -X POST "/api/v2/aml_studio/projects/submit_publish" \
-H "X-Holistics-Key: " \
-H "Content-Type: application/json"
```
This API triggers the publishing process at the **latest commit** on your **`master` branch** (the default production branch in Holistics) and returns a Job.
```json
{
"job": {
"id": 123456789,
"status": "created"
"existing_job_id": null
},
"data": null
}
```
[_See API doc_](/api/v2/reference/aml-studio-projects-submit-deploy)
### Poll for job completion
Retrieve the publishing results via the Job API. Keep polling until the job finishes.
:::info
GET `/api/v2/jobs//result`
:::
[_See API doc_](/api/v2/reference/jobs-get-result)
We recommend polling every **5 seconds** with a timeout (e.g., 30 attempts). Complex publishes can take over a minute.
While the job is running:
```json
{
"status": "running"
}
```
Once complete, the response contains the full publishing result (see below).
## Understanding the response
Both the GitHub Action and Publish API return the same response structure.
### Success
The publishing process completed successfully. Go to the Reporting page to see your latest changes.
example
```json
{
"status": "success", // job status
"error": null,
"result": {
// result of the publishing process
"type": "Publish",
"data": {
"status": "success", // publish status
"data": {
"preparing_production_job": {
"job_id": 1445236,
"status": "created"
},
"objects_status": [
{
"id": 27711,
"type": "Dashboard",
"uname": "ecommerce_dashboard",
"title": "Ecommerce",
"status": "updated"
}
]
},
"target_commit": "78ad9632735f8be605d71f6da4ccc762dc501efa"
}
}
}
```
- `object_status`: Objects updated or created in this publishing process. Currently, Holistics only supports status for Canvas Dashboards.
- `target_commit`: The commit version of this publish.
### Error: Syntax error
There is a syntax error in your project. Correct it and try publishing again.
example
```json
{
"status": "success", // job status
"error": null,
"result": {
// result of the publishing process
"type": "Publish",
"data": {
"status": "error", // publish status
"error_type": "syntax_error",
"error_details": {
"diagnostics": [
{
"category": "Error",
"code": 1000,
"message": "Unexpected ';'",
"filePath": "/ecommerce_dashboard.page.aml", // file path contain the error
"start": 1469, // offset of the error in the code
"end": 1470 // offset of the error in the code
}
]
},
"target_commit": "0bf1e7421b78eea7d9ce4ac9d07db9584e5c5d76"
}
}
}
```
### Error: Dashboard mapping
This error occurs when attempting to delete a Dashboard with dependencies (such as Shareable Links or Embedded Analytics). Review the code or remove the Dashboard's dependencies before proceeding.
example
```json
{
"status": "success", // job status
"error": null,
"result": {
// result of the publishing process
"type": "Publish",
"data": {
"status": "error", // publish status
"error_type": "dashboard_mapping",
"error_details": {
"dependants": [
{
"type": "Dashboard",
"id": 27711,
"uname": "ecommerce_dashboard", // the dashboard that is being deleted
"title": "Ecommerce",
"dependencies": [
{
"type": "ShareableLink",
"id": 27700
}
]
}
],
"message": "Failed to delete objects with dependencies"
},
"target_commit": "8ca2bad5fb0e7a9f1c37e92b42f29ddcf5c022d3"
}
}
}
```
### Error: Dataset mapping
This error occurs when attempting to delete a dataset that is currently in use by a Report or Dashboard. Review the code or perform Dataset Mapping to proceed.
example
```json
{
"status": "success", // job status
"error": null,
"result": {
// result of the publishing process
"type": "Publish",
"data": {
"status": "error", // publish status
"error_type": "dataset_mapping",
"error_details": {
"message": "Failed to Publish: Need to map production dataset to publising dataset",
"is_orphaned": true,
"orphaned_dataset": [
{
"id": 27678,
"uname": "ecommerce", // being deleted dataset
"title": "Ecommerce Dataset",
"reports": [
// this dataset is being consumed in some reports
{
"id": 28943,
"title": "Email"
}
]
}
],
"publishing_datasets": [
// list of publishing dataset
"ecommerce_rename"
]
},
"target_commit": "c3901ea88f86c7293bced31452a88e19a22b8731"
}
}
}
```
To perform Dataset Mapping, use:
- [Reporting Validation](/docs/development/reporting-validation#to-fix-an-already-broken-reporting-item)
- [Dataset Mapping UI](/docs/development/reporting-validation#to-fix-an-already-broken-reporting-item) in Holistics App
### Other errors
Error in Dashboard
```json
{
"status": "failure",
"error": "Dashboard \"ecommerce_dashboard\": Block \"v1\": Field !fields[0]: Referencing to an invalid field (email_error) of data model ecommerce_users in dataset ecommerce",
"result": {
"type": "Publish",
"data": null
}
}
```