Fixed merge conflicts
This commit is contained in:
commit
4e1b1f6188
7 changed files with 39 additions and 147 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
Release Date
|
Release Date
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
- 2026-02-05
|
- 2025-01-29
|
||||||
|
|
||||||
|
|
||||||
New Features
|
New Features
|
||||||
|
|
@ -23,7 +23,7 @@ Security
|
||||||
Fixes
|
Fixes
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
- settings: fixed VCS setting screen crash with some combination of Ai-related settings
|
- update_server: Moves update server to the rcstack, and fixes issue with wrong file check
|
||||||
|
|
||||||
|
|
||||||
Upgrade notes
|
Upgrade notes
|
||||||
|
|
|
||||||
33
docs/release-notes/release-notes-5.11.2.rst
Normal file
33
docs/release-notes/release-notes-5.11.2.rst
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
|RCE| 5.11.2 |RNS|
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Release Date
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- 2026-02-05
|
||||||
|
|
||||||
|
|
||||||
|
New Features
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
General
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
Security
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Fixes
|
||||||
|
^^^^^
|
||||||
|
|
||||||
|
- settings: fixed VCS setting screen crash with some combination of Ai-related settings
|
||||||
|
|
||||||
|
|
||||||
|
Upgrade notes
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- RhodeCode 5.11.2 is an unscheduled bugfix release
|
||||||
|
|
||||||
|
|
@ -9,6 +9,7 @@ Release Notes
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
release-notes-5.11.2.rst
|
||||||
release-notes-5.11.1.rst
|
release-notes-5.11.1.rst
|
||||||
release-notes-5.11.0.rst
|
release-notes-5.11.0.rst
|
||||||
release-notes-5.10.0.rst
|
release-notes-5.10.0.rst
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ line-ending = "auto"
|
||||||
|
|
||||||
|
|
||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "5.10.0"
|
current_version = "5.11.1"
|
||||||
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
||||||
serialize = ["{major}.{minor}.{patch}"]
|
serialize = ["{major}.{minor}.{patch}"]
|
||||||
search = "{current_version}"
|
search = "{current_version}"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
5.10.0
|
5.11.1
|
||||||
|
|
@ -297,7 +297,7 @@
|
||||||
<label for="rhodecode_ai_default_code_review${suffix}">${_('Enable AI review for pull requests')}</label>
|
<label for="rhodecode_ai_default_code_review${suffix}">${_('Enable AI review for pull requests')}</label>
|
||||||
%else:
|
%else:
|
||||||
<span class="tooltip" title="${_('AI features disabled, enable AI features to activate this checkbox.')}">
|
<span class="tooltip" title="${_('AI features disabled, enable AI features to activate this checkbox.')}">
|
||||||
${h.checkbox('rhodecode_ai_default_code_review' + suffix, 'True', checked=c.ai_default_code_review, disabled=True, **kwargs)}
|
${h.checkbox('rhodecode_ai_default_code_review' + suffix, 'True', checked=c.ai_default_code_review, disabled=True)}
|
||||||
<label for="rhodecode_ai_default_code_review${suffix}">${_('Enable AI review for pull requests')}</label>
|
<label for="rhodecode_ai_default_code_review${suffix}">${_('Enable AI review for pull requests')}</label>
|
||||||
</span>
|
</span>
|
||||||
%endif
|
%endif
|
||||||
|
|
|
||||||
142
update_server.py
142
update_server.py
|
|
@ -1,142 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import threading
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Py3
|
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
||||||
except ImportError:
|
|
||||||
# Py2
|
|
||||||
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
|
||||||
|
|
||||||
try:
|
|
||||||
from shlex import quote as shell_quote # Py3
|
|
||||||
except ImportError:
|
|
||||||
from pipes import quote as shell_quote # Py2 (Unix)
|
|
||||||
|
|
||||||
RCSTACK_PATH_NAME = "RCSTACK_PATH"
|
|
||||||
RCSTACK_PATH = os.environ.get(RCSTACK_PATH_NAME)
|
|
||||||
RCSTACK_LOG_NAME = os.environ.get("RCSTACK_LOG_NAME", "./rcstack_status.log")
|
|
||||||
STATUS = {"state": "ready"} # "ready" or "processing"
|
|
||||||
|
|
||||||
|
|
||||||
def _log_line(text, log_path):
|
|
||||||
# compatible with python 2
|
|
||||||
out = open(log_path, "ab")
|
|
||||||
try:
|
|
||||||
if not isinstance(text, bytes):
|
|
||||||
text = text.encode("utf-8")
|
|
||||||
out.write(text + b"\n")
|
|
||||||
out.flush()
|
|
||||||
finally:
|
|
||||||
out.close()
|
|
||||||
|
|
||||||
|
|
||||||
def _watch_process(popen_obj, log_path):
|
|
||||||
try:
|
|
||||||
rc = popen_obj.wait()
|
|
||||||
stamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
_log_line("[" + stamp + "] finished rc=" + str(rc), log_path=log_path)
|
|
||||||
except Exception as e:
|
|
||||||
stamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
_log_line("[" + stamp + "] watcher error: " + str(e), log_path=log_path)
|
|
||||||
finally:
|
|
||||||
STATUS["state"] = "ready"
|
|
||||||
|
|
||||||
|
|
||||||
class RcstackUpdater(BaseHTTPRequestHandler):
|
|
||||||
def __init__(self, request, client_address, server):
|
|
||||||
BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
|
||||||
|
|
||||||
def _send_json(self, obj, code=200):
|
|
||||||
body = json.dumps(obj).encode("utf-8")
|
|
||||||
self.send_response(code)
|
|
||||||
self.send_header("Content-Type", "application/json")
|
|
||||||
self.send_header("Content-Length", str(len(body)))
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write(body)
|
|
||||||
|
|
||||||
def do_GET(self):
|
|
||||||
if self.path == "/state":
|
|
||||||
return self._send_json({"state": STATUS["state"]})
|
|
||||||
|
|
||||||
elif self.path == "/rcstack/update":
|
|
||||||
# If already processing, return ok and do not spawn a new process.
|
|
||||||
if STATUS["state"] != "ready":
|
|
||||||
return self._send_json({"status": "ok", "state": STATUS["state"]})
|
|
||||||
|
|
||||||
ok, err_msg = self.spawn_rcstack_status()
|
|
||||||
# If spawn failed for real reasons (bad env/path/etc.), return 500
|
|
||||||
if not ok:
|
|
||||||
return self._send_http_error(err_msg.encode("utf-8"), status_code=500)
|
|
||||||
|
|
||||||
return self._send_json({"status": "ok", "state": STATUS["state"]})
|
|
||||||
|
|
||||||
return self._send_http_error(b"not found", status_code=404)
|
|
||||||
|
|
||||||
def spawn_rcstack_status(self):
|
|
||||||
if not RCSTACK_PATH:
|
|
||||||
return False, "%s env variable not set" % (RCSTACK_PATH_NAME,)
|
|
||||||
|
|
||||||
if not os.path.exists(RCSTACK_PATH) or not os.path.isfile(RCSTACK_PATH):
|
|
||||||
return False, "%s does not exist" % (RCSTACK_PATH,)
|
|
||||||
|
|
||||||
rcstack = os.path.expanduser(RCSTACK_PATH)
|
|
||||||
rcstack_dir = os.path.dirname(rcstack)
|
|
||||||
log_path = os.path.join(rcstack_dir, RCSTACK_LOG_NAME)
|
|
||||||
|
|
||||||
STATUS["state"] = "processing"
|
|
||||||
|
|
||||||
stamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
_log_line("[%s] spawn: %s status" % (stamp, rcstack), log_path=log_path)
|
|
||||||
|
|
||||||
out = open(log_path, "ab")
|
|
||||||
try:
|
|
||||||
cmd = "%s self-update && %s stack-upgrade all" % (shell_quote(rcstack), shell_quote(rcstack))
|
|
||||||
|
|
||||||
p = subprocess.Popen(
|
|
||||||
["/bin/sh", "-c", cmd],
|
|
||||||
cwd=rcstack_dir,
|
|
||||||
stdout=out,
|
|
||||||
stderr=out,
|
|
||||||
close_fds=True,
|
|
||||||
preexec_fn=os.setsid, # Unix only
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
STATUS["state"] = "ready"
|
|
||||||
_log_line("[%s] spawn error: %s" % (stamp, str(e)), log_path=log_path)
|
|
||||||
return False, "spawn failed: %s" % (str(e),)
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
out.close()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
t = threading.Thread(target=_watch_process, args=(p, log_path))
|
|
||||||
try:
|
|
||||||
t.daemon = True
|
|
||||||
except Exception:
|
|
||||||
t.setDaemon(True) # Py2
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
return True, None
|
|
||||||
|
|
||||||
def _send_http_error(self, msg, status_code):
|
|
||||||
self.send_response(status_code)
|
|
||||||
self.send_header("Content-Type", "text/plain")
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def main(host="127.0.0.1", port=10025):
|
|
||||||
httpd = HTTPServer((host, port), RcstackUpdater)
|
|
||||||
stamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
print("[%s] listening on http://%s:%d" % (stamp, host, port))
|
|
||||||
httpd.serve_forever()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue