From 9fb1fb164ec7b6baf589f1d56df7f9b6df95c5fc Mon Sep 17 00:00:00 2001 From: John Brittain Date: Sat, 24 Aug 2024 11:54:18 +0100 Subject: [PATCH] Permit push/pull and refresh of github repo status --- electron-app/src/api.ts | 1 + electron-app/src/handles.ts | 8 +++ electron-app/src/main.ts | 3 ++ electron-app/src/preload.ts | 2 + electron-app/src/python/pyrunner.py | 10 ++++ nodemapper/src/api.ts | 1 + nodemapper/src/gui/Settings/RepoOptions.tsx | 55 +++++++++++++++++++-- runner/runner/github/__init__.py | 1 + runner/runner/github/github.py | 53 ++++++++++++++++++++ 9 files changed, 131 insertions(+), 3 deletions(-) diff --git a/electron-app/src/api.ts b/electron-app/src/api.ts index e8b88948..cb9e621b 100644 --- a/electron-app/src/api.ts +++ b/electron-app/src/api.ts @@ -57,6 +57,7 @@ export type SettingsAPI = { GithubUnstageFiles: (query: Query) => Promise; GithubCommit: (query: Query) => Promise; GithubClone: (query: Query) => Promise; + GithubCommitAllChanges: (query: Query) => Promise; }; declare global { diff --git a/electron-app/src/handles.ts b/electron-app/src/handles.ts index 16b7476c..4280f7b5 100644 --- a/electron-app/src/handles.ts +++ b/electron-app/src/handles.ts @@ -486,3 +486,11 @@ export async function settings_GithubClone( ) { return await SafeProcessQuery(event, query, stderr_callback); } + +export async function settings_GithubCommitAllChanges( + event: Event, + query: Query, + stderr_callback: (cmd: string) => void, +) { + return await SafeProcessQuery(event, query, stderr_callback); +} diff --git a/electron-app/src/main.ts b/electron-app/src/main.ts index e0d3e113..82e37731 100644 --- a/electron-app/src/main.ts +++ b/electron-app/src/main.ts @@ -207,6 +207,9 @@ app.whenReady().then(() => { ipcMain.handle('settings/github-clone', (event: Event, query: Query) => handles.settings_GithubClone(event, query, stderr_callback), ); + ipcMain.handle('settings/github-commit-all-changes', (event: Event, query: Query) => + handles.settings_GithubCommitAllChanges(event, query, stderr_callback), + ); }); app.on('will-quit', () => { diff --git a/electron-app/src/preload.ts b/electron-app/src/preload.ts index 7e37acac..ce9af768 100644 --- a/electron-app/src/preload.ts +++ b/electron-app/src/preload.ts @@ -74,6 +74,8 @@ contextBridge.exposeInMainWorld('settingsAPI', { GithubUnstageFiles: (query: Query) => ipcRenderer.invoke('settings/github-unstage-files', query), GithubCommit: (query: Query) => ipcRenderer.invoke('settings/github-commit', query), GithubClone: (query: Query) => ipcRenderer.invoke('settings/github-clone', query), + GithubCommitAllChanges: (query: Query) => + ipcRenderer.invoke('settings/github-commit-all-changes', query), }); declare global { diff --git a/electron-app/src/python/pyrunner.py b/electron-app/src/python/pyrunner.py index 53e71661..883b59e4 100644 --- a/electron-app/src/python/pyrunner.py +++ b/electron-app/src/python/pyrunner.py @@ -385,6 +385,16 @@ def post(request): ), "returncode": 0, } + elif query == "settings/github-commit-all-changes": + author = data.get("author", None) + email = data.get("email", None) + data = { + "query": query, + "body": runner.github.CommitAllChanges( + data["repo"], data["message"], author, email + ), + "returncode": 0, + } else: raise NotImplementedError(f"Unknown query: {query}") diff --git a/nodemapper/src/api.ts b/nodemapper/src/api.ts index e8b88948..cb9e621b 100644 --- a/nodemapper/src/api.ts +++ b/nodemapper/src/api.ts @@ -57,6 +57,7 @@ export type SettingsAPI = { GithubUnstageFiles: (query: Query) => Promise; GithubCommit: (query: Query) => Promise; GithubClone: (query: Query) => Promise; + GithubCommitAllChanges: (query: Query) => Promise; }; declare global { diff --git a/nodemapper/src/gui/Settings/RepoOptions.tsx b/nodemapper/src/gui/Settings/RepoOptions.tsx index 248315d6..b1272858 100644 --- a/nodemapper/src/gui/Settings/RepoOptions.tsx +++ b/nodemapper/src/gui/Settings/RepoOptions.tsx @@ -38,8 +38,10 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { // Github repo status type ghStatusOpts = + // query states | 'unknown' | 'checking' + // return codes | 'not-a-repo' | 'up-to-date' | 'behind' @@ -72,8 +74,10 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { const [ghUntracked, setGhUntracked] = React.useState({ status: 'unknown' } as ghUntrackedProps); type ghIndicatorOpts = + // query states | 'unknown' | 'checking' + // return codes | 'not-a-repo' | 'up-to-date' | 'modified' @@ -88,6 +92,12 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { } }, []); + const RefreshGhStatus = () => { + setAnchorMenu(null); + setGhIndicator('checking'); + GithubGetRepoStatus(repo, branch); + } + const GithubGetRepoStatus = async (repo: string, branch: string) => { // Check if the repo is in sync with the remote const query = { @@ -146,6 +156,7 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { }; const onGhPull = async () => { + setGhIndicator('checking'); settingsAPI .GithubPull({ query: 'settings/github-pull', @@ -157,16 +168,19 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { .then((response) => { const result = response['body'] as { status: string; message: string }; if (result.status === 'success') { - // Force refresh of the repo status + RefreshGhStatus(); } else { dispatch( builderLogEvent(`Error pulling changes from Github for ${repo}: ${result.message}`), ); + setGhIndicator('error'); + setGhStatus({ status: 'error', message: result.message }); } }); }; const onGhPush = async () => { + setGhIndicator('checking'); settingsAPI .GithubPush({ query: 'settings/github-push', @@ -178,11 +192,36 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { .then((response) => { const result = response['body'] as { status: string; message: string }; if (result.status === 'success') { - // Force refresh of the repo status + RefreshGhStatus(); } else { dispatch( builderLogEvent(`Error pushing changes to Github for ${repo}: ${result.message}`), ); + setGhIndicator('error'); + setGhStatus({ status: 'error', message: result.message }); + } + }); + }; + + const ghCommitAllChanges = async () => { + settingsAPI + .GithubCommitAllChanges({ + query: 'settings/github-commit-all-changes', + data: { + repo: repo, + message: 'Commit from GRAPEVNE', + author: 'GRAPEVNE', + email: null, + }, + }) + .then((response) => { + const result = response['body'] as { status: string; message: string }; + if (result.status === 'success') { + // Force refresh of the repo status + } else { + dispatch( + builderLogEvent(`Error committing changes to Github for ${repo}: ${result.message}`), + ); } }); }; @@ -202,7 +241,12 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { {/* For 'unknown', 'checking' and 'not-a-repo' we don't show the github indicator */} {ghIndicator === 'up-to-date' && ( - + { + RefreshGhStatus(); + }} + /> )} {ghIndicator === 'checking' && ( @@ -240,6 +284,11 @@ const GithubMenu = ({ repo, branch }: GithubMenuProps) => { Conflicts with github detected - try pulling the latest changes )} + {(ghTracked.status === 'some' || ghUntracked.status === 'some') && ( + + )} {(ghStatus.status === 'behind' || ghStatus.status === 'diverged') && (