| 1 | --- |
| 2 | title: Projects |
| 3 | description: A project is what you build and run. Its code lives in its source; its deployments, secrets and variables belong to the project. |
| 4 | --- |
| 5 | |
| 6 | A project is the thing you are building and running: a site, an API, a |
| 7 | worker, a library. Every project has one **source**, where its code lives, |
| 8 | and everything about running it belongs to the project: |
| 9 | |
| 10 | | Belongs to the project | Belongs to its repository | |
| 11 | | --- | --- | |
| 12 | | [Deployments](/guides/deployments/): production and previews | Branches and commits | |
| 13 | | Its address on g1t.page | Issues and pull requests | |
| 14 | | [Secrets and variables](/guides/secrets-and-variables/) | Review, merge rules and the [merge queue](/guides/merge-queue/) | |
| 15 | | Its name, description and root directory | Webhooks | |
| 16 | |
| 17 | That split is what lets the code live anywhere while the project stays the |
| 18 | same. |
| 19 | |
| 20 | ## Your projects |
| 21 | |
| 22 | Every repository on g1t is a project of its own name, with nothing to set |
| 23 | up: `g1t.sh/acme/web` is the `web` project, built from the `acme/web` |
| 24 | repository. Repositories made before projects existed became projects the |
| 25 | first time their workspace was opened. |
| 26 | |
| 27 | A workspace's page, `g1t.sh/<workspace>`, shows your pinned projects and |
| 28 | its most active ones, each with where it is deployed, its latest build, and |
| 29 | its open issues and pull requests. **All projects** in the sidebar lists |
| 30 | every one, with search, filters and sorting; see |
| 31 | [the Projects page](/guides/workspaces/#the-projects-page). The sidebar keeps |
| 32 | your [pinned and recent projects](/guides/workspaces/#pinned-and-recent-projects). |
| 33 | |
| 34 | ## A project's pages |
| 35 | |
| 36 | | Page | Address | | |
| 37 | | --- | --- | --- | |
| 38 | | **Overview** | `g1t.sh/<workspace>/<project>` | What it is and its links; production wherever it is deployed, or for a library its packages; what is in progress, active branches, the latest commits, and its About. See [the overview](#the-overview). | |
| 39 | | **Code** | `…/code` | The repository's files, commits and branches. | |
| 40 | | **Issues**, **Pull requests**, **Merge queue** | `…/issues` and so on | As they always were. | |
| 41 | | **Actions** | `…/actions` | [GitHub Actions workflows](/guides/actions/). | |
| 42 | | **Deployments** | `…/deployments` | What is up now and every build. | |
| 43 | | **Settings** | `…/settings` | See below. | |
| 44 | |
| 45 | Every address that pointed into a repository before still works: the |
| 46 | project has the repository's name. |
| 47 | |
| 48 | ## The overview |
| 49 | |
| 50 | A project's overview is the first page you see. People with a |
| 51 | [role](/guides/access-and-roles/) on its repository see all of it; anyone |
| 52 | else sees what the project shares publicly. |
| 53 | |
| 54 | | Part | What it shows | |
| 55 | | --- | --- | |
| 56 | | **What it is** | A badge, such as **App, deployed elsewhere** or **Library**, beside its homepage and docs. People who can change its settings open the badge to change [what it is](#what-a-project-is) in one click. | |
| 57 | | **Production** | [Production's picture](#productions-picture), which opens the live site, beside the rest. For an app [deployed on g1t](/guides/deployments/): its address, the commit it runs and when it went up; **Visit** and **Redeploy**. For an app deployed elsewhere: production's address and **Visit**, with its latest reported production deployment or the default branch's latest commit. For an app nobody has placed yet: one question, where it runs. | |
| 58 | | **Packages** | For a library or a tool, in place of Production: the packages its repository publishes, each with its latest version and how to install it, or how to publish a first one. | |
| 59 | | **Documentation**, **Homepage** | For docs, where they are read; for anything else, its homepage. | |
| 60 | | **Right now** | Open pull requests moving from working to landed. | |
| 61 | | **Needs you** | What is waiting on a person: a failed production build, a pull request to merge or review, a stuck run. | |
| 62 | | **Active branches** | Branches other than the default, newest first. See [active branches](#active-branches). | |
| 63 | | **Recent changes**, **Latest on main**, **Activity**, **Previews** | What landed, the default branch's latest commits, what happened (pull requests opened, readied and merged, issues opened and closed, checks, reviews, comments, pushes to the default branch and production deploys), and the previews that are up. | |
| 64 | | **About** | Its description, its [links](#links), what it is, and its latest release (its newest tag). People who can change its settings edit the description and links from here. | |
| 65 | | **Health**, **Clone** | How often checks pass (on pull requests, or the project's workflow runs when it ships without them), recent builds and open issues by age; the clone address. | |
| 66 | |
| 67 | ### Production's picture |
| 68 | |
| 69 | The production card always has a picture of the app, wherever it runs. |
| 70 | It is the first of these there is: |
| 71 | |
| 72 | 1. **A screenshot of production.** For an app deployed on g1t, g1t takes |
| 73 | one each time production goes live (see |
| 74 | [the production screenshot](/guides/deployments/#the-production-screenshot)); |
| 75 | people with a role on the repository see it, like the rest of its |
| 76 | deployments. For an app deployed elsewhere, g1t takes one of |
| 77 | production's address: the address its latest production deployment |
| 78 | reported to g1t gives, or else the one set for it under **What it is**. |
| 79 | Anyone who can see the project sees it. |
| 80 | 2. **An image someone uploaded**, under **Settings** → **General** → |
| 81 | **Production image**. |
| 82 | 3. **A plain frame** with production's address. People who can change |
| 83 | the project's settings see **Add an image of your app** on it, which |
| 84 | opens **Production image**. |
| 85 | |
| 86 | A screenshot of production deployed elsewhere is taken: |
| 87 | |
| 88 | - when its address is set or changed; |
| 89 | - when a production deployment of it is reported to g1t and succeeds, |
| 90 | through the [API](/guides/deployments/) or by a workflow job with an |
| 91 | `environment:`; |
| 92 | - otherwise about once a day, when the one kept is a day old. Opening the |
| 93 | overview after that also takes a new one, in the background, while the |
| 94 | old one shows. |
| 95 | |
| 96 | g1t waits up to 12 seconds for the page to settle, as a 1280 by 800 |
| 97 | browser window sees it, then takes it as it is. Only public `http` and |
| 98 | `https` addresses on their usual ports are visited: an address on a |
| 99 | private network, a loopback or link-local address, or one of g1t's own |
| 100 | service addresses (other than `g1t.sh` itself) gets the uploaded image |
| 101 | or the frame instead. Screenshots are not charged. |
| 102 | |
| 103 | #### Uploading an image |
| 104 | |
| 105 | **Production image** takes a PNG, JPEG or WebP of at most 5 MB; wide |
| 106 | images fit best, such as 1280 by 800. It is checked by its contents, not |
| 107 | its name, and served from g1t's user-content address |
| 108 | (`g1tusercontent.com` on g1t.sh), never from the site itself. Its address |
| 109 | is made from its contents, so the card shows a new image as soon as it |
| 110 | is uploaded. Anyone with an image's address can open it, even for a |
| 111 | private project, so upload only what you would show. |
| 112 | |
| 113 | - The uploaded image shows whenever there is no screenshot: before the |
| 114 | first one, when one cannot be taken, or for an app with no production |
| 115 | address. |
| 116 | - **Use the uploaded image instead of a screenshot** shows it in place of |
| 117 | any screenshot. While it is on, g1t takes no screenshots of production |
| 118 | deployed elsewhere. |
| 119 | - **Remove** takes it away; the card goes back to the screenshot or the |
| 120 | frame. |
| 121 | |
| 122 | Anyone who can change the project's settings (the **Maintain** role on |
| 123 | its repository and up, as for production's address) can upload, replace |
| 124 | or remove it. |
| 125 | |
| 126 | ## What a project is |
| 127 | |
| 128 | A project is one of these, and its overview follows: |
| 129 | |
| 130 | | What it is | Its overview shows | |
| 131 | | --- | --- | |
| 132 | | **App or site, deployed on g1t** | Production on g1t.page, with previews and domains. | |
| 133 | | **App or site, deployed elsewhere** | Production at the address you give, deployed by your own pipeline, with **Visit**. It is never asked to turn on Deployments; Deployment settings stay one link away. | |
| 134 | | **Library or package** | The packages its repository publishes and how to install them. | |
| 135 | | **Tool or CLI** | The same as a library: its packages and releases. | |
| 136 | | **Documentation** | Where its docs are read. Docs can be published on g1t.page too, by turning on Deployments. | |
| 137 | | **Something else** | Its homepage and links. | |
| 138 | |
| 139 | Its **Deployments** page stays in the sidebar whatever it is. |
| 140 | |
| 141 | ### How g1t works it out |
| 142 | |
| 143 | Until you say, g1t works it out for itself, in this order: |
| 144 | |
| 145 | 1. If [Deployments](/guides/deployments/) are on for the project, it is |
| 146 | an app deployed on g1t. |
| 147 | 2. If its repository publishes a package other than a container image, |
| 148 | such as a [Composer](/guides/composer/) or [npm](/guides/npm/) |
| 149 | package, it is a library. |
| 150 | 3. If the files at the root of its default branch (or of its root |
| 151 | directory) say what it is, it is that: |
| 152 | |
| 153 | | File | Says | |
| 154 | | --- | --- | |
| 155 | | `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` | An app. | |
| 156 | | `mkdocs.yml`, `book.toml`, `docusaurus.config.js` (or `.ts`, `.mjs`) or `antora.yml` | Documentation. | |
| 157 | | `composer.json` | A library when its `type` is anything but `project`, such as `library`; or it has no `type`, has `autoload`, and has no `public/index.php`. | |
| 158 | | `Cargo.toml` | A library when it builds a library (`[lib]` or `src/lib.rs`) and no binary (`[[bin]]` or `src/main.rs`). | |
| 159 | | `go.mod` | A library when no `.go` file at the root is `package main`. | |
| 160 | | `pyproject.toml` | A library when it has a build backend and depends on no app framework, such as Django, Flask or FastAPI. | |
| 161 | | `package.json` | A tool when it has `bin` and nothing to import (no `main`, `module` or `exports`); a library when it has `main`, `exports`, `module`, `files` or `bin`; either way only with no `start` or `dev` script and no app framework such as Next.js, Astro, Nuxt, Remix or SvelteKit. | |
| 162 | |
| 163 | The language's own manifest is read before `package.json`, which many |
| 164 | projects carry only for tooling. An `index.html` at the root makes it |
| 165 | an app. |
| 166 | 4. Anything else is an app. |
| 167 | |
| 168 | The files are read again on every push to the default branch. |
| 169 | |
| 170 | An app found this way runs on g1t only while Deployments are on. Until |
| 171 | you say where it runs, its overview asks, in place of production: |
| 172 | **Deploy on g1t**, **It's deployed elsewhere** (with production's |
| 173 | address), or **It isn't deployed** (a library, a tool, documentation or |
| 174 | something else). |
| 175 | |
| 176 | ### Choosing it yourself |
| 177 | |
| 178 | From the overview, open the badge beside its name, such as **App**, and |
| 179 | choose one. Or open **Settings**, then **General**, and under **What it |
| 180 | is** choose **Detect automatically**, which shows what was detected and |
| 181 | why, or one of the kinds above. **App or site, deployed elsewhere** asks |
| 182 | for production's address. |
| 183 | |
| 184 | Choosing a library, a tool or something else while Deployments are on is |
| 185 | refused: turn them off first under **Settings**, then **Deployments**; |
| 186 | g1t does not turn them off for you. While it is set that way, Deployments |
| 187 | cannot be turned on. Turning Deployments on for an app deployed elsewhere |
| 188 | makes it an app deployed on g1t. |
| 189 | |
| 190 | Changing what it is needs the role that changes the project's settings. |
| 191 | |
| 192 | ### Active branches |
| 193 | |
| 194 | Up to five branches other than the default, the most recently changed |
| 195 | first. Each shows its last commit and who made it, how many commits it is |
| 196 | ahead of the default branch and behind it, and its open pull request, |
| 197 | with its checks, and preview, if it has them. A branch with no pull |
| 198 | request links to opening one, unless it has nothing the default branch |
| 199 | lacks, which says **Nothing to merge**. |
| 200 | |
| 201 | Ahead and behind are exact, merges included. g1t reads up to 1,000 |
| 202 | commits of each history to find where the two meet; a branch that left |
| 203 | the default branch further back than that shows no counts. Ten branches |
| 204 | are read, those with open pull requests first; a project with more says |
| 205 | how many it has. |
| 206 | |
| 207 | ## Links |
| 208 | |
| 209 | A project has a **homepage**, a **docs** address, and up to 10 other |
| 210 | links, each a label and an address, such as a status page or its listing |
| 211 | in a registry. They show in its overview's About and beside what it is, |
| 212 | on its card on its workspace's page, in its workspace's Projects, and on |
| 213 | Explore for a public project. |
| 214 | |
| 215 | To set them, open **Settings**, then **General**, and fill in **Links**; |
| 216 | or choose the pencil on the overview's **About**. Each is an http or |
| 217 | https address; `https://` is added when you leave it out. A label left |
| 218 | empty is the address's host name. Removing every row of other links |
| 219 | clears them. |
| 220 | |
| 221 | A repository's own project shows the repository's website as its |
| 222 | homepage until you give the project one of its own. For an app deployed |
| 223 | on g1t, its g1t.page address still shows as production; set the homepage |
| 224 | to production's own domain if you have one. |
| 225 | |
| 226 | ## Settings |
| 227 | |
| 228 | A project's **Settings** has a tab for each part: |
| 229 | |
| 230 | | Tab | What it holds | |
| 231 | | --- | --- | |
| 232 | | **General** | The project's name and description, its source, its **root directory**, [what it is](#what-a-project-is), its [links](#links), and its [production image](#uploading-an-image). A project shows its repository's description, and follows it as it changes, until you give the project one of its own; **Use the repository's description** goes back. | |
| 233 | | **Deployments** | Production, previews, build command, output directory and idle days. See [Deployments](/guides/deployments/#settings). | |
| 234 | | **Domains** | Custom domains for production. See [custom domains](/guides/deployments/#custom-domains). | |
| 235 | | **Guardrails** | What g1t's sandboxes may reach while they work here. See [guardrails](/guides/guardrails/). | |
| 236 | | **Repository** | The repository's name, description, website, [topics](/guides/search/#what-is-indexed) and default branch, and its danger zone: visibility, archive, transfer and delete. See [Managing a repository](/guides/managing-repositories/). | |
| 237 | | **Access** | Who has a [role](/guides/access-and-roles/) on the repository, and invitations. | |
| 238 | | **Branches and merging** | Auto-merge, the CODEOWNERS file's errors, and what the rules hold for the default branch. | |
| 239 | | **Rules** | [Rulesets](/guides/rules/): branch and tag protection, [required status checks](/guides/pull-requests/#required-status-checks), approvals and the merge queue, with Insights. | |
| 240 | | **Secrets and variables** | The project's rows. See [Secrets and variables](/guides/secrets-and-variables/). | |
| 241 | | **Runners** | The project's own [self-hosted runners](/guides/self-hosted-runners/). | |
| 242 | | **Webhooks** | The repository's [webhooks](/guides/webhooks/). | |
| 243 | |
| 244 | The **root directory** says where in the repository the project lives, |
| 245 | such as `apps/web`. Builds run there. Leave it empty for the whole |
| 246 | repository. |
| 247 | |
| 248 | Each tab needs a [role](/guides/access-and-roles/) on the project's |
| 249 | repository: |
| 250 | |
| 251 | | Tab | Needs | |
| 252 | | --- | --- | |
| 253 | | **General**, **Dependencies**, **Branches and merging**, and on **Repository** its description, website and topics | Maintain | |
| 254 | | **Rules**, **Guardrails** | Admin | |
| 255 | | **Access**: seeing who has a role; changing it | Write; Admin | |
| 256 | | **Deployments**, **Domains**, **Secrets and variables**, **Runners**, **Webhooks** | Admin | |
| 257 | | On **Repository**: its name, default branch, and the danger zone (visibility, archive) | Admin | |
| 258 | | Transfer and delete | An owner of the workspace | |
| 259 | |
| 260 | Someone without the role does not see the tab. |
| 261 | |
| 262 | ## Create a project |
| 263 | |
| 264 | 1. In the workspace the project belongs to, choose **New project** in the |
| 265 | sidebar, or go to `g1t.sh/new`. It's made in the workspace you're in; to |
| 266 | make one somewhere else, switch workspaces first. |
| 267 | 2. Choose where its code comes from: |
| 268 | - **Start empty**: a new repository on g1t. |
| 269 | - **Import code**: copy a public repository from GitHub or any git host |
| 270 | into a new one on g1t, with every branch and tag (up to 40 MB of |
| 271 | history). |
| 272 | - **Import from GitHub**: import repositories you can reach on GitHub, |
| 273 | private ones too, with every branch and tag and, if you like, their |
| 274 | issues. See [GitHub](/guides/github/). |
| 275 | 3. Give it a name and say who can see it, then choose **Create project**. |
| 276 | |
| 277 | Pushing a repository that does not exist yet makes one, and with it a |
| 278 | project: |
| 279 | |
| 280 | ```sh |
| 281 | git push https://g1t.sh/acme/my-app.git main |
| 282 | ``` |
| 283 | |
| 284 | ## Sources |
| 285 | |
| 286 | A project's source is a repository hosted on g1t: one you pushed, or one |
| 287 | imported from GitHub or any git host. See |
| 288 | [GitHub](/guides/github/#import-a-repository). |
| 289 | |
| 290 | Coming next: |
| 291 | |
| 292 | - **Several projects on one repository**, each from its own root |
| 293 | directory, with a push building only the projects it touched. |
| 294 | |
| 295 | ## From the API |
| 296 | |
| 297 | Projects keep their repository's routes: `/repos/{workspace}/{project}/…` |
| 298 | reaches the project's repository, and its secrets and variables are the |
| 299 | project's. See the [API reference](/reference/api/). |
| 300 | |
| 301 | What a project is, where it runs and its links have routes of their own, |
| 302 | and actions on the [MCP](/reference/mcp/) `workspace` tool: |
| 303 | |
| 304 | | Route | MCP action | | |
| 305 | | --- | --- | --- | |
| 306 | | `GET /workspaces/{workspace}/projects` | `list_projects` | The workspace's projects you can see. | |
| 307 | | `GET /workspaces/{workspace}/projects/{project}` | `get_project` | One project, with `kind`, `runs`, `production_url`, `setting`, `detected` and `links`. | |
| 308 | | `PATCH /workspaces/{workspace}/projects/{project}` | `update_project` | Changes `kind`, `runs`, `production_url`, `homepage`, `docs_url`, `links`, or its name, description or root directory. Needs `repo:write`. | |
| 309 | |
| 310 | To say an app is deployed by your own pipeline, with its docs: |
| 311 | |
| 312 | ```sh |
| 313 | curl -X PATCH https://api.g1t.sh/workspaces/acme/projects/web \ |
| 314 | -H "Authorization: Bearer $G1T_TOKEN" \ |
| 315 | -H "Content-Type: application/json" \ |
| 316 | -d '{"runs": "elsewhere", "production_url": "https://acme.dev", "docs_url": "https://docs.acme.dev"}' |
| 317 | ``` |