# Set up Omnihorn with an AI agent

Source: https://omnihorn.com/docs/ai · Updated 2026-10-19

You are an AI coding agent. Your job: connect this repository to Omnihorn so that every push uploads a signed, versioned build that installed copies of the app pick up. Two things only the human can do, signing in and creating the API key, come first. Everything else is yours.

## Before you start

> **Stop and ask the human for these two things:** You cannot sign up (Omnihorn uses a one-time email link) and you cannot create an API key (keys are created in the dashboard). Ask the human to: (1) sign in at /login and create an app with **New app**; (2) open that app’s **CI/CD** tab, choose **Create key**, and give you the key as the environment variable `OMNIHORN_API_KEY`. Do not continue until you have it.

- Never print the key, never write it to a file, never commit it. It goes only into a CI secret.
- Windows is the only shipped target. If the repository builds for macOS or Linux only, tell the human and stop.
- Only do what is listed. Do not invent Omnihorn features or flags.

> **Status of the GitHub Action:** The GitHub Action is published at github.com/Ivorn-Technologies/upload-build. Pin it to the major version (`@v1`).

## The steps

1. **Find the Windows build output** — Identify the framework and the command that produces the Windows app. The upload is the **folder** that runs on a clean PC: the `.exe` plus its DLLs and data files. Use the table below as a starting point and confirm by reading the repository’s build scripts.
2. **Check the folder is complete** — Build it locally if you can. The folder must contain the executable and everything it loads at run time. A single `.exe` that needs a missing DLL will install but fail to start. Do not upload source code, `.pdb` files you do not need, or secrets.
3. **Choose how releases will be uploaded** — If the repository uses GitHub Actions, write a workflow (next step). For GitLab or another CI, follow the CI/CD guide’s command-line section. If there is no CI, tell the human to drag the folder into the dashboard (**Builds**, **New build**) and stop here.
4. **Write the workflow** — Create `.github/workflows/release.yml` from the template below. Replace the build step with the real build command and set `path` to the output folder. Always keep the `branches:` filter.
5. **Store the key as a repository secret** — Run `gh secret set OMNIHORN_API_KEY` and paste the key when prompted (or ask the human to do it under Settings, Secrets and variables, Actions). Confirm with `gh secret list`. Do not echo the key.
6. **Commit on a branch and push** — Commit only the workflow and any build-script changes. Push to a branch that the workflow’s `branches:` filter matches. Open the run and read the job summary: it lists the version, the branch and what happened to the channels.
7. **Verify the build is active** — The job must finish with status `active`. If it fails, use the troubleshooting guide, fix the cause, and run again. Do not retry blindly more than twice.
8. **Hand back to the human** — Give the human the checklist at the end of this page. Two things remain for them: confirm which channel ships to users, and press **Build installer** on the app’s Installer tab (installers are built on request, not on every upload).

## Where common frameworks put the Windows output

| Stack | Typical command | Typical folder to upload |
| --- | --- | --- |
| Electron (electron-builder) | `npx electron-builder --win dir` | `dist/win-unpacked` |
| .NET (WPF, WinForms, WinUI) | `dotnet publish -c Release -r win-x64 --self-contained` | `bin/Release/<tfm>/win-x64/publish` |
| Flutter | `flutter build windows --release` | `build/windows/x64/runner/Release` |
| Qt | `windeployqt` next to the built `.exe` | The folder `windeployqt` filled |
| Tauri | `npm run tauri build` | The folder holding the built `.exe` and its resources |
| Go, Rust, C++ | Your release build | A folder with the `.exe` and any DLLs or data it needs |

> **Tip:** These are common defaults, not guarantees. Trust the repository’s own scripts over this table, and prefer a folder over an installer file: Omnihorn builds the installer for you.

## Workflow template

**.github/workflows/release.yml**

```yaml
name: "Release"

on:
  push:
    branches: [main, 'release/**']

jobs:
  release:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      # Replace with the repository's real build; its output must end up in ./dist
      - name: Build
        run: echo "Replace this step with your build command"

      - uses: Ivorn-Technologies/upload-build@v1
        with:
          api-key: ${{ secrets.OMNIHORN_API_KEY }}
          path: ./dist
          # Optional: also assign the build to an existing channel once it is active.
          # channel: production
```

Version: by default Omnihorn reuses the last base version and appends its own build counter (`1.4.0+build.42`). To set it from a tag, see the [CI/CD guide](/docs/ci-cd).

## Report back with this checklist

1. Which folder is uploaded, and the command that produces it.
2. The workflow file path, and that `OMNIHORN_API_KEY` exists as a repository secret (name only, never the value).
3. The run URL and the build’s version and status from the job summary.
4. What the human still has to do: confirm the shipping channel (**Channels** tab, `production` by default) and press **Build installer** (**Installer** tab).

## If it fails

| You see | Do this |
| --- | --- |
| `The API key was refused` | The secret is empty, mistyped or revoked. Ask the human for a new key and update the secret. |
| `Storage limit reached` | The plan’s storage is full. Tell the human; they can delete old builds or upgrade. |
| Fork or Dependabot run skipped | Expected: those runs get no secrets and are skipped with a notice. |
| Build stuck on processing | Large builds take longer to verify. Wait; check the app’s **Builds** tab. |

More cases are in [Troubleshooting](/docs/troubleshooting). Humans who prefer to read the full story can start at the [quickstart](/docs/getting-started).

**Can an AI agent create the Omnihorn account and API key itself?**

No. Sign-in is a one-time link sent to the human’s email, and API keys are created by a signed-in user in the dashboard. The agent asks the human for the key and does the rest.

**Does the agent build the Windows installer?**

No. The agent uploads the app’s build. The installer is built on request from the app’s Installer tab, which the human triggers once.

## The prompt a human gives you

```text
Set up Omnihorn releases for this repository.

Follow the runbook at https://omnihorn.com/docs/ai.md step by step. Do not skip its stop-and-ask points.
The Omnihorn API key is in the environment variable OMNIHORN_API_KEY. If it is not set, ask me for it; never write it into a file or a commit.
When you finish, give me the checklist from the last step of the runbook.
```
