Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

Render and GitHub: How Connecting a Repository Actually Works, What Auto-Deploy Does on Every Push, and the Settings That Bite

Sean

Platform Writer

Sep 15, 2026
8 min read

Connecting GitHub to Render installs a GitHub App on your account or organisation, grants it access to the repositories you choose, and from then on every push to the branch a service tracks triggers a build and a deploy. That is the whole model. The details that matter in practice are which branch, what happens to pull requests, how to push without deploying, why a collaborator cannot deploy a repo they do not own, and how to trigger a deploy from a GitHub Actions workflow instead of a push.

Render and GitHub: How Connecting a Repository Actually Works, What Auto-Deploy Does on Every Push, and the Settings That Bite

The top results are Render’s own deploy documentation, its Git provider page, a GitHub Marketplace action, and a forum question about deploying a friend’s private repository. Together they cover the mechanism and one of its gotchas. This post is the working version: the connection, the per-push behaviour, the branch and preview settings, and the four things that surprise people, written for someone deciding whether the model fits how their team ships.

Table of contents

What connecting a repository does

Render deploys from Git, and GitHub is the provider most people connect. The connection is a GitHub App installed on your personal account or on an organisation, with access to either all repositories or a list you pick. Render then sees those repositories when you create a service, and receives a webhook from GitHub on every push.

When you create a web service, static site, background worker or cron job, you choose a repository, a branch and a root directory, and Render records that as the service’s source. From the first deploy on, the workflow is: push to the tracked branch, GitHub notifies Render, Render clones the commit, runs the build command, and if the build succeeds, starts the new version and routes traffic to it. Each deploy is tied to a commit, which is what makes rollback a matter of picking an earlier one.

The is Vercel or Render better post covers where this model sits relative to the other Git-connected platforms. The mechanism is the same everywhere; what differs is what happens around it.

Auto-deploy: what one push actually triggers

Auto-deploy is on by default and does one thing: a push to the tracked branch starts a deploy of the pushed commit. Three details change what that means.

It is the branch, not the repository. A push to any other branch does nothing unless a preview environment is configured for it. Pushing to main deploys production; pushing to feature/x deploys nothing.

A failed build does not replace the running version. The build runs in isolation and the previous deploy keeps serving until the new one is healthy. If the health check fails, the deploy is marked failed and traffic stays where it was. This is the property that makes auto-deploy safe to leave on.

Every push is a deploy, including the ones that only touch a README. Which is why the skip mechanism exists:

git commit -m "[skip render] Update README"
git push

A commit message containing [skip render] or [render skip] is ignored by the webhook handler. It applies to the commit that is pushed last; if you push three commits and only the last has the marker, the deploy is skipped for the whole push.

Auto-deploy can also be turned off per service, in which case pushes accumulate and a deploy is started by hand from the dashboard or the CLI. Teams that want a release step between merge and production use this setting.

Branches, previews and the monorepo

Production tracks one branch. Everything else is a question of what you want to happen to the other branches.

Pull request previews create a temporary copy of the service for each open pull request, on its own URL, torn down when the PR closes. They are configured per service, and each preview is a real running instance that costs instance-hours while it is up. For a web app with a database, a preview usually needs its own database or a shared staging one, and that decision is yours to make in the service’s environment for previews.

A staging service is the simpler alternative: a second service tracking a staging branch, with its own environment variables. Merge to staging to deploy there, merge to main to deploy production. Two services, two bills, no per-PR churn.

Monorepos work with the root directory setting: a service builds from a subdirectory, and build filters limit which paths trigger a deploy, so a change to apps/web does not rebuild apps/api. Without filters, every push to the branch rebuilds every service that tracks it, which in a monorepo with six services is six builds per commit.

Private repositories, collaborators and permissions

The forum question in the search results is a common one: someone has a private repository, added a friend as a collaborator, and the friend cannot deploy it on their own Render account. The reason is how the GitHub App works.

The App is installed by the repository owner, on the owner’s account or organisation, and Render’s access to the repository comes from that installation. A collaborator on the repository does not own it, cannot install a GitHub App on it, and so their Render account cannot see it. Collaborator access on GitHub is about pushing code; App installation is about the account that owns the repository.

