Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh

Commit

An app that deploys itself says so, instead of "Deployed elsewhere". A project whose own workflows (or another pipeline) deploy it, as g1t's do, read as if g1t had nothing to do with it: grey "Deployed elsewhere" in the workspace's Projects, "App, deployed elsewhere" on its badge, and the API said `runs` is `g1t` "when g1t deploys it". What tells the two apart is who hosts it, so they are now named that way: App or site, hosted on g1t.page (badge App on g1t.page) and App or site that deploys itself (badge App, deploys itself), in settings, the badge's menu, the overview's "Where does it run?" (It deploys itself), the Deployments pages, the guides and the API's descriptions; `runs` keeps its values. In Projects an app that deploys itself shows the rocket, Deploys itself, and the Deploys filter counts it. Its production card says which workflow run deployed it when g1t Actions did ("deployed 16m ago by its workflow"), else "by its own pipeline". An app nobody has placed that deploys production itself (a successful production deployment from a workflow or the API, not g1t.page's) now deploys itself everywhere, where before only its overview inferred it: the projects service keeps that it has (migration 0013, `reports_production`), and Deployments being on or a setting still win. Checked: the site's typecheck (tsc -b --force), its 911 tests and a production build; the projects service's typecheck and 49 tests (new: an app that deploys production itself); the API's openapi tests with the docs copy regenerated; the deploy tool's 92 tests.

