From a6d1baf6091bfbafda740222bd761ac5d38cf9a6 Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Thu, 6 Jun 2024 13:30:47 +0530 Subject: [PATCH 01/11] Update response for internal version --- web-server/pages/api/internal/version.ts | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/web-server/pages/api/internal/version.ts b/web-server/pages/api/internal/version.ts index 12ceab77e..6ddc34f30 100644 --- a/web-server/pages/api/internal/version.ts +++ b/web-server/pages/api/internal/version.ts @@ -111,11 +111,15 @@ async function fetchLatestGitHubCommit(): Promise { return latestCommit; } -function isUpdateAvailable( - localVersionInfo: ProjectVersionInfo, - dockerLatestRemoteTag: TagCompressed, - githubLatestCommit: GitHubCommit -): boolean { +function isUpdateAvailable({ + localVersionInfo, + dockerLatestRemoteTag, + githubLatestCommit +}: { + localVersionInfo: ProjectVersionInfo; + dockerLatestRemoteTag: TagCompressed; + githubLatestCommit: GitHubCommit; +}): boolean { const env = process.env.NEXT_PUBLIC_APP_ENVIRONMENT; if (env == 'development') { @@ -156,11 +160,11 @@ async function checkNewImageRelease(): Promise { latest_docker_image: latestDockerImageLink, github_repo: githubRepLink, current_github_commit: versionInfo.merge_commit_sha, - is_update_available: isUpdateAvailable( - versionInfo, - latestTag, - githubLatestCommit - ), + is_update_available: isUpdateAvailable({ + dockerLatestRemoteTag: latestTag, + githubLatestCommit: githubLatestCommit, + localVersionInfo: versionInfo + }), latest_docker_image_build_date: latestRemoteDate }; } From 8941d9cbafb45ffbc25c16d1d29e35b49b48fbcd Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Thu, 6 Jun 2024 18:45:57 +0530 Subject: [PATCH 02/11] Add method to fetch if main branch was updated in cli --- cli/source/utils/update-checker.ts | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 cli/source/utils/update-checker.ts diff --git a/cli/source/utils/update-checker.ts b/cli/source/utils/update-checker.ts new file mode 100644 index 000000000..b5426ee32 --- /dev/null +++ b/cli/source/utils/update-checker.ts @@ -0,0 +1,57 @@ +import axios from 'axios'; +import { execSync } from 'child_process'; + +const githubOrgName = 'middlewarehq'; +const githubRepoName = 'middleware'; +const defaultBranch = 'main'; + +type GitHubCommit = { + sha: string; + commit: { + author: { + name: string; + email: string; + date: string; + }; + message: string; + }; +}; + +const getLatestCommitTimestamp = () => { + const commitSHA = execSync(`git rev-parse ${defaultBranch}`) + .toString() + .trim(); + const commitTimestamp = execSync(`git show -s --format=%cI ${commitSHA}`) + .toString() + .trim(); + return commitTimestamp; +}; + +async function fetchLatestGitHubCommit(): Promise { + const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits/${defaultBranch}`; + const response = await fetch(apiUrl); + + if (!response.ok) { + console.error(`Error fetching commit data: ${response.statusText}`); + return undefined; + } + + const data: GitHubCommit = await response.json(); + return data; +} + +export async function isLocalBranchBehindRemote(): Promise { + const commitTimestamp = getLatestCommitTimestamp(); + const latestGithubCommit = await fetchLatestGitHubCommit(); + + if (!latestGithubCommit) { + return true; + } + + const localCommitTimestamp = new Date(commitTimestamp); + const latestRemoteCommitDate = new Date( + latestGithubCommit.commit.author.date + ); + + return latestRemoteCommitDate > localCommitTimestamp; +} From 635ba9d65325ba5475d22fa650b1adb9cb798317 Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Thu, 6 Jun 2024 18:46:22 +0530 Subject: [PATCH 03/11] Update cli ui to show update warning --- cli/source/app.tsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cli/source/app.tsx b/cli/source/app.tsx index cc3a7a93f..43a546f40 100644 --- a/cli/source/app.tsx +++ b/cli/source/app.tsx @@ -21,6 +21,7 @@ import { useSelector, store, useDispatch } from './store/index.js'; import { getLineLimit } from './utils/line-limit.js'; import { runCommand } from './utils/run-command.js'; import CircularBuffer from './utils/circularBuffer.js'; +import { isLocalBranchBehindRemote } from './utils/update-checker.js'; const CliUi = () => { const dispatch = useDispatch(); @@ -32,6 +33,7 @@ const CliUi = () => { useLogsFromAllSources(); const [retryToggle, setRetryToggle] = useState(false); + const [isUpdateAvailable, setIsUpdateAvailable] = useState(false); const { exit } = useApp(); @@ -90,6 +92,12 @@ const CliUi = () => { }, 200); }, [dispatch, runCommandOpts]); + const handleVersionUpdates = useCallback(async () => { + await isLocalBranchBehindRemote().then((res) => { + setIsUpdateAvailable(res); + }); + }, [setIsUpdateAvailable]); + useEffect(() => { if (appState !== AppStates.TERMINATED) return; exit(); @@ -119,6 +127,10 @@ const CliUi = () => { } }); + useEffect(() => { + handleVersionUpdates(); + }, [handleVersionUpdates]); + useEffect(() => { const { process, promise } = runCommand( 'docker-compose', @@ -347,6 +359,14 @@ const CliUi = () => { {' '} exit + {isUpdateAvailable && ( + <> + + + (main branch is behind remote. pull and rebase) + + + )} ); case AppStates.TEARDOWN: From c70861b76d68ebf922e027eadeb205bfa0d7179f Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Thu, 6 Jun 2024 18:53:54 +0530 Subject: [PATCH 04/11] Add default branch to commits api call for web manager --- web-server/pages/api/internal/version.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web-server/pages/api/internal/version.ts b/web-server/pages/api/internal/version.ts index 6ddc34f30..f39705de4 100644 --- a/web-server/pages/api/internal/version.ts +++ b/web-server/pages/api/internal/version.ts @@ -4,6 +4,7 @@ import axios from 'axios'; const dockerRepoName = 'middlewareeng/middleware'; const githubOrgName = 'middlewarehq'; const githubRepoName = 'middleware'; +const defaultBranch = 'main' const endpoint = new Endpoint(nullSchema); @@ -105,7 +106,7 @@ async function fetchDockerHubTags(): Promise { } async function fetchLatestGitHubCommit(): Promise { - const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits`; + const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits/${defaultBranch}`; const response = await axios.get(apiUrl); const latestCommit = response.data[0]; return latestCommit; From 880d0cf58e077753c44f0ad88407aa2e70c6ead4 Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Thu, 6 Jun 2024 20:29:53 +0530 Subject: [PATCH 05/11] remove new line from cli --- cli/source/app.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/source/app.tsx b/cli/source/app.tsx index 43a546f40..fd29295fe 100644 --- a/cli/source/app.tsx +++ b/cli/source/app.tsx @@ -361,7 +361,6 @@ const CliUi = () => { {isUpdateAvailable && ( <> - (main branch is behind remote. pull and rebase) From c20bf2420e7e9406500f4d82db7fc2a5af77f244 Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 01:43:52 +0530 Subject: [PATCH 06/11] Fix list access of single commit --- web-server/pages/api/internal/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-server/pages/api/internal/version.ts b/web-server/pages/api/internal/version.ts index f39705de4..adbe52661 100644 --- a/web-server/pages/api/internal/version.ts +++ b/web-server/pages/api/internal/version.ts @@ -107,8 +107,8 @@ async function fetchDockerHubTags(): Promise { async function fetchLatestGitHubCommit(): Promise { const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits/${defaultBranch}`; - const response = await axios.get(apiUrl); - const latestCommit = response.data[0]; + const response = await axios.get(apiUrl); + const latestCommit = response.data; return latestCommit; } From 738257e70c1993636797efe0bd3446e5e5dbd3eb Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 01:44:32 +0530 Subject: [PATCH 07/11] Use git commands to fetch git diff data --- cli/source/app.tsx | 6 +-- cli/source/utils/update-checker.ts | 63 ++++++++++++------------------ 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/cli/source/app.tsx b/cli/source/app.tsx index fd29295fe..589a5ca7b 100644 --- a/cli/source/app.tsx +++ b/cli/source/app.tsx @@ -33,7 +33,7 @@ const CliUi = () => { useLogsFromAllSources(); const [retryToggle, setRetryToggle] = useState(false); - const [isUpdateAvailable, setIsUpdateAvailable] = useState(false); + const [isUpdateAvailable, setIsUpdateAvailable] = useState(""); const { exit } = useApp(); @@ -359,10 +359,10 @@ const CliUi = () => { {' '} exit - {isUpdateAvailable && ( + {Boolean(isUpdateAvailable) && ( <> - (main branch is behind remote. pull and rebase) + {isUpdateAvailable} )} diff --git a/cli/source/utils/update-checker.ts b/cli/source/utils/update-checker.ts index b5426ee32..45d55e13a 100644 --- a/cli/source/utils/update-checker.ts +++ b/cli/source/utils/update-checker.ts @@ -1,57 +1,42 @@ -import axios from 'axios'; import { execSync } from 'child_process'; -const githubOrgName = 'middlewarehq'; -const githubRepoName = 'middleware'; const defaultBranch = 'main'; -type GitHubCommit = { - sha: string; - commit: { - author: { - name: string; - email: string; - date: string; - }; - message: string; - }; +const fetchRemoteRepository = () => { + try { + execSync('git fetch origin'); + } catch (error) { + console.error(`Error fetching the remote repository: ${error}`); + } }; -const getLatestCommitTimestamp = () => { +const getLatestLocalCommitSHA = () => { + fetchRemoteRepository(); const commitSHA = execSync(`git rev-parse ${defaultBranch}`) .toString() .trim(); - const commitTimestamp = execSync(`git show -s --format=%cI ${commitSHA}`) - .toString() - .trim(); - return commitTimestamp; + return commitSHA; }; -async function fetchLatestGitHubCommit(): Promise { - const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits/${defaultBranch}`; - const response = await fetch(apiUrl); - - if (!response.ok) { - console.error(`Error fetching commit data: ${response.statusText}`); - return undefined; - } +export async function isLocalBranchBehindRemote(): Promise { + const latestLocalCommitSHA = getLatestLocalCommitSHA(); - const data: GitHubCommit = await response.json(); - return data; -} + const behindCommits = execSync( + `git rev-list ${latestLocalCommitSHA}..origin/main` + ) + .toString() + .trim() + .split('\n'); -export async function isLocalBranchBehindRemote(): Promise { - const commitTimestamp = getLatestCommitTimestamp(); - const latestGithubCommit = await fetchLatestGitHubCommit(); + const behindCommitsCount = behindCommits.filter((commit) => commit).length; - if (!latestGithubCommit) { - return true; + if (behindCommitsCount == 0) { + return ''; } - const localCommitTimestamp = new Date(commitTimestamp); - const latestRemoteCommitDate = new Date( - latestGithubCommit.commit.author.date - ); + if (behindCommitsCount == 1) { + return `(1 commit behind remote. pull and rebase)`; + } - return latestRemoteCommitDate > localCommitTimestamp; + return `(${behindCommitsCount} commits behind remote. pull and rebase)`; } From 09fe24ef989d58c8b59c378735ae1c5fef614ccc Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 02:27:32 +0530 Subject: [PATCH 08/11] Update dev.sh to populate BEHIND_COMMITS_COUNT in env --- dev.sh | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/dev.sh b/dev.sh index 473ad8bff..8cc15f298 100755 --- a/dev.sh +++ b/dev.sh @@ -4,16 +4,42 @@ docker-compose down cat env.example > .env +check_internet_connection() { + curl -s https://www.google.com > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + echo "No internet connection. Cannot fetch latest commits." + return 1 + fi + return 0 +} + +if ! check_internet_connection; then + BEHIND_COMMITS_COUNT=0 +else + git fetch origin + BEHIND_COMMITS_COUNT=$(git rev-list --count main..origin/main) +fi + GIT_COMMIT_HASH=$(git rev-parse main) GIT_COMMIT_DATE=$(git show -s --format=%cI $MERGE_COMMIT_SHA) -if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "s/^BUILD_DATE=.*/BUILD_DATE=$GIT_COMMIT_DATE/" .env - sed -i '' "s/^MERGE_COMMIT_SHA=.*/MERGE_COMMIT_SHA=$GIT_COMMIT_HASH/" .env -else - sed -i "s/^BUILD_DATE=.*/BUILD_DATE=$GIT_COMMIT_DATE/" .env - sed -i "s/^MERGE_COMMIT_SHA=.*/MERGE_COMMIT_SHA=$GIT_COMMIT_HASH/" .env -fi +update_or_add_env_var() { + local var_name=$1 + local var_value=$2 + if grep -q "^$var_name=" .env; then + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "s/^$var_name=.*/$var_name=$var_value/" .env + else + sed -i "s/^$var_name=.*/$var_name=$var_value/" .env + fi + else + echo "$var_name=$var_value" >> .env + fi +} + +update_or_add_env_var "BUILD_DATE" "$GIT_COMMIT_DATE" +update_or_add_env_var "MERGE_COMMIT_SHA" "$GIT_COMMIT_HASH" +update_or_add_env_var "BEHIND_COMMITS_COUNT" "$BEHIND_COMMITS_COUNT" cd ./cli || exit From c4108b50616ef6cca7bb1131c8147f807b5f345c Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 02:27:59 +0530 Subject: [PATCH 09/11] Update ProcessEnv to use BEHIND_COMMITS_COUNT --- web-server/libdefs/ambient.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web-server/libdefs/ambient.d.ts b/web-server/libdefs/ambient.d.ts index 994fa6caa..a548d8f81 100644 --- a/web-server/libdefs/ambient.d.ts +++ b/web-server/libdefs/ambient.d.ts @@ -84,5 +84,6 @@ declare namespace NodeJS { DB_USER: string; MERGE_COMMIT_SHA: string; BUILD_DATE: string; + BEHIND_COMMITS_COUNT?: string } } From 23d69cb40df3f5bf176db73bd717511c5907040d Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 02:28:32 +0530 Subject: [PATCH 10/11] Update version API for web manager --- web-server/pages/api/internal/version.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/web-server/pages/api/internal/version.ts b/web-server/pages/api/internal/version.ts index adbe52661..430c2f10d 100644 --- a/web-server/pages/api/internal/version.ts +++ b/web-server/pages/api/internal/version.ts @@ -4,7 +4,7 @@ import axios from 'axios'; const dockerRepoName = 'middlewareeng/middleware'; const githubOrgName = 'middlewarehq'; const githubRepoName = 'middleware'; -const defaultBranch = 'main' +const defaultBranch = 'main'; const endpoint = new Endpoint(nullSchema); @@ -114,22 +114,19 @@ async function fetchLatestGitHubCommit(): Promise { function isUpdateAvailable({ localVersionInfo, - dockerLatestRemoteTag, - githubLatestCommit + dockerLatestRemoteTag }: { localVersionInfo: ProjectVersionInfo; dockerLatestRemoteTag: TagCompressed; - githubLatestCommit: GitHubCommit; }): boolean { const env = process.env.NEXT_PUBLIC_APP_ENVIRONMENT; if (env == 'development') { - const localBuildDate = new Date(localVersionInfo.current_build_date); - const latestRemoteCommitDate = new Date( - githubLatestCommit.commit.author.date - ); - - return latestRemoteCommitDate > localBuildDate; + const behindCommitsCount = process.env.BEHIND_COMMITS_COUNT + ? Number(process.env.BEHIND_COMMITS_COUNT) + : 0; + console.log('behindCommitsCount', behindCommitsCount); + return behindCommitsCount > 0; } const localBuildDate = new Date(localVersionInfo.current_build_date); @@ -163,7 +160,6 @@ async function checkNewImageRelease(): Promise { current_github_commit: versionInfo.merge_commit_sha, is_update_available: isUpdateAvailable({ dockerLatestRemoteTag: latestTag, - githubLatestCommit: githubLatestCommit, localVersionInfo: versionInfo }), latest_docker_image_build_date: latestRemoteDate From a782d7f63334ce9e61451f26364549dfc405b253 Mon Sep 17 00:00:00 2001 From: Samad Yar Khan Date: Fri, 7 Jun 2024 10:51:59 +0530 Subject: [PATCH 11/11] remove log statment --- web-server/pages/api/internal/version.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/web-server/pages/api/internal/version.ts b/web-server/pages/api/internal/version.ts index 430c2f10d..1fbcc91a1 100644 --- a/web-server/pages/api/internal/version.ts +++ b/web-server/pages/api/internal/version.ts @@ -125,7 +125,6 @@ function isUpdateAvailable({ const behindCommitsCount = process.env.BEHIND_COMMITS_COUNT ? Number(process.env.BEHIND_COMMITS_COUNT) : 0; - console.log('behindCommitsCount', behindCommitsCount); return behindCommitsCount > 0; }