Skip to content

Commit e6880e7

Browse files
author
brandon.m@electronicscience.net
committed
Refactor GitHub context retrieval and improve remote URL fetching for submodules
1 parent 18132d6 commit e6880e7

2 files changed

Lines changed: 53 additions & 11 deletions

File tree

src/commands/triggerWorkflowRun.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import * as vscode from "vscode";
22

3-
import {getGitHead, getGitHubContextForWorkspaceUri, GitHubRepoContext} from "../git/repository";
3+
import {getGitHead, getGitHubContextForWorkspaceUri, GitHubRepoContext, getGitExtension} from "../git/repository";
44
import {getRepositoryRootForDocumentUri} from "../git/submoduleHelper";
55
import {getWorkflowUri, parseWorkflowFile} from "../workflow/workflow";
6+
import {Protocol} from "../external/protocol";
67

78
import {Workflow} from "../model";
89

@@ -11,6 +12,40 @@ interface TriggerRunCommandOptions {
1112
gitHubRepoContext: GitHubRepoContext;
1213
}
1314

15+
async function getGitHubContextForRepository(repositoryUri: vscode.Uri): Promise<GitHubRepoContext | undefined> {
16+
let context = await getGitHubContextForWorkspaceUri(repositoryUri);
17+
if (context) {
18+
return context;
19+
}
20+
21+
const git = await getGitExtension();
22+
if (!git) {
23+
return undefined;
24+
}
25+
26+
for (const repository of git.repositories) {
27+
if (repository.rootUri.fsPath === repositoryUri.fsPath) {
28+
await repository.status();
29+
const remote = repository.state.remotes.find(r => r.name === "origin") || repository.state.remotes[0];
30+
31+
if (remote?.pushUrl) {
32+
try {
33+
const protocol = new Protocol(remote.pushUrl);
34+
return {
35+
owner: protocol.owner,
36+
name: protocol.repositoryName,
37+
client: undefined as any
38+
} as GitHubRepoContext;
39+
} catch {
40+
return undefined;
41+
}
42+
}
43+
}
44+
}
45+
46+
return undefined;
47+
}
48+
1449
export function registerTriggerWorkflowRun(context: vscode.ExtensionContext) {
1550
context.subscriptions.push(
1651
vscode.commands.registerCommand(
@@ -39,7 +74,7 @@ export function registerTriggerWorkflowRun(context: vscode.ExtensionContext) {
3974
repositoryUri = workspaceFolder.uri;
4075
}
4176

42-
const gitHubRepoContext = await getGitHubContextForWorkspaceUri(repositoryUri);
77+
const gitHubRepoContext = await getGitHubContextForRepository(repositoryUri);
4378
if (!gitHubRepoContext) {
4479
return;
4580
}
@@ -93,7 +128,7 @@ export function registerTriggerWorkflowRun(context: vscode.ExtensionContext) {
93128
try {
94129
const workflowPath = workflowUri.fsPath;
95130
const repositoryPath = repositoryUri.fsPath;
96-
const relativeWorkflowPath = workflowPath.substring(repositoryPath.length + 1);
131+
const relativeWorkflowPath = require("path").relative(repositoryPath, workflowPath).replace(/\\/g, "/");
97132

98133
await gitHubRepoContext.client.actions.createWorkflowDispatch({
99134
owner: gitHubRepoContext.owner,

src/git/submoduleHelper.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,27 @@ import * as path from "path";
44
import {getGitExtension} from "./repository";
55
import {logDebug} from "../log";
66

7-
async function getGitRemoteForPath(documentPath: string): Promise<string | undefined> {
7+
async function getGitRemoteForPath(directoryPath: string): Promise<string | undefined> {
88
try {
9-
const dir = path.dirname(documentPath);
10-
const cp = await import("child_process");
9+
const fs = await import("fs/promises");
10+
const stats = await fs.stat(directoryPath);
11+
const cwd = stats.isDirectory() ? directoryPath : path.dirname(directoryPath);
12+
13+
const child_process = await import("child_process");
1114
const util = await import("util");
12-
const execPromise = util.promisify(cp.exec);
13-
const {stdout} = await execPromise("git config --get remote.origin.url", {cwd: dir});
15+
const execFile = util.promisify(child_process.execFile);
16+
const {stdout} = await execFile("git", ["config", "--get", "remote.origin.url"], {cwd});
1417
return stdout.trim();
1518
} catch {
1619
return undefined;
1720
}
1821
}
1922

23+
function isPathWithin(childPath: string, parentPath: string): boolean {
24+
const relative = path.relative(parentPath, childPath);
25+
return !relative.startsWith("..") && !path.isAbsolute(relative);
26+
}
27+
2028
export async function getRepositoryRootForDocumentUri(documentUri: vscode.Uri): Promise<vscode.Uri | undefined> {
2129
const git = await getGitExtension();
2230
if (!git || git.repositories.length === 0) {
@@ -28,14 +36,13 @@ export async function getRepositoryRootForDocumentUri(documentUri: vscode.Uri):
2836
for (const repository of git.repositories) {
2937
const repoPath = repository.rootUri.fsPath;
3038

31-
if (documentPath.startsWith(repoPath)) {
32-
await repository.status();
39+
if (isPathWithin(documentPath, repoPath)) {
3340
const state = repository.state;
3441

3542
if (state && state.submodules && state.submodules.length > 0) {
3643
for (const submodule of state.submodules) {
3744
const submodulePath = path.join(repoPath, submodule.path);
38-
if (documentPath.startsWith(submodulePath)) {
45+
if (isPathWithin(documentPath, submodulePath)) {
3946
logDebug("Found document in submodule:", submodule.path);
4047
const remoteUrl = await getGitRemoteForPath(submodulePath);
4148
if (remoteUrl) {

0 commit comments

Comments
 (0)