Skip to content

Compare changes

Choose two branches to see what one has that the other does not, then open a pull request for it.

Open a pull request

1 commit

6 files+46−190/6 viewed
+1−1
646646 const words: Record<string, string> = {
647647 settings: "Account",
648648 explore: "Explore",
649− new: "New repository",
649+ new: "New project",
650650 search: "Search",
651651 workspaces: "New workspace",
652652 };
+2−2
169169 <>
170170 <Link
171171 to="/new"
172− aria-label="New repository"
172+ aria-label="New project"
173173 className="rounded-md border border-line p-1.5 text-muted transition-colors hover:border-line-strong hover:text-fg"
174174 >
175175 <Plus size={16} />
214214 <DropdownMenuItem asChild>
215215 <Link to="/new">
216216 <Plus />
217− New repository
217+ New project
218218 </Link>
219219 </DropdownMenuItem>
220220 <DropdownMenuSeparator />
+1−1
8080 {role && (
8181 <ButtonLink to={`/new?workspace=${workspace.slug}`}>
8282 <Plus size={15} />
83− New repository
83+ New project
8484 </ButtonLink>
8585 )}
8686 </div>
+7−6
482482 /// and its running app get.
483483 pub async fn resolve_settings(&self, a: ResolveSettingsArgs) -> Result<ResolvedSettings> {
484484 let environment = a.environment.as_deref();
485− let (project_id, slug) = match (a.project_id, a.project_slug) {
486− (Some(id), Some(slug)) => (id, slug),
487− _ => match self.project_of(&a.repo_id).await? {
488− Some(project) => (project.id, project.slug),
489− None => return Ok(ResolvedSettings::default()),
490− },
485+ // Rows kept under the repository from before projects move to its
486+ // primary project first, however the project is named here.
487+ let primary = self.project_of(&a.repo_id).await?;
488+ let (project_id, slug) = match (a.project_id, a.project_slug, primary) {
489+ (Some(id), Some(slug), _) => (id, slug),
490+ (_, _, Some(project)) => (project.id, project.slug),
491+ _ => return Ok(ResolvedSettings::default()),
491492 };
492493 Ok(ResolvedSettings {
493494 secrets: self
+23−2
3333 /** Serves the site's files, for an app that brings no code of its own. */
3434 const ASSETS_ONLY = `export default { fetch(request, env) { return env.ASSETS.fetch(request); } };\n`;
3535
36−const HTML_HANDLING = ["auto-trailing-slash", "force-trailing-slash", "drop-trailing-slash", "none"];
36+/** What an app answers between being taken down and being gone. */
37+const TAKEN_DOWN = `export default {
38+ fetch() {
39+ return new Response("<!doctype html><meta charset=utf-8><meta name=robots content=noindex><title>Not up</title><body style='font:16px system-ui;background:#121214;color:#ececf1;display:grid;place-items:center;min-height:100vh;margin:0'><main><h1>This app is not up</h1><p style='color:#9a9aa6'>It was taken down. Deploying it again brings it back.</p></main>", { status: 404, headers: { "content-type": "text/html; charset=utf-8", "x-robots-tag": "noindex", "cache-control": "no-store" } });
40+ },
41+};
42+`;
43+
44+const HTML_HANDLING =["auto-trailing-slash", "force-trailing-slash", "drop-trailing-slash", "none"];
3745 const NOT_FOUND_HANDLING = ["single-page-application", "404-page", "none"];
3846
3947 export class Cloudflare {
148156 );
149157 }
150158
151− /** Takes an app down. Already gone is fine. */
159+ /**
160+ * Takes an app down. Already gone is fine.
161+ *
162+ * A deleted app can keep answering for a while where Cloudflare still has
163+ * it warm. So it is first replaced by a notice that it is down, which
164+ * reaches the edge as fast as any deploy, and deleted after.
165+ */
152166 async deleteScript(script: string): Promise<void> {
167+ const form = new FormData();
168+ form.append(
169+ "metadata",
170+ JSON.stringify({ main_module: "index.js", compatibility_date: "2026-09-26", bindings: [], tags: ["taken-down"] }),
171+ );
172+ form.append("index.js", new File([TAKEN_DOWN], "index.js", { type: "application/javascript+module" }));
173+ await this.call("PUT", this.scriptPath(script), form).catch(() => undefined);
153174 try {
154175 await this.call("DELETE", `${this.scriptPath(script)}?force=true`);
155176 } catch (error) {
+12−7
22 * The dispatcher for g1t.page: every app deployed by g1t is served here.
33 *
44 * The hostname's first label is the app's script name in the Workers for
5− * Platforms namespace (`pr-12--web--acme.g1t.page` is pull request 12's
6− * preview of acme/web), so a request needs no lookup: the app is fetched
7− * by name and runs only for as long as it answers. An app no one visits
5+ * Platforms namespace (`web-git-fix-login-acme.g1t.page` is the fix-login
6+ * branch's preview of acme's web project), so a request needs no lookup:
7+ * the app is fetched by name and runs only for as long as it answers. An app no one visits
88 * runs nothing and costs nothing.
99 *
1010 * Kept apart from g1t.sh, so apps share no cookies or origin with the site
8181 );
8282 }
8383 // Previews are for the people reviewing a change, not search engines.
84− if (label.startsWith("pr-")) {
84+ if (isPreview(label)) {
8585 response = new Response(response.body, response);
8686 response.headers.set("x-robots-tag", "noindex");
8787 }
8989 },
9090 } satisfies ExportedHandler<Env>;
9191
92+/** A branch's preview: `<project>-git-<branch>-<workspace>`. */
93+function isPreview(label: string): boolean {
94+ return label.includes("-git-");
95+}
96+
9297 function missing(label: string): Response {
93− const preview = label.startsWith("pr-");
98+ const preview = isPreview(label);
9499 return page(
95100 404,
96101 preview ? "This preview is not up" : "Nothing deployed here",
97102 preview
98− ? `<p>A preview comes down when its pull request is closed or merged, or after its repository's idle days without a visit. Pushing to the pull request, or redeploying it from the repository's Deployments page, brings it back.</p>`
99− : `<p>No app is deployed at <code>${escape(label)}.${DOMAIN}</code>. Deployments are turned on per repository, from its Deployments page on g1t.</p>`,
103+ ? `<p>A preview comes down when its pull request is closed or merged, or after its project's idle days without a visit. Pushing to the branch, or redeploying it from the project's Deployments page, brings it back.</p>`
104+ : `<p>No app is deployed at <code>${escape(label)}.${DOMAIN}</code>. Deployments are turned on per project, from its Settings on g1t.</p>`,
100105 );
101106 }