Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ branch_name:
default: "18.0"
help: Odoo version

# TODO change the place of this option before merging
# I just put here to avoid conflict
# it should be moved after org_name
use_manual_bump:
type: bool
help: Bump your image manually instead of using UI, this allow to use migrate script

odoo_version:
# odoo_version is more readable
# branch_name is required by huddle, more generic
Expand Down
24 changes: 23 additions & 1 deletion src/.gitlab-ci.yml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ stages:
# because usually it's only
# needed before the merge
- test
{% if use_manual_bump %} - docker_push{% endif %}

before_script:
# TODO: manage mulitple preprod ?
Expand Down Expand Up @@ -421,6 +422,26 @@ review_preprod:
- job: "build"
optional: true

{# # TODO we should merge this two solution
# But as it need time and test get the two solution for now
# so we can use the same template, update project and then merge it #}
{% if use_manual_bump %}
# Send the docker image to the registry in order to be downloaded in prod
docker_push:
stage: docker_push
script:
- export TAG="${CI_COMMIT_MESSAGE//Bump version /}"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker tag $BUILD_NAME $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
- docker tag $BUILD_NAME $CI_REGISTRY_IMAGE:$TAG
- docker push $CI_REGISTRY_IMAGE:$TAG
rules:
- if: $CI_COMMIT_TITLE =~ /^Bump version/ && $AK_IS_MR == null
needs:
- update_db
- test
{% else %}
prepare_release:
stage: deploy
script:
Expand Down Expand Up @@ -450,6 +471,7 @@ prepare_release:
needs:
- build


publish:
# creates a gitlab release
stage: deploy
Expand Down Expand Up @@ -519,7 +541,7 @@ publish:
when: never
- if: $AK_IS_MAJOR_BRANCH == "true"
# run on protected branches only

{% endif %}

init_source_cache:
stage: maintenance
Expand Down
102 changes: 102 additions & 0 deletions src/odoo/bin/migrate
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
# pylint: disable=print-used

import logging
import os

from click_odoo_contrib.update import main

from odoo import release, sql_db
from odoo.modules import module
from odoo.modules.registry import Registry

_logger = logging.getLogger(__name__)

TOP_MODULE_PATH = "/odoo/local-src/custom_all"

FAKE_VERSION = f"{release.major_version}.9999.9.9"

ori_load_information_from_description_file = (
module.load_information_from_description_file
)


# As odoo only run migration script when the version change
# We patch odoo when loading the manifest to increment virtually the version when
# a "pending" migration script exist
# The version is always set to the number X.X.9999.9.9
# Note: odoo natively support to process the migration in the directory 0.0.0
# so we do not need to hack this part
def load_information_from_description_file(module_name, mod_path=None):
info = ori_load_information_from_description_file(module_name, mod_path=mod_path)
if not mod_path:
mod_path = module.get_module_path(module_name, downloaded=True)
if "local-src" in mod_path:
if os.path.exists(f"{mod_path}/migrations/0.0.0"):
files = os.listdir(f"{mod_path}/migrations/0.0.0")
if files != [".keep"]:
# If we have real file in 0.0.0
info["version"] = FAKE_VERSION
return info


module.load_information_from_description_file = load_information_from_description_file


# Process before-XXX.sql script in custom_all/migrations/{version}/


def add_sql_migration(todo, version):
path = f"{TOP_MODULE_PATH}/migrations/{version}"
for filename in os.listdir(path):
if filename.startswith("before") and filename[-4:] == ".sql":
file_path = f"{path}/{filename}"
todo.append((file_path, open(file_path).read()))


def get_before_request(cr):
cr.execute("SELECT latest_version FROM ir_module_module WHERE name='custom_all'")
todo = []
db_version = cr.fetchone()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add something like :
db_version = db_version and db_version[0] or False
Because the result of the sql query is None if custom_all does not exists in ir_module_module (which is fine)
But it is (None,) if it exists but is not installed. Which is evaluated as True and make the script to fail later.

Of course the line db_version = db_version[0] above should then be removed.
@sebastienbeau

if not db_version:
_logger.error("No version found for custom_all, skip begin script")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it misses a return todo here I guess... Because right now, the script is not skipped and will fail when comparing None to the version !

db_version = db_version[0]
migr_path = f"{TOP_MODULE_PATH}/migrations"
if os.path.exists(migr_path):
versions = os.listdir(migr_path)
versions.sort()
if versions and versions[0] == "0.0.0":
# always run pending version add the end
versions.append(versions.pop(0))
# Run all version that are superior to the db version
# And run version of 0.0.0 if FAKE_VERSION is not applied
for version in versions:
if version > db_version or version == "0.0.0" and FAKE_VERSION > db_version:
add_sql_migration(todo, version)
return todo


ori_new = Registry.new


@classmethod
def new(cls, db_name, force_demo=False, status=None, update_module=False):
conn = sql_db.db_connect(db_name)
with conn.cursor() as cr:
for file_path, requests in get_before_request(cr):
_logger.info(
"Execute before sql request \n=== %s \n%s===\n", file_path, requests
)
cr.execute(requests)
return ori_new(
db_name, force_demo=force_demo, status=status, update_module=update_module
)


Registry.new = new


# Call native click-odoo-update

if __name__ == "__main__": # pragma: no cover
main()
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ then
exit 0
fi
echo "START UPDATING USING CLICK ODOO"

{% if use_manual_bump %}
migrate --i18n-overwrite
{% else %}
click-odoo-update --i18n-overwrite
{% endif %}
70 changes: 70 additions & 0 deletions src/{% if use_manual_bump %}bump{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
# pylint: disable=print-used

import ast
import os
import subprocess
from datetime import datetime

import click

ODOO_VERSION = "14.0"


@click.command()
def main():
subprocess.run("git pull", shell=True, check=True)
version = datetime.now().strftime(f"{ODOO_VERSION}.%y%m.%d.0")
with open("odoo/local-src/custom_all/__manifest__.py") as f:
data = ast.literal_eval(f.read())
last_version = data["version"]

# increment last digit if needed
if last_version >= version:
odoo_version, zero, year_month, day, inc = last_version.split(".")
inc = str(int(inc) + 1)
version = ".".join([odoo_version, zero, year_month, day, inc])

# increment modules versions
for module_name in os.listdir("odoo/local-src"):
module_path = f"odoo/local-src/{module_name}"
manifest_path = f"{module_path}/__manifest__.py"
# Check if it's an odoo module
if os.path.exists(manifest_path):
update_version = False
# in case of pending migration script increment it
if os.path.exists(f"{module_path}/migrations/0.0.0"):
files = os.listdir(f"{module_path}/migrations/0.0.0")
if files != [".keep"]:
subprocess.run(
f"mkdir {module_path}/migrations/{version}",
shell=True,
check=True,
)
subprocess.run(
(
f"git mv {module_path}/migrations/0.0.0/* "
f"{module_path}/migrations/{version}"
),
shell=True,
check=True,
)
update_version = True
if update_version or module_name == "custom_all":
print(f"Update version of {module_name} to {version}")
with open(manifest_path) as f:
raw_data = f.read()
data = ast.literal_eval(raw_data)
with open(manifest_path, "w") as f:
raw_data = raw_data.replace(data["version"], version)
f.write(raw_data)
subprocess.run(f"git add {manifest_path}", shell=True, check=True)

subprocess.run(f"git commit -m'Bump version {version}'", shell=True, check=True)
subprocess.run(f"git tag {version}", shell=True, check=True)
subprocess.run("git push origin --tag", shell=True, check=True)
subprocess.run(f"git push origin {ODOO_VERSION}", shell=True, check=True)
Comment on lines +64 to +66
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
subprocess.run(f"git tag {version}", shell=True, check=True)
subprocess.run("git push origin --tag", shell=True, check=True)
subprocess.run(f"git push origin {ODOO_VERSION}", shell=True, check=True)
subprocess.run("git push origin", shell=True, check=True)
subprocess.run(f"glab ci trigger publish", shell=True, check=True)



if __name__ == "__main__":
main()