Deploying from a repository¶
hub git bind ties an app to a branch of a git repository, so that merging into the branch
deploys the app. This page covers binding an app, the two kinds of repository URL, and what the
hub does with the repository.
Once an app is bound, the hub checks the branch once a minute and builds every new head once.
Nobody has to run a command or have a session open. The hub refuses hub deploy for a bound
app.
$ hub git bind git@github.com:acme/sales.git --branch main
hub: github.com:22 host key pinned: SHA256:...
hub: git@github.com:acme/sales.git@main is at 4f2c9a1
hub: building sales as ...
...
hub: bound to git@github.com:acme/sales.git@main: a push to the branch deploys within a minute, 'hub deploy' is off for 'sales'
Two kinds of URL¶
SSH, written git@host:path or ssh://host/path. The hub creates a key pair for the
binding. The first hub git bind prints the public key and the fingerprints of the server's
host key, then stops. To finish the binding:
- Register the key with the repository as a read-only deploy key (GitHub, GitLab, Gitea) or access key (Bitbucket).
- Compare the fingerprints with those your forge publishes.
- Run the same command again.
You paste nothing into the hub, and no token can expire. hub git status shows the key again.
hub git unbind discards it, and the next bind creates a new one.
HTTPS, with a read-only token. Use a project or deploy token of the repository. A personal
token stops working when its owner leaves, and the binding breaks with it. Pass the token with
--token or in the environment variable HUB_GIT_TOKEN. Without either, the command asks for
it in the terminal, which keeps it out of your shell history. Each forge expects its own user name with a token, which you pass with --user:
oauth2 for GitLab, x-token-auth for Bitbucket, and any name for GitHub and Azure DevOps.
The hub refuses plain http://. It stores the token only after the first build has succeeded,
so a failed bind leaves nothing behind.
Both kinds take these options: --branch (default main), --path for an app in a
subdirectory of the repository, and --name to give the app a name other than the
repository's. If the hub.yaml in the repository sets name, the app must have that name, so
pass it with --name when it differs from the repository's name.
What the hub does with the repository¶
The hub reads hub.yaml from the repository, as in any deploy. A committed .Renviron becomes
the app's secret, so keep secrets out of the repository and set them with hub env set
instead. The app's directory in the repository has the size limit of an upload: 200 MB
compressed. To get it, the hub clones the latest commit of the whole branch, also for an app in
a subdirectory, and refuses a branch that is larger than 1 GB compressed. Keep large data out
of the repository.
Nobody watches a build that a push started. hub git status <name> shows the repository, the
branch head and when the hub last checked it. It also shows the last build and its result, and
for a failed build the end of its output. The hub builds a failing commit once and tries again
only when the branch moves. hub history lists these deploys as by git, and hub apps shows
the repository next to the app. On a hub with
monitoring, admins also see the build logs in Grafana.
Everything else works as it does for any app: rollback, env, apikey, run and delete.
The people who may push to the branch are not maintainers of the app on the hub. To let them
run these commands, list them in hub.yaml as described in
Work on an app as a team.
Unbind an app¶
hub git unbind <name> removes the binding and its credential. hub deploy works again, and
the app's history stays. To try something out while an app is bound, either push to the
branch, or deploy a copy of the directory with another name in its hub.yaml.