Commit ceaef5a3 authored by Rafael Monnerat's avatar Rafael Monnerat

erp5_payzen_secure_payment: Move Payzen to REST API

See merge request nexedi/erp5!1326
parents 36477a37 d6dcd5a4
Pipeline #13046 running with stage
...@@ -4,9 +4,11 @@ from Products.ERP5Type import Permissions, PropertySheet ...@@ -4,9 +4,11 @@ from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
import hashlib import hashlib
from zLOG import LOG, WARNING from zLOG import LOG, WARNING
import base64
import datetime import datetime
import os import os
import time import time
import requests
from Products.DCWorkflow.DCWorkflow import ValidationFailed from Products.DCWorkflow.DCWorkflow import ValidationFailed
present = False present = False
...@@ -16,250 +18,79 @@ if 'TZ' in os.environ: ...@@ -16,250 +18,79 @@ if 'TZ' in os.environ:
tz = os.environ['TZ'] tz = os.environ['TZ']
os.environ['TZ'] = 'UTC' os.environ['TZ'] = 'UTC'
time.tzset() time.tzset()
try: def setUTCTimeZone(fn):
import suds def wrapped(*args, **kwargs):
except ImportError: present = False
class PayzenSOAP: tz = None
pass if 'TZ' in os.environ:
else: present = True
def setUTCTimeZone(fn): tz = os.environ['TZ']
def wrapped(*args, **kwargs): os.environ['TZ'] = 'UTC'
present = False time.tzset()
tz = None try:
if 'TZ' in os.environ: return fn(*args, **kwargs)
present = True finally:
tz = os.environ['TZ'] if present:
os.environ['TZ'] = 'UTC' os.environ['TZ'] = tz
time.tzset()
try:
return fn(*args, **kwargs)
finally:
if present:
os.environ['TZ'] = tz
else:
del(os.environ['TZ'])
time.tzset()
return wrapped
class PayzenSOAP:
"""SOAP communication
Methods are returning list of:
* parsed response
* signature check (True or False)
* sent XML
* received XML
SOAP protocol is assumed as untrusted and dangerous, users of those methods
are encouraged to log such messages for future debugging."""
def _check_transactionInfoSignature(self, data):
"""Checks transactionInfo signature
Can raise.
"""
received_sorted_keys = ['errorCode', 'extendedErrorCode',
'transactionStatus', 'shopId', 'paymentMethod', 'contractNumber',
'orderId', 'orderInfo', 'orderInfo2', 'orderInfo3', 'transmissionDate',
'transactionId', 'sequenceNb', 'amount', 'initialAmount', 'devise',
'cvAmount', 'cvDevise', 'presentationDate', 'type', 'multiplePaiement',
'ctxMode', 'cardNumber', 'cardNetwork', 'cardType', 'cardCountry',
'cardExpirationDate', 'customerId', 'customerTitle', 'customerName',
'customerPhone', 'customerMail', 'customerAddress', 'customerZipCode',
'customerCity', 'customerCountry', 'customerLanguage', 'customerIP',
'transactionCondition', 'vadsEnrolled', 'vadsStatus', 'vadsECI',
'vadsXID', 'vadsCAVVAlgorithm', 'vadsCAVV', 'vadsSignatureValid',
'directoryServer', 'authMode', 'markAmount', 'markDevise', 'markDate',
'markNb', 'markResult', 'markCVV2_CVC2', 'authAmount', 'authDevise',
'authDate', 'authNb', 'authResult', 'authCVV2_CVC2', 'warrantlyResult',
'captureDate', 'captureNumber', 'rapprochementStatut', 'refoundAmount',
'refundDevise', 'litige', 'timestamp']
signature = self._getSignature(data, received_sorted_keys)
return signature == data.signature
@setUTCTimeZone
def soap_getInfo(self, transmissionDate, transactionId):
"""Returns getInfo as dict, booelan, string, string
transmissionDate is "raw" date in format YYYYMMDD, without any marks
transactionId is id of transaction for this date
As soon as communication happeneded does not raise.
"""
client = suds.client.Client(self.wsdl_link.getUrlString())
sorted_keys = ['shopId', 'transmissionDate', 'transactionId',
'sequenceNb', 'ctxMode']
kw = dict(
transactionId=transactionId,
ctxMode=self.getPayzenVadsCtxMode(),
shopId=self.getServiceUsername(),
sequenceNb=1,
transmissionDate=transmissionDate,
)
kw['wsSignature'] = self._getSignature(kw, sorted_keys)
data = client.service.getInfo(**kw)
# Note: Code shall not raise since now, as communication begin and caller
# will have to log sent/received messages.
try:
data_kw = dict(data)
for k in data_kw.keys():
v = data_kw[k]
if not isinstance(v, str):
data_kw[k] = str(v)
except Exception:
data_kw = {}
signature = False
LOG('PayzenService', WARNING,
'Issue during processing data_kw:', error=True)
else: else:
try: del(os.environ['TZ'])
signature = self._check_transactionInfoSignature(data) time.tzset()
except Exception: return wrapped
LOG('PayzenService', WARNING, 'Issue during signature calculation:',
error=True)
signature = False
try:
last_sent = str(client.last_sent())
except Exception:
LOG('PayzenService', WARNING,
'Issue during converting last_sent to string:', error=True)
signature = False
try:
last_received = str(client.last_received())
except Exception:
LOG('PayzenService', WARNING,
'Issue during converting last_received to string:', error=True)
signature = False
return [data_kw, signature, last_sent, last_received]
@setUTCTimeZone
def soap_duplicate(self, transmissionDate, transactionId, presentationDate,
newTransactionId, amount, devise, orderId='', orderInfo='', orderInfo2='',
orderInfo3='', validationMode=0, comment=''):
# prepare with passed parameters
kw = dict(transmissionDate=transmissionDate, transactionId=transactionId,
presentationDate=presentationDate, newTransactionId=newTransactionId,
amount=amount, devise=devise, orderId=orderId, orderInfo=orderInfo,
orderInfo2=orderInfo2, orderInfo3=orderInfo3,
validationMode=validationMode, comment=comment)
signature_sorted_key_list= ['shopId', 'transmissionDate', 'transactionId',
'sequenceNb', 'ctxMode', 'orderId', 'orderInfo', 'orderInfo2',
'orderInfo3', 'amount', 'devise', 'newTransactionId',
'presentationDate', 'validationMode', 'comment']
kw.update(
ctxMode=self.getPayzenVadsCtxMode(),
shopId=self.getServiceUsername(),
sequenceNb=1,
)
kw['wsSignature'] = self._getSignature(kw, signature_sorted_key_list)
# Note: Code shall not raise since now, as communication begin and caller
# will have to log sent/received messages.
client = suds.client.Client(self.wsdl_link.getUrlString())
data = client.service.duplicate(**kw)
# Note: Code shall not raise since now, as communication begin and caller
# will have to log sent/received messages.
try:
data_kw = dict(data)
for k in data_kw.keys():
v = data_kw[k]
if not isinstance(v, str):
data_kw[k] = str(v)
except Exception:
data_kw = {}
signature = False
LOG('PayzenService', WARNING,
'Issue during processing data_kw:', error=True)
else:
try:
signature = self._check_transactionInfoSignature(data)
except Exception:
LOG('PayzenService', WARNING, 'Issue during signature calculation:',
error=True)
signature = False
try:
last_sent = str(client.last_sent())
except Exception:
LOG('PayzenService', WARNING,
'Issue during converting last_sent to string:', error=True)
signature = False
try:
last_received = str(client.last_received())
except Exception:
LOG('PayzenService', WARNING,
'Issue during converting last_received to string:', error=True)
signature = False
return [data_kw, signature, last_sent, last_received]
@setUTCTimeZone
def soap_cancel(self, transmissionDate, transactionId, comment=''):
# prepare with passed parameters
kw = dict(transmissionDate=transmissionDate, transactionId=transactionId,
comment=comment)
signature_sorted_key_list= ['shopId', 'transmissionDate', 'transactionId',
'sequenceNb', 'ctxMode', 'comment']
kw.update(
ctxMode=self.getPayzenVadsCtxMode(),
shopId=self.getServiceUsername(),
sequenceNb=1,
)
kw['wsSignature'] = self._getSignature(kw, signature_sorted_key_list)
# Note: Code shall not raise since now, as communication begin and caller
# will have to log sent/received messages.
client = suds.client.Client(self.wsdl_link.getUrlString())
data = client.service.cancel(**kw)
# Note: Code shall not raise since now, as communication begin and caller
# will have to log sent/received messages.
try:
data_kw = dict(data)
for k in data_kw.keys():
v = data_kw[k]
if not isinstance(v, str):
data_kw[k] = str(v)
except Exception:
data_kw = {}
signature = False
LOG('PayzenService', WARNING,
'Issue during processing data_kw:', error=True)
else:
try:
signature = self._check_transactionInfoSignature(data)
except Exception:
LOG('PayzenService', WARNING, 'Issue during signature calculation:',
error=True)
signature = False
try: if present:
last_sent = str(client.last_sent()) os.environ['TZ'] = tz
except Exception: else:
LOG('PayzenService', WARNING, del(os.environ['TZ'])
'Issue during converting last_sent to string:', error=True) time.tzset()
signature = False
try: class PayzenREST:
last_received = str(client.last_received()) """REST communication
except Exception:
LOG('PayzenService', WARNING, Methods are returning list of:
'Issue during converting last_received to string:', error=True) * parsed response
signature = False * sent Data
* received Data
"""
def callPayzenApi(self, URL, payzen_dict):
base64string = base64.encodestring(
'%s:%s' % (
self.getServiceUsername(),
self.getServiceApiKey())).replace('\n', '')
header = {"Authorization": "Basic %s" % base64string}
LOG('callPayzenApi', WARNING,
"data = %s URL = %s" % (str(payzen_dict), URL), error=False)
# send data
result = requests.post(URL, data=payzen_dict, headers=header)
try:
data = result.json()
except Exception:
data = {}
LOG('PayzenService', WARNING,
'Issue during processing data_kw:', error=True)
return data, result.text
@setUTCTimeZone
def rest_getInfo(self, transmissionDate, transactionId):
"""Returns getInfo as dict, booelan, string, string
transmissionDate is "raw" date in format YYYYMMDD, without any marks
transactionId is id of transaction for this date
As soon as communication happeneded does not raise.
"""
URL = "https://api.payzen.eu/api-payment/V4/Order/Get"
kw = dict(
orderId=transactionId,
)
sent_data = str(kw)
data_kw, received_data = self.callPayzenApi(URL, kw)
return [data_kw, sent_data, received_data]
return [data_kw, signature, last_sent, last_received]
finally:
if present:
os.environ['TZ'] = tz
else:
del(os.environ['TZ'])
time.tzset()
from erp5.component.interface.IPaymentService import IPaymentService from erp5.component.interface.IPaymentService import IPaymentService
class PayzenService(XMLObject, PayzenSOAP): class PayzenService(XMLObject, PayzenREST):
meta_type = 'Payzen Service' meta_type = 'Payzen Service'
portal_type = 'Payzen Service' portal_type = 'Payzen Service'
......
...@@ -6,10 +6,22 @@ ...@@ -6,10 +6,22 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>PayzenService</string> </value> <value> <string>PayzenService</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>document.erp5.PayzenService</string> </value> <value> <string>document.erp5.PayzenService</string> </value>
...@@ -24,6 +36,24 @@ ...@@ -24,6 +36,24 @@
<none/> <none/>
</value> </value>
</item> </item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple>
<string>W: 24, 4: Redefining name \'tz\' from outer scope (line 15) (redefined-outer-name)</string>
<string>W: 23, 4: Redefining name \'present\' from outer scope (line 14) (redefined-outer-name)</string>
<string>W:190, 4: Unreachable code (unreachable)</string>
<string>W:195, 4: Unreachable code (unreachable)</string>
<string>W:200, 4: Unreachable code (unreachable)</string>
</tuple>
</value>
</item>
<item> <item>
<key> <string>version</string> </key> <key> <string>version</string> </key>
<value> <string>erp5</string> </value> <value> <string>erp5</string> </value>
...@@ -31,13 +61,28 @@ ...@@ -31,13 +61,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -50,7 +95,7 @@ ...@@ -50,7 +95,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -59,7 +104,7 @@ ...@@ -59,7 +104,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
...@@ -74,33 +119,6 @@ ...@@ -74,33 +119,6 @@
<key> <string>action</string> </key> <key> <string>action</string> </key>
<value> <string>validate</string> </value> <value> <string>validate</string> </value>
</item> </item>
<item>
<key> <string>actor</string> </key>
<value> <string>ERP5TypeTestCase</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1377844605.75</float>
<string>GMT+9</string>
</tuple>
</state>
</object>
</value>
</item>
<item> <item>
<key> <string>validation_state</string> </key> <key> <string>validation_state</string> </key>
<value> <string>validated</string> </value> <value> <string>validated</string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>service_api_key_property</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>read_permission</string> </key>
<value> <string>Manage portal</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
<list> <list>
<string>my_link_url_string</string> <string>my_link_url_string</string>
<string>my_service_username</string> <string>my_service_username</string>
<string>my_service_api_key</string>
<string>my_service_password</string> <string>my_service_password</string>
<string>my_payzen_vads_ctx_mode</string> <string>my_payzen_vads_ctx_mode</string>
<string>my_payzen_vads_version</string> <string>my_payzen_vads_version</string>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="StringField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_service_api_key</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>too_long</string> </key>
<value> <string>Too much input was given.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_maxwidth</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_width</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>input_type</string> </key>
<value> <string>text</string> </value>
</item>
<item>
<key> <string>max_length</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Password</string> </value>
</item>
<item>
<key> <string>truncate</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -227,6 +227,10 @@ ...@@ -227,6 +227,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string>text</string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -237,7 +241,7 @@ ...@@ -237,7 +241,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Certificate</string> </value> <value> <string>Key</string> </value>
</item> </item>
<item> <item>
<key> <string>truncate</string> </key> <key> <string>truncate</string> </key>
......
...@@ -227,6 +227,10 @@ ...@@ -227,6 +227,10 @@
<key> <string>hidden</string> </key> <key> <string>hidden</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>input_type</string> </key>
<value> <string>text</string> </value>
</item>
<item> <item>
<key> <string>max_length</string> </key> <key> <string>max_length</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
...@@ -237,7 +241,7 @@ ...@@ -237,7 +241,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>VADS Site ID</string> </value> <value> <string>User</string> </value>
</item> </item>
<item> <item>
<key> <string>truncate</string> </key> <key> <string>truncate</string> </key>
......
  • @rafael @tomo I think this erp5-vifib branch was rebased. Tests on 1.0 now fail with

    2021-01-21 23:21:14 slapos[16081] INFO fatal: Could not parse object 'ceaef5a3c5469a04f5650376cda54cb162abf38a'.

    wouldn't it be easier to use a dedicated private repository for the vifib fork ?

  • wouldn't it be easier to use a dedicated private repository for the vifib fork ?

    one day, we will merge our changes to master :)

    Anyway, as soon as we do rebase instead of merge, we can lose our commits at any time so it means we must tag all the commits that appear in slapos 1.0 branch to be sure to never lose them due to garbage collector.

  • Thanks, yes, hopefully these changes will be merged :)

    Note that it does not have to be a tag, it can also be a branch. Also branches can be a folder, so we can use vifib/something. Not sure it's better, it's just possible.

    FYI, this commit will not be garbage collected because there is discussion on it. What gitlab uses is another namespace, branches are in refs/heads/* and in git config we have by default:

    [remote "origin"]
      url = https://lab.nexedi.com/nexedi/erp5.git
      fetch = +refs/heads/*:refs/remotes/origin/*

    gitlab uses refs/keep-around to "keep around" (prevent garbage collection) of commits, so if you change git config to :

    [remote "origin"]
      url = https://lab.nexedi.com/nexedi/erp5.git
      fetch = +refs/heads/*:refs/remotes/origin/*
      fetch = +refs/keep-around/*:refs/remotes/keep-around/*

    and git fetch again, you can get this commit locally. Then you can push it again in a new branch and this repairs the failing build.

    There's this Could not parse object error, because the commit is not fetched by default, because git only fetches branches (refs/heads) and tags (refs/tags), it's still there somewhere in refs/keep-around, which is not fetched by default.

  • Oups, I didn't see your comment :( it would have been much easier for me...

    So I went to git clone --mirror in order to retrieve everything and then I tagged from there. I used erp5-vifib-20201229 tag name.

  • it was my mistake to not push a tag along with the rebase, sorry on this and thanks to @tomo for fix.

Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment