Thinkube GitOps
Change your app and ship it
Edit the code, run its tests, push, and the new version is live
- Level
- beginner
- Time
- 30 min
- Risk
- low
- Updated
- 2026-10-04
Overview
Basic idea
Shipping a change is one push. In a GitOps platform the repository is the only thing you touch: you commit and push, and the platform tests the code, builds new images and replaces the running version. What runs is always a commit you can read, and going back is pushing the previous one.
-
Your checkout is the working copy. The app is already checked out in Thinkube IDE, at
~/apps/<name>. -
Tests guard the push. The build runs the app’s tests first; a failing test stops the release.
-
The push is the deploy.
What you’ll accomplish
You add an endpoint to the notes app that counts your tasks, run its test in Thinkube IDE, push it, and call it on the live app.
What to know before starting
Required
-
An app from the web app template. Build a web app from the template makes
notes. -
Reading short Python.
Optional
-
What is in the web app template, to find your way in the code.
Instructions
Step 1. Make the change
Ask your agent:
› in apps/notes add GET /api/v1/tasks/count that returns how many tasks I have and how many are done, with a test
On the reference run the agent added a route to backend/app/api/tasks.py, before the route that takes a task id so count is not read as an id:
@router.get("/count", response_model=TaskCount)
async def count_tasks(
db: Session = Depends(get_db),
current_user: dict = Depends(get_current_user)
):
"""
Count the current user's tasks.
Requires authentication.
"""
mine = db.query(TaskModel).filter(TaskModel.user_id == current_user.sub)
return TaskCount(
total=mine.count(),
done=mine.filter(TaskModel.status == TaskStatus.DONE).count(),
)
and a test file, backend/tests/test_task_count.py, that creates three tasks, two of them done, and expects {"total": 3, "done": 2}.
Step 2. Run the test
Every container of the template has a run_tests.sh: with no argument it runs the whole suite, with a file it runs that file only. The tests use the platform’s PostgreSQL, and every test’s rows are rolled back when it ends.
Ask your agent:
› run backend/tests/test_task_count.py in apps/notes
Or by hand:
cd ~/apps/notes/backend && ./run_tests.sh tests/test_task_count.py
Expected output:
tests/test_task_count.py::test_task_count_unauthenticated PASSED tests/test_task_count.py::test_task_count_counts_done PASSED ======================== 2 passed, 11 warnings in 0.17s ========================
Step 3. Commit and push
Ask your agent:
› commit the task count and push notes
Or by hand:
git add backend/app/api/tasks.py backend/tests/test_task_count.py git commit -m "Count tasks: GET /api/v1/tasks/count" git pull --rebase git push
The push starts the build: the backend and frontend tests, the images for amd64 and arm64, then the rollout.
Step 4. Call it on the live app
Ask your agent:
› tell me when /api/v1/tasks/count is live on notes, then call it as me
Expected output: on the reference run the endpoint appeared in the app’s API description, https://notes.thinkube.com/api/v1/openapi.json, 171 seconds after the push. Called with the signed-in user’s token:
{"total":1,"done":0}
Without a token it answers {"detail":"Not authenticated"}, as every endpoint of the app does.
Step 5. Next steps
To undo: Revert the commit and push.
-
Pass configuration to your app: values the app reads at run time, and the ones the browser may see.
-
Publish your app as a template: publish your version for others.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
A test run in Thinkube IDE fails with |
|
Load them before the run: |
|
After every deploy the build commits the new image tag to the repository, so your checkout is one commit behind |
Run |