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

> ## Agent Instructions
> To act on a user's behalf in Guild, use the Guild REST API at https://api.guild.ai/v1.
> The OpenAPI spec is unauthenticated: https://docs.guild.ai/openapi.json (or openapi.yaml).
> Authenticate with an account API key, sent as HTTP Basic (key id as username, secret as password) or as `Authorization: Bearer <api_key_id>:<api_key_secret>`. See https://docs.guild.ai/api-reference/introduction#authentication.
> To run one agent on demand without account-wide access, use an API trigger instead: https://docs.guild.ai/platform/api-triggers.
> To search these docs from an MCP client, connect to https://docs.guild.ai/mcp. The full page index is https://docs.guild.ai/llms.txt.

# Publish from GitHub Actions

> Publish agents from your GitHub repository with the Publish Agent to Guild Action and an account API key, released manually or on every merge.

The [Publish Agent to Guild](https://github.com/marketplace/actions/publish-agent-to-guild) Action uploads an agent directory, validates it, and publishes a version. Your repository can be private. The workflow sends the files to Guild, so Guild never needs access to your GitHub repository.

The [v1.0.0 release](https://github.com/guildaidev/publish-agent-action/releases/tag/v1.0.0) installs Guild CLI 0.27.2. You don't need to clone the agent first, add a `guild.json` file, or create the agent in advance.

Start with one manual release, then switch to automatic releases if you want them. You can also [give the setup instructions to your coding agent](#set-up-with-a-coding-agent).

## Choose authentication

* **GitHub Actions:** use an account API key. The Action runs unattended, so it can't use browser OAuth or your local login. Don't copy a browser token into Actions secrets.
* **Local CLI:** use [`guild auth login`](/cli/commands/auth#login) to sign in through your browser. Commands run as your user, with your account permissions. See [Publish locally with browser login](#publish-locally-with-browser-login).

## Prepare your account

1. Create an [account API key](/platform/api-keys) in the Guild account that will own the agent. Give it **Agents: Read & write** (`agents:write`).
2. In your GitHub repository, open **Settings > Secrets and variables > Actions**. Add the full `<api_key_id>:<api_key_secret>` value as a repository secret named `GUILD_API_KEY`. Don't commit the key or paste it into a coding-agent conversation.
3. Choose a target in `owner~name` form, such as `myorg~hello`. The owner must match the key's Guild account.

<Warning>
  The key can write every agent in its account, not just this one. Give it only to trusted release workflows. Never expose it to untrusted pull-request code.
</Warning>

You need permission to add workflows and configure Actions secrets in the repository. Your GitHub organization must also allow the Action to run. If these controls are restricted, ask your repository owner. You don't need to install a GitHub App or authorize Guild to read the repository.

## Prepare one agent directory

Start with a package that matches its [agent type](/guide/agent-types). For a minimal [Goose agent](/guide/goose-agents), save this as `agents/hello/recipe.yaml`:

```yaml theme={null}
title: Hello
description: A minimal agent for your first release.
instructions: |
  Reply with a brief greeting. Do not request private information or use tools.
```

This recipe has no skill or integration dependencies. For your own package, check the [supported recipe fields](/guide/goose-agents#recipe-fields) and install any skills or integrations it needs first. If the package depends on private skills, the key also needs **Skills: Read**.

Other agent types must be enabled in your account and use that type's file format. The Action doesn't convert between formats.

Point `path` at the agent folder, not the whole monorepo. CLI 0.27.2 applies `.gitignore` rules from the repository root, parent folders, and nested folders. Local-only files such as `.env*`, `.npmrc`, `.guild`, `node_modules`, and `dist` are always excluded. Source files must be UTF-8. See [which files are saved](/cli/commands/agent#which-files-are-saved).

## Add a release workflow

Save this as `.github/workflows/publish-agent.yml`:

```yaml theme={null}
name: Publish agent
on:
  workflow_dispatch:
    inputs:
      version:
        description: New agent version
        required: true
        default: '1.0.0'
        type: string

permissions:
  contents: read

concurrency:
  group: guild-publish-myorg-hello
  cancel-in-progress: false

jobs:
  publish:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
        with:
          persist-credentials: false
      - name: Publish to Guild
        id: publish
        uses: guildaidev/publish-agent-action@v1.0.0
        with:
          path: agents/hello
          agent: myorg~hello
          version: ${{ inputs.version }}
          create-if-missing: 'true'
          agent-type: GOOSE
          overwrite: 'true'
        env:
          GUILD_API_KEY: ${{ secrets.GUILD_API_KEY }}
```

Then adjust it for your repository:

* Replace `myorg~hello` with your target, and `agents/hello` with your agent directory.
* If your default branch isn't `main`, change the branch condition.
* Merge the workflow onto your default branch. **Run workflow** appears only after the merge.

Every run publishes a version. There's no dry run.

The concurrency group stops two releases to the same target from overlapping. Give each target its own group. Reuse that group in any other workflow in the repository that publishes the same agent.

To pin the Action to an immutable commit, replace `@v1.0.0` with `@d5f1dc7abe6bab172653d1ab16f4d5f68ea54e0c`. The Action doesn't install newer CLI versions on its own. Review Action upgrades in a pull request.

`create-if-missing` lets the Action create the target as a **private** agent if it doesn't exist. If the target exists, its type must match `agent-type`. Double-check the target name before you run the workflow.

<Warning>
  With `overwrite: 'true'`, your repository's files replace any edits made in the Guild editor. Set it only when the repository is your source of truth. If you omit it, a conflicting save stops so you can review it.

  `overwrite` never replaces a version that's already published. It also never changes the agent's visibility.
</Warning>

## Release and verify

1. Open **Actions > Publish agent > Run workflow**. Select `main` and enter a version. Use `1.0.0` for a new target. For an existing target, use a version higher than its latest published one.
2. Wait for the job to succeed. In Guild, find your agent and confirm the published version. A new target is private. An existing target keeps its visibility.
3. Change the greeting instruction in a pull request and merge it. Run the workflow again with the next version, such as `1.0.1`.
4. Confirm that the agent now has the new published version.

The Action returns `agent-id`, `version-id`, and `version` as step outputs. For example, a later step can read `steps.publish.outputs.version-id`.

If validation fails, the workflow fails and the previously published version stays in place. A failed first release can leave an unpublished private agent behind for you to inspect.

Publishing doesn't create a workspace or start a session. To check how the agent behaves, [add it to a test workspace](/platform/agents) and run it. Each workspace's autoupdate setting decides whether its installation picks up the new version.

## Choose automatic release timing

To release on every merge, replace the manual trigger with a push trigger on your default branch:

```yaml theme={null}
on:
  push:
    branches: [main]
    paths: ['agents/hello/**', '.github/workflows/publish-agent.yml']
```

A push has no inputs, so the version must come from somewhere else. You have two options:

* **Explicit version (recommended):** replace `version: ${{ inputs.version }}` with a value in source, such as `version: '1.0.2'`. Increase it in each release pull request. Never reuse a published version number.
* **Automatic version:** omit the `version` input. TypeScript agents use the version in `package.json`. Agents without a `package.json`, such as Goose agents, get the next patch version, starting at `1.0.0`.

The Action doesn't edit or bump your source version. It also doesn't read a `VERSION` file. To use one, read it in an earlier step and pass its value as `version`.

Never pass the publishing key to untrusted pull-request code or a `pull_request_target` workflow. Validate pull requests in a separate workflow, and publish only after merge.

## Publish multiple agents

Each step publishes one directory to one agent. To release several agents, repeat the step with a different `path`, `agent`, and `version` for each. Use sequential steps when one agent depends on another, and a matrix for independent agents. If you use separate jobs, give each target its own concurrency group.

Include only the agents you intend to release, each with a new version. Republishing an unchanged agent at an existing version fails.

The Action doesn't discover packages or install dependencies between agents. Releases aren't atomic: if a later step fails, earlier publications stay published.

## Publish locally with browser login

You can publish the same directory from your terminal without GitHub Actions or an API key. [Install the CLI](/cli/introduction#install), version 0.27.2 or later, and prepare the agent directory. Then run:

```bash theme={null}
unset GUILD_API_KEY
guild auth login
guild auth status
guild agent save myorg~hello --path ./agents/hello \
  --create-if-missing --agent-type GOOSE \
  --version-number 1.0.0 --no-bump --publish
```

Replace `myorg~hello` with a target in an account where you can write agents. `GUILD_API_KEY` takes precedence over your browser login, so the first line clears it. If you're already signed in, skip `auth login`. Check the identity that `auth status` reports before you publish.

The command creates a missing private agent and publishes `1.0.0`. For an existing agent, use a version higher than its latest published one.

If the agent has edits from the Guild editor, the CLI asks before replacing them. Pass `--force` only when you want your local files to win. Local and Actions publishing use the same upload, validation, and publishing API.

## Set up with a coding agent

Copy this prompt into Claude Code, Codex, or another coding agent that has access to your repository. The agent prepares a workflow for you to review. It never asks for your key or publishes without your confirmation.

```text theme={null}
Help me publish agents from this repository to Guild using the official Action:
https://github.com/marketplace/actions/publish-agent-to-guild
Read the setup guide: https://docs.guild.ai/cli/github-actions

1. Inspect the repository and propose agent directories, types, and dependencies.
   Check Guild's supported package format. Report incompatibilities; do not
   silently remove unsupported recipe fields or change agent behavior.
2. Ask me to confirm the Guild owner~name target for each directory, whether
   missing targets may be created privately, and whether repository source may
   replace Guild editor changes. Ask whether releases should be manual or on merge.
3. Add a workflow using guildaidev/publish-agent-action@v1.0.0 with contents: read,
   checkout with persist-credentials: false, and the confirmed directory mapping.
   Use per-target concurrency with cancel-in-progress: false. Keep publishing off
   pull_request and pull_request_target; pass GUILD_API_KEY only to the publish step.
4. Tell me how to create an account key with Agents: Read & write and store it as
   the GUILD_API_KEY Actions secret. Never ask me to paste it here, read it back,
   print it, or commit it. Explain any extra dependency-read permissions needed.
5. Use an explicit version per target: 1.0.0 for a new agent, otherwise higher
   than the latest published version. Do not assume the Action reads VERSION files.
   For automatic releases, keep versions in source and explain where to bump them.
6. Validate the YAML and workflow, then show me the diff for approval. Do not
   merge, trigger a release, change visibility, or create a workspace without asking.
   After I authorize a test release, verify the resulting agent/version and report
   any validation errors. Publishing success does not prove runtime behavior.
```

## Troubleshoot a release

| Failure | What to check |
| - | - |
| Missing or rejected API key | Confirm the `GUILD_API_KEY` secret holds the full key, belongs to the target's account, and has `agents:write`. The Action doesn't use browser login. |
| Missing dependency | Install the required skill or integration, and grant the key read access to it. The Action doesn't provision dependencies. |
| Unsupported recipe field | Check the [supported Goose fields](/guide/goose-agents#recipe-fields). The Action doesn't rewrite your recipe or bypass Guild validation. |
| Version already published | Choose a new version. Retrying the same version fails. |
| Timeout or lost connection | Check the agent's versions in Guild before you retry. Publishing may have finished after the runner stopped waiting. |

If you stop releasing from the repository, delete the GitHub secret and [revoke the key](/platform/api-keys#revoke-a-key).

For other CI systems, run [`guild agent save` with an API key](/cli/commands/agent#save-from-your-own-repository). Publishing is one-way: changes made in Guild don't sync back to your repository.

## Related pages

* [`guild agent save`](/cli/commands/agent#save) for every save option, including `--create-if-missing` and `--agent-type`
* [Agent types](/guide/agent-types) for the package format each type expects
* [Goose agents](/guide/goose-agents), [OpenClaw agents](/guide/openclaw-agents), and [LangGraph agents](/guide/langgraph-agents) for bringing agents you've already built elsewhere into Guild
* [Versions](/guide/versions) for how drafts, published versions, and workspace updates work
* [API keys](/platform/api-keys) for creating, rotating, and revoking the publishing key
* [GitHub integration](/integrations/github) for giving your agents access to GitHub at runtime
