---
title: CI/CD
description: Run the Notiflows CLI in continuous integration — environment-based authentication, idempotent pushes, publishing, and a GitHub Actions example.
---

Because notiflows are stored as files in your repo, you can deploy them the same way you deploy code: commit changes, open a pull request, review the diff, and let CI push the merged result to Notiflows.

## Authenticate with environment variables

In CI you don't run `notiflows login`. Instead, set the token and project as environment variables — the CLI resolves them automatically (`NOTIFLOWS_TOKEN` for auth, `NOTIFLOWS_PROJECT` for the target project):

```bash
export NOTIFLOWS_TOKEN=nf_at_xxx     # store as a CI secret
export NOTIFLOWS_PROJECT=my-app      # or keep it in notiflows.json
```

Store `NOTIFLOWS_TOKEN` as an encrypted secret in your CI provider. `NOTIFLOWS_PROJECT` can either be an env var or the `project` field in `notiflows.json`. Use a dedicated, descriptively named [account token](/docs/cli/account-tokens) for CI (e.g. `github-ci`) so its actions are attributable and easy to revoke.

## Push is idempotent

`notiflows push` is safe to run on every build. The Management API discards a draft whose content matches the version it branched from, so **re-pushing unchanged content creates no new version** — only genuinely changed notiflows bump a version. That keeps a push-on-merge pipeline free of noise.

Add `--publish` to publish in the same step so the merged notiflows go live:

```bash
notiflows push --force --publish
```

Use `--force` in non-interactive environments to skip the confirmation prompt. (Be aware that `--force` also skips the conflict check; if you expect concurrent dashboard edits, push without `--force` and resolve conflicts by pulling first.)

## GitHub Actions

A GitHub Actions workflow that pushes and publishes notiflows on merge to `main`:

```yaml
name: Deploy notiflows

on:
  push:
    branches: [main]

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

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install the Notiflows CLI
        run: npm install -g @notiflows/cli

      - name: Push and publish notiflows
        env:
          NOTIFLOWS_TOKEN: ${{ secrets.NOTIFLOWS_TOKEN }}
          NOTIFLOWS_PROJECT: my-app
        run: notiflows push --force --publish
```

<Callout type="info">
To gate merges on validity, run `notiflows diff` (or `notiflow validate`) on pull requests and `notiflows push --publish` only on merge to your main branch.
</Callout>

## Related

- [Command reference](/docs/cli/commands) — `push`, `diff`, `validate`, and `publish`.
- [Notiflows as code](/docs/cli/notiflows-as-code) — the files your pipeline deploys.