syntaqxcommitted Parent6cd780fBrowse files
21 files+77−605 files not counted0/21 viewed
+3−3
17451745 Op::GetContents => crate::contents::description(),
17461746 Op::ListCommits => crate::commits::description(),
17471747 Op::ListProjects => {
1748− "A workspace's projects that you can see, by name. A project is what a workspace builds and runs, from a repository or a root directory in one; every repository has a project of its own name. Each has what it is (`kind`: app, library, tool, docs or other) and why (`kind_reason`), where it runs (`runs`: `g1t` when g1t deploys it, `elsewhere` when it is deployed by other means, at `production_url`), and its `links`."
1748+ "A workspace's projects that you can see, by name. A project is what a workspace builds and runs, from a repository or a root directory in one; every repository has a project of its own name. Each has what it is (`kind`: app, library, tool, docs or other) and why (`kind_reason`), where it runs (`runs`: `g1t` when it is hosted on g1t.page, `elsewhere` when it deploys itself to hosting of its own, with a workflow on g1t Actions or another pipeline, at `production_url`), and its `links`."
17491749 }
17501750 Op::GetProject => {
17511751 "A project: what it is (`kind`, and `kind_reason` saying why), where it runs (`runs` and `production_url`), what you set and what detection decides (`setting` and `detected`), its repository and `root_dir`, and its homepage, docs and other `links`. A private repository's project is found only by those who can see the repository."
30503050 "runs": {
30513051 "type": "string",
30523052 "enum": ["auto", "g1t", "elsewhere"],
3053− "description": "Where it runs: g1t when g1t deploys it, elsewhere when it is deployed by other means. auto leaves it to Deployments.",
3053+ "description": "Where it runs: g1t when it is hosted on g1t.page, elsewhere when it deploys itself (a workflow on g1t Actions, or another pipeline) to hosting of its own. auto leaves it to Deployments, and to whether it has deployed production itself.",
30543054 },
3055− "production_url": { "type": ["string", "null"], "description": "Production's address when it runs elsewhere. null or \"\" clears it." },
3055+ "production_url": { "type": ["string", "null"], "description": "Production's address when it deploys itself. null or \"\" clears it." },
30563056 "homepage": { "type": ["string", "null"], "description": "Its homepage. null or \"\" follows its repository's website again." },
30573057 "docs_url": { "type": ["string", "null"], "description": "Where its documentation is read. null or \"\" clears it." },
30583058 "links": {
+3−3
71917191 "kind": "app",
71927192 "kind_reason": {
71937193 "by": "set",
7194− "detail": "Set to an app that runs elsewhere."
7194+ "detail": "Set in its settings: it deploys itself."
71957195 },
71967196 "runs": "elsewhere",
71977197 "production_url": "https://g1t.sh",
72907290 "kind": "app",
72917291 "kind_reason": {
72927292 "by": "set",
7293− "detail": "Set to an app that runs elsewhere."
7293+ "detail": "Set in its settings: it deploys itself."
72947294 },
72957295 "runs": "elsewhere",
72967296 "production_url": "https://g1t.sh",
73577357 "kind": "app",
73587358 "kind_reason": {
73597359 "by": "set",
7360− "detail": "Set to an app that runs elsewhere."
7360+ "detail": "Set in its settings: it deploys itself."
73617361 },
73627362 "runs": "elsewhere",
73637363 "production_url": "https://g1t.sh",
+1−1
2727 | **Branches** | Beside each branch's latest commit |
2828 | **Tags** | Beside each tagged commit |
2929 | A pull request | Beside its head commit, in the sidebar; its merge box lists them too |
30−| A project's overview | For an app deployed elsewhere that has reported no deployment, beside the latest commit in its production card |
30+| A project's overview | For an app that deploys itself and has reported no deployment, beside the latest commit in its production card |
3131
3232 A page reads the checks of all its commits at once, after the page itself
3333 has loaded: each mark shows a placeholder until they arrive.
+7−6
7878 Production starts building at once from the default branch. Every pull
7979 request opened or pushed to from then on gets a preview.
8080
81−Deployments are for projects g1t runs. Not every project is one: a
81+Deployments are for projects g1t.page hosts. Not every project is one: a
8282 library, a tool or documentation is published rather than deployed, and
83−an app may be deployed by its own pipeline somewhere else. Only a project
84−that is [an app or site deployed on g1t](/guides/projects/#what-a-project-is)
83+an app may deploy itself, with [a workflow](#deploying-from-a-workflow)
84+or another pipeline, to hosting of its own. Only a project that is
85+[an app or site hosted on g1t.page](/guides/projects/#what-a-project-is)
8586 is asked to turn deployments on. Any other project's **Deployments** page
86−still turns them on; doing so makes it an app deployed on g1t, including
87−one that was deployed elsewhere. A project set to be a library, a tool or
87+still turns them on; doing so makes it an app hosted on g1t.page,
88+including one that deployed itself. A project set to be a library, a tool or
8889 something else cannot have deployments turned on until that setting
8990 changes.
9091
423424 uploaded image shows instead.
424425 - Screenshots are not charged.
425426
426−An app deployed elsewhere gets a screenshot of its production address
427+An app that deploys itself gets a screenshot of its production address
427428 too, and any project can show an uploaded image instead. See
428429 [production's picture](/guides/projects/#productions-picture).
429430
+14−14
5959
6060 | Part | What it shows |
6161 | --- | --- |
62−| **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. |
63−| **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. |
62+| **What it is** | A badge, such as **App, deploys itself** 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. |
63+| **Production** | [Production's picture](#productions-picture), which opens the live site, beside the rest. For an app [hosted on g1t.page](/guides/deployments/): its address, the commit it runs and when it went up; **Visit** and **Redeploy**. For an app that deploys itself: production's address and **Visit**, with its latest reported production deployment (and the workflow run that made it, when g1t Actions did) or the default branch's latest commit. For an app nobody has placed yet: one question, where it runs. |
6464 | **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. |
6565 | **Documentation**, **Homepage** | For docs, where they are read; for anything else, its homepage. |
6666 | **Facts** | Under production: its latest release (or, where the card does not already say it, production's state), how often checks pass, and either how many changes pass on the first try and what is open, or, for people with a role when [Observability](/guides/observability/) has data, requests and the error rate over the last day with how many errors are open. |
7878 The production card always has a picture of the app, wherever it runs.
7979 It is the first of these there is:
8080
81−1. **A screenshot of production.** For an app deployed on g1t, g1t takes
81+1. **A screenshot of production.** For an app hosted on g1t.page, g1t takes
8282 one each time production goes live (see
8383 [the production screenshot](/guides/deployments/#the-production-screenshot));
8484 people with a role on the repository see it, like the rest of its
85− deployments. For an app deployed elsewhere, g1t takes one of
85+ deployments. For an app that deploys itself, g1t takes one of
8686 production's address: the address its latest production deployment
8787 reported to g1t gives, or else the one set for it under **What it is**.
8888 Anyone who can see the project sees it.
9292 the project's settings see **Add an image of your app** on it, which
9393 opens **Production image**.
9494
95−A screenshot of production deployed elsewhere is taken:
95+A screenshot of an app that deploys itself is taken:
9696
9797 - when its address is set or changed;
9898 - when a production deployment of it is reported to g1t and succeeds,
123123 first one, when one cannot be taken, or for an app with no production
124124 address.
125125 - **Use the uploaded image instead of a screenshot** shows it in place of
126− any screenshot. While it is on, g1t takes no screenshots of production
127− deployed elsewhere.
126+ any screenshot. While it is on, g1t takes no screenshots of an app
127+ that deploys itself.
128128 - **Remove** takes it away; the card goes back to the screenshot or the
129129 frame.
130130
138138
139139 | What it is | Its overview shows |
140140 | --- | --- |
141−| **App or site, deployed on g1t** | Production on g1t.page, with previews and domains. |
142−| **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. |
141+| **App or site, hosted on g1t.page** | g1t builds and hosts it: production on g1t.page, with previews and domains. |
142+| **App or site that deploys itself** | Its own [workflows](/guides/deployments/#deploying-from-a-workflow) on g1t Actions, or another pipeline, deploy it to hosting of its own. Production at the address its deployments report or you give, with **Visit**. It is never asked to turn on Deployments; Deployment settings stay one link away. |
143143 | **Library or package** | The packages its repository publishes and how to install them. |
144144 | **Tool or CLI** | The same as a library: its packages and releases. |
145145 | **Documentation** | Where its docs are read. Docs can be published on g1t.page too, by turning on Deployments. |
152152 Until you say, g1t works it out for itself, in this order:
153153
154154 1. If [Deployments](/guides/deployments/) are on for the project, it is
155− an app deployed on g1t.
155+ an app hosted on g1t.page.
156156 2. If its repository publishes a package other than a container image,
157157 such as a [Composer](/guides/composer/) or [npm](/guides/npm/)
158158 package, it is a library.
178178
179179 An app found this way runs on g1t only while Deployments are on. Until
180180 you say where it runs, its overview asks, in place of production:
181−**Deploy on g1t**, **It's deployed elsewhere** (with production's
181+**Deploy on g1t**, **It deploys itself** (with production's
182182 address), or **It isn't deployed** (a library, a tool, documentation or
183183 something else).
184184
187187 From the overview, open the badge beside its name, such as **App**, and
188188 choose one. Or open **Settings**, then **General**, and under **What it
189189 is** choose **Detect automatically**, which shows what was detected and
190−why, or one of the kinds above. **App or site, deployed elsewhere** asks
190+why, or one of the kinds above. **App or site that deploys itself** asks
191191 for production's address.
192192
193193 Choosing a library, a tool or something else while Deployments are on is
194194 refused: turn them off first under **Settings**, then **Deployments**;
195195 g1t does not turn them off for you. While it is set that way, Deployments
196−cannot be turned on. Turning Deployments on for an app deployed elsewhere
197−makes it an app deployed on g1t.
196+cannot be turned on. Turning Deployments on for an app that deploys itself
197+makes it an app hosted on g1t.page.
198198
199199 Changing what it is needs the role that changes the project's settings.
200200
+0−0

Binary or large file; its contents are not shown.

+3−3
134134
135135 /**
136136 * What a project is, as a choice of one, with production's address beside
137− * Deployed elsewhere. Posts `choice` and `productionUrl`. `blocked` says
137+ * Deploys itself. Posts `choice` and `productionUrl`. `blocked` says
138138 * why a choice that stops it deploying cannot be saved yet.
139139 */
140140 export function KindFields({
193193
194194 /** The one-click choices the overview offers, without Detect, in order. */
195195 const MENU: { value: KindChoice; label: string }[] = [
196− { value: "g1t", label: "Deployed on g1t" },
197− { value: "elsewhere", label: "Deployed elsewhere" },
196+ { value: "g1t", label: "Hosted on g1t.page" },
197+ { value: "elsewhere", label: "Deploys itself" },
198198 { value: "library", label: "Library or package" },
199199 { value: "tool", label: "Tool or CLI" },
200200 { value: "docs", label: "Documentation" },
+23−10
11 /**
2− * The top of a project's overview for what g1t does not deploy: an app
3− * deployed elsewhere, an app nobody has said where it runs, docs, and
2+ * The top of a project's overview for what g1t.page does not host: an app
3+ * that deploys itself, an app nobody has said where it runs, docs, and
44 * anything else. An app on g1t keeps its production card, and a library
55 * or a tool its packages (routes/repo/overview.tsx).
66 */
1717 import { Hint } from "./ui/hint";
1818
1919 /**
20− * A deployment reported to g1t from outside it, such as by a pipeline that
21− * deploys production itself. When there is one for production, the card
22− * shows it.
20+ * A deployment g1t.page did not build: one a workflow's job made, or one
21+ * reported by another pipeline. When there is one for production, the
22+ * card shows it.
2323 */
2424 export type ExternalDeployment = {
2525 environment: string;
2828 state: string;
2929 sha: string;
3030 created_at: string;
31+ /** The workflow run that made it, when g1t Actions did. */
32+ run_url?: string | null;
3133 };
3234
3335 /** A reported deployment's state, as g1t's own deployments show theirs. */
120122 }
121123
122124 /**
123− * An app deployed by its own pipeline: production at the address it was
125+ * An app that deploys itself (its workflows, or another pipeline): production at the address it was
124126 * given, with the latest reported deployment, or else the default branch's
125127 * latest commit and its checks.
126128 */
161163 </span>
162164 <span>
163165 deployed <TimeAgo at={deployment.created_at} />
166+ {deployment.run_url ? (
167+ <>
168+ {" "}
169+ by{" "}
170+ <Link to={deployment.run_url} className="underline-offset-4 hover:text-fg hover:underline">
171+ its workflow
172+ </Link>
173+ </>
174+ ) : (
175+ " by its own pipeline"
176+ )}
164177 </span>
165178 </>
166179 ) : (
167180 <>
168− <span>Deployed by its own pipeline</span>
181+ <span>Deploys itself</span>
169182 {commit && (
170183 <span className="inline-flex items-center gap-1.5">
171184 <span className="text-faint">·</span>
185198 <>
186199 <p className="mt-2 text-lg font-medium">Where is production?</p>
187200 <p className="mt-1 max-w-lg text-sm text-muted">
188− {project.name} is deployed by its own pipeline. Give production's address, and this card links to it.
201+ {project.name} deploys itself. Give production's address, and this card links to it.
189202 </p>
190203 <AddressForm field="productionUrl" placeholder="https://example.com" label="Production's address" extra={{ intent: "kind", choice: "elsewhere" }} />
191204 </>
192205 ) : (
193− <p className="mt-2 text-sm text-muted">Deployed by its own pipeline.</p>
206+ <p className="mt-2 text-sm text-muted">Deploys itself.</p>
194207 )}
195208 <DeployQuietly base={base} canDeploy={canDeploy} what="it" />
196209 </div>
251264 variant="outline"
252265 >
253266 <Globe size={14} />
254− It's deployed elsewhere
267+ It deploys itself
255268 </Button>
256269 <DropdownMenu>
257270 <DropdownMenuTrigger asChild>
+5−2
142142
143143 /**
144144 * Production deployed somewhere other than g1t.page (by g1t Actions, or
145− * reported through the API), as an app deployed elsewhere shows it: the
145+ * reported through the API), as an app that deploys itself shows it: the
146146 * production environment's latest deployment, when it is not a g1t.page
147− * build. `created_at` is its latest status.
147+ * build. `created_at` is its latest status; `run_url` the workflow run
148+ * that made it, for one g1t Actions made.
148149 */
149150 export function reportedProduction(environments: readonly DeploymentEnvironment[]): {
150151 environment: string;
152153 state: string;
153154 sha: string;
154155 created_at: string;
156+ run_url: string | null;
155157 } | null {
156158 const reported = productionEnvironment(environments);
157159 if (!reported?.latest || reported.latest.source === "g1t_page") return null;
161163 state: reported.latest.state,
162164 sha: reported.latest.sha,
163165 created_at: reported.latest.updated_at,
166+ run_url: reported.latest.source === "actions" ? reported.latest.run_url : null,
164167 };
165168 }
166169
+2−2
6969 });
7070
7171 test("a project's badge says what it is and where it runs", () => {
72− assert.equal(kindLabel({ kind: "app", runs: "elsewhere" }), "App, deployed elsewhere");
73− assert.equal(kindLabel({ kind: "app", runs: "g1t" }), "App on g1t");
72+ assert.equal(kindLabel({ kind: "app", runs: "elsewhere" }), "App, deploys itself");
73+ assert.equal(kindLabel({ kind: "app", runs: "g1t" }), "App on g1t.page");
7474 assert.equal(kindLabel({ kind: "app", runs: null }), "App");
7575 assert.equal(kindLabel({ kind: "tool", runs: null }), "Tool");
7676 assert.equal(kindLabel({ kind: "other", runs: null }), "Project");
+5−5
4747 /** The choices for "What it is" in a project's settings, in order. */
4848 export const KIND_CHOICES: { value: KindChoice; label: string; hint: string }[] = [
4949 { value: "auto", label: "Detect automatically", hint: "From whether Deployments are on, the packages it publishes and the files at its root." },
50− { value: "g1t", label: "App or site, deployed on g1t", hint: "g1t builds it: production on g1t.page from the default branch, and a preview for every pull request." },
50+ { value: "g1t", label: "App or site, hosted on g1t.page", hint: "g1t builds and hosts it: production on g1t.page from the default branch, and a preview for every pull request." },
5151 {
5252 value: "elsewhere",
53− label: "App or site, deployed elsewhere",
54− hint: "Your own pipeline deploys it. Its overview shows production at the address you give.",
53+ label: "App or site that deploys itself",
54+ hint: "Its own workflows on g1t Actions, or another pipeline, deploy it to your hosting. Its overview shows production at the address it reports or you give.",
5555 },
5656 { value: "library", label: "Library or package", hint: "Installed by other code: its overview shows its packages and releases." },
5757 { value: "tool", label: "Tool or CLI", hint: "Installed and run by people: its overview shows its releases and packages." },
7777 export function kindLabel(project: Pick<Project, "kind" | "runs">): string {
7878 switch (project.kind) {
7979 case "app":
80− return project.runs === "g1t" ? "App on g1t" : project.runs === "elsewhere" ? "App, deployed elsewhere" : "App";
80+ return project.runs === "g1t" ? "App on g1t.page" : project.runs === "elsewhere" ? "App, deploys itself" : "App";
8181 case "library":
8282 return "Library";
8383 case "tool":
8484 return "Tool";
8585 case "docs":
86− return project.runs === "g1t" ? "Docs on g1t" : "Docs";
86+ return project.runs === "g1t" ? "Docs on g1t.page" : "Docs";
8787 default:
8888 return "Project";
8989 }
+1−1
6161 python: "Python",
6262 };
6363
64−/** What the list needs of a project, with whether its Deployments are on. */
64+/** What the list needs of a project, with whether it deploys: on g1t.page, or by its own workflows. */
6565 export type Listed = Pick<
6666 Project,
6767 "id" | "slug" | "name" | "description" | "private" | "archived" | "kind" | "ecosystem" | "updatedAt" | "pushedAt" | "activity"
+2−2
710710 </p>
711711 {pages.notDeploying ? (
712712 <p className="mt-4 max-w-2xl text-sm text-muted">
713− This project is set to be something that doesn't deploy here, such as a library, a tool or an app deployed
714− elsewhere. To host it on g1t.page, choose App or site, deployed on g1t, in{" "}
713+ This project is set to be something that doesn't deploy here, such as a library, a tool or an app that
714+ deploys itself. To host it on g1t.page, choose App or site, hosted on g1t.page, in{" "}
715715 <Link to={`${base}/settings#kind`} className="text-fg underline underline-offset-4">
716716 its settings
717717 </Link>{" "}
+1−1
142142 {notDeploying ? (
143143 <p className="mt-4 text-sm text-muted">
144144 This project is set to be something that doesn't deploy, such as a library or a tool. To deploy it, choose
145− App or site, deployed on g1t, under{" "}
145+ App or site, hosted on g1t.page, under{" "}
146146 <Link to={`${base}/settings#kind`} className="text-fg underline underline-offset-4">
147147 General
148148 </Link>{" "}
+4−4
6767 description: form.get("inherit") === "description" ? null : String(form.get("description") ?? ""),
6868 rootDir: String(form.get("rootDir") ?? ""),
6969 ...(set ?? {}),
70− // Production's address is asked for beside Deployed elsewhere, and kept otherwise.
70+ // Production's address is asked for beside Deploys itself, and kept otherwise.
7171 ...(form.has("productionUrl") ? { productionUrl: String(form.get("productionUrl")) } : {}),
7272 homepage: String(form.get("homepage") ?? ""),
7373 docsUrl: String(form.get("docsUrl") ?? ""),
173173 </h2>
174174 <p className="max-w-2xl text-xs text-muted">
175175 Its overview follows: production for what is deployed, packages and releases for a library or a tool, and
176− the steps that apply to it. Only an app or site deployed on g1t is asked to turn on Deployments.
176+ the steps that apply to it. Only an app or site hosted on g1t.page is asked to turn on Deployments.
177177 </p>
178178 <KindFields project={project} choice={choice} onChoice={setChoice} />
179179 {blocked && (
229229 Production image
230230 </h2>
231231 <p className="max-w-2xl text-xs text-muted">
232− The picture on its overview's production card. A screenshot is taken by itself for an app deployed on g1t,
233− and of production's address for one deployed elsewhere, about once a day and after each production deployment
232+ The picture on its overview's production card. A screenshot is taken by itself for an app hosted on g1t.page,
233+ and of production's address for one that deploys itself, about once a day and after each production deployment
234234 reported to g1t.
235235 </p>
236236 <ProductionImageField
+3−3
6565 updatedAt: project.updatedAt,
6666 pushedAt: project.pushedAt ?? null,
6767 activity: project.activity ?? 0,
68− deploying: live.get(project.slug)?.enabled ?? false,
68+ // Hosted on g1t.page, or an app that deploys itself (its own workflows or pipeline).
69+ deploying: (live.get(project.slug)?.enabled ?? false) || (project.kind === "app" && project.runs === "elsewhere"),
6970 }));
7071 const matched = filterProjects(all, query);
7172 const shown = pageOf(matched, query.page);
101102 <>
102103 {language && <span>{language}</span>}
103104 {project.kind !== "app" && <span>{kindLabel(project)}</span>}
104− {project.kind === "app" && project.runs === "elsewhere" && <span>Deployed elsewhere</span>}
105105 {project.deploying && (
106106 <span className="inline-flex items-center gap-1 text-success">
107107 <Rocket size={11} />
108− Deploys
108+ {project.runs === "elsewhere" ? "Deploys itself" : "Deploys"}
109109 </span>
110110 )}
111111 <span className="text-faint">
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…

Comments

Sign in to comment.