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

# CI/CD

> Deploy Edge Compute functions from CI: install a pinned CLI release, authenticate with an API key, and ship — working pipelines for GitHub Actions, GitLab CI, and CircleCI.

Every Edge Compute deployment from CI is the same three steps: install a pinned `telnyx-edge` binary, authenticate with `auth api-key set`, and run `ship`. This page gives you those steps as working pipelines for GitHub Actions, GitLab CI, and CircleCI, plus the patterns for staging/production and rollback.

## The three steps every pipeline runs

```bash theme={null}
TELNYX_EDGE_VERSION=v0.2.3

# 1. Install — release assets are version-stamped and extract into a versioned directory
curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
sudo mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/

# 2. Authenticate — the CLI does NOT read $TELNYX_API_KEY from the environment
telnyx-edge auth api-key set "$TELNYX_API_KEY"

# 3. Deploy the function in the current directory (or --from-dir <path>)
telnyx-edge ship
```

Three facts these steps depend on:

* **The CLI ships as GitHub release binaries only** — it is not on npm and there is no package manager formula. There is also no un-versioned "latest" asset: `releases/latest/download/...` URLs return 404. Pin a version in a `TELNYX_EDGE_VERSION` variable so bumping is a one-line change. For arm64 runners, use the `linux-arm64` asset.
* **`telnyx-edge` does not read a `TELNYX_API_KEY` environment variable on its own.** Store your API key as a CI secret and run `telnyx-edge auth api-key set "$TELNYX_API_KEY"` as a pipeline step — it persists the key to `~/.telnyx-edge/config.toml` for the rest of the job.
* **`ship` has no environment flag.** It deploys the function identified by `func.toml` in the shipped directory, and its flags are `--from-dir` and `--timeout` only. Staging and production are [separate functions](#staging-and-production).

On success, `ship` prints the function's live URL (`https://{func-name}-{org-nickname}.telnyxcompute.com` — see [Routes & Domains](/docs/edge-compute/configuration/routing)). The URL is stable across deploys.

## GitHub Actions

A complete workflow that tests on every push and deploys on pushes to `main`. Only the install, authenticate, and ship steps are Telnyx-specific — the test job is ordinary `npm` and assumes a committed lockfile and a `test` script (the scaffold ships neither); substitute your project's own checks.

```yaml theme={null}
# .github/workflows/deploy.yml
name: Deploy Edge Function

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  TELNYX_EDGE_VERSION: v0.2.3

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install telnyx-edge
        run: |
          curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
          sudo mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/

      - name: Authenticate
        env:
          TELNYX_API_KEY: ${{ secrets.TELNYX_API_KEY }}
        run: telnyx-edge auth api-key set "$TELNYX_API_KEY"

      - name: Deploy
        run: telnyx-edge ship
```

Add the secret under **Settings → Secrets and variables → Actions → New repository secret**, named `TELNYX_API_KEY`.

## GitLab CI

```yaml theme={null}
# .gitlab-ci.yml
stages:
  - deploy

variables:
  TELNYX_EDGE_VERSION: v0.2.3

deploy:
  stage: deploy
  image: ubuntu:24.04
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  before_script:
    - apt-get update -qq && apt-get install -y -qq curl ca-certificates
    - curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
    - mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/
    - telnyx-edge auth api-key set "$TELNYX_API_KEY"
  script:
    - telnyx-edge ship
```

Define `TELNYX_API_KEY` as a **masked** variable under **Settings → CI/CD → Variables**. The `ubuntu:24.04` image runs as root, so no `sudo` is needed.

## CircleCI

```yaml theme={null}
# .circleci/config.yml
version: 2.1

jobs:
  deploy:
    docker:
      - image: cimg/base:current
    environment:
      TELNYX_EDGE_VERSION: v0.2.3
    steps:
      - checkout
      - run:
          name: Install telnyx-edge
          command: |
            curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
            sudo mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/
      - run:
          name: Authenticate
          command: telnyx-edge auth api-key set "$TELNYX_API_KEY"
      - run:
          name: Deploy
          command: telnyx-edge ship

workflows:
  deploy:
    jobs:
      - deploy:
          filters:
            branches:
              only: main
```

Set `TELNYX_API_KEY` as a project environment variable (**Project Settings → Environment Variables**) or in a context.

## Staging and production

There is no `--env` flag and no environment promotion — `ship` always deploys the function that `func.toml` names. Environments are separate functions, e.g. `my-api-staging` and `my-api`, each with its own URL, secrets bindings, and revision history.

Register both once, locally (`new-func` creates the function server-side and writes its UUID `func_id` into that directory's `func.toml` — this is a one-time setup step, not a CI step):

```bash theme={null}
telnyx-edge new-func -l=ts -n=my-api-staging
telnyx-edge new-func -l=ts -n=my-api
```

Keep one codebase and both generated `func.toml` files in the repo; each pipeline job copies the matching one into place before shipping:

```
my-api/
├── index.ts
├── package.json
├── func.toml                 # production — func_id of my-api
└── deploy/
    └── func.staging.toml     # staging — func_id of my-api-staging
```

Because bindings are declared in `func.toml`, the two files can also point at per-environment resources — for example a separate [KV namespace](/docs/edge-compute/kv) id per environment.

```yaml theme={null}
# .github/workflows/deploy.yml — staging on main, production on v* tags
name: Deploy

on:
  push:
    branches: [main]
    tags: ['v*']

env:
  TELNYX_EDGE_VERSION: v0.2.3

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install telnyx-edge
        run: |
          curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
          sudo mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/
      - name: Authenticate
        env:
          TELNYX_API_KEY: ${{ secrets.TELNYX_API_KEY }}
        run: telnyx-edge auth api-key set "$TELNYX_API_KEY"
      - name: Ship the staging function
        run: |
          cp deploy/func.staging.toml func.toml
          telnyx-edge ship

  deploy-production:
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install telnyx-edge
        run: |
          curl -fsSL "https://github.com/team-telnyx/edge-compute/releases/download/${TELNYX_EDGE_VERSION}/telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64.tar.gz" | tar xz
          sudo mv "telnyx-edge-${TELNYX_EDGE_VERSION}-linux-amd64/telnyx-edge" /usr/local/bin/
      - name: Authenticate
        env:
          TELNYX_API_KEY: ${{ secrets.TELNYX_API_KEY }}
        run: telnyx-edge auth api-key set "$TELNYX_API_KEY"
      - name: Ship the production function
        run: telnyx-edge ship
```

If you prefer fully separate directories over the `func.toml` swap, keep one function directory per environment and ship each with `telnyx-edge ship --from-dir <path>`. If staging and production live in different Telnyx accounts, store one API key secret per account and reference the right one in each job.

## Rollback

Every successful `ship` produces an immutable revision. Rolling back retargets traffic to a previous revision instantly — no rebuild, no re-upload:

```bash theme={null}
# List recent revisions (newest first) with their ids
telnyx-edge revisions list my-api

# Retarget traffic to a previous revision
telnyx-edge rollback my-api a1b2c3d
```

Only revisions that reached `deploy_ok` can be rolled back to. You can wire these commands into a manually triggered pipeline job (e.g. `workflow_dispatch` on GitHub Actions), but they work just as well from a laptop — rollback does not need your source tree.

A `git revert` + re-ship also works, but it goes through a full build; `rollback` is the fast path.

## Smoke test after deploy

The function URL is stable, and the TypeScript/JavaScript scaffold answers `/health` with 200 — on other runtimes, point the check at a route your function serves. A post-deploy check is one step:

```yaml theme={null}
- name: Smoke test
  run: curl -fsS --retry 5 --retry-delay 2 --retry-all-errors https://my-api-<org-nickname>.telnyxcompute.com/health
```

If it fails, roll back with `telnyx-edge rollback` as above. There is no platform metrics or logs surface to poll — see [Observability](/docs/edge-compute/observability) for what your function should emit instead.

## CI secrets vs. function secrets

Two different things:

|                  | Where it lives                                                   | What it's for                                       |
| ---------------- | ---------------------------------------------------------------- | --------------------------------------------------- |
| `TELNYX_API_KEY` | Your CI platform's secret store                                  | Lets the pipeline run `auth api-key set` and `ship` |
| Function secrets | The Telnyx platform, via `telnyx-edge secrets add <key> <value>` | Values your function reads at runtime               |

Function secrets are not deployed from CI variables — manage them with the CLI (the arguments are positional). Values are injected into function containers at deploy time, so re-ship a function after changing a secret it uses. See [Secrets](/docs/edge-compute/configuration/secrets).

## Troubleshooting

| Symptom                                             | Fix                                                                                                                                                                        |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ship` fails with an authentication error           | The CLI does not pick up `$TELNYX_API_KEY` from the environment. Run `telnyx-edge auth api-key set "$TELNYX_API_KEY"` as a prior step; `telnyx-edge auth status` confirms. |
| Install step 404s                                   | The un-versioned `releases/latest/download/...` URL does not exist. Use the version-stamped asset URL shown above.                                                         |
| Function stuck in `build_failed` or `deploy_failed` | `telnyx-edge reset-func <name>` tears down the failed deploy and returns the function to `created` (id, name, and config preserved), then re-ship.                         |
| `ship` monitoring times out                         | Default monitoring timeout is 5 minutes. Raise it with `--timeout` (e.g. `telnyx-edge ship --timeout 10m`).                                                                |
| Obscure failures                                    | Re-run with `-v` for verbose logging.                                                                                                                                      |

## Next Steps

* [CLI reference](/docs/edge-compute/reference/cli) — every command and flag.
* [Versions & Rollback](/docs/edge-compute/configuration/versions) — how revisions and rollback work.
* [Secrets](/docs/edge-compute/configuration/secrets) — runtime secrets for your functions.
* [Observability](/docs/edge-compute/observability) — what you can (and can't) see after a deploy.
