From 743c88c30d8dd39fc3730ce72433c037610a023a Mon Sep 17 00:00:00 2001
From: Alexey Zinoviev <alexey.zinoviev@xored.com>
Date: Mon, 9 Sep 2024 19:17:19 +0400
Subject: [PATCH] UBERF-8044: staging model version (#6492)

Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
---
 .github/workflows/main.yml       |  1 +
 common/scripts/show_version.js   | 42 ++++++++++++++++++++++++++------
 server/account/src/operations.ts | 24 +++++++++---------
 3 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 7f721b2adb..dbd4342226 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -40,6 +40,7 @@ env:
     .prettierrc
     tools
   PublishTempFolder: publish_artifacts
+  MODEL_VERSION_MODE: ${{ startsWith(github.ref, 'refs/tags/s') && 'tagTime' || 'file' }}
 
 # A workflow run is made up of one or more jobs that can run sequentially or in parallel
 jobs:
diff --git a/common/scripts/show_version.js b/common/scripts/show_version.js
index 99a17e30b5..0ac52f770d 100644
--- a/common/scripts/show_version.js
+++ b/common/scripts/show_version.js
@@ -15,12 +15,40 @@
 
 const fs = require('fs')
 const path = require('path')
+const exec = require('child_process').exec
 
-try {
-  const versionFilePath = path.resolve(__dirname, 'version.txt')
-  const version = fs.readFileSync(versionFilePath, 'utf8').trim()
-  
-  console.log(version)
-} catch (error) {
-  console.log('0.6.0')
+function main (mode) {
+  exec('git describe --tags --abbrev=0', (err, stdout) => {
+    if (err !== null) {
+      console.log('"0.7.0"')
+      return
+    }
+
+    const tag = stdout.trim()
+
+    if (mode === 'tagTime') {
+      // Take tagged git commit date as model version
+      exec(`git for-each-ref --shell --format="%(creatordate:format:%s)" "refs/tags/${tag}"`, (err, stdout) => {
+        console.log(`"0.7.${err === null ? stdout.trim().slice(1, -1) : 0}"`)
+      })
+    } else {
+      // Take version from file
+      let version
+      try {
+        const versionFilePath = path.resolve(__dirname, 'version.txt')
+        version = fs.readFileSync(versionFilePath, 'utf8').trim()
+      } catch (error) {
+        version = '"0.6.0"'
+      }
+
+      console.log(version)
+    }
+  })
 }
+
+let mode = process.env.MODEL_VERSION_MODE
+if (mode !== 'tagTime') {
+  mode = 'file'
+}
+
+main(mode)
diff --git a/server/account/src/operations.ts b/server/account/src/operations.ts
index 70626d33f9..3f735d996c 100644
--- a/server/account/src/operations.ts
+++ b/server/account/src/operations.ts
@@ -1480,22 +1480,20 @@ export async function getPendingWorkspace (
           ? pendingUpgradeQuery
           : [...pendingCreationQuery, ...pendingUpgradeQuery]
   }
-  let query: Filter<Workspace>
+  const attemptsQuery = { $or: [{ attempts: { $exists: false } }, { attempts: { $lte: 3 } }] }
 
-  if (region !== '') {
-    query = {
-      ...operationQuery,
-      region
-    }
-  } else {
-    query = {
-      $and: [operationQuery, defaultRegionQuery]
-    }
+  // We must have all the conditions in the DB query and we cannot filter anything in the code
+  // because of possible concurrency between account services. We have to update "lastProcessingTime"
+  // at the time of retrieval and not after some additional processing.
+  const query: Filter<Workspace> = {
+    $and: [
+      operationQuery,
+      attemptsQuery,
+      region !== '' ? { region } : defaultRegionQuery,
+      { lastProcessingTime: { $lt: Date.now() - processingTimeoutMs } }
+    ]
   }
 
-  query.lastProcessingTime = { $lt: Date.now() - processingTimeoutMs }
-  query.attempts = { $lte: 3 }
-
   return (
     (await wsCollection.findOneAndUpdate(
       query,