Tests only protect you if they actually run. Running them by hand works until the day you forget — so the next step is to have them run automatically, on every push, before your code ever reaches Falix. That's continuous integration (CI), and the standard place to do it is GitHub Actions. This guide sets up a minimal one and, just as importantly, is honest about where the line between GitHub and Falix sits.
| At a glance | |
|---|---|
| You need | a project on GitHub with a test suite |
| Plan | any — CI runs on GitHub, not on your server |
| Time | twenty minutes |
The honest boundary
Read this first, because it saves a lot of confusion:
⚠️ Falix does not run CI. A deploy copies files and starts your app — it never runs
npm testorpytest. Your tests run on GitHub, on GitHub's machines, before Falix pulls anything. Falix's job is to run your app; the test gate belongs upstream.
So the shape of a safe pipeline is: you push → GitHub Actions runs your tests → the checks go green → your code lands on the deploy branch → Falix auto-deploys it. GitHub is the gate; Falix is the delivery. They're two separate systems doing two separate jobs.
A minimal workflow
A GitHub Actions workflow is a YAML file in your repo under .github/workflows/. Here's a complete one for a Node project — it checks out your code, installs dependencies, and runs the test suite on every push and pull request:
.github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test
The Python equivalent swaps the middle three steps:
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install -r requirements.txt
- run: python -m pytest
Commit the file, push it, and GitHub starts running it. (These use standard, stable published actions — checkout, setup-node, setup-python — that GitHub maintains.)
💡 Tip: Match the workflow's version to your server's. If your Falix server runs Node 20, set
node-version: '20'so CI tests on the same runtime you deploy to. A test that passes on Node 22 but your server runs 20 hasn't really tested your deploy.
Reading green and red
After a push, open the Actions tab on your repo (or look at the check mark beside the commit):
- Green check — every step passed, including your tests. This commit is safe to deploy.
- Red X — a step failed. Click into the run to see which one and read the log; a failed
npm testshows exactly which test broke.
Pull requests show the status inline, so you see whether a change is green before you merge it.
Wiring the gate to your Falix deploy
Here's the part that makes CI actually protect production. On its own, Falix's auto-deploy webhook fires on every push to the deploy branch — it doesn't wait for your checks, because it can't see them. So the gate has to be enforced on the GitHub side, and the clean way is branch protection:
- Point your Falix server at a branch you keep clean —
mainor a dedicatedproduction. - In your GitHub repo settings, add a branch protection rule on that branch requiring the CI check to pass before anyone can merge into it.
- Do your work on feature branches and merge via pull request. Only green PRs merge; only merged (green) code reaches the deploy branch; Falix auto-deploys that branch.
The result: red code physically can't reach the branch Falix watches, so a failing test blocks the deploy without Falix needing to know anything about your tests.
🎯 Good to know: If you skip branch protection and push straight to the deploy branch, Falix deploys whatever you pushed — green or red. The protection rule is what turns "CI runs" into "CI gates."
Verify it works
Open a pull request that deliberately breaks a test. GitHub Actions should run, go red, and — with branch protection on — block the merge. Fix the test, watch the check flip to green, and the merge unlocks. If a broken PR can't merge and a fixed one can, your gate is real.
Troubleshooting
- The workflow never ran — the file has to be at
.github/workflows/*.ymlon the branch you pushed. Check the path and that it's valid YAML. - CI passes but my server still fails — you're probably testing on a different runtime version than your server runs. Match
node-version/python-versionto your Falix Settings. - A red PR merged anyway — branch protection isn't set, or the required check isn't the one you think. Re-check the rule names the CI job.
npm cifails butnpm installworks —npm cineeds a committedpackage-lock.json. Commit your lockfile (and never.gitignoreit).
Where to go deeper
The Falix-shaped part ends here — the rest is standard GitHub Actions. The official documentation at docs.github.com/actions covers matrices, caching, secrets, and everything beyond a single test job.