> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eigenpal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflow promotion

> Release workflows between installations through GitHub or GitLab.

Each environment runs a separate EigenPal installation. Git shares released workflow definitions and version pointers; a shared artifact store carries dataset files. Credentials and access policies stay local.

## Connect environments

Use the same ordered list in each installation, selecting its own `environment`. The first environment allows authoring; later ones receive releases.

```yaml theme={null}
promotion:
  enabled: true
  environment: acceptance
  environments:
    - name: authoring
      label: Authoring
      approvers: workflow authors
      url: https://authoring.example.internal
    - name: acceptance
      label: Acceptance
      approvers: technical reviewers
      url: https://acceptance.example.internal
  git:
    provider: github
    repository: company/workflow-releases
    branch: main
    tokenSecret:
      existingSecret: eigenpal-promotion
      key: token
  artifactStore:
    s3:
      bucket: eigenpal-release-artifacts
      region: eu-central-1
  pullSchedule: '*/15 * * * *'
```

Configure a GitHub or GitLab credential and branch approval rules. Every installation must reach the Git host and artifact store. Required file-source names must exist in each environment with local credentials.

## Release a workflow

Save a numbered workflow version in the first environment, add a note, and start a release. The receiving environment validates a candidate with its own connections. After approval and merge, it activates that version and opens the next environment's request.

The UI shows the version desired and actually live in each environment, plus any reason promotion has paused.

## Variables across environments

[Variables](https://docs.eigenpal.com/concepts/variables.md) (`{{ env.NAME }}`) keep their values in each
environment; only names and types travel with a release.

Environments never read each other's database. On each pull, every
environment publishes to the environments repository which variables it
defines, by name, type and workflow id (never values). The first environment
reads those reports:

* **Before releasing**, its Variables page shows, per variable, whether each
  later environment defines it, and Release refuses to start into an
  environment that lacks one or defines it with another type.
* **Define in SIT** (for each gap, when the environment's `url` is set in the
  promotion config) opens that environment's Variables page with the form
  filled in: name, type, and the workflows it applies to. An owner or admin
  there types the value, which never goes in the link. A workflow's variable
  can be defined there before the workflow's first release arrives, since
  workflows keep their ids across environments. If that environment already
  shares a variable of that name between workflows, the link adds the
  workflow to it instead of making a copy.
* The next pull there reports the new variable, and Release goes ahead.
* **In the receiving environment**, a version that still needs a variable it
  does not define (one defined after the report, or removed since) waits. Its
  Variables page lists what each waiting release needs, with a Define button,
  and the next pull takes the release.
* Release format 5 adds variables. Upgrade every environment before the next
  release; versions released under format 4 still read.

## Integration details

> [accordion] Git permissions and approvals
>
> GitHub credentials need contents, pull requests, statuses and deployments read/write, plus administration read for branch rules. GitHub App authentication uses `promotion.git.app`.
>
> For GitLab, set `provider: gitlab`, the full project path and `apiUrl` for a self-managed server. Use a project-scoped API credential with the required project role. GitLab report storage also needs a protected reporting branch; the installation setup check verifies it.
>
> The `approvers` label is display text. Enforce approvals through Git-host rules. Automatic merging requires readable rules that prevent relevant authors from approving their own changes; otherwise reviewers merge in Git.

> [accordion] Repository structure
>
> * `workflows/<name>/<version>/` stores immutable released definitions and manifests. Ordinary development saves stay in the local database.
> * `environments/<environment>/<workflow>.yaml` pins the desired version.
> * `rollouts/<workflow>.yaml` records release intent, requester, note and start time. Git history and promotion requests retain earlier changes and approvals.
>
> Missing or invalid rollout intent pauses continuation. Closed requests stay closed until reopened or replaced by a new release. A filesystem artifact store must refer to genuinely shared storage across installations.

> [accordion] Repository callbacks and polling
>
> Later environments poll every 15 minutes by default. For faster reconciliation, enable callbacks:
>
> ```yaml theme={null}
> promotion:
>   notifications:
>     enabled: true
>     secret:
>       existingSecret: eigenpal-promotion-notifications
>       key: secret
> ```
>
> Configure the repository to call `https://<receiving-host>/api/webhooks/promotion` with the same random secret of at least 32 characters. Configure each receiving installation separately and keep TLS verification enabled.
>
> Use GitHub push, pull request and pull request review events, or GitLab push and merge request events. GitHub signs the request body with HMAC; GitLab supplies `X-Gitlab-Token`.
>
> Verified deliveries enter a durable queue with deduplication and retries. Polling recovers missed events. Callbacks trigger reconciliation; Git approvals still control deployment.

See the [Helm fields](https://docs.eigenpal.com/self-hosting/helm-values.md#promotion) for Secret references and the [YAML fields](https://docs.eigenpal.com/self-hosting/yaml-reference.md#promotion) for direct configuration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.