The fixes, in order of how often they are right:

  1. Move the repository to an organisation, install the Render App on the organisation, and add both people to a Render team that owns the service. This is the correct shape for anything two people ship together.
  2. Have the owner install the App and create the service on their own Render account, then invite the collaborator to the Render team.
  3. Fork, if the collaborator genuinely needs their own independent deployment.

The same rule explains why a repository moved between accounts stops deploying: the installation was on the old owner. Reinstall on the new one and reconnect the service.

Deploying from GitHub Actions instead of a push

Some teams want the deploy to happen after tests pass, not on push. Auto-deploy does not know about your CI; it deploys the commit as soon as it lands. Two mechanisms put CI in the loop.

A deploy hook. Every service has a unique URL; a request to it starts a deploy of the tracked branch’s latest commit. Turn auto-deploy off, and call the hook from the end of a successful workflow:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]
jobs:
  test-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
      - name: Trigger deploy
        run: curl -fsS "${{ secrets.RENDER_DEPLOY_HOOK_URL }}"

The hook URL is a secret; anyone who has it can deploy your service.

The API or the CLI, for deploying a specific commit or for creating a GitHub Deployment record that shows in the repository’s Environments tab. The marketplace action in the search results wraps the API for that purpose. From a terminal, the CLI does the same:

render deploys create srv-abc123 --commit def456

The auto deploy an app from GitHub post covers the equivalent connection on RunxBuild, where the same GitHub App model applies: install on the account that owns the repository, pick a branch, and every push to it builds and deploys with the build log and the runtime log in the same place.

Four things that surprise people

The build command runs on every deploy, from scratch. There is no incremental build by default; a large monorepo with a slow install pays that on every push. Cache what the platform lets you cache, and use build filters.

Environment variables are not in the repository. They are set on the service, and a new service created from the same repository starts with none. Keep a documented list, or use an environment group shared across services.

A rename or transfer of the repository breaks the connection. The service keeps pointing at the old name until you reconnect it. GitHub redirects clones but the App installation does not follow.

The tracked branch is a setting, not a convention. A service created from master keeps tracking master after the repository’s default branch is renamed to main, and pushes to main do nothing until the setting is changed. This is the quiet reason for the most common why-is-my-push-not-deploying question.

How this fits the rest of the stack

Connecting GitHub to Render is a GitHub App installed by the repository owner, a tracked branch per service, and a deploy on every push to it, with skip markers, previews, deploy hooks and the CLI as the controls around that loop. Know which branch each service tracks, install the App on the account that owns the repository, and put CI in front of the deploy with a hook when tests should gate production. For a sense of what the services behind those deploys cost, the RunxBuild hosting calculator shows each web service, worker and database as its own line item, which is the same arithmetic on any Git-connected platform.

Useful related references:

FAQ

How do I deploy a GitHub repository on Render?

Connect GitHub from your Render account, which installs a GitHub App with access to the repositories you choose. Create a service, pick the repository, branch and root directory, and set the build and start commands. The first deploy runs immediately, and with auto-deploy on, every later push to that branch builds and deploys the pushed commit.

Why does my push to GitHub not deploy on Render?

Check which branch the service tracks; a service created from master keeps tracking master after a rename to main. Check auto-deploy is on for the service, that the commit message does not contain a skip marker, and that the repository has not been renamed or transferred since the service was created, which breaks the connection until you reconnect it.

How do I skip a Render deploy for a commit?

Include [skip render] or [render skip] in the commit message of the last commit in the push. The webhook handler ignores that push. To stop deploying on push altogether, turn auto-deploy off for the service and start deploys manually from the dashboard, a deploy hook, or the CLI.

Can a collaborator deploy my private GitHub repo on Render?

Not from their own Render account. Render’s access comes from the GitHub App installed by the repository owner, and collaborators cannot install Apps on repositories they do not own. Move the repository to an organisation and use a Render team, or have the owner create the service and invite the collaborator to the team.

How do I deploy to Render only after tests pass?

Turn auto-deploy off and trigger the deploy from your CI. The simplest way is a deploy hook: a unique URL for the service that starts a deploy when requested. Call it with curl from the last step of a GitHub Actions workflow after the tests succeed, keeping the URL in a repository secret. The API and CLI can deploy a specific commit if you need that control.

#render github#render deploy from github#render auto deploy#render pull request previews#github deploy hooks