> ## Documentation Index
> Fetch the complete documentation index at: https://agno-v2-docs-whatsapp-interface-documentation.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD Automation

> Automate builds with GitHub Actions

## Choose Your Method

| Method             | When to Use                      | Setup Effort |
| ------------------ | -------------------------------- | ------------ |
| Manual builds      | Small teams, infrequent deploys  | Low          |
| DockerHub + GitHub | Using DockerHub, simpler setup   | Medium       |
| ECR + GitHub OIDC  | Using ECR, no stored credentials | Higher       |

<Note>
  For manual builds, see [Deploy - AWS
  Setup](/deploy/templates/aws/deploy#step-1-aws-setup). ECR
  tokens expire after 12 hours.
</Note>

## PR Validation

Every PR runs automatic validation. The workflow is in `.github/workflows/validate.yml`:

```yaml theme={null}
# Runs on every PR
on:
  pull_request:
```

This checks formatting, tests, and types before merging.

<img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/validate-cicd.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=e34d7b675a23f5a64aa36940b1194f27" alt="PR validation workflow" width="940" height="353" data-path="images/validate-cicd.png" />

## DockerHub with GitHub

Build and push images on GitHub release. Workflow: `.github/workflows/docker-images.yml`

<Steps>
  <Step title="Create Docker Access Token">
    Go to [Docker Hub Settings → Security](https://hub.docker.com/settings/security) and create an access token.

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/docker-access-token.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=52ec228400a5a4c6855b9fd0351b8eff" alt="Docker Hub access token" width="742" height="568" data-path="images/docker-access-token.png" />
  </Step>

  <Step title="Add GitHub Secrets">
    In your GitHub repo, go to **Settings → Secrets and variables → Actions**.

    Add these secrets:

    | Name                 | Value                        |
    | -------------------- | ---------------------------- |
    | `DOCKERHUB_USERNAME` | Your Docker Hub username     |
    | `DOCKERHUB_TOKEN`    | The access token from Step 1 |

    Add this variable:

    | Name                  | Value                                             |
    | --------------------- | ------------------------------------------------- |
    | `DOCKERHUB_NAMESPACE` | Your Docker Hub namespace (usually your username) |

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-actions-docker-secrets.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=5bb3f9f4149d161654d8049dee0c96fa" alt="GitHub Actions secrets configuration" width="1143" height="822" data-path="images/github-actions-docker-secrets.png" />
  </Step>

  <Step title="Trigger a Release">
    ```bash theme={null}
    gh release create v0.1.0 --title "v0.1.0" -n ""
    ```

    The workflow builds and pushes `your-namespace/agentos-template:dev` and `:prd` tags.

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-actions-build-docker.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=967dde13f5d10d0215bc646a08fab0ca" alt="GitHub Actions Docker build workflow" width="1042" height="732" data-path="images/github-actions-build-docker.png" />
  </Step>
</Steps>

## ECR with GitHub OIDC

Build and push to ECR using OpenID Connect. No IAM access keys stored in GitHub.

Workflow: `.github/workflows/ecr-images.yml`

### Set Up OIDC Provider

<Steps>
  <Step title="Add OIDC Identity Provider">
    1. Open IAM Console → **Identity providers** → **Add provider**
    2. Provider type: **OpenID Connect**
    3. Provider URL: `https://token.actions.githubusercontent.com`
    4. Click **Get thumbprint**
    5. Audience: `sts.amazonaws.com`

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-oidc-provider.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=96711da8349d51edc739f3c213f9a8a3" alt="AWS IAM OIDC Provider configuration" width="1125" height="799" data-path="images/github-oidc-provider.png" />
  </Step>

  <Step title="Create IAM Role">
    1. After adding the provider, click **Assign role** → **Create a new role**

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-oidc-provider-assign-role.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=375f1a405695604b3a79b46da42fe896" alt="Assign role to OIDC provider" width="1347" height="587" data-path="images/github-oidc-provider-assign-role.png" />

    2. Select **Create a new role**

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-oidc-provider-create-new-role.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=5b672a508653121e1346021e2d5f1a18" alt="Create new IAM role" width="604" height="278" data-path="images/github-oidc-provider-create-new-role.png" />

    3. Confirm **Web identity** is selected as trusted entity, Identity provider shows GitHub, and Audience is `sts.amazonaws.com`

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-oidc-provider-trusted-entity.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=d3e690096e12096d7af31b5b8951e9ef" alt="Configure trusted entity" width="1300" height="934" data-path="images/github-oidc-provider-trusted-entity.png" />

    4. Add permission: `AmazonEC2ContainerRegistryPowerUser`
    5. Role name: `GithubActionsRole`
    6. Copy the Role ARN (format: `arn:aws:iam::[ACCOUNT_ID]:role/GithubActionsRole`)

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-oidc-role.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=1ac541cb1e85c2cb8667e34dd771d8dd" alt="GitHub Actions IAM Role" width="1389" height="710" data-path="images/github-oidc-role.png" />
  </Step>

  <Step title="Update Workflow File">
    Edit `.github/workflows/ecr-images.yml`:

    ```yaml theme={null}
    env:
      ECR_REPO: [ACCOUNT_ID].dkr.ecr.us-east-1.amazonaws.com
      AWS_ROLE: arn:aws:iam::[ACCOUNT_ID]:role/GithubActionsRole
      AWS_REGION: us-east-1
    ```
  </Step>

  <Step title="Change Trigger to Release">
    The workflow defaults to `workflow_dispatch` (manual trigger). To trigger on release:

    ```yaml theme={null}
    on:
      release:
        types: [published]
    ```

    If using ECR, disable the DockerHub workflow by changing its trigger:

    ```yaml theme={null}
    # In docker-images.yml
    on: workflow_dispatch
    ```
  </Step>

  <Step title="Trigger Build">
    ```bash theme={null}
    gh release create v0.1.0 --title "v0.1.0" -n ""
    ```

    Or trigger manually:

    ```bash theme={null}
    gh workflow run ecr-images.yml
    ```

    <img src="https://mintcdn.com/agno-v2-docs-whatsapp-interface-documentation/P2C2FvFdUFM-bIli/images/github-actions-build-ecr.png?fit=max&auto=format&n=P2C2FvFdUFM-bIli&q=85&s=ce695172e2ebb7bdfd08369a0527db19" alt="GitHub Actions ECR build workflow" width="1389" height="710" data-path="images/github-actions-build-ecr.png" />
  </Step>
</Steps>

<Note>
  **Why OIDC?** GitHub Actions requests a temporary token from AWS instead of
  using stored credentials. More secure, no credential rotation needed.
</Note>

## After CI/CD Builds

After a new image is pushed, update your ECS deployment:

<CodeGroup>
  ```bash Full Options theme={null}
  ag infra patch --env prd --infra aws --name service
  ```

  ```bash Shorthand theme={null}
  ag infra patch prd:aws::service
  ```
</CodeGroup>

This triggers a new deployment with the latest image.
