| name | keboola-git |
| description | Use when accessing a Keboola-managed Git (Forgejo) repo for a python-js data app via the kbagent CLI — provisioning the repo, finding its repo_url, minting a git_clone_url / push credential with create_python_js_data_app_git_credential, pushing source to Keboola git, copying source between GitHub and Keboola git, working around the ~15MB / HTTP 413 push cap with build-at-deploy, or deploying a data app from its managed git repo. Triggers: kbagent, Keboola managed git, Forgejo, data app repo, repo_url, git_clone_url, create git credential, push to Keboola git, build-at-deploy, HTTP 413, deploy from git. |
Keboola-Managed Git (Forgejo) for Data Apps
Keboola python-js data apps can host their source in a Keboola-managed Git repo (Forgejo) instead of GitHub. This skill gives you the context to access those repos through the kbagent CLI: provision a repo, mint a push credential, push source in with raw git, and deploy. kbagent has no repo-copy helper — you drive git clone / git remote add / git push yourself.
What this does / when not
Use this for: reading or writing a managed Forgejo repo for a python-js data app; moving an app's source between GitHub and Keboola git; pushing source and deploying from the managed repo.
Not for: authoring the contents of keboola-config/ (nginx, supervisord, setup.sh) — that's the dataapp-developer:dataapp-deployment skill. Not for Streamlit app development — that's dataapp-developer:dataapp-dev. This skill assumes the app source already exists somewhere; it handles the git plumbing to get it into Keboola and deployed.
Working Directory Context
All git and kbagent operations run from the user's project root or a scratch clone created under the user's CWD — never from this skill/plugin directory.
- Do clone/copy work in
./.keboola-git-work/<app>/ under the user's CWD. Add .keboola-git-work/ to the project .gitignore so the scratch clone is never committed.
- Before any in-place git operation on an existing repo, validate it's a worktree:
git rev-parse --is-inside-work-tree.
- Never run git commands against the plugin install directory.
Prerequisites
- kbagent installed and on
PATH (kbagent --version). Install: see the kbagent docs / kbagent:kbagent skill.
- Project registered with kbagent (one-time per project):
kbagent --json project add --project <alias> --stack <stack-url> --storage-token "$KBC_TOKEN"
- Conversation id exported once per shell session:
export KBAGENT_CONVERSATION_ID=$(uuidgen)
- Always pass
--json to tool calls so you can parse configuration_id, repo_url, git_clone_url reliably.
1. Access the managed repo
Existing app — find its repo and config:
kbagent --json tool call get_data_apps --project <alias> --input '{}'
Note the configuration_id, data_app_id, and repo_url
(https://git.<stack>/keboola/app-<data_app_id>.git).
Provision a new app + repo:
kbagent --json tool call modify_python_js_data_app --project <alias> \
--input '{"name":"<Display Name>","slug":"<slug>","description":"<desc>"}'
Returns configuration_id, data_app_id, repo_url. Two-app model: the prod config owns the only repo; draft branches advance from it.
2. Mint a push credential (one-time secret)
kbagent --json tool call create_python_js_data_app_git_credential --project <alias> \
--input '{"configuration_id":"<cfg>"}'
Returns git_clone_url = https://kai:<secret>@git.<stack>/keboola/app-<data_app_id>.git.
3. Clone / push pattern (raw git)
mkdir -p ./.keboola-git-work && cd ./.keboola-git-work
git clone --single-branch --branch <branch> <source-repo> app && cd app
git remote add keboola "$URL"
git push keboola HEAD:main
- The pre-receive hook declines branch deletes — pushing new commits to
main or a draft branch advances normally, but you cannot delete a remote branch.
- Never force-push a shared/managed branch.
4. The 15MB / HTTP 413 cap + build-at-deploy (CRITICAL)
Forgejo rejects pushes over ~15MB with HTTP 413. A single file over the limit cannot be split — you must not track it.
Push source only. Repos that commit their build (e.g. frontend/.next ~55MB, often including a 15.3MB macOS sharp binary that's also the wrong binary for the Linux runtime) must move the build into deploy time:
-
Size guard before pushing:
find . -size +15M -not -path '*/.git/*'
-
If a build dir is tracked, stop tracking it and gitignore it:
git rm -r --cached frontend/.next
printf '%s\n' 'frontend/.next/' 'node_modules/' >> .gitignore
-
Move the build into keboola-config/setup.sh so it runs in the Linux container at deploy:
cd frontend && npm ci && npm run build
cp -r .next/static .next/standalone/.next/static
cp -r public .next/standalone/public
For the exact setup.sh / nginx / supervisord wiring, cross-reference the dataapp-developer:dataapp-deployment skill.
-
Commit the source-only tree, then re-run the size guard (no tracked file >15MB).
-
Check git history, not just the working tree (CRITICAL). git push sends every
object reachable from the pushed ref — so a build committed in an earlier commit still
gets pushed and still 413s, even after step 2 removes it from HEAD. The find guard only
sees the working tree. Check reachable blobs:
git rev-list --objects HEAD \
| git cat-file --batch-check='%(objecttype) %(objectsize) %(rest)' \
| awk '$1=="blob" && $2>15000000 {print $2, $3}'
If anything prints, the over-cap blob is in history. Two remedies:
If a push still 413s, re-run both guards (working tree and history) and report the
offending file — the user must decide how to externalize it (it can't be split).
5. Deploy + verify
kbagent --json tool call deploy_data_app --project <alias> \
--input '{"action":"deploy","configuration_id":"<cfg>"}'
Verify from the logs — they are the authoritative signal (build is ~90s+ for npm ci + next build; setup_sh can take ~2min total):
kbagent --allow-env-manage-token data-app logs --project <alias> --app-id <data_app_id> --lines 300
Look for, in order: ✓ Compiled successfully and Generating static pages (the next build
finished), Completed: setup_sh (the static-asset cp succeeded — under set -e a wrong
copy path would abort here), then success: node-frontend entered RUNNING state and
✓ Ready in …ms (the standalone server is up on :3000). The python service shows
success: python-api entered RUNNING state. If a deeper window is dominated by one service's
restart loop, raise --lines to see the other service's earlier startup.
Do NOT rely on an HTTP probe to confirm the frontend. An unauthenticated GET / returns
the Keboola platform login gate (HTTP 200, <title>Login</title>, no _next/static
references) — that's the platform auth proxy in front of the container, not your app. And
POST / returns 200 from the nginx location = / health rule regardless of app state. Real
proof that the built frontend serves is node-frontend entered RUNNING + Ready in in the
logs (optionally: authenticate with the app password, then check the HTML references
/_next/static/…).
Get the app password / set secrets + redeploy as needed:
kbagent --json --allow-env-manage-token data-app password --project <alias> --app-id <data_app_id>
kbagent --allow-env-manage-token data-app secrets-set --project <alias> --app-id <data_app_id> '#KEY=VAL'
Success = repo in Keboola git + app deploys + container builds + node-frontend RUNNING + backend process starts. Backend data errors — e.g. python-api crash-looping on a Storage 404 Not Found from its startup data load — mean the app is running and looking for tables that don't exist in an empty project. That's a data condition, not a git/deploy failure.
Gotchas
Full command catalog, the 413/build-at-deploy recipe, and the gotchas table live in
references/managed-git.md.