All posts
Joe Connolly deploying, github, preview deployments, environment variables

Push to deploy from GitHub, with PR previews

Connect a GitHub repository to velixir and every push is live in about a minute. Each pull request gets its own preview app, with its own empty database.

Push to deploy from GitHub, with PR previews

Until today, getting every push to deploy on velixir meant adding a GitHub Actions workflow to your repository and an API key to its secrets. It worked, and plenty of you use it, but it's a file to keep working and a key to rotate, and it does nothing for the question every team asks next: can I see this pull request running before I merge it?

Now you can connect the repository instead.

How does push to deploy work on velixir?

On your app's Deploys tab, press Connect GitHub. GitHub asks which repositories velixir may read: all of them, or just the ones you pick. Private repositories are fine. Back on velixir, choose the repository, the branch that deploys, and, if it's a monorepo, the folder the app lives in.

From then on, every push to that branch builds and goes live, usually in about a minute. You don't add a workflow file or store an API key, and there's still no Dockerfile: velixir works out the language from your project files and builds it, the same way the CLI does.

GitHub shows you where each push has got to. The commit gets a velixir/your-app status that links to the build log while it builds and to your app once it's live, and the deploy appears under the repository's environments.

A few details that matter once you push a lot:

  • If you push three times in a minute, only the newest commit builds. Older builds that haven't started yet are cancelled, so a burst of commits doesn't queue up behind itself.
  • Put [skip deploy] in a commit message to push without deploying.
  • In a monorepo, tick only deploy when this folder changes and a push that only touches another app is ignored.

What do pull request previews look like?

blog-github-app-maquette

Turn on Preview pull requests and every pull request into your deploy branch gets an app of its own, at your-app-pr-42.velixir.run. velixir comments on the pull request with the link and keeps that one comment up to date as you push, so reviewers click it and see the change running, not a diff. Close or merge the pull request and the preview goes away.

The part I cared most about is data. A preview that talks to your production database is one careless migration away from a very bad afternoon, so it doesn't. If your app has a database or a cache, each preview gets a new, empty one under the same environment variable names. Your code finds DATABASE_URL where it expects it, and production is never touched. Seed it the way you would a fresh environment, in a migration or on startup when VELIXIR_PREVIEW is set.

How do I keep production secrets out of previews?

Pull requests run code nobody has reviewed yet, so previews shouldn't get your live keys. Environment variables now have a scope. Mark one Production only and previews never see it. Mark one Previews only and previews use it instead of the shared value. A Stripe key is the usual example: your live key for production, your test key for previews, both under STRIPE_KEY.

From the terminal that's:

velixir env set STRIPE_KEY=sk_live_... --production --secret
velixir env set STRIPE_KEY=sk_test_... --previews --secret

For the same reason, pull requests from forks never get a preview. Their code would run with your preview variables, and a public repository's fork could be anyone's.

What does it cost?

Push to deploy works on every plan, Free included.

Previews are on paid plans: one open at a time on Hobby, three on Starter, five on Standard, ten on Pro and twenty on Business. A preview runs on the Free size and sleeps when nobody is looking at it, so the preview itself costs nothing. Its database and cache are real ones, billed hourly like any other while the preview exists, and deleted with it. A preview with no new commits for seven days is removed, and pushing to its pull request brings it back. Pricing has the hourly rates.

What isn't it for?

It's GitHub only, for now. If your code lives on GitLab or Bitbucket, the CLI in your pipeline is still the way.

It doesn't wait for your tests. If a deploy should only happen after CI passes, keep the GitHub Actions workflow and leave deploy on every push off, or the push deploys twice.

And previews run on the Free size, a quarter of a CPU and 256 MB of memory. That's plenty for most web apps, but a heavy one may be slow to start there.

Where does it run?

In EU data centres, like everything on velixir, previews included. If you'd like to try it, create an app from a GitHub repository, or read how it works in the docs.


Got an app to ship? velixir hosts it in any language, on servers in the EU.

Start free - your first month's on us