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

# Anaconda GitHub Actions

Use Anaconda's [GitHub Actions](https://github.com/anaconda/actions) to install tools and publish packages in CI/CD workflows.

The examples install the latest Anaconda CLI. The GitHub Actions themselves are pinned to `v0.3.1` for reproducibility; action versions are independent of CLI versions.

## setup-anaconda-cli

Install the [Anaconda CLI](https://anaconda.com/docs/cli-reference/anaconda-cli/getting-started.md) on your runner for use in subsequent workflow steps. The action skips bootstrap. On a fresh runner, install ana first, authenticate, and then install any companion tools you need.

### Setup usage example

```yaml theme={null}
- uses: anaconda/actions/setup-anaconda-cli@v0.3.1
  with:
    version: latest
- name: Authenticate Anaconda CLI
  shell: bash
  env:
    ANACONDA_API_KEY: ${{ secrets.ANACONDA_API_KEY }}
  run: printf '%s\n' "$ANACONDA_API_KEY" | ana login --force -
- name: Install companion tools
  shell: bash
  run: |
    ana tool install anaconda-cli
    ana tool install pixi
```

Store an anaconda.com API key as the `ANACONDA_API_KEY` secret. This logs ana in so it can install tools. Use a separate registry token to upload packages. If you only need to install ana, omit the login and companion-tool steps until you need them.

### Setup inputs

Input

Description

Default

`version`

CLI release tag to install, or `latest` to use the installer's default version

`latest`

`tools`

Space- or comma-separated list of [available managed tools](https://anaconda.com/docs/cli-reference/anaconda-cli/tools.md#available-managed-tools) to install; requires existing ana credentials on the runner. On a fresh runner, leave this empty and install tools after login as shown above.

None

### Outputs

Output

Description

`version`

Installed CLI version (see note below)

> [!NOTE]
>
> The current action can return an empty `version` output. To check the installed version, run `ana --version` in a later step instead.

### Platform support

The setup action supports Linux, macOS, and Windows runners with Bash and curl available. Choose a runner architecture supported by the [CLI release](https://anaconda.com/docs/cli-reference/anaconda-cli/getting-started.md).

## upload-package

Upload conda or Python packages to Anaconda.org or Package Security Manager (PSM). The `target-type` input selects the registry.

Complete the [setup sequence](#setup-usage-example) first to use the latest CLI and install the companion tools. The upload action skips tool installation when `ana` is already on `PATH`; without a prior setup step, it uses its own bundled CLI version instead of selecting the latest release.

Use a Linux runner for the upload examples. The upload action's Anaconda.org support is not Windows-compatible.

### Upload usage examples

Add one of these upload steps after the setup, login, and companion-tool installation steps above.

> [tab] Anaconda.org
>
> Upload a conda package to your Anaconda.org organization:
>
> ```yaml theme={null}
> - uses: anaconda/actions/upload-package@v0.3.1
>   with:
>     token: ${{ secrets.ANACONDA_ORG_TOKEN }}
>     channel: <ORG_NAME>
>     packages: ./build/noarch/*.conda
> ```
>
> Comments
>
> Replace \<ORG\_NAME> with your Anaconda.org username or organization name.
>
> Upload a Python wheel as a private package with labels:
>
> ```yaml theme={null}
> - uses: anaconda/actions/upload-package@v0.3.1
>   with:
>     token: ${{ secrets.ANACONDA_ORG_TOKEN }}
>     channel: <ORG_NAME>
>     packages: ./dist/*.whl
>     private: true
>     labels: main,dev
> ```
>
> Comments
>
> Replace \<ORG\_NAME> with your Anaconda.org username or organization name.

> [tab] Package Security Manager
>
> Upload a conda package to Package Security Manager:
>
> ```yaml theme={null}
> - uses: anaconda/actions/upload-package@v0.3.1
>   with:
>     token: ${{ secrets.PSM_TOKEN }}
>     channel: <CHANNEL_NAME>
>     packages: ./build/noarch/*.conda
>     target-type: psm
>     repository-url: https://<PSM_HOST>/api/repo
> ```
>
> Comments
>
> Replace \<CHANNEL\_NAME> with your PSM channel name.\\
>
> Replace \<PSM\_HOST> with the hostname of your PSM instance.
>
> > [!NOTE]
> >
> > Your GitHub Actions runner must have network access to your PSM instance.

### Authentication

The `upload-package` action requires an API token for the registry you're publishing to. Generate a token for your target registry, then store it as a [GitHub Actions secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) in your repository or organization settings.

* **Anaconda.org**: [Generate a token](https://anaconda.com/docs/anaconda-org/admin-guide/tokens.md) with the `api:write` scope.
* **Package Security Manager**: [Generate a token](https://anaconda.com/docs/psm-on-prem/6.8.0/user/auth_token.md) with **Write** permissions for your target channel.

### Upload inputs

Input

Description

Default

`token`

Required API token for authentication

None

`packages`

Required Path or glob pattern to package files (for example, `./build/noarch/*.conda`)

None

`channel`

Required Channel to publish your package to, unless the deprecated `owner` input is set \
\[!TIP] For Anaconda.org, this is your username or organization name.

None

`target-type`

`anaconda.org` or `psm`

`anaconda.org`

`repository-url`

Repository URL (required for `psm` target)

None

`package-type`

`conda` or `pypi` (auto-detected from file extension if omitted)

None

`verbose`

Enable verbose output

`false`

The following inputs apply only when `target-type` is `anaconda.org`:

Input

Description

Default

`summary`

Package summary

None

`private`

Make the package private

`false`

`labels`

Comma-separated labels (for example, `main,dev`)

None

`force`

Overwrite existing packages (not forwarded to PSM)

`false`

`disable-new-cli`

Stop forcing the new `anaconda-client` parser

`false`

For existing workflows, `owner` is a deprecated alias for `channel`, and `target-type: repository` is a deprecated alias for `psm`. Use `channel` and `psm` in new workflows. If both `channel` and `owner` are set, `channel` takes precedence.

> [!NOTE]
>
> Summaries containing spaces do not work correctly with action v0.3.1. Omit the `summary` input and set the summary in your package metadata instead.

## Full workflow example

This workflow builds a conda package on push to a version tag and publishes it to Anaconda.org. It assumes your repository contains a noarch recipe in `recipe/` that produces a `.conda` package:

```yaml expandable theme={null}
name: Build and publish

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Miniconda
        uses: conda-incubator/setup-miniconda@v3
        with:
          channels: defaults

      - name: Build conda package
        shell: bash -el {0}
        run: |
          conda install --yes conda-build
          conda build recipe --output-folder ./build

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: conda-package
          path: ./build/noarch/*.conda

  publish:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: conda-package
          path: ./dist

      - name: Set up Anaconda CLI
        uses: anaconda/actions/setup-anaconda-cli@v0.3.1
        with:
          version: latest

      - name: Authenticate Anaconda CLI
        shell: bash
        env:
          ANACONDA_API_KEY: ${{ secrets.ANACONDA_API_KEY }}
        run: printf '%s\n' "$ANACONDA_API_KEY" | ana login --force -

      - name: Install companion tools
        shell: bash
        run: |
          ana tool install anaconda-cli
          ana tool install pixi

      - name: Publish to Anaconda.org
        uses: anaconda/actions/upload-package@v0.3.1
        with:
          token: ${{ secrets.ANACONDA_ORG_TOKEN }}
          channel: <ORG_NAME>
          packages: ./dist/*.conda
```

Comments

Replace \<ORG\_NAME> with your Anaconda.org username or organization name.

## Migrating from existing workflows

If you're currently using CLI commands directly in your workflows, you can replace them with the `upload-package` action. Run the [setup sequence](#setup-usage-example) before the replacement upload step so it uses the latest CLI:

> [tab] Anaconda.org
>
> **Before:**
>
> ```yaml theme={null}
> - name: Install anaconda-client
>   run: conda install --yes anaconda-client
> - name: Upload
>   env:
>     ANACONDA_API_TOKEN: ${{ secrets.TOKEN }}
>   run: |
>     anaconda --token "$ANACONDA_API_TOKEN" upload \
>       --user <ORG_NAME> \
>       --private \
>       ./build/*.conda
> ```
>
> Comments
>
> Replace \<ORG\_NAME> with your Anaconda.org username or organization name.
>
> **After:**
>
> ```yaml theme={null}
> - uses: anaconda/actions/upload-package@v0.3.1
>   with:
>     token: ${{ secrets.TOKEN }}
>     channel: <ORG_NAME>
>     packages: ./build/*.conda
>     private: true
> ```
>
> Comments
>
> Replace \<ORG\_NAME> with your Anaconda.org username or organization name.

> [tab] Package Security Manager
>
> **Before:**
>
> ```yaml theme={null}
> - name: Install conda-repo-cli
>   run: conda install --yes conda-repo-cli
> - name: Upload
>   env:
>     PSM_TOKEN: ${{ secrets.TOKEN }}
>   run: |
>     conda repo config --set sites.mysite.url https://<PSM_HOST>/api/repo
>     conda repo --token "$PSM_TOKEN" --site mysite upload \
>       --channel <CHANNEL_NAME> \
>       --package-type conda \
>       ./build/*.conda
> ```
>
> Comments
>
> Replace \<PSM\_HOST> with the hostname of your PSM instance.\\
>
> Replace \<CHANNEL\_NAME> with your PSM channel name.
>
> **After:**
>
> ```yaml theme={null}
> - uses: anaconda/actions/upload-package@v0.3.1
>   with:
>     token: ${{ secrets.TOKEN }}
>     channel: <CHANNEL_NAME>
>     packages: ./build/*.conda
>     target-type: psm
>     repository-url: https://<PSM_HOST>/api/repo
> ```
>
> Comments
>
> Replace \<CHANNEL\_NAME> with your PSM channel name.\\
>
> Replace \<PSM\_HOST> with the hostname of your PSM instance.

## Release history

For action versions and changes, see the [GitHub Actions releases](https://github.com/anaconda/actions/releases). For the implementation documented here, see the [setup action source](https://github.com/anaconda/actions/blob/v0.3.1/setup-anaconda-cli/action.yml) and [upload action source](https://github.com/anaconda/actions/blob/v0.3.1/upload-package/action.yml).
