Skip to content
Merged
19 changes: 19 additions & 0 deletions cli/source/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -32,6 +33,7 @@ const CliUi = () => {
useLogsFromAllSources();

const [retryToggle, setRetryToggle] = useState<Boolean>(false);
const [isUpdateAvailable, setIsUpdateAvailable] = useState<string>("");

const { exit } = useApp();

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -119,6 +127,10 @@ const CliUi = () => {
}
});

useEffect(() => {
handleVersionUpdates();
}, [handleVersionUpdates]);

useEffect(() => {
const { process, promise } = runCommand(
'docker-compose',
Expand Down Expand Up @@ -347,6 +359,13 @@ const CliUi = () => {
</Text>{' '}
exit
</Text>
{Boolean(isUpdateAvailable) && (
<>
<Text bold color="yellow">
{isUpdateAvailable}
</Text>
</>
)}
</Box>
);
case AppStates.TEARDOWN:
Expand Down
42 changes: 42 additions & 0 deletions cli/source/utils/update-checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { execSync } from 'child_process';

const defaultBranch = 'main';

const fetchRemoteRepository = () => {
try {
execSync('git fetch origin');
} catch (error) {
console.error(`Error fetching the remote repository: ${error}`);
}
};

const getLatestLocalCommitSHA = () => {
fetchRemoteRepository();
const commitSHA = execSync(`git rev-parse ${defaultBranch}`)
.toString()
.trim();
return commitSHA;
};

export async function isLocalBranchBehindRemote(): Promise<string> {
const latestLocalCommitSHA = getLatestLocalCommitSHA();

const behindCommits = execSync(
`git rev-list ${latestLocalCommitSHA}..origin/main`
)
.toString()
.trim()
.split('\n');

const behindCommitsCount = behindCommits.filter((commit) => commit).length;

if (behindCommitsCount == 0) {
return '';
}

if (behindCommitsCount == 1) {
return `(1 commit behind remote. pull and rebase)`;
}

return `(${behindCommitsCount} commits behind remote. pull and rebase)`;
}
40 changes: 33 additions & 7 deletions dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions web-server/libdefs/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,6 @@ declare namespace NodeJS {
DB_USER: string;
MERGE_COMMIT_SHA: string;
BUILD_DATE: string;
BEHIND_COMMITS_COUNT?: string
}
}
38 changes: 19 additions & 19 deletions web-server/pages/api/internal/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -105,26 +106,26 @@ async function fetchDockerHubTags(): Promise<TagCompressed[]> {
}

async function fetchLatestGitHubCommit(): Promise<GitHubCommit> {
const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits`;
const response = await axios.get<GitHubCommit[]>(apiUrl);
const latestCommit = response.data[0];
const apiUrl = `https://api.github.com/repos/${githubOrgName}/${githubRepoName}/commits/${defaultBranch}`;
const response = await axios.get<GitHubCommit>(apiUrl);
const latestCommit = response.data;
return latestCommit;
}

function isUpdateAvailable(
localVersionInfo: ProjectVersionInfo,
dockerLatestRemoteTag: TagCompressed,
githubLatestCommit: GitHubCommit
): boolean {
function isUpdateAvailable({
localVersionInfo,
dockerLatestRemoteTag
}: {
localVersionInfo: ProjectVersionInfo;
dockerLatestRemoteTag: TagCompressed;
}): 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;
return behindCommitsCount > 0;
}

const localBuildDate = new Date(localVersionInfo.current_build_date);
Expand Down Expand Up @@ -156,11 +157,10 @@ async function checkNewImageRelease(): Promise<CheckNewVersionResponse> {
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,
localVersionInfo: versionInfo
}),
latest_docker_image_build_date: latestRemoteDate
};
}
Expand Down