Skip to content

Commit 5830afc

Browse files
committed
support SSH github remotes
1 parent a7ba250 commit 5830afc

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

src/deploy.ts

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,37 @@ function settingsUrl(deployTarget: DeployTargetInfo) {
4949
return `${OBSERVABLE_UI_ORIGIN}projects/@${deployTarget.workspace.login}/${deployTarget.project.slug}`;
5050
}
5151

52+
/**
53+
* Returns the ownerName and repoName of the first GitHub remote (HTTPS or SSH)
54+
* on the current repository, or null.
55+
*/
56+
async function getGitHubRemote() {
57+
const remotes = (await promisify(exec)("git remote -v")).stdout
58+
.split("\n")
59+
.filter((d) => d)
60+
.map((d) => {
61+
const [, url] = d.split(/\s/g);
62+
if (url.startsWith("https://github.com/")) {
63+
// HTTPS: https://github.com/observablehq/framework.git
64+
const [ownerName, repoName] = new URL(url).pathname
65+
.slice(1)
66+
.replace(/\.git$/, "")
67+
.split("/");
68+
return {ownerName, repoName};
69+
} else if (url.startsWith("[email protected]:")) {
70+
// SSH: git@github.com:observablehq/framework.git
71+
const [ownerName, repoName] = url
72+
.replace(/^git@github.com:/, "")
73+
.replace(/\.git$/, "")
74+
.split("/");
75+
return {ownerName, repoName};
76+
}
77+
});
78+
const remote = remotes.find((d) => d && d.ownerName && d.repoName);
79+
if (!remote) throw new CliError("No GitHub remote found.");
80+
return remote ?? null;
81+
}
82+
5283
export interface DeployOptions {
5384
config: Config;
5485
deployConfigPath: string | undefined;
@@ -246,28 +277,23 @@ class Deployer {
246277
if (deployTarget.create) {
247278
throw new Error("Incorrect deploy target state");
248279
}
249-
// We only support cloud builds from the root directory so this ignores this.deployOptions.config.root
280+
if (!deployTarget.project.build_environment_id) {
281+
// TODO: allow setting build environment from CLI
282+
throw new CliError("No build environment configured.");
283+
}
284+
// We only support cloud builds from the root directory so this ignores
285+
// this.deployOptions.config.root
250286
const isGit = existsSync(".git");
251287
if (!isGit) throw new CliError("Not at root of a git repository.");
252-
const remotes = (await promisify(exec)("git remote -v", {cwd: this.deployOptions.config.root})).stdout
253-
.split("\n")
254-
.filter((d) => d)
255-
.map((d) => d.split(/\s/g));
256-
const gitHub = remotes.find(([, url]) => url.startsWith("https://github.com/"));
257-
if (!gitHub) throw new CliError("No GitHub remote found.");
258-
// TODO: validate "Your branch is up to date" & "nothing to commit, working tree clean"
259-
260-
if (!deployTarget.project.build_environment_id) throw new CliError("No build environment configured.");
261-
// TODO: allow setting build environment from CLI
262-
263-
const [ownerName, repoName] = formatGitUrl(gitHub[1]).split("/");
264-
const branch = (await promisify(exec)("git rev-parse --abbrev-ref HEAD", {cwd: this.deployOptions.config.root}))
265-
.stdout;
266288

289+
const {ownerName, repoName} = await getGitHubRemote();
290+
const branch = (await promisify(exec)("git rev-parse --abbrev-ref HEAD")).stdout;
267291
let localRepo = await this.apiClient.getGitHubRepository({ownerName, repoName});
268292

269293
// If a source repository has already been configured, check that it’s
270-
// accessible and matches the local repository and branch
294+
// accessible and matches the local repository and branch.
295+
// TODO: validate local/remote refs match, "Your branch is up to date",
296+
// and "nothing to commit, working tree clean".
271297
if (deployTarget.project.source) {
272298
if (localRepo && deployTarget.project.source.provider_id !== localRepo.provider_id) {
273299
throw new CliError(
@@ -283,7 +309,6 @@ class Deployer {
283309
)}`
284310
);
285311
}
286-
// TODO: validate local/remote refs match
287312
const remoteAuthedRepo = await this.apiClient.getGitHubRepository({
288313
providerId: deployTarget.project.source.provider_id
289314
});
@@ -295,7 +320,7 @@ class Deployer {
295320
)}`
296321
);
297322
}
298-
323+
299324
// Configured repo is OK; proceed
300325
return;
301326
}

0 commit comments

Comments
 (0)